Class: SkinnyControllers::Policy::Base

Inherits:
Object
  • Object
show all
Defined in:
lib/skinny_controllers/policy/base.rb

Direct Known Subclasses

AllowAll, Default, DenyAll

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(user, object, authorized_via_parent: false) ⇒ Base

Returns a new instance of Base.

Parameters:

  • user (User)

    the being to check if they have access to object

  • object (ActiveRecord::Base)

    the object that we are wanting to check the authorization of user for

  • authorized_via_parent (Boolean) (defaults to: false)

    if this object is authorized via a prior authorization from a parent class / association



12
13
14
15
16
# File 'lib/skinny_controllers/policy/base.rb', line 12

def initialize(user, object, authorized_via_parent: false)
  self.user = user
  self.object = object
  self.authorized_via_parent = authorized_via_parent
end

Dynamic Method Handling

This class handles dynamic methods through the method_missing method

#method_missing(method_name, *args, &block) ⇒ Object

Parameters:

  • method_name (Symbol)
  • args (Array)
  • block (Proc)


21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
# File 'lib/skinny_controllers/policy/base.rb', line 21

def method_missing(method_name, *args, &block)
  # unless the method ends in a question mark, re-route to default method_missing
  return super unless method_name.to_s =~ /(.+)\?/

  action = Regexp.last_match(1)
  # alias destroy to delete
  # TODO: this means that a destroy method, if defined,
  #       will never be called.... good or bad?
  #       should there be a difference between delete and destroy?
  return send('delete?') if action == 'destroy'

  # we know that these methods don't take any parameters,
  # so args and block can be ignored
  SkinnyControllers.logger.warn("method '#{action}' in policy '#{self.class.name}' was not found. Using :default?")
  send(:default?)
end

Instance Attribute Details

#authorized_via_parentObject

Returns the value of attribute authorized_via_parent.



5
6
7
# File 'lib/skinny_controllers/policy/base.rb', line 5

def authorized_via_parent
  @authorized_via_parent
end

#objectObject

Returns the value of attribute object.



5
6
7
# File 'lib/skinny_controllers/policy/base.rb', line 5

def object
  @object
end

#userObject

Returns the value of attribute user.



5
6
7
# File 'lib/skinny_controllers/policy/base.rb', line 5

def user
  @user
end

Instance Method Details

#default?Boolean

if a method is not defined for a particular verb or action, this will be used.

Examples:

Operation::Object::SendReceipt.run is called, since

`send_receipt` doesn't exist in this class, this `default?`
method will be used.

Returns:

  • (Boolean)


48
49
50
# File 'lib/skinny_controllers/policy/base.rb', line 48

def default?
  SkinnyControllers.allow_by_default
end

#read?(o = object) ⇒ Boolean

this should be used when checking access to a single object

Returns:

  • (Boolean)


53
54
55
# File 'lib/skinny_controllers/policy/base.rb', line 53

def read?(o = object)
  default?
end

#read_all?Boolean

this should be used when checking access to multilpe objects it will call read? on each object of the array

if the operation used a scope to find records from an association, then authorized_via_parent could be true, in which case, the loop would be skipped.

TODO: think of a way to override the authorized_via_parent functionality

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
73
# File 'lib/skinny_controllers/policy/base.rb', line 65

def read_all?
  return true if authorized_via_parent
  # This is expensive, so try to avoid it
  # TODO: look in to creating a cache for
  # these look ups that's invalidated upon
  # object save
  accessible = object.map { |ea| read?(ea) }
  accessible.all?
end

#respond_to_missing?(method_name, include_private = false) ⇒ Boolean

Returns:

  • (Boolean)


38
39
40
# File 'lib/skinny_controllers/policy/base.rb', line 38

def respond_to_missing?(method_name, include_private = false)
  method_name.to_s =~ /(.+)\?/ || super
end