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"
# }
# }
# }
- F
- M
- N
- P
- S
- T
DENY | = | 'deny' |
Permission is denied; the action should not be permitted. |
||
ALLOW | = | 'allow' |
Permission is granted; the action should be permitted. |
||
ASK | = | 'ask' |
Something else (e.g. a service application) needs to be asked to see if it permits the action. |
||
ALLOWED_POLICIES | = | [ DENY, ALLOW, ASK ] |
All currently known (allowed/supported) permission policies. |
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.
Source: show
# 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
Overwrite this instances's permissions with those from the given Hash.
hash
-
Permissions hash, which must come (directly or indirectly) from a to_h call.
Source: show
# 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 a to_h call.
Source: show
# 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
.
Source: show
# 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.
Source: show
# 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.
Source: show
# 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.
Source: show
# 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.
Source: show
# 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