Class: Authorization::Engine
- Inherits:
-
Object
- Object
- Authorization::Engine
- Defined in:
- lib/declarative_authorization/authorization.rb
Overview
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.
Defined Under Namespace
Classes: AttributeValidator
Instance Attribute Summary collapse
-
#auth_rules ⇒ Object
readonly
Returns the value of attribute auth_rules.
-
#privilege_hierarchy ⇒ Object
readonly
Returns the value of attribute privilege_hierarchy.
-
#privileges ⇒ Object
readonly
Returns the value of attribute privileges.
-
#rev_priv_hierarchy ⇒ Object
readonly
Returns the value of attribute rev_priv_hierarchy.
-
#rev_role_hierarchy ⇒ Object
readonly
Returns the value of attribute rev_role_hierarchy.
-
#role_descriptions ⇒ Object
readonly
Returns the value of attribute role_descriptions.
-
#role_hierarchy ⇒ Object
readonly
Returns the value of attribute role_hierarchy.
-
#role_titles ⇒ Object
readonly
Returns the value of attribute role_titles.
-
#roles ⇒ Object
readonly
Returns the value of attribute roles.
Class Method Summary collapse
-
.instance(dsl_file = nil) ⇒ Object
Returns an instance of Engine, which is created if there isn’t one yet.
Instance Method Summary collapse
-
#description_for(role) ⇒ Object
Returns the description for the given role.
-
#initialize(reader = nil) ⇒ Engine
constructor
If
reader
is not given, a new one is created with the default authorization configuration ofAUTH_DSL_FILE
. -
#initialize_copy(from) ⇒ Object
:nodoc:.
-
#obligations(privilege, options = {}) ⇒ Object
Returns the obligations to be met by the current user for the given privilege as an array of obligation hashes in form of [=> 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. -
#permit!(privilege, options = {}) ⇒ Object
Returns true if privilege is met by the current user.
-
#permit?(privilege, options = {}, &block) ⇒ Boolean
Calls permit! but rescues the AuthorizationException and returns false instead.
-
#roles_for(user) ⇒ Object
Returns the role symbols of the given user.
-
#roles_with_hierarchy_for(user) ⇒ Object
Returns the role symbols and inherritted role symbols for the given user.
-
#title_for(role) ⇒ Object
Returns the title for the given role.
Constructor Details
#initialize(reader = nil) ⇒ Engine
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.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/declarative_authorization/authorization.rb', line 67 def initialize (reader = nil) if reader.nil? begin reader = Reader::DSLReader.load(AUTH_DSL_FILE) rescue SystemCallError reader = Reader::DSLReader.new end elsif reader.is_a?(String) reader = Reader::DSLReader.load(reader) end @privileges = reader.privileges_reader.privileges # {priv => [[priv, ctx],...]} @privilege_hierarchy = reader.privileges_reader.privilege_hierarchy @auth_rules = reader.auth_rules_reader.auth_rules @roles = reader.auth_rules_reader.roles @role_hierarchy = reader.auth_rules_reader.role_hierarchy @role_titles = reader.auth_rules_reader.role_titles @role_descriptions = reader.auth_rules_reader.role_descriptions @reader = reader # {[priv, ctx] => [priv, ...]} @rev_priv_hierarchy = {} @privilege_hierarchy.each do |key, value| value.each do |val| @rev_priv_hierarchy[val] ||= [] @rev_priv_hierarchy[val] << key end end @rev_role_hierarchy = {} @role_hierarchy.each do |higher_role, lower_roles| lower_roles.each do |role| (@rev_role_hierarchy[role] ||= []) << higher_role end end end |
Instance Attribute Details
#auth_rules ⇒ Object (readonly)
Returns the value of attribute auth_rules.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def auth_rules @auth_rules end |
#privilege_hierarchy ⇒ Object (readonly)
Returns the value of attribute privilege_hierarchy.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def privilege_hierarchy @privilege_hierarchy end |
#privileges ⇒ Object (readonly)
Returns the value of attribute privileges.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def privileges @privileges end |
#rev_priv_hierarchy ⇒ Object (readonly)
Returns the value of attribute rev_priv_hierarchy.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def rev_priv_hierarchy @rev_priv_hierarchy end |
#rev_role_hierarchy ⇒ Object (readonly)
Returns the value of attribute rev_role_hierarchy.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def rev_role_hierarchy @rev_role_hierarchy end |
#role_descriptions ⇒ Object (readonly)
Returns the value of attribute role_descriptions.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def role_descriptions @role_descriptions end |
#role_hierarchy ⇒ Object (readonly)
Returns the value of attribute role_hierarchy.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def role_hierarchy @role_hierarchy end |
#role_titles ⇒ Object (readonly)
Returns the value of attribute role_titles.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def role_titles @role_titles end |
#roles ⇒ Object (readonly)
Returns the value of attribute roles.
60 61 62 |
# File 'lib/declarative_authorization/authorization.rb', line 60 def roles @roles end |
Class Method Details
.instance(dsl_file = nil) ⇒ Object
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.
252 253 254 255 256 257 258 |
# File 'lib/declarative_authorization/authorization.rb', line 252 def self.instance (dsl_file = nil) if dsl_file or ENV['RAILS_ENV'] == 'development' @@instance = new(dsl_file) else @@instance ||= new end end |
Instance Method Details
#description_for(role) ⇒ Object
Returns the description for the given role. The description may be specified with the authorization rules. Returns nil
if none was given.
216 217 218 |
# File 'lib/declarative_authorization/authorization.rb', line 216 def description_for (role) role_descriptions[role] end |
#initialize_copy(from) ⇒ Object
:nodoc:
104 105 106 107 108 109 110 |
# File 'lib/declarative_authorization/authorization.rb', line 104 def initialize_copy (from) # :nodoc: [ :privileges, :privilege_hierarchy, :roles, :role_hierarchy, :role_titles, :role_descriptions, :rev_priv_hierarchy, :rev_role_hierarchy ].each {|attr| instance_variable_set(:"@#{attr}", from.send(attr).clone) } @auth_rules = from.auth_rules.collect {|rule| rule.clone} end |
#obligations(privilege, options = {}) ⇒ Object
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!
204 205 206 207 208 209 210 211 |
# File 'lib/declarative_authorization/authorization.rb', line 204 def obligations (privilege, = {}) = {:context => nil}.merge() user, roles, privileges = (privilege, ) attr_validator = AttributeValidator.new(self, user, nil, privilege, [:context]) matching_auth_rules(roles, privileges, [:context]).collect do |rule| rule.obligations(attr_validator) end.flatten end |
#permit!(privilege, options = {}) ⇒ Object
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.
132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 |
# File 'lib/declarative_authorization/authorization.rb', line 132 def permit! (privilege, = {}) return true if Authorization.ignore_access_control = { :object => nil, :skip_attribute_test => false, :context => nil }.merge() # Make sure we're handling all privileges as symbols. privilege = privilege.is_a?( Array ) ? privilege.flatten.collect { |priv| priv.to_sym } : privilege.to_sym # # If the object responds to :proxy_reflection, we're probably working with # an association proxy. Use 'new' to leverage ActiveRecord's builder # functionality to obtain an object against which we can check permissions. # # Example: permit!( :edit, :object => user.posts ) # if [:object].respond_to?( :proxy_reflection ) && [:object].respond_to?( :new ) [:object] = [:object].new end [:context] ||= [:object] && [:object].class.to_s.downcase.pluralize.to_sym rescue NoMethodError user, roles, privileges = (privilege, ) # find a authorization rule that matches for at least one of the roles and # at least one of the given privileges attr_validator = AttributeValidator.new(self, user, [:object], privilege, [:context]) rules = matching_auth_rules(roles, privileges, [:context]) if rules.empty? raise NotAuthorized, "No matching rules found for #{privilege} for #{user.inspect} " + "(roles #{roles.inspect}, privileges #{privileges.inspect}, " + "context #{[:context].inspect})." end # Test each rule in turn to see whether any one of them is satisfied. unless rules.any? {|rule| rule.validate?(attr_validator, [:skip_attribute_test])} raise AttributeAuthorizationError, "#{privilege} not allowed for #{user.inspect} on #{([:object] || [:context]).inspect}." end true end |
#permit?(privilege, options = {}, &block) ⇒ Boolean
Calls permit! but rescues the AuthorizationException and returns false instead. If no exception is raised, permit? returns true and yields to the optional block.
180 181 182 183 184 185 186 |
# File 'lib/declarative_authorization/authorization.rb', line 180 def permit? (privilege, = {}, &block) # :yields: permit!(privilege, ) yield if block_given? true rescue NotAuthorized false end |
#roles_for(user) ⇒ Object
Returns the role symbols of the given user.
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 |
# File 'lib/declarative_authorization/authorization.rb', line 228 def roles_for (user) raise AuthorizationUsageError, "User object doesn't respond to roles" \ if !user.respond_to?(:role_symbols) and !user.respond_to?(:roles) RAILS_DEFAULT_LOGGER.info("The use of user.roles is deprecated. Please add a method " + "role_symbols to your User model.") if defined?(RAILS_DEFAULT_LOGGER) and !user.respond_to?(:role_symbols) roles = user.respond_to?(:role_symbols) ? user.role_symbols : user.roles raise AuthorizationUsageError, "User.#{user.respond_to?(:role_symbols) ? 'role_symbols' : 'roles'} " + "doesn't return an Array of Symbols (#{roles.inspect})" \ if !roles.is_a?(Array) or (!roles.empty? and !roles[0].is_a?(Symbol)) (roles.empty? ? [:guest] : roles) end |
#roles_with_hierarchy_for(user) ⇒ Object
Returns the role symbols and inherritted role symbols for the given user
245 246 247 |
# File 'lib/declarative_authorization/authorization.rb', line 245 def roles_with_hierarchy_for(user) flatten_roles(roles_for(user)) end |
#title_for(role) ⇒ Object
Returns the title for the given role. The title may be specified with the authorization rules. Returns nil
if none was given.
223 224 225 |
# File 'lib/declarative_authorization/authorization.rb', line 223 def title_for (role) role_titles[role] end |