User:LeoJY/sandbox

= Introduction = CanCan is an authorization library for Ruby on Rails which gives restrictions on both the resources and different actions to a given user to access within each resource. All the restrictions are specified in the same "ability.rb" files ( folder "models" ) and do not need to be copied across different controllers, views and database queries.

"Cancan" gem is no longer maintained and updated any more. "Cancancan" gem is the authorization library for Ruby on Rails which is under maintenance.

= Installation =

Install in Rails 3
In Rails 3, it is easy to implement by including the following code into the Gemfile and then running the "bundle install" command in the terminal.

Install in Rails 2
In Rails 2, simply add the code to the "environment.rb" file.

Install as a Plugin
As a substitute, it can be installed as a plugin.

= Basic Operations = In "ability.rb" file ("Ability" class), user access permissions are defined.

Create "Ability" Class
CanCan 1.5 and latter versions include a Rails 3 generator for creating this class in the "models" folder. "Ability" class is created by run the following command in the terminal. There will be a file called "ability.rb" created in the path of "app/models/ability.rb", in which we can define all the permissions. The initialized "Ability" class is  The current user is passed to the method in the initialization method. Any of the user attributes can be used to define and modify the permissions of the user. No assumption are made by CanCan about how roles are handled in your application.

Permission Define Structure
In the "Ability" class, usually we use conditional statement like "if...else..." to define all the permissions.

For example, here we have the user.admin and normal user types for the project and different permissions for them are defined separately in the conditional statement.

Define Abilities & Authorization
The current user's permissions can be defined using the "can" and "cannot" methods.

"can" method
The "can" method is used to define permissions, which requires two arguments. The first argument is the action you're setting the permission for, the second one is the class of object you're setting it on.

For example, here we define the current user can edit the article. Common actions include ":read", ":create", ":update" and ":destroy", but it can be anything.

You can also pass an array for either of these parameters to match any one.

For example, here the user will have the ability to read or update both questions and answers. A hash of conditions can be passed to give further restricts which records this permission applies to.

For example, here the user will only have permission to update project which is active and belongs to the user.

"cannot" method
The "cannot" method takes the same arguments as "can" method and defines the actions the user is not allowed to access. This is normally done after a more generic "can" call, like ":manage".

For example, here the current user will have the ability to do everything except destroy the project.

Check Abilities & Authorization
After defining abilities, you can use the "can?" and "cannot?" methods in the controller or view to check the user's permission for a given action and object.

For example, here we check whether the current user can or cannot destroy the project using the "can?" and "cannot?" methods. or either the "can?" or "cannot?" methods. Note: If a block or hash of conditions exist in the definition of the abilities, they will be ignored when checking on a class.

For example, here we define a user can update the project when the project is active, however when we check whether the user can update project, it will always return "true".

=== Applications of Abilities & Authorization === Using the conditional statements, we can check the permissions using "can?" and "cannot?" method.

For example, here we check whether the current user have the permission to update the article or not. If true, then we show the link "Edit" to the edit path.

Force Authorization Check
Although as we can use "can?" and "cannot?" method to check authorization and decide whether to show the link to action in the webpage, the actual page of the action in the webpage exists, we may manually input the URL such as "../projects/(projects id)/edit" in the web browser to avoid the Authorization Check and gain the access to edit the project.

To solve this problem, you should always remember to go to the specific action you want to authorize and force authorization check.

For example, here we force the authorization check in the show action to make sure every time the show action need to go through a check. If the user have no permission to edit the project, even if he enter the URL as "../projects/(projects id)/edit" in the web browser, the user will have to go through the authorization check and have the result as permission denied.

=== Handle Unauthorized Access === A CanCan::AccessDenied exception will be raised if the user authorization fails. You can catch this exception and modify its behavior in the controller.

For example, here we redirect the webpage to the "projects_url" and show the authorization fails message.

= Exception: Cancan::Error =

CanCan::AccessDenied
This error occurs when a user isn't allowed to access a given controller action. This usually happens within a call to ControllerAdditions#authorize!. This exception can also be raised manually if more custom behavior is needed.

CanCan::AuthorizationNotPerformed
This error occurs when users use check_authorization without calling authorized!

CanCan::ImplementationRemoved
This error is raised when removed code is called, an alternative solution is provided in message.

CanCan::NotImplemented
This error is raised when the behavior is not implemented, usually used in an abstract class.

= Version History = The following table is based on information from rubygems.org.

=References=