Module: Authorization::Controller::Rails::ClassMethods
- Defined in:
- lib/declarative_authorization/controller/rails.rb
Instance Method Summary collapse
-
#add_filter! ⇒ Object
Add the filtering before_action.
-
#filter_resource_access(options = {}) ⇒ Object
To DRY up the filter_access_to statements in restful controllers, filter_resource_access combines typical filter_access_to and before_action calls, which set up the instance variables.
-
#reset_filter! ⇒ Object
Move the filtering to the end of the before_action list.
Instance Method Details
#add_filter! ⇒ Object
Add the filtering before_action
27 28 29 |
# File 'lib/declarative_authorization/controller/rails.rb', line 27 def add_filter! before_action(:filter_access_filter) end |
#filter_resource_access(options = {}) ⇒ Object
To DRY up the filter_access_to statements in restful controllers, filter_resource_access combines typical filter_access_to and before_action calls, which set up the instance variables.
The simplest case are top-level resource controllers with only the seven CRUD methods, e.g.
class CompanyController < ApplicationController
filter_resource_access
def index...
end
Here, all CRUD actions are protected through a filter_access_to :all statement. :attribute_check
is enabled for all actions except for the collection action :index
. To have an object for attribute checks available, filter_resource_access will set the instance variable @company
in before filters. For the member actions (:show
, :edit
, :update
, :destroy
) @company is set to Company.find(params). For new
actions (:new
, :create
), filter_resource_access creates a new object from company parameters: Company.new(params.
For nested resources, the parent object may be loaded automatically.
class BranchController < ApplicationController
filter_resource_access :nested_in => :companies
end
Again, the CRUD actions are protected. Now, for all CRUD actions, the parent object @company is loaded from params. It is also used when creating @branch for new
actions. Here, attribute_check is enabled for the collection :index
as well, checking attributes on a In many cases, the default seven CRUD actions are not sufficient. As in the resource definition for routing you may thus give additional member, new and collection methods. The options
allow you to specify the required privileges for each action by providing a hash or an array of pairs. By default, for each action the action name is taken as privilege (action search in the example below requires the privilege :index :companies). Any controller action that is not specified and does not belong to the seven CRUD actions is handled as a member method.
class CompanyController < ApplicationController
filter_resource_access :collection => [[:search, :index], :index],
:additional_member => {:mark_as_key_company => :update}
end
The additional_
* options add to the respective CRUD actions, the other options (:member
, :collection
, :new
) replace their respective CRUD actions.
filter_resource_access :member => { :toggle_open => :update }
Would declare :toggle_open as the only member action in the controller and require that permission :update is granted for the current user.
filter_resource_access :additional_member => { :toggle_open => :update }
Would add a member action :toggle_open
to the default members, such as :show
.
If :collection
is an array of method names filter_resource_access will associate a permission with the method that is the same as the method name and no attribute checks will be performed unless
:attribute_check => true
is added in the options.
You can override the default object loading by implementing any of the following instance methods on the controller. Examples are given for the BranchController (with nested_in
set to :companies
):
new_branch_from_params
-
Used for
new
actions. new_branch_for_collection
-
Used for
collection
actions if thenested_in
option is set. load_branch
-
Used for
member
actions. load_company
-
Used for all
new
,member
, andcollection
actions if thenested_in
option is set.
All options:
- :
member
-
Member methods are actions like
show
, which have an params from which to load the controller object and assign it to @controller_name, e.g. @branch
.By default, member actions are [:
show
, :edit
, :update
, :destroy
]. Also, any action not belonging to the seven CRUD actions are handled as member actions.There are three different syntax to specify member, collection and new actions.
-
Hash: Lets you set the required privilege for each action: => :
show
, :mark_as_important
=> :update
-
Array of actions or pairs: [:
show
, [:mark_as_important
, :update
]], with single actions requiring the privilege of the same name as the method. -
Single method symbol: :
show
-
- :
additional_member
-
Allows to add additional member actions to the default resource
member
actions. - :
collection
-
Collection actions are like :
index
, actions without any controller object to check attributes of. Ifnested_in
is given, a new object is created from the parent object, e.g. @company.branches.new. Withoutnested_in
, attribute check is deactivated for these actions. By default, collection is set to :index
. - :
additional_collection
-
Allows to add additional collection actions to the default resource
collection
actions. - :
new
-
new
methods are actions such asnew
andcreate
, which don’t receive a params to load an object from, but a params hash with attributes for a new object. The attributes will be used here to create a new object and check the object against the authorization rules. The object is assigned to @controller_name_singular, e.g. @branch.If
nested_in
is given, the new object is created from the parent_object.controller_name proxy, e.g. company.branches.new(params). By default,new
is set to [:new, :create]. - :
additional_new
-
Allows to add additional new actions to the default resource
new
actions. - :
context
-
The context is used to determine the model to load objects from for the before_actions and the context of privileges to use in authorization checks.
- :
nested_in
-
Specifies the parent controller if the resource is nested in another one. This is used to automatically load the parent object, e.g. @
company
from params for a BranchController nested in a CompanyController. - :
shallow
-
Only relevant when used in conjunction with
nested_in
. Specifies a nested resource as being a shallow nested resource, resulting in the controller not attempting to load a parent object for all member actions defined bymember
andadditional_member
or rather the default member actions (:show
, :edit
, :update
, :destroy
). - :
no_attribute_check
-
Allows to set actions for which no attribute check should be performed. See filter_access_to on details. By default, with no
nested_in
,no_attribute_check
is set to all collections. Ifnested_in
is givenno_attribute_check
is empty by default. - :
strong_parameters
-
If set to true, relies on controller to provide instance variable and create new object in :create action. Set true if you use strong_params and false if you use protected_attributes.
177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 |
# File 'lib/declarative_authorization/controller/rails.rb', line 177 def filter_resource_access( = {}) = { :new => [:new, :create], :additional_new => nil, :member => [:show, :edit, :update, :destroy], :additional_member => nil, :collection => [:index], :additional_collection => nil, #:new_method_for_collection => nil, # only symbol method name #:new_method => nil, # only symbol method name #:load_method => nil, # only symbol method name :no_attribute_check => nil, :context => nil, :model => nil, :nested_in => nil, :strong_parameters => nil }.merge() .merge!({ :strong_parameters => true }) if [:strong_parameters] == nil new_actions = actions_from_option( [:new] ).merge( actions_from_option([:additional_new]) ) members = actions_from_option([:member]).merge( actions_from_option([:additional_member])) collections = actions_from_option([:collection]).merge( actions_from_option([:additional_collection])) no_attribute_check_actions = [:strong_parameters] ? actions_from_option([:collection]).merge(actions_from_option([:create])) : collections [:no_attribute_check] ||= no_attribute_check_actions.keys unless [:nested_in] unless [:nested_in].blank? load_parent_method = :"load_#{[:nested_in].to_s.singularize}" shallow_exceptions = [:shallow] ? {:except => members.keys} : {} before_action shallow_exceptions do |controller| if controller.respond_to?(load_parent_method, true) controller.send(load_parent_method) else controller.send(:load_parent_controller_object, [:nested_in]) end end new_for_collection_method = :"new_#{controller_name.singularize}_for_collection" before_action :only => collections.keys do |controller| # new_for_collection if controller.respond_to?(new_for_collection_method, true) controller.send(new_for_collection_method) else controller.send(:new_controller_object_for_collection, [:context] || controller_name, [:nested_in], [:strong_parameters]) end end end unless [:strong_parameters] new_from_params_method = :"new_#{controller_name.singularize}_from_params" before_action :only => new_actions.keys do |controller| # new_from_params if controller.respond_to?(new_from_params_method, true) controller.send(new_from_params_method) else controller.send(:new_controller_object_from_params, [:context] || controller_name, [:nested_in], [:strong_parameters]) end end else new_object_method = :"new_#{controller_name.singularize}" before_action :only => :new do |controller| # new_from_params if controller.respond_to?(new_object_method, true) controller.send(new_object_method) else controller.send(:new_blank_controller_object, [:context] || controller_name, [:nested_in], [:strong_parameters], [:model]) end end end load_method = :"load_#{controller_name.singularize}" before_action :only => members.keys do |controller| # load controller object if controller.respond_to?(load_method, true) controller.send(load_method) else controller.send(:load_controller_object, [:context] || controller_name, [:model]) end end filter_access_to :all, :attribute_check => true, :context => [:context], :model => [:model] members.merge(new_actions).merge(collections).each do |action, privilege| if action != privilege or ([:no_attribute_check] and [:no_attribute_check].include?(action)) = { :strong_parameters => [:strong_parameters], :context => [:context], :attribute_check => ![:no_attribute_check] || ![:no_attribute_check].include?(action), :model => [:model] } [:require] = privilege if action != privilege filter_access_to(action, ) end end end |
#reset_filter! ⇒ Object
Move the filtering to the end of the before_action list
34 35 36 37 |
# File 'lib/declarative_authorization/controller/rails.rb', line 34 def reset_filter! skip_before_action(:filter_access_filter) if method_defined?(:filter_access_filter) before_action :filter_access_filter end |