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.

Methods

instance   new   obligations   permit!   permit?  

Attributes

roles  [R] 

Public Class methods

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.

[Source]

     # 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.

[Source]

    # 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

Public Instance methods

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

:context
See permit!
:user
See permit!

[Source]

     # 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:

:context
The context part of the privilege. Defaults either to the table_name of the given :object, if given. That is, either :users for :object of type User. Raises AuthorizationUsageError if context is missing and not to be infered.
:object
An context object to test attribute checks against.
:skip_attribute_test
Skips those attribute checks in the authorization rules. Defaults to false.
:user
The user to check the authorization for. Defaults to Authorization#current_user.

[Source]

     # 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.

[Source]

     # 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

[Validate]