Module: Legion::Identity::Broker
- Defined in:
- lib/legion/identity/broker.rb
Constant Summary collapse
- GROUPS_CACHE_TTL =
60- AUDIT_QUEUE_MAX =
1000- AUDIT_DROP_LOG_INTERVAL =
100
Class Method Summary collapse
- .authenticated? ⇒ Boolean
- .credentials_available(provider_name) ⇒ Object
- .credentials_for(provider_name, qualifier: nil, service: nil) ⇒ Object
- .emails ⇒ Object
- .groups ⇒ Object
- .invalidate_groups_cache! ⇒ Object
- .lease_for(provider_name, qualifier: nil) ⇒ Object
- .leases ⇒ Object
- .providers ⇒ Object
- .refresh_credential(provider_name, qualifier: nil) ⇒ Object
- .register_provider(provider_name, provider:, lease:, qualifier: :default, default: false) ⇒ Object
- .renewer_for(provider_name, qualifier: nil) ⇒ Object
- .reset! ⇒ Object
- .shutdown ⇒ Object
- .token_for(provider_name, qualifier: nil, for_context: nil, purpose: nil, context: nil) ⇒ Object
Class Method Details
.authenticated? ⇒ Boolean
96 97 98 |
# File 'lib/legion/identity/broker.rb', line 96 def authenticated? Identity::Process.resolved? end |
.credentials_available(provider_name) ⇒ Object
141 142 143 144 145 |
# File 'lib/legion/identity/broker.rb', line 141 def credentials_available(provider_name) name = provider_name.to_sym all_keys = (renewers.keys + static_leases.keys) all_keys.select { |k| k.first == name }.map(&:last).uniq end |
.credentials_for(provider_name, qualifier: nil, service: nil) ⇒ Object
40 41 42 43 44 45 46 47 |
# File 'lib/legion/identity/broker.rb', line 40 def credentials_for(provider_name, qualifier: nil, service: nil) name = provider_name.to_sym resolved = qualifier || default_qualifier_for(name) lease = lease_for(name, qualifier: resolved) return nil unless lease&.valid? { token: lease.token, provider: name, service: service, lease: lease } end |
.emails ⇒ Object
130 131 132 133 134 |
# File 'lib/legion/identity/broker.rb', line 130 def emails process_state = Identity::Process.identity_hash = process_state[:metadata] || {} Array([:emails]) end |
.groups ⇒ Object
100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 |
# File 'lib/legion/identity/broker.rb', line 100 def groups cached = @groups_cache&.get return cached[:groups] if cached && (Time.now - cached[:fetched_at]) < GROUPS_CACHE_TTL if @groups_fetch_in_progress.make_true begin fetched = fetch_groups @groups_cache.set({ groups: fetched, fetched_at: Time.now }) fetched ensure @groups_fetch_in_progress.make_false end else loop do current = @groups_cache&.get return current[:groups] if current break unless @groups_fetch_in_progress.true? sleep(0.01) end cached ? cached[:groups] : [] end end |
.invalidate_groups_cache! ⇒ Object
126 127 128 |
# File 'lib/legion/identity/broker.rb', line 126 def invalidate_groups_cache! @groups_cache.set(nil) end |
.lease_for(provider_name, qualifier: nil) ⇒ Object
22 23 24 25 26 27 28 29 30 31 32 |
# File 'lib/legion/identity/broker.rb', line 22 def lease_for(provider_name, qualifier: nil) name = provider_name.to_sym resolved = qualifier || default_qualifier_for(name) key = [name, resolved].freeze renewer = renewers[key] return renewer.current_lease if renewer static_ref = static_leases[key] static_ref&.get end |
.leases ⇒ Object
147 148 149 150 151 152 153 154 155 156 157 158 159 160 |
# File 'lib/legion/identity/broker.rb', line 147 def leases result = {} renewers.each do |key, renewer| provider_name, qualifier = key result[provider_name] ||= {} result[provider_name][qualifier] = renewer.current_lease&.to_h end static_leases.each do |key, ref| provider_name, qualifier = key result[provider_name] ||= {} result[provider_name][qualifier] = ref.get&.to_h unless result[provider_name].key?(qualifier) end result end |
.providers ⇒ Object
136 137 138 139 |
# File 'lib/legion/identity/broker.rb', line 136 def providers all_keys = (renewers.keys + static_leases.keys) all_keys.map(&:first).uniq end |
.refresh_credential(provider_name, qualifier: nil) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 |
# File 'lib/legion/identity/broker.rb', line 78 def refresh_credential(provider_name, qualifier: nil) name = provider_name.to_sym resolved = qualifier || default_qualifier_for(name) key = [name, resolved].freeze ref = static_leases[key] return false unless ref provider = provider_instances[name] return false unless provider.respond_to?(:provide_token) new_lease = provider.provide_token return false unless new_lease&.valid? ref.set(new_lease) true end |
.register_provider(provider_name, provider:, lease:, qualifier: :default, default: false) ⇒ Object
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 74 75 76 |
# File 'lib/legion/identity/broker.rb', line 49 def register_provider(provider_name, provider:, lease:, qualifier: :default, default: false) name = provider_name.to_sym qual = qualifier key = [name, qual].freeze # Set default qualifier: first registration or explicit default: true default_qualifiers[name] = qual if default || !default_qualifiers.key?(name) # Store provider instance (first-write-wins per provider name) provider_instances[name] ||= provider # Stop existing renewer for this specific tuple key renewers[key]&.stop! if lease&.expires_at.nil? && !lease&.renewable # Static credential — store without a background renewal thread renewers.delete(key) static_leases[key] = Concurrent::AtomicReference.new(lease) else # Dynamic credential — create LeaseRenewer static_leases.delete(key) renewers[key] = LeaseRenewer.new( provider_name: name, provider: provider, lease: lease ) end end |
.renewer_for(provider_name, qualifier: nil) ⇒ Object
34 35 36 37 38 |
# File 'lib/legion/identity/broker.rb', line 34 def renewer_for(provider_name, qualifier: nil) name = provider_name.to_sym resolved = qualifier || default_qualifier_for(name) renewers[[name, resolved].freeze] end |
.reset! ⇒ Object
175 176 177 178 179 180 181 182 183 |
# File 'lib/legion/identity/broker.rb', line 175 def reset! shutdown @groups_cache = Concurrent::AtomicReference.new(nil) @groups_fetch_in_progress = Concurrent::AtomicBoolean.new(false) @audit_queue = Concurrent::Array.new @audit_drops = Concurrent::AtomicFixnum.new(0) @audit_drainer = nil @audit_drainer_started = Concurrent::AtomicBoolean.new(false) end |
.shutdown ⇒ Object
162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/legion/identity/broker.rb', line 162 def shutdown renewers.each_value do |r| r.stop! rescue Exception # rubocop:disable Lint/RescueException nil end renewers.clear static_leases.clear provider_instances.clear default_qualifiers.clear stop_audit_drainer end |
.token_for(provider_name, qualifier: nil, for_context: nil, purpose: nil, context: nil) ⇒ Object
13 14 15 16 17 18 19 20 |
# File 'lib/legion/identity/broker.rb', line 13 def token_for(provider_name, qualifier: nil, for_context: nil, purpose: nil, context: nil) name = provider_name.to_sym resolved = resolve_qualifier(name, qualifier: qualifier, for_context: for_context) lease = lease_for(name, qualifier: resolved) token = lease&.valid? ? lease.token : nil emit_audit(provider: name, qualifier: resolved, purpose: purpose, context: context, granted: !token.nil?) token end |