From c84469f7c79f2f1044c5b39dbeef0390c5a1bc24 Mon Sep 17 00:00:00 2001 From: yarivNatural Date: Tue, 4 Dec 2012 11:16:50 +0200 Subject: [PATCH 1/3] Adding the option to set permission on all actions in a controller. For example: has_permission_on :users, :to => :all --- lib/declarative_authorization/reader.rb | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/lib/declarative_authorization/reader.rb b/lib/declarative_authorization/reader.rb index cc04a303..d2905145 100644 --- a/lib/declarative_authorization/reader.rb +++ b/lib/declarative_authorization/reader.rb @@ -279,6 +279,17 @@ def has_permission_on (*args, &block) context = args.flatten raise DSLError, "has_permission_on only allowed in role blocks" if @current_role.nil? + + # Adding the option to set permission on all actions in a controller. + # For example: has_permission_on :users, :to => :all + if options[:to].include? :all + controller = Object::const_get(context[0].to_s.camelize + "Controller") + actions = [] + controller.action_methods.each { |m| actions << m.to_sym } + options[:to] = actions + end + ########################################################################## + options = {:to => [], :join_by => :or}.merge(options) privs = options[:to] From 634fed5791c0aa32eddbe1a748e3f4d35af49953 Mon Sep 17 00:00:00 2001 From: yarivNatural Date: Wed, 5 Dec 2012 16:42:19 +0200 Subject: [PATCH 2/3] Fixed the option to set permission on all actions in a controller. For example: has_permission_on :users, :to => :all --- lib/declarative_authorization/reader.rb | 64 +++++++++++++++---------- 1 file changed, 40 insertions(+), 24 deletions(-) diff --git a/lib/declarative_authorization/reader.rb b/lib/declarative_authorization/reader.rb index d2905145..9b85f572 100644 --- a/lib/declarative_authorization/reader.rb +++ b/lib/declarative_authorization/reader.rb @@ -45,7 +45,7 @@ class DSLFileNotFoundError < Exception; end class DSLError < Exception; end # Signals errors in the syntax of an authorization DSL. class DSLSyntaxError < DSLError; end - + # Top-level reader, parses the methods +privileges+ and +authorization+. # +authorization+ takes a block with authorization rules as described in # AuthorizationRulesReader. The block to +privileges+ defines privilege @@ -70,10 +70,10 @@ def initialize_copy (from) # :nodoc: # String or Array - it will treat it as if you have passed a path or an array of paths and attempt to load those. def self.factory(obj) case obj - when Reader::DSLReader - obj - when String, Array - load(obj) + when Reader::DSLReader + obj + when String, Array + load(obj) end end @@ -189,7 +189,7 @@ def includes (*privileges) class AuthorizationRulesReader attr_reader :roles, :role_hierarchy, :auth_rules, - :role_descriptions, :role_titles, :omnipotent_roles # :nodoc: + :role_descriptions, :role_titles, :omnipotent_roles # :nodoc: def initialize # :nodoc: @current_role = nil @@ -205,7 +205,7 @@ def initialize # :nodoc: def initialize_copy (from) # :nodoc: [:roles, :role_hierarchy, :auth_rules, - :role_descriptions, :role_titles, :omnipotent_roles].each do |attribute| + :role_descriptions, :role_titles, :omnipotent_roles].each do |attribute| instance_variable_set(:"@#{attribute}", from.send(attribute).clone) end end @@ -245,7 +245,13 @@ def includes (*roles) @role_hierarchy[@current_role] ||= [] @role_hierarchy[@current_role] += roles.flatten end - + + def class_from_string(str) + str.split('::').inject(Object) do |mod, class_name| + mod.const_get(class_name) + end + end + # Allows the definition of privileges to be allowed for the current role, # either in a has_permission_on block or directly in one call. # role :admin @@ -277,28 +283,38 @@ def includes (*roles) def has_permission_on (*args, &block) options = args.extract_options! context = args.flatten - + raise DSLError, "has_permission_on only allowed in role blocks" if @current_role.nil? # Adding the option to set permission on all actions in a controller. # For example: has_permission_on :users, :to => :all if options[:to].include? :all - controller = Object::const_get(context[0].to_s.camelize + "Controller") - actions = [] - controller.action_methods.each { |m| actions << m.to_sym } - options[:to] = actions + begin + routes = Rails.application.routes.routes.routes + raw_name = context[0].to_s + results = routes.select { |route| route.defaults.blank? ? false : route.defaults[:controller].split(/[\/_]/).join('_') == raw_name } + controller_parts = results.first.defaults[:controller].split('/') + controller_parts.each { |part| part.capitalize! } + controller_name = controller_parts.push(controller_parts.pop.camelize).join("::") + controller = class_from_string(controller_name.camelize + "Controller") + + actions = [] + controller.action_methods.each { |m| actions << m.to_sym } + options[:to] = actions + rescue + end end ########################################################################## options = {:to => [], :join_by => :or}.merge(options) - - privs = options[:to] + + privs = options[:to] privs = [privs] unless privs.is_a?(Array) raise DSLError, "has_permission_on either needs a block or :to option" if !block_given? and privs.empty? file, line = file_and_line_number_from_call_stack rule = AuthorizationRule.new(@current_role, privs, context, options[:join_by], - :source_file => file, :source_line => line) + :source_file => file, :source_line => line) @auth_rules << rule if block_given? @current_rule = rule @@ -327,7 +343,7 @@ def description (text) raise DSLError, "description only allowed in role blocks" if @current_role.nil? role_descriptions[@current_role] = text end - + # Sets a human-readable title for the current role. E.g. # role :admin # title "Administrator" @@ -337,7 +353,7 @@ def title (text) raise DSLError, "title only allowed in role blocks" if @current_role.nil? role_titles[@current_role] = text end - + # Used in a has_permission_on block, to may be used to specify privileges # to be assigned to the current role under the conditions specified in # the current block. @@ -463,9 +479,9 @@ def if_permitted_to (privilege, attr_or_hash = nil, options = {}) # only :context option in attr_or_hash: attr_or_hash = nil if attr_or_hash.is_a?(Hash) and attr_or_hash.empty? @current_rule.append_attribute AttributeWithPermission.new(privilege, - attr_or_hash, options[:context]) + attr_or_hash, options[:context]) end - + # In an if_attribute statement, is says that the value has to be # met exactly by the if_attribute attribute. For information on the block # argument, see if_attribute. @@ -498,7 +514,7 @@ def does_not_contain (&block) def intersects_with (&block) [:intersects_with, block] end - + # In an if_attribute statement, is_in says that the value has to # contain the attribute value. # For information on the block argument, see if_attribute. @@ -510,7 +526,7 @@ def is_in (&block) def is_not_in (&block) [:is_not_in, block] end - + # Less than def lt (&block) [:lt, block] @@ -545,11 +561,11 @@ def parse_attribute_conditions_hash! (hash) end hash.merge!(merge_hash) end - + def file_and_line_number_from_call_stack caller_parts = caller(2).first.split(':') [caller_parts[0] == "(eval)" ? nil : caller_parts[0], - caller_parts[1] && caller_parts[1].to_i] + caller_parts[1] && caller_parts[1].to_i] end end end From 920cafbb93af2a7a0d101d09d59952f7226a3231 Mon Sep 17 00:00:00 2001 From: yarivNatural Date: Sun, 23 Dec 2012 14:05:39 +0200 Subject: [PATCH 3/3] Modify authorization.rb to always reload from database. Updated the gem version. --- declarative_authorization.gemspec | 2 +- lib/declarative_authorization/authorization.rb | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 2 deletions(-) diff --git a/declarative_authorization.gemspec b/declarative_authorization.gemspec index 009f2add..a66311a7 100644 --- a/declarative_authorization.gemspec +++ b/declarative_authorization.gemspec @@ -2,7 +2,7 @@ Gem::Specification.new do |s| s.name = "declarative_authorization" - s.version = "0.5.6" + s.version = "0.5.7" s.required_ruby_version = ">= 1.8.6" s.authors = ["Steffen Bartsch"] diff --git a/lib/declarative_authorization/authorization.rb b/lib/declarative_authorization/authorization.rb index 6a4ce4e7..3dc73bea 100644 --- a/lib/declarative_authorization/authorization.rb +++ b/lib/declarative_authorization/authorization.rb @@ -278,6 +278,19 @@ def roles_with_hierarchy_for(user) flatten_roles(roles_for(user)) end + def self.force_reload + @@force_reload = true + end + + def self.force_reload? + #if defined? @@force_reload + # temp = @@force_reload + # @@force_reload = false + #end + #temp + true + end + def self.development_reload? if Rails.env.development? mod_time = AUTH_DSL_FILES.map { |m| File.mtime(m) rescue Time.at(0) }.flatten.max @@ -293,7 +306,7 @@ def self.development_reload? # yet. If +dsl_file+ is given, it is passed on to Engine.new and # a new instance is always created. def self.instance (dsl_file = nil) - if dsl_file or development_reload? + if dsl_file or development_reload? or force_reload? @@instance = new(dsl_file) else @@instance ||= new