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:

  • the being to check if they have access to object

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

  • (defaults to: false)

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



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

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:



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

def method_missing(method_name, *args, &block)
  # if the method ends in a question mark, re-route to default
  if 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?'.freeze) if action == 'destroy'.freeze

    # we know that these methods don't take any parameters,
    # so args and block can be ignored
    send(:default?)
  else
    super
  end
end

Instance Attribute Details

#authorized_via_parentObject

Returns the value of attribute authorized_via_parent.



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

def authorized_via_parent
  @authorized_via_parent
end

#objectObject

Returns the value of attribute object.



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

def object
  @object
end

#userObject

Returns the value of attribute user.



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

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:



44
45
46
# File 'lib/skinny_controllers/policy/base.rb', line 44

def default?
  SkinnyControllers.allow_by_default
end

#read?(o = object) ⇒ Boolean

this should be used when checking access to a single object

Returns:



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

def read?(o = object)
  o.send(accessible_method, user)
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:



61
62
63
64
65
66
67
68
69
# File 'lib/skinny_controllers/policy/base.rb', line 61

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