Update:Remora Permissions
Backdrop
We tried to use db_acl, but the implementation meant too much overhead for our relatively simple requirements. Mainly we wanted to lock down access by group/role. We opted to go with the 33 lines of magic approach which is simpler by design and was shaver's first preferred choice. Read the blog to see why it can get the job done even if it isn't completely normalized and abstracted.
Permissions
There are two ways to grant permissions:
- group
- user
These permissions can be used together. The resulting permissions will be the union of these.
Formatting permissions is a matter of entering Controller:action permissions in a comma delimited list in either User.rules or Group.rules. Examples would be:
// Grants access to all Users and Groups controller actions. Users:*,Groups:* // Grants access to all possible controllers and actions. *:* // Grants access to only Editor actions. Reviewers:* // Grants access to only review adding. Reviews:add
Our implementation deviates from the 33 lines of magic approach in two ways:
- aclException checks
- user->group map is a many-to-many relationship using a map table instead of a simple group_id injected into the users table
Using Permissions in Controllers
Since ACLs are turned on from app_controller you pick up permissions for free based on Controller:action. For example, if you're in the Images controller and you're adding an image with the add() action, SimpleAcl will just check group and user permissions for Images:add automatically and deny the user access if it fails.
There is a way to do a manual check using the SimpleAcl component. If you're wanting to use it for display logic or some other use that requires and explicit check, you may need to use this method:
// Check to see if the user has access to the entire Reviewers controller. if ($this->SimpleAcl->actionAllowed('Reviewers','*')) { // Do something }
Normally this would be done in an action. I was not able to use this in a beforeFilter, because that would access member variables and functions not yet loaded.
I was able to use this even when I was in an action that was in the aclExceptions array.
I was not able to use this when ->enabled=false for SimpleAcl and SimpleAuth. It seems that disabling the components render them useless. So that means that for all-public controllers, if you want to access permission data you'll have to use aclExceptions instead of using the beforeFilter method of turning off permissions. If you don't, you'll get false for all inquiries because the components are disabled.
Disabling Permissions in Controllers
SimpleAcl and SimpleAuth are instantiated in the app_controller, which means they are loaded for all controllers by default. This means:
- New controller actions will be locked down by default
- You have to enable them by one of two ways...
Add the desired action to aclExeption in your controller:
// Lets the world (even non-logged in users) access view and edit. var $aclException = array('view','edit');
Disable ACL checking for the entire controller:
// Disables all ACL checking for the entire controller. function beforeFilter { $this->SimpleAuth->enabled=false; $this->SimpleAcl->enabled=false; }
Note that when you disable ACLs using this method, you may not manually check permissions because this method essentially disables the components.
ACL Concerns and Feedback
- We have overlap between ACL and the user login and user ownership checks. Do we want to consolidate or just keep things the way they are? What would we gain from the better consistency?
- If a user is editing their personal profile is it possible for them to forge a form and edit their own rules field even if they shouldn't have the permissions to do it?
Controller Notepad
Controllers, actions and their permissions.
- addons_controller -- all public -- used enabled=false
- display
- browse
- home
- browse
- recommended
- policy
- previews
- versions
- rss
- developers_controller -- all private (Users) -- used enabled=false, checking defaults to existing login/ownership check
- index
- summary
- details
- add
- edit
- editVersion
- nominate
- authorLookup
- downloads_controller -- all public -- used enabled=false
- file
- editors_controller -- all private (Editors) -- added Editors:* to Editors group permissions
- index
- queue
- review
- file
- favorites_controller -- (empty)
- features_controller -- (empty)
- files_controller -- all public used enabled=false
- groups_controller -- all private (Admins) -- added by *:* for admins
- index
- add
- edit
- delete
- images_controller -- all public -- used enabled=false
- setImage ...should not be an action?
- addon_icon
- addon_preview
- application_icon
- platform_icon
- preview_thumb
- preview
- legacy_url_controller -- all public -- used enabled=false
- addonId
- authorId
- pages_controller -- all public -- used enabled=false
- display
- previews_controller -- all private (Users) -- defer to login check and ownership check, enalbed=false
- add
- edit
- reviews_controller -- used enabled=false
- display -- public
- add -- Users only
- search_controller -- all public -- used enabled=false
- index
- rss
- users_controller -- used enabled=false
- index
- register
- verify
- pwreset
- login
- logout
- edit -- Users only
- info