| Class | Authorization::Engine |
| In: |
lib/authorization.rb
|
| Parent: | Object |
Authorization::Engine implements the reference monitor. It may be used for querying the permission and retrieving obligations under which a certain privilege is granted for the current user.
| roles | [R] |
Returns an instance of Engine, which is created if there isn‘t one yet. If dsl_file is given, it is passed on to Engine.new and a new instance is always created.
# File lib/authorization.rb, line 178
178: def self.instance (dsl_file = nil)
179: if dsl_file or ENV['RAILS_ENV'] == 'development'
180: @@instance = new(dsl_file)
181: else
182: @@instance ||= new
183: end
184: end
If reader is not given, a new one is created with the default authorization configuration of AUTH_DSL_FILE. If given, may be either a Reader object or a path to a configuration file.
# File lib/authorization.rb, line 50
50: def initialize (reader = nil)
51: if reader.nil?
52: begin
53: reader = Reader::DSLReader.load(AUTH_DSL_FILE)
54: rescue SystemCallError
55: reader = Reader::DSLReader.new
56: end
57: elsif reader.is_a?(String)
58: reader = Reader::DSLReader.load(reader)
59: end
60: @privileges = reader.privileges_reader.privileges
61: # {priv => [[priv, ctx],...]}
62: @privilege_hierarchy = reader.privileges_reader.privilege_hierarchy
63: @auth_rules = reader.auth_rules_reader.auth_rules
64: @roles = reader.auth_rules_reader.roles
65: @role_hierarchy = reader.auth_rules_reader.role_hierarchy
66:
67: # {[priv, ctx] => [priv, ...]}
68: @rev_priv_hierarchy = {}
69: @privilege_hierarchy.each do |key, value|
70: value.each do |val|
71: @rev_priv_hierarchy[val] ||= []
72: @rev_priv_hierarchy[val] << key
73: end
74: end
75: end
Returns the obligations to be met by the current user for the given privilege as an array of obligation hashes in form of
[{:object_attribute => obligation_value, ...}, ...]
where obligation_value is either (recursively) another obligation hash or a value spec, such as
[operator, literal_value]
The obligation hashes in the array should be OR‘ed, conditions inside the hashes AND‘ed.
Example
{:branch => {:company => [:is, 24]}, :active => [:is, true]}
Options
# File lib/authorization.rb, line 163
163: def obligations (privilege, options = {})
164: options = {:context => nil}.merge(options)
165: user, roles, privileges = user_roles_privleges_from_options(privilege, options)
166: attr_validator = AttributeValidator.new(user)
167: matching_auth_rules(roles, privileges, options[:context]).collect do |rule|
168: #p rule
169: #obligation = {}
170: rule.attributes.collect {|attr| attr.obligation(attr_validator) }
171: #obligation
172: end.flatten
173: end
Returns true if privilege is met by the current user. Raises AuthorizationError otherwise. privilege may be given with or without context. In the latter case, the :context option is required.
Options:
# File lib/authorization.rb, line 97
97: def permit! (privilege, options = {})
98: return true if Authorization.ignore_access_control
99: options = {
100: :object => nil,
101: :skip_attribute_test => false,
102: :context => nil
103: }.merge(options)
104: options[:context] ||= options[:object] && options[:object].class.table_name.to_sym rescue NoMethodError
105:
106: user, roles, privileges = user_roles_privleges_from_options(privilege, options)
107:
108: # find a authorization rule that matches for at least one of the roles and
109: # at least one of the given privileges
110: attr_validator = AttributeValidator.new(user, options[:object])
111: #puts "All rules: #{@auth_rules.inspect}"
112: #rules_matching_roles = @auth_rules.select {|r| roles.include?(r.role) }
113: #puts "Matching for roles: #{rules_matching_roles.inspect}"
114: #puts "Matching rules for user #{user.inspect},"
115: #puts " roles #{roles.inspect},"
116: #puts " privs #{privileges.inspect}:"
117: #puts " #{matching_auth_rules(roles, privileges).inspect}"
118: rules = matching_auth_rules(roles, privileges, options[:context])
119: if rules.empty?
120: raise NotAuthorized, "No matching rules found for #{privilege} for #{user.inspect} " +
121: "(roles #{roles.inspect}, privileges #{privileges.inspect}, " +
122: "context #{options[:context].inspect})."
123: end
124:
125: grant_permission = rules.any? do |rule|
126: options[:skip_attribute_test] or
127: rule.attributes.empty? or
128: rule.attributes.any? {|attr| attr.validate? attr_validator }
129: end
130: unless grant_permission
131: raise AttributeAuthorizationError, "#{privilege} not allowed for #{user.inspect} on #{options[:object].inspect}."
132: end
133: true
134: end
Calls permit! but rescues the AuthorizationException and returns false instead. If no exception is raised, permit? returns true and yields to the optional block.
# File lib/authorization.rb, line 139
139: def permit? (privilege, options = {}, &block) # :yields:
140: permit!(privilege, options)
141: yield if block_given?
142: true
143: rescue NotAuthorized
144: false
145: end