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