Module: Authorization::AuthorizationInController::ClassMethods
- Defined in:
- lib/in_controller.rb
Instance Method Summary collapse
-
#all_filter_access_permissions ⇒ Object
Collecting all the ControllerPermission objects from the controller hierarchy.
-
#filter_access_to(*args, &filter_block) ⇒ Object
Defines a filter to be applied according to the authorization of the current user.
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.
217 218 219 220 221 222 223 224 225 226 227 228 |
# File 'lib/in_controller.rb', line 217 def # :nodoc: ancestors.inject([]) do |perms, mod| if mod.respond_to?(:filter_access_permissions) perms + mod..collect do |p1| p1.clone.remove_actions(perms.inject(Set.new) {|actions, p2| actions + p2.actions}) end else perms end end 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 action. The all :all statement is only employed if no specific statement is present.
class UserController < ActionController
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 infered 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
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 controller_name, pluralized.
- :
attribute_check -
Enables the check of attributes defined in the authorization rules. Defaults to false. If enabled, filter_access_to will try to load a context object employing either
-
the method from the :
load_methodoption or -
a find on the context model, using
params[:id] as id value.
Any of these loading methods will only be employed if :
attribute_checkis 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 behaviour:
filter_access_to :show, :attribute_check => true, :load_method => lambda { User.find(params[:id]) }
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 |
# File 'lib/in_controller.rb', line 185 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 }.merge!() privilege = [:require] context = [:context] actions = args.flatten # collect permits in controller array for use in one before_filter unless filter_chain.any? {|filter| filter.method == :filter_access_filter} before_filter :filter_access_filter end .each do |perm| perm.remove_actions(actions) end << ControllerPermission.new(actions, privilege, context, [:attribute_check], [:model], [:load_method], filter_block) end |