GL2 ACLs

Tuesday, June 24 2003 @ 04:51 PM EDT

Contributed by: vinny

Last week I posted a variation to the below document to the geeklog-devel mailing list. After collecting some feedback, I have posted it here for several reasons. First, to garner additional input on ways to improve and or expand the described system. Second, I hope the fact that implementation of GL2 has begun will help Tony in his efforts to recruit developers and documentors to the Geeklog 2 project.

It should be noted that the ACL system described here is only responsible for controlling access to items (such as articles, polls, links, etc) and does not include user authentication or group membership which will be handled by Tony's A&A portion of Geeklog 2.

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 have chosen to use the following the access rights, each right represented by one bit in a bit field.

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 bit wise 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 access 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 useful to about 10% (or less) of the users of Geeklog. However, for those users, this finer level of control could be very useful. 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 powerful 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 manageable 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 usefulness 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

Any feed back concerning this implementation of an ACL system would be welcome as would alternative suggestions. Even simple 'yea or nay' type feedback would be helpful.

Note: I had hoped to find a decent, generic description of what ACLs are to help people unfamiliar . My googling only came up with links to Cisco, Linux and AFS implementations (and one php implementation) of ACLs. If someone can find a link to a more generic description and post it as a comment, 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 example');
INSERT INTO items (item, data) VALUES ('two', 'this is just another example');
INSERT INTO items (item, data) VALUES ('three', 'this is just one more example');

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----

Comments (0)


Geeklog
http://www.geeklog.net/article.php/20030624165124211