Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Newer
Older
100644 130 lines (120 sloc) 4.816 kb
44b36ce @ryanb adding controller additions with basic behavior.
authored
1 module CanCan
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
2
3 # This module is automatically included into all controllers.
4 # It also makes the "can?" and "cannot?" methods available to all views.
44b36ce @ryanb adding controller additions with basic behavior.
authored
5 module ControllerAdditions
a5f9882 @ryanb turning load and authorize resource methods into class methods which set...
authored
6 module ClassMethods
7 # Sets up a before filter which loads and authorizes the current resource. This accepts the
8 # same arguments as load_resource and authorize_resource. See those methods for details.
9 #
10 # class BooksController < ApplicationController
11 # load_and_authorize_resource
12 # end
13 #
14 def load_and_authorize_resource(*args)
15 before_filter { |c| ResourceAuthorization.new(c, c.params, *args).load_and_authorize_resource }
16 end
17
18 # Sets up a before filter which loads the appropriate model resource into an instance variable.
19 # For example, given an ArticlesController it will load the current article into the @article
20 # instance variable. It does this by either calling Article.find(params[:id]) or
21 # Article.new(params[:article]) depending upon the action. It does nothing for the "index"
22 # action.
23 #
24 # You would call this method directly on the controller class.
25 #
26 # class BooksController < ApplicationController
27 # load_resource
28 # end
29 #
30 # See load_and_authorize_resource to automatically authorize the resource too.
31 def load_resource(*args) # TODO add documentation for options which can be passed.
32 before_filter { |c| ResourceAuthorization.new(c, c.params, *args).load_resource }
33 end
34
35 # Sets up a before filter which authorizes the current resource using the instance variable.
36 # For example, if you have an ArticlesController it will check the @article instance variable
37 # and ensure the user can perform the current action on it. Under the hood it is doing
38 # something like the following.
39 #
40 # unauthorized! if cannot?(params[:action].to_sym, @article || Article)
41 #
42 # You would call this method directly on the controller class.
43 #
44 # class BooksController < ApplicationController
45 # authorize_resource
46 # end
47 #
48 # See load_and_authorize_resource to automatically load the resource too.
49 def authorize_resource(*args)
50 before_filter { |c| ResourceAuthorization.new(c, c.params, *args).authorize_resource }
51 end
52 end
53
44b36ce @ryanb adding controller additions with basic behavior.
authored
54 def self.included(base)
a5f9882 @ryanb turning load and authorize resource methods into class methods which set...
authored
55 base.extend ClassMethods
0f49b54 @ryanb adding 'cannot?' method which performs opposite check of 'can?' - closes...
authored
56 base.helper_method :can?, :cannot?
44b36ce @ryanb adding controller additions with basic behavior.
authored
57 end
58
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
59 # Raises the CanCan::AccessDenied exception. This is often used in a
60 # controller action to mark a request as unauthorized.
61 #
62 # def show
63 # @article = Article.find(params[:id])
64 # unauthorized! if cannot? :read, @article
65 # end
66 #
67 # You can rescue from the exception in the controller to specify
68 # the user experience.
69 #
70 # class ApplicationController < ActionController::Base
71 # rescue_from CanCan::AccessDenied, :with => :access_denied
72 #
73 # protected
74 #
75 # def access_denied
76 # flash[:error] = "Sorry, you are not allowed to access that page."
77 # redirect_to root_url
78 # end
79 # end
80 #
81 # See the load_and_authorize_resource method to automatically add
82 # the "unauthorized!" behavior to a RESTful controller's actions.
44b36ce @ryanb adding controller additions with basic behavior.
authored
83 def unauthorized!
84 raise AccessDenied, "You are unable to access this page."
85 end
86
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
87 # Creates and returns the current user's ability. You generally do not invoke
88 # this method directly, instead you can override this method to change its
89 # behavior if the Ability class or current_user method are different.
90 #
91 # def current_ability
92 # UserAbility.new(current_account) # instead of Ability.new(current_user)
93 # end
94 #
44b36ce @ryanb adding controller additions with basic behavior.
authored
95 def current_ability
1edf583 @ryanb BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to s...
authored
96 ::Ability.new(current_user)
44b36ce @ryanb adding controller additions with basic behavior.
authored
97 end
98
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
99 # Use in the controller or view to check the user's permission for a given action
100 # and object.
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
101 #
102 # can? :destroy, @project
103 #
104 # You can also pass the class instead of an instance (if you don't have one handy).
105 #
106 # <% if can? :create, Project %>
107 # <%= link_to "New Project", new_project_path %>
108 # <% end %>
109 #
5bd1a85 @ryanb little fixes to inline documentation (rdocs)
authored
110 # This simply calls "can?" on the current_ability. See Ability#can?.
44b36ce @ryanb adding controller additions with basic behavior.
authored
111 def can?(*args)
112 (@current_ability ||= current_ability).can?(*args)
113 end
1034c81 @ryanb adding a before filter for loading and authorizing a resource
authored
114
b9227eb @ryanb adding a lot of inline documentation to code for rdocs
authored
115 # Convenience method which works the same as "can?" but returns the opposite value.
116 #
117 # cannot? :destroy, @project
118 #
0f49b54 @ryanb adding 'cannot?' method which performs opposite check of 'can?' - closes...
authored
119 def cannot?(*args)
120 (@current_ability ||= current_ability).cannot?(*args)
121 end
44b36ce @ryanb adding controller additions with basic behavior.
authored
122 end
123 end
124
aaed265 @ryanb turning into a funtioning Rails plugin
authored
125 if defined? ActionController
126 ActionController::Base.class_eval do
127 include CanCan::ControllerAdditions
128 end
1edf583 @ryanb BACKWARDS INCOMPATIBLE: use Ability#initialize instead of 'prepare' to s...
authored
129 end
Something went wrong with that request. Please try again.