Module: Zuul::ActiveRecord::AuthorizationMethods::InstanceMethods

Defined in:
lib/zuul/active_record.rb

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.included(base) ⇒ Object



213
214
215
# File 'lib/zuul/active_record.rb', line 213

def self.included(base)
  # TODO figure out how to delegate tasks to self.class
end

Instance Method Details

#auth_scope(scope = nil, *exec_args, &block) ⇒ Object

Return the requested scope, call a method within a scope or execute an optional block within that scope

If an optional block is passed, it will be executed within the provided scope. This allows you to call methods on the model or the auth scope without having to specify a scope each time. The exec_args hash can be used to pass arguments through to the block.

If a block is not passed, exec_args can be used to provide a method and arguments to be called on the object within the requested scope.

The reason this is defined separately at the class and instance level is because it uses instance_exec to execute the block within the scope of the object (either class or instance) and then uses method_missing temporarily to provide the auth scope methods.



233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
# File 'lib/zuul/active_record.rb', line 233

def auth_scope(scope=nil, *exec_args, &block)
  scope ||= current_auth_scope
  raise ::Zuul::Exceptions::UndefinedScope unless auth_scopes.has_key?(scope)

  if block_given? || (exec_args.length > 0 && exec_args[0].is_a?(Symbol) && respond_to?(exec_args[0]))
    old_scope = current_auth_scope
    self.current_auth_scope = scope
    
    instance_eval do
      def method_missing (meth,*args)
        return auth_scopes[current_auth_scope].send(meth, *args) if auth_scopes[current_auth_scope].respond_to?(meth)
        raise NoMethodError, "#{self.class.name}##{meth} does not exist."
      end
    end
    exec_result = block_given? ? instance_exec(*exec_args, &block) : send(exec_args.slice!(0), *exec_args)
    instance_eval do
      undef method_missing
    end
    
    self.current_auth_scope = old_scope
    return exec_result
  end

  auth_scopes[scope]
end

#auth_scope_eval(scope = nil, &block) ⇒ Object



259
260
261
# File 'lib/zuul/active_record.rb', line 259

def auth_scope_eval(scope=nil, &block)
  self.class.auth_scope_eval(scope, &block)
end

#auth_scopesObject



217
218
219
# File 'lib/zuul/active_record.rb', line 217

def auth_scopes
  self.class.auth_scopes
end

#current_auth_scopeObject



263
264
265
# File 'lib/zuul/active_record.rb', line 263

def current_auth_scope
  self.class.current_auth_scope
end

#current_auth_scope=(scope) ⇒ Object



267
268
269
# File 'lib/zuul/active_record.rb', line 267

def current_auth_scope=(scope)
  self.class.current_auth_scope = scope
end

#sql_is_or_equal(value) ⇒ Object

Simple helper for “IS NULL” vs “= ‘VALUE’” SQL syntax (this must already exist somewhere in AREL? can’t find it though…)



331
332
333
# File 'lib/zuul/active_record.rb', line 331

def sql_is_or_equal(value)
  value.nil? ? "IS" : "="
end

#target_permission(permission, context, force_context = nil) ⇒ Object

Looks for the permission slug with the closest contextual match, working it’s way upwards.

If the provided permission is already a Permission, just return it without checking for a match.

This allows a way to provide a specific permission that isn’t necessarily the best match for the provided context to metods like assign_permission, but still assign them in the provided context, letting you assign a permission like [‘edit’, SomeThing, nil] to the resource SomeThing.find(1), even if you also have a [‘edit’, SomeThing, 1] permission.



301
302
303
304
305
306
307
308
309
310
311
312
313
# File 'lib/zuul/active_record.rb', line 301

def target_permission(permission, context, force_context=nil)
  auth_scope_eval do
    return permission if permission.is_a?(permission_class)
    force_context ||= config.force_context
    
    context = Zuul::Context.parse(context)
    target_permission = permission_class.where(:slug => permission.to_s.underscore, :context_type => context.class_name, :context_id => context.id).first
    return target_permission if force_context
    target_permission ||= permission_class.where(:slug => permission.to_s.underscore, :context_type => context.class_name, :context_id => nil).first unless context.id.nil?
    target_permission ||= permission_class.where(:slug => permission.to_s.underscore, :context_type => nil, :context_id => nil).first unless context.class_name.nil?
    target_permission
  end
end

#target_role(role, context, force_context = nil) ⇒ Object

Looks for the role slug with the closest contextual match, working it’s way up the context chain.

If the provided role is already a Role, just return it without checking for a match.

This allows a way to provide a specific role that isn’t necessarily the best match for the provided context to methods like assign_role, but still assign them in the provided context, letting you assign a role like [‘admin’, SomeThing, nil] to the resource SomeThing.find(1), even if you also have a [‘admin’, SomeThing, 1] role.



279
280
281
282
283
284
285
286
287
288
289
290
291
# File 'lib/zuul/active_record.rb', line 279

def target_role(role, context, force_context=nil)
  auth_scope_eval do
    return role if role.is_a?(role_class)
    force_context ||= config.force_context
    
    context = Zuul::Context.parse(context)
    target_role = role_class.where(:slug => role.to_s.underscore, :context_type => context.class_name, :context_id => context.id).first
    return target_role if force_context
    target_role ||= role_class.where(:slug => role.to_s.underscore, :context_type => context.class_name, :context_id => nil).first unless context.id.nil?
    target_role ||= role_class.where(:slug => role.to_s.underscore, :context_type => nil, :context_id => nil).first unless context.class_name.nil?
    target_role
  end
end

#verify_target_context(target, context, force_context = nil) ⇒ Object

Verifies whether a role or permission (target) is allowed to be used within the provided context. The target’s context must either match the one provided or be higher up the context chain.

SomeThing, 1

CANNOT be used with [SomeThing, nil] or [OtherThing, 1]

SomeThing, nil

CAN be used for [SomeThing, 1], [SomeThing, 2], etc.

nil, nil

global targets can be used for ANY context



321
322
323
324
325
326
327
# File 'lib/zuul/active_record.rb', line 321

def verify_target_context(target, context, force_context=nil)
  return false if target.nil?
  force_context ||= auth_scope.config.force_context
  context = Zuul::Context.parse(context)
  return (target.context.class_name == context.class_name && target.context.id == context.id) if force_context
  (target.context.class_name.nil? && target.context.id.nil?) || (target.context.class_name == context.class_name && (target.context.id.nil? || target.context.id == context.id))
end