Permissions in PHP webapps without headaches?
March 6, 2006 3:03 PM Subscribe
Best practices for managing massive permission systems for a giant home-brewed PHP CMS?
I'm in a job that has a web CMS with a frontend and backend that has grown up over the years. User permissions are currently done with a mostly randomly assigned number on a one-to-one with username that relates back to a set of permissions.
I'd like to move to something that's a lot more customizeable, and doesn't force us to grant such large swaths of permissions.
However, there's literally going to be 400 permissions for the site due to the need to extensively silo content. Is there an easier way to set things up? What best practices have been found in other situations for applications this large, and has anything been written about retrofitting this kind of functionality into an existing large application?
I'm in a job that has a web CMS with a frontend and backend that has grown up over the years. User permissions are currently done with a mostly randomly assigned number on a one-to-one with username that relates back to a set of permissions.
I'd like to move to something that's a lot more customizeable, and doesn't force us to grant such large swaths of permissions.
However, there's literally going to be 400 permissions for the site due to the need to extensively silo content. Is there an easier way to set things up? What best practices have been found in other situations for applications this large, and has anything been written about retrofitting this kind of functionality into an existing large application?
Can the permissions be grouped together at all, either by type or by topic. That's the way I would go.
posted by cillit bang at 3:33 PM on March 6, 2006
posted by cillit bang at 3:33 PM on March 6, 2006
PHP Generic Access Control Lists is a pretty good, flexible framework for setting up permissions systems.
It's a pretty complete ACL implementation that uses an SQL database (it supports a table prefix so you can use it in an existing db) to store permission data, so if either of those attributes sound like over-engineering you may want to look elsewhere.
It works pretty much like you'd suspect. Users can be assigned to an arbitrary number of groups, groups can be nested, permissions can be assigned to users or groups, and are applied in less-specific to most-specific, DENY trumps ALLOW order. Basically, if you've used Windows NTFS permissions, you should feel right at home.
posted by boaz at 4:37 PM on March 6, 2006
It's a pretty complete ACL implementation that uses an SQL database (it supports a table prefix so you can use it in an existing db) to store permission data, so if either of those attributes sound like over-engineering you may want to look elsewhere.
It works pretty much like you'd suspect. Users can be assigned to an arbitrary number of groups, groups can be nested, permissions can be assigned to users or groups, and are applied in less-specific to most-specific, DENY trumps ALLOW order. Basically, if you've used Windows NTFS permissions, you should feel right at home.
posted by boaz at 4:37 PM on March 6, 2006
Movable Type (perl, not php, but database-backed CMS nonetheless and similar enough) uses the bitwise permissions system (cf. BSummers above). Here's a link that introduces the idea.
posted by evariste at 4:50 PM on March 6, 2006
posted by evariste at 4:50 PM on March 6, 2006
Here's what it looks like in the database:
This is a system with 4 blogs and one user. If you had multiple users, you would just throw more rows into your version of the mt_permission table. The permission_role_mask field contains the decimal representation of that user's permissions on that blog. Retool as necessary for your homebrew CMS.
posted by evariste at 4:57 PM on March 6, 2006
mysql> describe mt_permission;
+------------------------+--------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+------------------------+--------------+------+-----+---------+----------------+
| permission_id | int(11) | | PRI | NULL | auto_increment |
| permission_author_id | int(11) | | | 0 | |
| permission_blog_id | int(11) | | MUL | 0 | |
| permission_role_mask | smallint(6) | YES | | NULL | |
| permission_entry_prefs | varchar(255) | YES | | NULL | |
+------------------------+--------------+------+-----+---------+----------------+
5 rows in set (0.05 sec)
mysql> select * from mt_permission;
+---------------+----------------------+--------------------+----------------------+--------------------------------------------------------------------------+
| permission_id | permission_author_id | permission_blog_id | permission_role_mask | permission_entry_prefs |
+---------------+----------------------+--------------------+----------------------+--------------------------------------------------------------------------+
| 2 | 1 | 2 | 2046 | category,extended,excerpt,allow_comments,convert_breaks,authored_on|Both |
| 3 | 1 | 3 | 2046 | Advanced|Both |
| 4 | 1 | 4 | 2047 | NULL |
| 5 | 1 | 5 | 2047 | NULL |
+---------------+----------------------+--------------------+----------------------+--------------------------------------------------------------------------+
This is a system with 4 blogs and one user. If you had multiple users, you would just throw more rows into your version of the mt_permission table. The permission_role_mask field contains the decimal representation of that user's permissions on that blog. Retool as necessary for your homebrew CMS.
posted by evariste at 4:57 PM on March 6, 2006
Uh, 1:1 is baaaad. BSummers' method is what we do at work (financial services co.), sans the bitwise-route (an extra JOIN to a code table isn't a really big deal, transactionally).
posted by Civil_Disobedient at 8:01 PM on March 6, 2006
posted by Civil_Disobedient at 8:01 PM on March 6, 2006
This thread is closed to new comments.
posted by BSummers at 3:23 PM on March 6, 2006