[geeklog-devel] ACL follow-up

Tony Bibbs tony at tonybibbs.com
Fri Jun 20 15:20:05 EDT 2003


Vinny, I think I'm right on with you on the ACL system.  However, one 
point of disagreement is that notion you support that EDIT + ADMIN = 
OWNER.  That isn't true, we should track the creator of the item as the 
owner. Ok, wait, now that I actually read the SQL you gave, you do have 
a uid field so I have to assume you are tracking it as I suggested. 
Never mind ;-)

Now, to adequately address the real possibility of having multiple ACL's 
let me give a high level objet model:

ACL_Factory: Class that creates ACL libraries on the fly.  The specific 
ACL system to use is determined by a config.php setting.  All this 
object does is instantiate the right ACL system and returns it.

BaseACL: Abstract class (not instantiated directly) that all ACL systems 
inherit from.  The methods here would be similar to the ones found in GL 
1.3.x's lib-security.php (i.e. getUserGroups, inGroup, hasAccess, 
getUserPermissions, etc).

Default_ACL: This extends BaseACL by implementing the system that Vinny 
is talking about.

For those who care, using the factory design pattern now lets you 
implement any ACL system  All it has to do is inherit from BaseACL.  The 
data model vinny is proposing seems to me to be generic enough to handle 
any ACL system.  Only thing I am fuzzy on is how you plan on tying 
people to groups and groups to groups?  The same way as 1.3.x does?

--Tony


Vinny's Original Post
-------------------------

Date: Tue, 17 Jun 2003 10:27:39 -0400
From: Vincent Furia <vmf at abtech.org>
To: geeklog-devel at lists.geeklog.net
Subject: [geeklog-devel] Geeklog2 -- ACLs
Reply-To: geeklog-devel at lists.geeklog.net

THE SYSTEM

For Geeklog2, I propose expanding the existing unix-like item permission
system into a full fledged ACL system.  The sql below (created for
MySQL) describes two tables and some data used to demonstrate some
sample queries.  The data loaded below includes three 'items' (which, in
the context of geeklog, could be articles, polls, links, etc).  It also
contains two users: 1, 2 and two groups: 1, 2.  A couple of important
things to note about these tables.  First, no permissions data is kept
within the items table.  Second, 'item' is a foreign key within the acl
table that links to 'item' in the items table.

I've choosen to use the following the access rights, each right
represented by one bit in a bit field.
List - 1:  The user has permission to list this item.
Read - 2:  The user has permission to read or view this item.
Write - 4:  The user has permission to append or edit this item.
Delete - 8:  The user has permission to delete or remove this item.
Admin - 16:  The user has permission to controll access to this item.

These rights are just an initial idea of the rights usually associated
with ACLs.  Of course these rights should be edited and/or added to.

To make the manipulation of the rights easier, we can assign a php
constant to each access level.  These constants then can be bitwise
And'd (&) or Or'd (|) to produce complex set of permissions.  Below I
will refer to these constants as LIST, READ, WRITE, DELETE, ADMIN.  I
will also define the composite acess levels:  LOOK as (LIST & READ);
EDIT as (LOOK & WRITE & DELETE); OWNER as (EDIT & ADMIN).

HOW IT WILL WORK

In the code:
Implementing look-ups using this system is pretty straight forward.  For
instance, to list all the items that a user has LOOK access to, I'd use
the following query:
SELECT items.* FROM acl, items WHERE items.item = acl.item AND ((acl.uid
= <userid> OR acl.gid IN (<user_group_membership>)) AND (acl.access &
LOOK)) GROUP BY items.item;

To get all the access rights a user has for an item, use this:
SELECT BIT_OR(acl.access), items.item FROM acl, items WHERE items.item =
acl.item AND items.item = <item> AND (acl.uid = <userid> OR acl.gid IN
(<user_group_membership)) GROUP BY items.item.

This code may seem complex but consider that, like in 1.3.x (though not
fully utilized there), much of the SQL involved in fetching permissions
can be generated by functions.

In the GUI:
Initially the GUI for access/permission to items can stay exactly the
same as it is currently in 1.3.x.  It should be clear that by having
four (4) rows in the acl table for each item (one each for anonymous,
members, group, and owner) we can perfectly simulate the current unix
like access that 1.3.x provides.

