[geeklog-devel] Geeklog2 -- ACLs

Vincent Furia vmf at abtech.org
Tue Jun 17 10:27:39 EDT 2003


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