112 lines
4.8 KiB
Plaintext
112 lines
4.8 KiB
Plaintext
= CanCan
|
|
|
|
Wiki[https://github.com/ryanb/cancan/wiki] | RDocs[http://rdoc.info/projects/ryanb/cancan] | Screencast[http://railscasts.com/episodes/192-authorization-with-cancan]
|
|
|
|
CanCan is an authorization library for Ruby on Rails which restricts what resources a given user is allowed to access. All permissions are defined in a single location (the +Ability+ class) and not duplicated across controllers, views, and database queries.
|
|
|
|
|
|
== Installation
|
|
|
|
In <b>Rails 3</b>, add this to your Gemfile and run the +bundle+ command.
|
|
|
|
gem "cancan"
|
|
|
|
In <b>Rails 2</b>, add this to your environment.rb file.
|
|
|
|
config.gem "cancan"
|
|
|
|
Alternatively, you can install it as a plugin.
|
|
|
|
rails plugin install git://github.com/ryanb/cancan.git
|
|
|
|
|
|
== Getting Started
|
|
|
|
CanCan expects a +current_user+ method to exist in the controller. First, set up some authentication (such as Authlogic[https://github.com/binarylogic/authlogic] or Devise[https://github.com/plataformatec/devise]). See {Changing Defaults}[https://github.com/ryanb/cancan/wiki/changing-defaults] if you need different behavior.
|
|
|
|
|
|
=== 1. Define Abilities
|
|
|
|
User permissions are defined in an +Ability+ class. CanCan 1.5 includes a Rails 3 generator for creating this class.
|
|
|
|
rails g cancan:ability
|
|
|
|
See {Defining Abilities}[https://github.com/ryanb/cancan/wiki/defining-abilities] for details.
|
|
|
|
|
|
=== 2. Check Abilities & Authorization
|
|
|
|
The current user's permissions can then be checked using the <tt>can?</tt> and <tt>cannot?</tt> methods in the view and controller.
|
|
|
|
<% if can? :update, @article %>
|
|
<%= link_to "Edit", edit_article_path(@article) %>
|
|
<% end %>
|
|
|
|
See {Checking Abilities}[https://github.com/ryanb/cancan/wiki/checking-abilities] for more information
|
|
|
|
The <tt>authorize!</tt> method in the controller will raise an exception if the user is not able to perform the given action.
|
|
|
|
def show
|
|
@article = Article.find(params[:id])
|
|
authorize! :read, @article
|
|
end
|
|
|
|
Setting this for every action can be tedious, therefore the +load_and_authorize_resource+ method is provided to automatically authorize all actions in a RESTful style resource controller. It will use a before filter to load the resource into an instance variable and authorize it for every action.
|
|
|
|
class ArticlesController < ApplicationController
|
|
load_and_authorize_resource
|
|
|
|
def show
|
|
# @article is already loaded and authorized
|
|
end
|
|
end
|
|
|
|
See {Authorizing Controller Actions}[https://github.com/ryanb/cancan/wiki/authorizing-controller-actions] for more information.
|
|
|
|
|
|
=== 3. Handle Unauthorized Access
|
|
|
|
If the user authorization fails, a <tt>CanCan::AccessDenied</tt> exception will be raised. You can catch this and modify its behavior in the +ApplicationController+.
|
|
|
|
class ApplicationController < ActionController::Base
|
|
rescue_from CanCan::AccessDenied do |exception|
|
|
redirect_to root_url, :alert => exception.message
|
|
end
|
|
end
|
|
|
|
See {Exception Handling}[https://github.com/ryanb/cancan/wiki/exception-handling] for more information.
|
|
|
|
|
|
=== 4. Lock It Down
|
|
|
|
If you want to ensure authorization happens on every action in your application, add +check_authorization+ to your ApplicationController.
|
|
|
|
class ApplicationController < ActionController::Base
|
|
check_authorization
|
|
end
|
|
|
|
This will raise an exception if authorization is not performed in an action. If you want to skip this add +skip_authorization_check+ to a controller subclass. See {Ensure Authorization}[https://github.com/ryanb/cancan/wiki/Ensure-Authorization] for more information.
|
|
|
|
|
|
== Wiki Docs
|
|
|
|
* {Upgrading to 1.6}[https://github.com/ryanb/cancan/wiki/Upgrading-to-1.6]
|
|
* {Defining Abilities}[https://github.com/ryanb/cancan/wiki/Defining-Abilities]
|
|
* {Checking Abilities}[https://github.com/ryanb/cancan/wiki/Checking-Abilities]
|
|
* {Authorizing Controller Actions}[https://github.com/ryanb/cancan/wiki/Authorizing-Controller-Actions]
|
|
* {Exception Handling}[https://github.com/ryanb/cancan/wiki/Exception-Handling]
|
|
* {Changing Defaults}[https://github.com/ryanb/cancan/wiki/Changing-Defaults]
|
|
* {See more}[https://github.com/ryanb/cancan/wiki]
|
|
|
|
|
|
== Questions or Problems?
|
|
|
|
If you have any issues with CanCan which you cannot find the solution to in the documentation[https://github.com/ryanb/cancan/wiki], please add an {issue on GitHub}[https://github.com/ryanb/cancan/issues] or fork the project and send a pull request.
|
|
|
|
To get the specs running you should call +bundle+ and then +rake+. See the {spec/README}[https://github.com/ryanb/cancan/blob/master/spec/README.rdoc] for more information.
|
|
|
|
|
|
== Special Thanks
|
|
|
|
CanCan was inspired by declarative_authorization[https://github.com/stffn/declarative_authorization/] and aegis[https://github.com/makandra/aegis]. Also many thanks to the CanCan contributors[https://github.com/ryanb/cancan/contributors]. See the CHANGELOG[https://github.com/ryanb/cancan/blob/master/CHANGELOG.rdoc] for the full list.
|