Class: ApiEngineBase::Authorization::Role
- Inherits:
-
Object
- Object
- ApiEngineBase::Authorization::Role
- Defined in:
- lib/api_engine_base/authorization/role.rb
Instance Attribute Summary collapse
-
#allow_everything ⇒ Object
readonly
Returns the value of attribute allow_everything.
-
#description ⇒ Object
readonly
Returns the value of attribute description.
-
#entities ⇒ Object
readonly
Returns the value of attribute entities.
-
#name ⇒ Object
readonly
Returns the value of attribute name.
Class Method Summary collapse
- .create_role(name:, description:, entities: nil, allow_everything: false) ⇒ Object
- .roles ⇒ Object
- .roles_reset! ⇒ Object
Instance Method Summary collapse
- #authorized?(controller:, method:, user:) ⇒ Boolean
- #controller_entity_mapping ⇒ Object
- #guards ⇒ Object
-
#initialize(name:, description:, entities:, allow_everything: false) ⇒ Role
constructor
A new instance of Role.
Constructor Details
#initialize(name:, description:, entities:, allow_everything: false) ⇒ Role
Returns a new instance of Role.
39 40 41 42 43 44 |
# File 'lib/api_engine_base/authorization/role.rb', line 39 def initialize(name:, description:, entities:, allow_everything: false) @name = name @entities = Array(entities) @description = description @allow_everything = allow_everything end |
Instance Attribute Details
#allow_everything ⇒ Object (readonly)
Returns the value of attribute allow_everything.
38 39 40 |
# File 'lib/api_engine_base/authorization/role.rb', line 38 def allow_everything @allow_everything end |
#description ⇒ Object (readonly)
Returns the value of attribute description.
38 39 40 |
# File 'lib/api_engine_base/authorization/role.rb', line 38 def description @description end |
#entities ⇒ Object (readonly)
Returns the value of attribute entities.
38 39 40 |
# File 'lib/api_engine_base/authorization/role.rb', line 38 def entities @entities end |
#name ⇒ Object (readonly)
Returns the value of attribute name.
38 39 40 |
# File 'lib/api_engine_base/authorization/role.rb', line 38 def name @name end |
Class Method Details
.create_role(name:, description:, entities: nil, allow_everything: false) ⇒ Object
7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
# File 'lib/api_engine_base/authorization/role.rb', line 7 def create_role(name:, description:, entities: nil, allow_everything: false) if roles[name] raise Error, "Role [#{name}] already exists. Must use different name" end if allow_everything Rails.logger.info { "Authorization Role: #{name} is granted authorization to all roles" } else unless Array(entities).all? { Entity === _1 } raise Error, "Parameter :entities must include objects of or inherited by ApiEngineBase::Authorization::Entity" end end roles[name] = new(name:, description:, entities:, allow_everything:) # A role is `intended` to be immutable (attr_reader) # Once the role is defined it will not get changed # After it is created, add the mapping to the source of truth list of mapped method names to their controllers ApiEngineBase::Authorization.add_mapping!(role: roles[name]) roles[name] end |
.roles ⇒ Object
29 30 31 |
# File 'lib/api_engine_base/authorization/role.rb', line 29 def roles @roles ||= ActiveSupport::HashWithIndifferentAccess.new end |
.roles_reset! ⇒ Object
33 34 35 |
# File 'lib/api_engine_base/authorization/role.rb', line 33 def roles_reset! @roles = ActiveSupport::HashWithIndifferentAccess.new end |
Instance Method Details
#authorized?(controller:, method:, user:) ⇒ Boolean
46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/api_engine_base/authorization/role.rb', line 46 def (controller:, method:, user:) return_value = { role: name, description: } return return_value.merge(authorized: true, reason: "#{name} allows all authorizations") if allow_everything matched_controllers = controller_entity_mapping[controller] # if Role does not match any of the controllers # explicitly return nil here to ensure upstream knows this role does not care about the route return return_value.merge(authorized: nil, reason: "#{name} does not match") if matched_controllers.nil? rejected_entities = matched_controllers.map do |entity| case entity.matches?(controller:, method:) when false, nil { authorized: false, entity: entity.name, controller:, readable: entity.humanize, status: "Rejected by inclusion" } when true # Entity matches all inclusions if entity.(user:) # Do nothing! Entity has authorized the user else { authorized: false, entity: entity.name, controller:, readable: entity.humanize, status: "Rejected via custom Entity Authorization" } end end end.compact # If there were no entities that rejected authorization, return authorized return return_value.merge(authorized: true, reason: "All entities approve authorization") if rejected_entities.empty? return_value.merge(authorized: false, reason: "Subset of Entities Rejected authorization", rejected_entities:) end |
#controller_entity_mapping ⇒ Object
96 97 98 |
# File 'lib/api_engine_base/authorization/role.rb', line 96 def controller_entity_mapping @controller_entity_mapping ||= @entities.group_by(&:controller) end |
#guards ⇒ Object
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/api_engine_base/authorization/role.rb', line 75 def guards mapping = {} controller_entity_mapping.each do |controller, entities| mapping[controller] ||= [] entities.map do |entity| if entity.only # We only care about these methods on the controller mapping[controller] += entity.only elsif entity.except # We care about all methods on the controller except these mapping[controller] += controller.instance_methods(false) - entity.except else # We care about all methods on the controller mapping[controller] += controller.instance_methods(false) end end end mapping end |