class Hoodoo::Services::Permissions
The Permissions
class provides a way to store and recall information on action behaviour for resources. It is just a way to store and query this information; actually enforcing the result is up to the caller.
Permissions
are based on the standard actions - list
, show
, create
, update
and delete
- with defined permissions of constants DENY
(prohibit access), ALLOW
(allow access) and ASK
. The intention of ASK
is that some other component - usually a service application - should be passed details of the request and asked if it should be permitted.
Callers must ensure they only use the DENY
, ALLOW
and ASK
constants defined herein, without making assumptions about their assigned values.
There is both a default set of permissions in addition to per-resource permissions and there is a fallback for cases where a permission for a particular action has not been defined. This lets you define the baseline behaviour in the fallback cases and only describe exceptions to that baseline through the Permissions
interface, minimising caller workload.
Hoodoo::Services::Middleware
uses an instance of this class to determine whether or not it should pass on inbound requests to service applications.
Example:
Here, an object is created with a default fallback of DENY
, then has the action “list” allowed for all resources and says that resource “Member” must ask someone for permission if its “show” action is requested. Another resource “Ping” allows any action unconditionally.
p = Hoodoo::Services::Permissions.new p.set_default( :list, Hoodoo::Services::Permissions::ALLOW ) p.set_resource( :Member, :show, Hoodoo::Services::Permissions::ASK ) p.set_resource_fallback( :Ping, Hoodoo::Services::Permissions::ALLOW ) puts JSON.pretty_generate( p.to_h() ) # Yields... # # { # "default": { # "else": "deny", # "actions": { # "list": "allow" # } # }, # "resources": { # "Member": { # "actions": { # "show": "ask" # } # }, # "Ping": { # "else": "allow" # } # } # }
Constants
- ALLOW
Permission is granted; the action should be permitted.
- ALLOWED_POLICIES
All currently known (allowed/supported) permission policies.
- ASK
Something else (e.g. a service application) needs to be asked to see if it permits the action.
- DENY
Permission is denied; the action should not be permitted.
Public Class Methods
Create a new Permissions
instance, optionally from a Hash of the format returned by to_h
.
By default the object is initialised with a default fallback which denies all actions for all resources.
# File lib/hoodoo/services/services/permissions.rb, line 98 def initialize( hash = nil ) if hash.nil? @permissions = {} set_default_fallback( DENY ) else from_h!( hash ) end end
Public Instance Methods
Overwrite this instances’s permissions with those from the given Hash.
hash
-
Permissions
hash, which must come (directly or indirectly) from ato_h
call.
# File lib/hoodoo/services/services/permissions.rb, line 214 def from_h!( hash ) @permissions = Hoodoo::Utilities.stringify( hash ) end
Merge the permissions described by the given Hash with those inside this instance. This will add to, or overwrite permissions with those from the given input Hash.
hash
-
Permissions
hash, which must come (directly or indirectly) from ato_h
call.
# File lib/hoodoo/services/services/permissions.rb, line 225 def merge!( hash ) @permissions = Hoodoo::Utilities.deep_merge_into( @permissions, Hoodoo::Utilities.stringify( hash ) ) end
For the given resource, is the given action permitted? Returns one of the ALLOW
, DENY
or ASK
constant values.
resource_name
-
Resource name as a Symbol or String, e.g. “
Purchase
” or:Member
. action_name
-
Action as a String or Symbol, from:
list
,show
,create
,update
ordelete
.
# File lib/hoodoo/services/services/permissions.rb, line 183 def permitted?( resource_name, action_name ) resource_name = resource_name.to_s action_name = action_name.to_s tree = if @permissions.has_key?( 'resources' ) @permissions[ 'resources' ][ resource_name ] end || {} result = permitted_in?( tree, action_name ) if result.nil? tree = @permissions[ 'default' ] || {} result = permitted_in?( tree, action_name ) end return result || DENY end
Set the default permission for the given action. If a resource does not have a specific entry for it in the Permissions
object but the action matches the given name, then this permission is used.
action_name
-
Action as a String or Symbol, from:
list
,show
,create
,update
ordelete
. permission
# File lib/hoodoo/services/services/permissions.rb, line 129 def set_default( action_name, permission ) action_name = action_name.to_s @permissions[ 'default' ] ||= {} @permissions[ 'default' ][ 'actions' ] ||= {} @permissions[ 'default' ][ 'actions' ][ action_name ] = permission end
Set the default fallback for actions. If a resource does not have a specific entry for it in the Permissions
object and if the action does not have a default permission, then this permission used.
# File lib/hoodoo/services/services/permissions.rb, line 113 def set_default_fallback( permission ) action_name = action_name.to_s @permissions[ 'default' ] ||= {} @permissions[ 'default' ][ 'else' ] = permission end
Set the permissions an action on a resource.
resource_name
-
Resource name as a Symbol or String, e.g. “
Purchase
” or:Member
. action_name
-
Action as a String or Symbol, from:
list
,show
,create
,update
ordelete
. permission
# File lib/hoodoo/services/services/permissions.rb, line 164 def set_resource( resource_name, action_name, permission ) resource_name = resource_name.to_s action_name = action_name.to_s @permissions[ 'resources' ] ||= {} @permissions[ 'resources' ][ resource_name ] ||= {} @permissions[ 'resources' ][ resource_name ][ 'actions' ] ||= {} @permissions[ 'resources' ][ resource_name ][ 'actions' ][ action_name ] = permission end
Set the default fallback for a resource. If the resource is asked to perform an action that’s not otherwise listed in the resource’s entry in the Permissions
object, then this permission is used.
resource_name
-
Resource name as a Symbol or String, e.g. “
Purchase
” or:Member
. permission
# File lib/hoodoo/services/services/permissions.rb, line 146 def set_resource_fallback( resource_name, permission ) resource_name = resource_name.to_s @permissions[ 'resources' ] ||= {} @permissions[ 'resources' ][ resource_name ] ||= {} @permissions[ 'resources' ][ resource_name ][ 'else' ] = permission end
Return a Hash representative of this permissions object, which can be stored elsewhere, used to initialise another instance or written to an existing instance with from_h!
.
# File lib/hoodoo/services/services/permissions.rb, line 205 def to_h @permissions end