Module: Hecks::Ports::Authorization
- Defined in:
- lib/hecks/ports/authorization.rb
Overview
TWO YES/NO QUESTIONS AND ONE VALUE an application asks BEFORE
binding a caller — resolved the same way Ports::IdentityGeneration
resolves its own adapter: one adapter registry-wide answers this
port, not a per-aggregate binding, since a domain has no reason to
want a different authorization source per aggregate. What answers
it is deliberately not named here — the governance-backed adapter
is one implementation, not the only possible one, the same way
SequentialIdentity and SecureRandomIdentity are two
implementations of identity_generation.
A caller decides what to DO with the answer — dispatch under that
role, refuse, log, prefer it over some other fallback value — this
only answers the question asked. Nothing here binds a
Runtime::Caller, and nothing here is consulted by
CommandRules::Authorization: that rule still only compares an
ALREADY-BOUND caller's role against a command's, the same as it
always has. spec/act_as_spec.rb remains the precedent for the
OTHER shape — two separate registries, queried directly by name —
for whenever Governance is not in the same boot as the caller;
this port is the same two questions asked through one adapter
when it is.
Constant Summary collapse
- NAME =
"authorization"
Class Method Summary collapse
- .adapter(registry) ⇒ Object
- .authorized_as?(registry, from_role:, to_role:) ⇒ Boolean
- .holds_role?(registry, actor_id:, role:) ⇒ Boolean
- .live_role_for(registry, actor_id:) ⇒ Object
Class Method Details
.adapter(registry) ⇒ Object
43 44 45 46 47 48 49 50 51 52 53 54 55 56 |
# File 'lib/hecks/ports/authorization.rb', line 43 def adapter(registry) implementations = registry.adapters.values.select { |a| a.port == NAME } case implementations.size when 1 then Adapters.const_get(implementations.first.name) when 0 raise Runtime::WiringError, "no adapter implements the #{NAME} port — nothing can answer a role check" else raise Runtime::WiringError, "#{implementations.size} adapters implement the #{NAME} port " \ "(#{implementations.map(&:name).sort.join(', ')}) — the runtime will not choose for you" end end |
.authorized_as?(registry, from_role:, to_role:) ⇒ Boolean
35 36 37 |
# File 'lib/hecks/ports/authorization.rb', line 35 def (registry, from_role:, to_role:) adapter(registry).(registry, from_role: from_role, to_role: to_role) end |
.holds_role?(registry, actor_id:, role:) ⇒ Boolean
31 32 33 |
# File 'lib/hecks/ports/authorization.rb', line 31 def holds_role?(registry, actor_id:, role:) adapter(registry).holds_role?(registry, actor_id: actor_id, role: role) end |
.live_role_for(registry, actor_id:) ⇒ Object
39 40 41 |
# File 'lib/hecks/ports/authorization.rb', line 39 def live_role_for(registry, actor_id:) adapter(registry).live_role_for(registry, actor_id: actor_id) end |