lib/checkpoint/agent/resolver.rb in checkpoint-1.0.3 vs lib/checkpoint/agent/resolver.rb in checkpoint-1.1.0

- old
+ new

@@ -1,33 +1,63 @@ # frozen_string_literal: true module Checkpoint class Agent - # An Agent Resolver takes a concrete user (or other account/actor) object and - # resolves it into the set of {Agent}s that the user represents. This has the - # effect of allowing a Permit to any of those agents to take effect when - # authorizing an action by this user. + # An Agent Resolver is the bridge between a concrete user (or other + # account/actor) and {Agent}s that the user represents. # - # This implementation only resolves the user into one agent, using the default - # conversion. + # There are two basic operations: # - # To extend the set of {Agent}s resolved, implement a specialized version - # that returns an array of agents from #resolve. This customized + # - Conversion maps an actor to a single Agent + # - Expansion maps an actor to all of the Agents it represents + # + # These allow credentials to be granted, matched, or revoked with the + # appropriate semantics, depending on the operation. In general, a Grant + # is given to or revoked from a single Agent, while matching is applied + # to all Agents the actor represents. + # + # This implementation does not implement any expansion semantics other + # than to convert the actor into an Agent and return it as a list. + # + # To extend the set of {Agent}s resolved, implement a subclass + # that returns an array of agents from #expand. This customized # implementation would typically be injected to an application-wide # {Checkpoint::Authority}, rather than being used directly. # # For example, a custom resolver might add a group agent for each group that # the user is a member of, or IP address-based geographical regions or # organizational affiliations. class Resolver - # Resolve an actor to a list of agents it represents. + # Expand an actor to a list of Agents it represents. # - # If extending or overriding, you will most likely want to either call - # super, or use the default conversion directly. - # @return [[Checkpoint::Agent]] an array of agents for this actor - # @see Checkpoint::Agent.from - def resolve(actor) - [Checkpoint::Agent.from(actor)] + # This implementation simply converts the actor and wraps the resulting + # Agent in an array. + # + # If extending or overriding, you will likely want to call super or + # {#convert} on the concrete actor to make sure that the most specific + # Agent is included. It is acceptable to return subclasses of Agent, + # though that is generally unnecessary because of its design of + # delegating to actor methods. + # + # @return [Agent] an array of agents for this actor + def expand(actor) + [convert(actor)] + end + + # Default conversion from an actor to an {Agent}. + # + # If the actor implements #to_agent, we will delegate to it. Otherwise, + # we will instantiate an {Agent} with the supplied actor. + # + # Override this method to use a different or conditional Agent type. + # + # @return [Agent] the actor converted to an agent + def convert(actor) + if actor.respond_to?(:to_agent) + actor.to_agent + else + Agent.new(actor) + end end end end end