From 1f9c2e626440aab4167999a3bc32c79ab148af2d Mon Sep 17 00:00:00 2001 From: Jeroen van Dijk Date: Wed, 26 Aug 2009 16:43:06 +0200 Subject: [PATCH] Implement a :namespace option for filter_access_to in order to handle namespaced controllers. Conflicts: declarative_authorization.gemspec.src test/controller_test.rb Merge uhees and stffn --- .../in_controller.rb | 28 +++++++++-- test/controller_test.rb | 47 +++++++++++++++++++ 2 files changed, 72 insertions(+), 3 deletions(-) diff --git a/lib/declarative_authorization/in_controller.rb b/lib/declarative_authorization/in_controller.rb index 6fa68031..d1b2e590 100644 --- a/lib/declarative_authorization/in_controller.rb +++ b/lib/declarative_authorization/in_controller.rb @@ -222,6 +222,14 @@ module ClassMethods # Privilege required; defaults to action_name # [:+context+] # The privilege's context, defaults to controller_name, pluralized. + # [:+namespace+] + # Prefix the default controller context with. + # * +true+: the model namespace(s) separated with underscores, + # * +Symbol+ or +String+: the given symbol or string + # * else: no prefix + # Example: + # filter_access_to :show, :namespace => true + # filter_access_to :delete, :namespace => :foo # [:+attribute_check+] # Enables the check of attributes defined in the authorization rules. # Defaults to false. If enabled, filter_access_to will use a context @@ -250,6 +258,7 @@ def filter_access_to (*args, &filter_block) options = { :require => nil, :context => nil, + :namespace => nil, :attribute_check => false, :model => nil, :load_method => nil @@ -268,6 +277,7 @@ def filter_access_to (*args, &filter_block) end filter_access_permissions << ControllerPermission.new(actions, privilege, context, + options[:namespace], options[:attribute_check], options[:model], options[:load_method], @@ -498,19 +508,31 @@ def actions_from_option (option) # :nodoc: end class ControllerPermission # :nodoc: - attr_reader :actions, :privilege, :context, :attribute_check - def initialize (actions, privilege, context, attribute_check = false, + attr_reader :actions, :privilege, :context, :namespace, :attribute_check + def initialize (actions, privilege, context, namespace, attribute_check = false, load_object_model = nil, load_object_method = nil, filter_block = nil) @actions = actions.to_set @privilege = privilege @context = context + @namespace = namespace @load_object_model = load_object_model @load_object_method = load_object_method @filter_block = filter_block @attribute_check = attribute_check end + def controller_context(contr) + case @namespace + when true + "#{contr.class.name.gsub(/::/, "_").gsub(/Controller$/, "").underscore}".to_sym + when String, Symbol + "#{@namespace.to_s}_#{contr.class.controller_name}".to_sym + else + contr.class.controller_name.to_sym + end + end + def matches? (action_name) @actions.include?(action_name.to_sym) end @@ -519,7 +541,7 @@ def permit! (contr) if @filter_block return contr.instance_eval(&@filter_block) end - context = @context || contr.class.controller_name.to_sym + context = @context || controller_context(contr) object = @attribute_check ? load_object(contr, context) : nil privilege = @privilege || :"#{contr.action_name}" diff --git a/test/controller_test.rb b/test/controller_test.rb index 1b81a45c..c96163cd 100644 --- a/test/controller_test.rb +++ b/test/controller_test.rb @@ -2,6 +2,9 @@ class LoadMockObject < MockDataObject + def self.find(*args) + new :id => args[0] + end end ################## @@ -367,3 +370,47 @@ def test_controller_hierarchy assert !@controller.authorized? end end + +################## +module Foo + class CommonController < MocksController + filter_access_to :all + filter_access_to :new + filter_access_to :show, :namespace => :bar + filter_access_to :delete, :namespace => true + + define_action_methods :new, :show, :delete + end +end +class NamespacedControllerTest < ActionController::TestCase + tests Foo::CommonController + def test_namespaced_controller + reader = Authorization::Reader::DSLReader.new + reader.parse %{ + authorization do + role :test_role1 do + has_permission_on :common, :to => [:new, :show, :delete] + end + role :test_role2 do + has_permission_on :common, :to => [:new] + has_permission_on :bar_common, :to => [:show] + has_permission_on :foo_common, :to => [:delete] + end + end + } + request!(MockUser.new(:test_role1), "new", reader) + assert @controller.authorized? + request!(MockUser.new(:test_role1), "show", reader) + assert !@controller.authorized? + request!(MockUser.new(:test_role1), "delete", reader) + assert !@controller.authorized? + + request!(MockUser.new(:test_role2), "new", reader) + assert @controller.authorized? + request!(MockUser.new(:test_role2), "show", reader) + assert @controller.authorized? + request!(MockUser.new(:test_role2), "delete", reader) + assert @controller.authorized? + end +end +