Authorization
Authorization is the process of checking whether an authenticated user has the correct permissions to perform an action. It is handled by Pundit, and based around a concept called policies.
Policies
Authorization is handled by simple, pure OO classes called policies. Policies are usually (but not always) linked to some model for which we wish to authorize the actions of.
Policies achieve authorization through the use of simple instance methods within the policy class. Read this section of the Pundit readme for more information.
CLI tasks
Headless policies
As mentioned earlier, policies don't always have to be linked to a model. A policy of this kind is referred to as a headless policy.
A typical example of this would be a policy for authorizing general actions on a site, such as whether a certain type of user can access a part of the site. Since there is no model for the site itself, we use a headless policy.
A headless policy file is characterized by the class inheriting from a struct, like:
Non-headless policies
A typical policy is non-headless (associated with a model). For example, a Product
model, which has permissions such as adding, editing and deleting a product.
The policy file looks similar to that of a headless policy file, but with no inheritance from a struct:
Models and tables
After setting up authorization, a Role
model will have been created along with a roles
table.
The purpose of the roles
table is to specify the roles that a user has for each policy.
The roles
table is a weak entity, with a one-to-one dependency on the users
table. This means that every record in the roles
table should be associated with a record in the users
table. Additionally, whenever a user is deleted, the corresponding record in the roles
will also be deleted.
An after_create
callback is added to the User
model after the authorization setup. This callback automatically creates a new record in the roles
table when a new user is added to the users
table.
Policy roles table
Each generated policy also comes with an associated policy roles table. For example, eucalypt security policy g post -p create edit delete
would generate a post_policy.rb
file, and a post_roles
table (with create, edit and delete permissions).
The columns in this table represent the different roles for the policy. For example, a post might have author and editor roles (as well as an admin and default role, which every policy has by default).
The rows in this table represent the different permissions that each role can have.
The post_roles
table might look like:
Admin | Default | Author | Editor | |
Create |
|
|
|
|
Edit |
|
|
|
|
Delete |
|
|
|
|
CLI tasks
Authorization helper
During authorization setup, two helper methods were defined to help with authorization.
The
authorized?
method is defined as a boolean method that specifies whether or not the currently authenticated user is authorized to perform an action on a certain policy.The
authorized?
method takes two arguments:The model object (or class) to check authorization for.
If using a headless policy, this can also be a symbol.
The permission to check for. This is a symbol, and must end with a question mark
?
.The permission must be one of the permissions defined in the associated policy roles table. e.g.
:add?
,edit?
,delete?
The method returns false if there is no currently authenticated user, or if the authenticated user is not authorized to perform the specified action. The method returns true if the currently authenticated user is authorized to perform the specified action.
For example:
The
authorized?
method can be used in controllers and views (for conditional displays).The
authorize
method (which comes as part of the Pundit gem) permits an action to be performed if done by an authorized user.If the user is not authorized, then a
Pundit::NotAuthorizedError
is raised. This error can be handled however you like.This is typically placed somewhere in a route handler (as seen in this example):
Last updated