Module: Authorization::Controller::DSL
- Defined in:
- lib/declarative_authorization/controller/dsl.rb
Instance Method Summary collapse
-
#all_filter_access_permissions ⇒ Object
Collecting all the ControllerPermission objects from the controller hierarchy.
-
#decl_auth_context ⇒ Object
Returns the context for authorization checks in the current controller.
-
#filter_access_to(*args, &filter_block) ⇒ Object
Defines a filter to be applied according to the authorization of the current user.
-
#no_filter_access_to(*args) ⇒ Object
Disables authorization entirely.
Instance Method Details
#all_filter_access_permissions ⇒ Object
Collecting all the ControllerPermission objects from the controller hierarchy. Permissions for actions are overwritten by calls to filter_access_to in child controllers with the same action.
145 146 147 148 149 150 151 152 153 154 155 156 |
# File 'lib/declarative_authorization/controller/dsl.rb', line 145 def # :nodoc: ancestors.inject([]) do |perms, mod| if mod.respond_to?(:filter_access_permissions, true) perms + mod..collect do |p1| p1.clone.remove_actions(perms.inject(Set.new) {|actions, p2| actions + p2.actions}) end else perms end end end |
#decl_auth_context ⇒ Object
Returns the context for authorization checks in the current controller. Uses the controller_name and prepends any namespaces underscored and joined with underscores.
E.g. AllThosePeopleController => :all_those_people AnyName::Space::ThingsController => :any_name_space_things
166 167 168 169 |
# File 'lib/declarative_authorization/controller/dsl.rb', line 166 def decl_auth_context prefixes = name.split('::')[0..-2].map(&:underscore) ((prefixes + [controller_name]) * '_').to_sym end |
#filter_access_to(*args, &filter_block) ⇒ Object
Defines a filter to be applied according to the authorization of the current user. Requires at least one symbol corresponding to an action as parameter. The special symbol :+all+ refers to all actions. The all :+all+ statement is only employed if no specific statement is present. class UserController < ApplicationController filter_access_to :index filter_access_to :new, :edit filter_access_to :all ... end
The default is to allow access unconditionally if no rule matches.
Thus, including the filter_access_to :+all+ statement is a good
idea, implementing a default-deny policy.
When the access is denied, the method permission_denied is called
on the current controller, if defined. Else, a simple "you are not
allowed" string is output. Log.info is given more information on the
reasons of denial.
def
flash[:error] = 'Sorry, you are not allowed to the requested page.'
respond_to do |format|
format.html { redirect_to(:back) rescue redirect_to('/') }
format.xml { head :unauthorized }
format.js { head :unauthorized }
end
end
By default, required privileges are inferred from the action name and
the controller name. Thus, in UserController :+edit+ requires
:+edit+ users. To specify required privilege, use the option :+require+
filter_access_to :new, :create, :require => :create, :context => :users
Without the :+attribute_check+ option, no constraints from the
authorization rules are enforced because for some actions (collections,
new, create), there is no object to evaluate conditions against. To
allow attribute checks on all actions, it is a common pattern to provide
custom objects through before_actions:
class BranchesController < ApplicationController
before_action :load_company
before_action :new_branch_from_company_and_params,
:only => [:index, :new, :create]
filter_access_to :all, :attribute_check => true
protected
def new_branch_from_company_and_params
@branch = @company.branches.new(params[:branch])
end
end
NOTE: before_actions need to be defined before the first
filter_access_to call.
For further customization, a custom filter expression may be formulated in a block, which is then evaluated in the context of the controller on a matching request. That is, for checking two objects, use the following:
filter_access_to :merge do
permitted_to!(:update, User.find(params[:original_id])) and
permitted_to!(:delete, User.find(params[:id]))
end
The block should raise a Authorization::AuthorizationError or return false if the access is to be denied.
Later calls to filter_access_to with overlapping actions overwrite previous ones for that action.
All options: [:+require+] Privilege required; defaults to action_name [:+context+] The privilege's context, defaults to decl_auth_context, which consists of controller_name, prepended by any namespaces [:+attribute_check+] Enables the check of attributes defined in the authorization rules. Defaults to false. If enabled, filter_access_to will use a context object from one of the following sources (in that order):
* the method from the :+load_method+ option,
* an instance variable named after the singular of the context
(by default from the controller name, e.g. @post for PostsController),
* a find on the context model, using +params+[:id] as id value.
Any of these methods will only be employed if :+attribute_check+
is enabled.
[:+model+]
The data model to load a context object from. Defaults to the
context, singularized.
[:+load_method+]
Specify a method by symbol or a Proc object which should be used
to load the object. Both should return the loaded object.
If a Proc object is given, e.g. by way of
lambda, it is called in the instance of the controller.
Example demonstrating the default behavior:
filter_access_to :show, :attribute_check => true,
:load_method => lambda { User.find(params) }
104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 |
# File 'lib/declarative_authorization/controller/dsl.rb', line 104 def filter_access_to(*args, &filter_block) = args.last.is_a?(Hash) ? args.pop : {} = { :require => nil, :context => nil, :attribute_check => false, :model => nil, :load_method => nil, :strong_parameters => nil }.merge!() privilege = [:require] context = [:context] actions = args.flatten reset_filter! .each do |perm| perm.remove_actions(actions) end << ControllerPermission.new(actions, privilege, context, [:strong_parameters], [:attribute_check], [:model], [:load_method], filter_block) end |
#no_filter_access_to(*args) ⇒ Object
Disables authorization entirely. Requires at least one symbol corresponding to an action as parameter. The special symbol :+all+ refers to all actions. The all :+all+ statement is only employed if no specific statement is present.
136 137 138 139 140 |
# File 'lib/declarative_authorization/controller/dsl.rb', line 136 def no_filter_access_to(*args) filter_access_to args do true end end |