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[:id]) }
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 |