module Eaco::Resource

A Resource is an object that can be authorized. It has an {ACL}, that defines the access levels of {Designator}s. {Actor}s have many designators and the highest priority ones that matches the {ACL} yields the access level of the {Actor} to this {Resource}.

If there is no match between the {Actor}'s designators and the {ACL}, then access is denied.

Authorized resources are defined through the DSL, see {DSL::Resource}.

TODO Negative authorizations

@see ACL @see Actor @see Designator

@see DSL::Resource

Public Class Methods

included(base) click to toggle source

@private

# File lib/eaco/resource.rb, line 25
def self.included(base)
  base.extend ClassMethods
end

Public Instance Methods

allows?(action, actor) click to toggle source

@return [Boolean] whether the given action is allowed to the given actor.

@param action [Symbol] @param actor [Actor]

# File lib/eaco/resource.rb, line 147
def allows?(action, actor)
  self.class.allows?(action, actor, self)
end
batch_grant(role, designators) click to toggle source

Grants the given set of designators access as to this Resource as the given role.

@param role [Symbol] @param designators [Array] of {Designator}, see {ACL#add}

@return [ACL]

@see change_acl

# File lib/eaco/resource.rb, line 199
def batch_grant(role, designators)
  self.check_role!(role)

  change_acl do |acl|
    designators.each do |designator|
      acl.add(role, designator)
    end
    acl
  end
end
grant(role, *designator) click to toggle source

Grants the given designator access to this Resource as the given role.

@param role [Symbol] @param designator [Variadic], see {ACL#add}

@return [ACL]

@see change_acl

# File lib/eaco/resource.rb, line 170
def grant(role, *designator)
  self.check_role!(role)

  change_acl {|acl| acl.add(role, *designator) }
end
revoke(*designator) click to toggle source

Revokes the given designator access to this Resource.

@param designator [Variadic], see {ACL#del}

@return [ACL]

@see change_acl

# File lib/eaco/resource.rb, line 185
def revoke(*designator)
  change_acl {|acl| acl.del(*designator) }
end
role_of(actor) click to toggle source

@return [Symbol] the role of the given actor

@param actor [Actor]

# File lib/eaco/resource.rb, line 156
def role_of(actor)
  self.class.role_of(actor, self)
end

Protected Instance Methods

change_acl() { |acl.try(:dup) || class.acl| ... } click to toggle source

Changes the ACL, calling the persistance setter if it changes.

@yield [ACL] the current ACL or a new one if no ACL is set

@return [ACL] the new ACL

# File lib/eaco/resource.rb, line 218
def change_acl
  acl = yield self.acl.try(:dup) || self.class.acl.new

  self.acl = acl unless acl == self.acl

  return self.acl
end
check_role!(role) click to toggle source

Checks whether the given role is valid for this Resource.

@param role [Symbol] the role name.

@raise [Eaco::Error] if not valid.

# File lib/eaco/resource.rb, line 233
def check_role!(role)
  unless self.class.role?(role)
    raise Error,
      "The `#{role}' role is not valid for `#{self.class.name}' objects. " \
      "Valid roles are: `#{self.class.roles.join(', ')}'"
  end
end