Class: Keycardai::OAuth::AccessContext
- Inherits:
-
Object
- Object
- Keycardai::OAuth::AccessContext
- Defined in:
- lib/keycardai/oauth/access_context.rb
Overview
The per-request container of exchanged downstream tokens, keyed by resource, with per-resource error tracking. The grant layer constructs and populates it before the handler runs; handlers read it from the request context. Population is non-throwing by design: failures land on the context so a partial-success flow can proceed when only some exchanges failed.
Reading is split between the throwing accessor #access and the non-throwing getters (#resource_error, #error, #errors?, #status, ...), so handlers can inspect state and choose to proceed, degrade, or fail.
Instance Method Summary collapse
-
#access(resource) ⇒ TokenResponse
The exchanged token for a resource.
-
#error ⇒ Object?
The global (context-wide) error.
-
#error? ⇒ Boolean
Whether a global error was set.
-
#errors ⇒ Hash
{ resources: Hash=> Object, error: Object | nil }.
-
#errors? ⇒ Boolean
Whether a global error or any per-resource error exists.
-
#failed_resources ⇒ Array<String>
Resources with a recorded error.
-
#initialize(tokens = {}) ⇒ AccessContext
constructor
A new instance of AccessContext.
-
#merge(other) ⇒ void
Merge another context's tokens and errors into this one.
-
#resource_error(resource) ⇒ Object?
The recorded error for the resource, nil when it succeeded.
- #resource_error?(resource) ⇒ Boolean
-
#set_bulk_tokens(tokens) ⇒ void
Record multiple successful tokens at once.
-
#set_error(error) ⇒ void
Record a global (context-wide) error.
-
#set_resource_error(resource, error) ⇒ void
Record a per-resource error, clearing any prior token for the resource.
-
#set_token(resource, token) ⇒ void
Record a successful token, clearing any prior error for the resource.
- #status ⇒ "success", ...
-
#successful_resources ⇒ Array<String>
Resources holding a successful token.
Constructor Details
#initialize(tokens = {}) ⇒ AccessContext
Returns a new instance of AccessContext.
17 18 19 20 21 22 |
# File 'lib/keycardai/oauth/access_context.rb', line 17 def initialize(tokens = {}) @tokens = tokens.dup @resource_errors = {} @error = nil @mutex = Mutex.new end |
Instance Method Details
#access(resource) ⇒ TokenResponse
The exchanged token for a resource.
31 32 33 34 35 36 37 38 39 40 |
# File 'lib/keycardai/oauth/access_context.rb', line 31 def access(resource) @mutex.synchronize do raise_access_error("global_error", resource, details: @error) if @error if @resource_errors.key?(resource) raise_access_error("resource_error", resource, details: @resource_errors[resource]) end @tokens[resource] || raise_access_error("missing_token", resource, available: @tokens.keys) end end |
#error ⇒ Object?
Returns the global (context-wide) error.
49 50 51 |
# File 'lib/keycardai/oauth/access_context.rb', line 49 def error @mutex.synchronize { @error } end |
#error? ⇒ Boolean
Returns whether a global error was set.
65 66 67 |
# File 'lib/keycardai/oauth/access_context.rb', line 65 def error? @mutex.synchronize { !@error.nil? } end |
#errors ⇒ Hash
Returns { resources: Hash=> Object, error: Object | nil }.
54 55 56 |
# File 'lib/keycardai/oauth/access_context.rb', line 54 def errors @mutex.synchronize { { resources: @resource_errors.dup, error: @error } } end |
#errors? ⇒ Boolean
Returns whether a global error or any per-resource error exists.
70 71 72 |
# File 'lib/keycardai/oauth/access_context.rb', line 70 def errors? @mutex.synchronize { !@error.nil? || !@resource_errors.empty? } end |
#failed_resources ⇒ Array<String>
Returns resources with a recorded error.
90 91 92 |
# File 'lib/keycardai/oauth/access_context.rb', line 90 def failed_resources @mutex.synchronize { @resource_errors.keys } end |
#merge(other) ⇒ void
This method returns an undefined value.
Merge another context's tokens and errors into this one.
139 140 141 142 143 144 145 146 |
# File 'lib/keycardai/oauth/access_context.rb', line 139 def merge(other) snapshot = other.errors unless snapshot[:error] set_bulk_tokens(other.successful_resources.to_h { |resource| [resource, other.access(resource)] }) end snapshot[:resources].each { |resource, error| set_resource_error(resource, error) } set_error(snapshot[:error]) if snapshot[:error] end |
#resource_error(resource) ⇒ Object?
Returns the recorded error for the resource, nil when it succeeded.
44 45 46 |
# File 'lib/keycardai/oauth/access_context.rb', line 44 def resource_error(resource) @mutex.synchronize { @resource_errors[resource] } end |
#resource_error?(resource) ⇒ Boolean
60 61 62 |
# File 'lib/keycardai/oauth/access_context.rb', line 60 def resource_error?(resource) @mutex.synchronize { @resource_errors.key?(resource) } end |
#set_bulk_tokens(tokens) ⇒ void
This method returns an undefined value.
Record multiple successful tokens at once.
109 110 111 112 113 114 115 116 |
# File 'lib/keycardai/oauth/access_context.rb', line 109 def set_bulk_tokens(tokens) @mutex.synchronize do tokens.each do |resource, token| @resource_errors.delete(resource) @tokens[resource] = token end end end |
#set_error(error) ⇒ void
This method returns an undefined value.
Record a global (context-wide) error.
131 132 133 |
# File 'lib/keycardai/oauth/access_context.rb', line 131 def set_error(error) @mutex.synchronize { @error = error } end |
#set_resource_error(resource, error) ⇒ void
This method returns an undefined value.
Record a per-resource error, clearing any prior token for the resource.
121 122 123 124 125 126 |
# File 'lib/keycardai/oauth/access_context.rb', line 121 def set_resource_error(resource, error) @mutex.synchronize do @tokens.delete(resource) @resource_errors[resource] = error end end |
#set_token(resource, token) ⇒ void
This method returns an undefined value.
Record a successful token, clearing any prior error for the resource. Called by the grant layer, not by handlers.
98 99 100 101 102 103 |
# File 'lib/keycardai/oauth/access_context.rb', line 98 def set_token(resource, token) @mutex.synchronize do @resource_errors.delete(resource) @tokens[resource] = token end end |
#status ⇒ "success", ...
75 76 77 78 79 80 81 82 |
# File 'lib/keycardai/oauth/access_context.rb', line 75 def status @mutex.synchronize do next "error" unless @error.nil? next "partial_error" unless @resource_errors.empty? "success" end end |
#successful_resources ⇒ Array<String>
Returns resources holding a successful token.
85 86 87 |
# File 'lib/keycardai/oauth/access_context.rb', line 85 def successful_resources @mutex.synchronize { @tokens.keys } end |