Skip to content
Newer
Older
100644 163 lines (95 sloc) 7.4 KB
6c6a57b @ryanb adding documentation placeholder
authored
1 = CanCan
2
66ff1f2 @ryanb removing metrics link in readme, farewell Caliper :(
authored
3 Wiki[http://wiki.github.com/ryanb/cancan] | RDocs[http://rdoc.info/projects/ryanb/cancan] | Screencast[http://railscasts.com/episodes/192-authorization-with-cancan]
a13f78d @ryanb listing additional resources at top of readme page (including metrics…
authored
4
6c3e87e @ryanb updating readme and documentation
authored
5 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.
b1d3d66 @ryanb filling readme
authored
6
7
8 == Installation
9
6c3e87e @ryanb updating readme and documentation
authored
10 In <b>Rails 3</b>, add this to your Gemfile.
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
11
6c3e87e @ryanb updating readme and documentation
authored
12 gem "cancan"
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
13
6c3e87e @ryanb updating readme and documentation
authored
14 In <b>Rails 2</b>, add this to your environment.rb file.
18dcf2a @ryanb mention Rails 3 installation in README - closes #56
authored
15
6c3e87e @ryanb updating readme and documentation
authored
16 config.gem "cancan"
18dcf2a @ryanb mention Rails 3 installation in README - closes #56
authored
17
6c3e87e @ryanb updating readme and documentation
authored
18 Alternatively, you can install it as a plugin.
28eaf1b @ryanb releasing gem v0.1.0
authored
19
6c3e87e @ryanb updating readme and documentation
authored
20 rails plugin install git://github.com/ryanb/cancan.git
b1d3d66 @ryanb filling readme
authored
21
22
f7480d1 @ryanb releasing gem v1.0.0 (backwards incompatible, see changelog)
authored
23 == Getting Started
b1d3d66 @ryanb filling readme
authored
24
6c3e87e @ryanb updating readme and documentation
authored
25 CanCan expects a +current_user+ method to exist. If you have not already, set up some authentication (such as Authlogic[http://github.com/binarylogic/authlogic] or Devise[http://github.com/plataformatec/devise]). See {Changing Defaults}[http://wiki.github.com/ryanb/cancan/changing-defaults] if you need different behavior.
26
27 Next create a class called +Ability+ in "models/ability.rb" or anywhere else in the load path. It should look similar to this.
b1d3d66 @ryanb filling readme
authored
28
29 class Ability
30 include CanCan::Ability
25637bb @ryanb removing extra white space at end of lines
authored
31
1edf583 @ryanb BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' t…
authored
32 def initialize(user)
b1d3d66 @ryanb filling readme
authored
33 if user.admin?
34 can :manage, :all
35 else
36 can :read, :all
37 end
38 end
39 end
40
6c3e87e @ryanb updating readme and documentation
authored
41 The +current_user+ is passed in to this method which is where the abilities are defined. See the "Defining Abilities" section below for more information.
b1d3d66 @ryanb filling readme
authored
42
283f58e @ryanb improving readme with links to wiki
authored
43 The current user's permissions can be accessed using the "can?" and "cannot?" methods in the view and controller.
b1d3d66 @ryanb filling readme
authored
44
45 <% if can? :update, @article %>
46 <%= link_to "Edit", edit_article_path(@article) %>
47 <% end %>
48
283f58e @ryanb improving readme with links to wiki
authored
49 See {Checking Abilities}[http://wiki.github.com/ryanb/cancan/checking-abilities] for more information
50
51 The "authorize!" method in the controller will raise an exception if the user is not able to perform the given action.
b1d3d66 @ryanb filling readme
authored
52
53 def show
54 @article = Article.find(params[:id])
8903fee @ryanb removing unauthorized! in favor of authorize! and including more info…
authored
55 authorize! :read, @article
b1d3d66 @ryanb filling readme
authored
56 end
57
b9995c6 @ryanb minor changes to readme
authored
58 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 each action.
b1d3d66 @ryanb filling readme
authored
59
60 class ArticlesController < ApplicationController
f7480d1 @ryanb releasing gem v1.0.0 (backwards incompatible, see changelog)
authored
61 load_and_authorize_resource
25637bb @ryanb removing extra white space at end of lines
authored
62
b1d3d66 @ryanb filling readme
authored
63 def show
283f58e @ryanb improving readme with links to wiki
authored
64 # @article is already loaded and authorized
b1d3d66 @ryanb filling readme
authored
65 end
66 end
67
283f58e @ryanb improving readme with links to wiki
authored
68 See {Authorizing Controller Actions}[http://wiki.github.com/ryanb/cancan/authorizing-controller-actions] for more information
69
6c3e87e @ryanb updating readme and documentation
authored
70 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+.
b1d3d66 @ryanb filling readme
authored
71
72 class ApplicationController < ActionController::Base
f919ac5 @ryanb releasing gem v1.0.1
authored
73 rescue_from CanCan::AccessDenied do |exception|
6c3e87e @ryanb updating readme and documentation
authored
74 flash[:alert] = exception.message
b1d3d66 @ryanb filling readme
authored
75 redirect_to root_url
76 end
77 end
78
283f58e @ryanb improving readme with links to wiki
authored
79 See {Exception Handling}[http://wiki.github.com/ryanb/cancan/exception-handling] for more information.
8903fee @ryanb removing unauthorized! in favor of authorize! and including more info…
authored
80
b1d3d66 @ryanb filling readme
authored
81
82 == Defining Abilities
83
6c3e87e @ryanb updating readme and documentation
authored
84 As shown above, the +Ability+ class is where all user permissions are defined. The current user model is passed into the initialize method so the permissions can be modified based on any user attributes. CanCan makes no assumption about how roles are handled in your application. See {Role Based Authorization}[http://wiki.github.com/ryanb/cancan/role-based-authorization] for an example.
b1d3d66 @ryanb filling readme
authored
85
283f58e @ryanb improving readme with links to wiki
authored
86 The +can+ method is used to define permissions and requires two arguments. The first one is the action you're setting the permission for, the second one is the class of object you're setting it on.
b1d3d66 @ryanb filling readme
authored
87
88 can :update, Article
89
283f58e @ryanb improving readme with links to wiki
authored
90 You can pass an array for either of these parameters to match any one. In this case the user will have the ability to update or destroy both articles and comments.
b1d3d66 @ryanb filling readme
authored
91
92 can [:update, :destroy], [Article, Comment]
93
283f58e @ryanb improving readme with links to wiki
authored
94 Use :+manage+ to represent any action and :+all+ to represent any class. Here are some examples.
b1d3d66 @ryanb filling readme
authored
95
283f58e @ryanb improving readme with links to wiki
authored
96 can :manage, Article # has permissions to do anything to articles
97 can :read, :all # has permission to read any model
98 can :manage, :all # has permission to do anything to any model
99
6c3e87e @ryanb updating readme and documentation
authored
100 You can pass a hash of conditions as the third argument to further define what the user is able to access. Here the user will only have permission to read active projects which he owns.
b1d3d66 @ryanb filling readme
authored
101
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
102 can :read, Project, :active => true, :user_id => user.id
103
283f58e @ryanb improving readme with links to wiki
authored
104 See {Defining Abilities with Hashes}[http://wiki.github.com/ryanb/cancan/defining-abilities-with-hashes] for more information.
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
105
283f58e @ryanb improving readme with links to wiki
authored
106 Blocks can also be used if you need more control.
baeef0b @ryanb adding conditions behavior to Ability#can and fetch with Ability#cond…
authored
107
108 can :update, Project do |project|
6c3e87e @ryanb updating readme and documentation
authored
109 project.groups.include?(user.group)
b1d3d66 @ryanb filling readme
authored
110 end
111
6c3e87e @ryanb updating readme and documentation
authored
112 If the block returns true then the user has that ability for that project, otherwise he will be denied access. See {Defining Abilities with Blocks}[http://wiki.github.com/ryanb/cancan/defining-abilities-with-blocks] for more information.
0f49b54 @ryanb adding 'cannot?' method which performs opposite check of 'can?' - clo…
authored
113
b1d3d66 @ryanb filling readme
authored
114
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - closes
authored
115 == Aliasing Actions
116
b9995c6 @ryanb minor changes to readme
authored
117 You will usually be working with four actions when defining and checking permissions: :+read+, :+create+, :+update+, :+destroy+. These aren't the same as the 7 RESTful actions in Rails. CanCan automatically adds some default aliases for mapping those actions.
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - closes
authored
118
119 alias_action :index, :show, :to => :read
120 alias_action :new, :to => :create
121 alias_action :edit, :to => :update
122
6c3e87e @ryanb updating readme and documentation
authored
123 Notice the +edit+ action is aliased to +update+. This means if the user is able to update a record he also has permission to edit it. You can define your own aliases in the +Ability+ class.
d4405e6 @ryanb adding cannot method to define which abilities cannot be done - closes
authored
124
283f58e @ryanb improving readme with links to wiki
authored
125 alias_action :update, :destroy, :to => :modify
126 can :modify, Comment
127 can? :update, Comment # => true
f7480d1 @ryanb releasing gem v1.0.0 (backwards incompatible, see changelog)
authored
128
737f8ac @ryanb make it clear in readme that alias_action is an instance method - clo…
authored
129 The +alias_action+ method is an instance method and usually called in +initialize+. See {Custom Actions}[http://wiki.github.com/ryanb/cancan/custom-actions] for information on adding other actions.
f7480d1 @ryanb releasing gem v1.0.0 (backwards incompatible, see changelog)
authored
130
131
37f482e @ryanb default ActiveRecordAdditions#can method action to :read and use 'sco…
authored
132 == Fetching Records
133
6c3e87e @ryanb updating readme and documentation
authored
134 It is possible to fetch records which the user has permission to read using the +accessible_by+ scope in Active Record.
37f482e @ryanb default ActiveRecordAdditions#can method action to :read and use 'sco…
authored
135
240c281 @ryanb renaming ActiveRecordAdditions#can method to accessible_by since it f…
authored
136 @articles = Article.accessible_by(current_ability)
37f482e @ryanb default ActiveRecordAdditions#can method action to :read and use 'sco…
authored
137
6c3e87e @ryanb updating readme and documentation
authored
138 Since version 1.4 this is done automatically when loading resources in the index action, so one rarely needs to do it manually.
139
4fe44af @ryanb be more clear about blocks not working with accessible_by - closes #130
authored
140 This will only work when abilities are defined using hash conditions, not blocks. See {Fetching Records}[http://wiki.github.com/ryanb/cancan/fetching-records] for more information.
df27653 @ryanb adding documentation for testing abilities - closes #6
authored
141
37f482e @ryanb default ActiveRecordAdditions#can method action to :read and use 'sco…
authored
142
283f58e @ryanb improving readme with links to wiki
authored
143 == Additional Docs
37f482e @ryanb default ActiveRecordAdditions#can method action to :read and use 'sco…
authored
144
6c3e87e @ryanb updating readme and documentation
authored
145 * {Upgrading to 1.4}[http://github.com/ryanb/cancan/wiki/Upgrading-to-1.4]
13427e1 @ryanb updating readme
authored
146 * {Nested Resources}[http://wiki.github.com/ryanb/cancan/nested-resources]
283f58e @ryanb improving readme with links to wiki
authored
147 * {Testing Abilities}[http://wiki.github.com/ryanb/cancan/testing-abilities]
148 * {Accessing Request Data}[http://wiki.github.com/ryanb/cancan/accessing-request-data]
e1652ea @ryanb adding admin namespace wiki page link to readme
authored
149 * {Admin Namespace}[http://wiki.github.com/ryanb/cancan/admin-namespace]
283f58e @ryanb improving readme with links to wiki
authored
150 * {See more}[http://wiki.github.com/ryanb/cancan/]
df27653 @ryanb adding documentation for testing abilities - closes #6
authored
151
18b45d5 @ryanb adding Gemfile, to get specs running just bundle and rake - closes #163
authored
152
153 == Questions or Problems?
154
6c3e87e @ryanb updating readme and documentation
authored
155 If you have any issues with CanCan which you cannot find the solution to in the documentation, please add an {issue on GitHub}[http://github.com/ryanb/cancan/issues] or fork the project and send a pull request.
18b45d5 @ryanb adding Gemfile, to get specs running just bundle and rake - closes #163
authored
156
157 To get the specs running you should call +bundle+ and then +rake+. Specs currently do not work in Ruby 1.9 due to the RR mocking framework.
158
159
9d58226 @ryanb couple fixes in readme
authored
160 == Special Thanks
161
5eae169 @ryanb mentioning CanCan contributors in README
authored
162 CanCan was inspired by declarative_authorization[http://github.com/stffn/declarative_authorization/] and aegis[http://github.com/makandra/aegis]. Also many thanks to the CanCan contributors[http://github.com/ryanb/cancan/contributors]. See the CHANGELOG[http://github.com/ryanb/cancan/blob/master/CHANGELOG.rdoc] for the full list.
Something went wrong with that request. Please try again.