Simple, declarative, role-based access
control system for Rails and Ruby
Add this line to your application's Gemfile:
Or install the gem directly via:
SimonSays consists of two parts. One is a model concern called Roleable. The other is a controller concern called Authorizer. The idea is that you give users some set of roles and find and authorize resources against those roles on a controller (and action) basis.
First, we need to define some roles. Generally speaking roles will exist on either "User" models or on relationship models (like a through model linking a User to another resource).
Here's a quick example:
User can now have zero or more roles:
Roles are stored as an integer and bitmasking is used to determine authorization logic. When using Roleable you need to add a roles_mask column. Note that we do not have any generators for this yet. Feel free to fork and add them!
You can customize the role attribute using the :as option. For example:
Roleablewill expect there to be a access_mask column and attribute.
You can also use Roleable on through models. For example:
Calling has_roles will dynamically generate several methods as well as a dynamically named scope. Be sure to also checkout the docs for more details!
Next up is the Authorizer. This concern provides several methods that can be used within your controllers to declaratively find resources and ensure certain role-based conditions are met.
Please note, certain assumptions are made with Authorizer. Building upon the above User and Admin models, Authorizer would assume there is a current_user and current_admin method. If these models correspond to devise scopes this would be the case by default. Additionally there would need to be an authenticate_user! and authenticate_admin! method, which devise provides as well.
Eventually, we would like to see better customization around the authentication aspects. This library is intended to solve the problem of authorization and access control. It is not an authentication library.
The first step is to include the concern within the ApplicationController and to configure the default authorization scope (which is used with the through option):
Let's start with an example; here we'll create a reports resource that only Admin's with support access to use. The roles are supplied within the authorize_resource method. Note that, multiple roles can be supplied; access is granted if one or more are met.
Using the :from option here is also important. This is done so the find_resource call to load the @report resource is properly scoped to the current_admin. When this option is not used, the resource's class is used directly with a where call.
Here's another example using the Membership through model and multiple calls to find_and_authorize to setup various role-based requirements.
Note that we do not need to use the :from option here since, when using the :through option, the default_authorization_scope is used. If the default_authorization_scope is not what the through option is for, then the from option should be used instead.
The document model will not be found if the membership relationship does not exist and an ActiveRecord::NotFound exception will be raised.
If the membership record exists, but the role conditions are not met, Authorizer will raise a Denied exception.
If the document is found and the user has the access to it. It will be set as the @document instance variable. Be sure to checkout the docs for more details!
Get a website like this for your open source project for free!
- Fork it
- Create your new feature branch
- Commit your changes
- Push changes to the branch
- Create a new and submit a new Pull Request!
- Add Rails generators to make installation and customization even easier
- Expand the model API via the Roleable concern
- Authentication customization and more complex user logic