In the long run, we can expand the capabilities of Geeklog through
modifications to the GUI.  These additions can be as simple or as
complex as needed for a given task, and is only really limited by our
imagination and ingenuity.

WHY?

Finer control.  As Tony pointed out in IRC, the finer control would only
be usefull to about 10% (or less) of the users of geeklog.  However, for
those users, this finer level of control could be very usefull.   We can
potentially leverage ACLs to give GL2 real potential in the corporate
CMS market place.

<management BS>
Geeklog has, since its inception, been a leader in security among peer
software.  Geeklog's access control system in particular is the most
powerfull of any competing software [that I know of].  To maintain this
dominance and the advantages of the reputation that goes with it, I
think it is necessary to expand beyond the status quo and set a new bar
for security.  I believe ACLs can get us there.
</management BS>

Finally, the 'coolness' factor.  ACLs will be fun to implement and
provide a set of managable challenges that will keep us developers
interested (well, certainly myself).  Also we'll really be taking
advantage of the power that relational databases provide.

FUTURE EXPANSION

What I have described above (and below in the SQL) is a fairly basic
implementation of ACLs.  To have a more complex implementation, and
hence finer control over access to items, it would be possible to add a
"negative rights table".  This table would be used, once access rights
for a user (and the groups he is a member of) is determined to
afterwards limit that users access based on his user id and group
memberships.  One example of usefullness for this is if you have a group
you want to grant access to item A, but there is a member of that group
(user 1) that you don't want to have the same access.  You could reduce
that users access by adding the user and the access you wish to restrict
to the "negative rights table".

The complexity of implementing this, in addition to the basic ACL tasks
described above makes me hesitant to make this part of the initial
requirements/release of GL2.  However, adding it in the future would be
possible without side effects to the permissions (ACLs) on items that
would be established prior to the negative rights implementation and
release.

CONCLUSION

I encourage feed-back.  Even simply 'yea, nay' type feedback would be
helpfull.  But suggestions to improve or refine this schema for access
control would be especially welcome.  I hope, within the next week, to
take this post (appended with any responses) and post to geeklog.net
under the Geeklog2 topic.  So please take a few minutes in the next
couple days (the sooner the better) to grok and respond.

Thanks,
Vinny

P.S.  I looked around the web for a decent, generic description of what
an ACL does.  My googling only came up with links to cisco, linux and
afs implementations (and one php implementation) of ACLs.  If someone
can find a generic link and post it, I'd be appreciative.

----BEGIN FILE ACL.SQL----

CREATE TABLE acl (
     id mediumint(8) AUTO_INCREMENT PRIMARY KEY,
     item varchar(20) NOT NULL,
     uid mediumint(8),
     gid mediumint(8),
     access smallint(8) NOT NULL DEFAULT 0,
     INDEX item_idx (item),
     INDEX uid_idx (uid),
     INDEX gui_idx (gid)
);

CREATE TABLE items (
     id mediumint(8) AUTO_INCREMENT PRIMARY KEY,
     item varchar(20) UNIQUE NOT NULL,
     data text
);

INSERT INTO items (item, data) VALUES ('one', 'this is just an exmple');
INSERT INTO items (item, data) VALUES ('two', 'this is just another
exmple');
INSERT INTO items (item, data) VALUES ('three', 'this is just one more
exmple');


INSERT INTO acl (item, uid, access) VALUES ('one', 1, 15);
INSERT INTO acl (item, uid, access) VALUES ('two', 1, 15);
INSERT INTO acl (item, uid, access) VALUES ('one', 2, 15);
INSERT INTO acl (item, uid, access) VALUES ('three', 3, 15);
INSERT INTO acl (item, gid, access) VALUES ('one', 1, 5);
INSERT INTO acl (item, gid, access) VALUES ('two', 1, 5);
INSERT INTO acl (item, gid, access) VALUES ('three', 1, 5);
INSERT INTO acl (item, gid, access) VALUES ('two', 2, 1);

----END FILE ACL.SQL----




More information about the geeklog-devel mailing list