Module: Legion::Identity::Broker

Defined in:
lib/legion/identity/broker.rb

Constant Summary collapse

GROUPS_CACHE_TTL =
60

Class Method Summary collapse

Class Method Details

.authenticated?Boolean

Returns:

  • (Boolean)


71
72
73
# File 'lib/legion/identity/broker.rb', line 71

def authenticated?
  Identity::Process.resolved?
end

.credentials_for(provider_name, service: nil) ⇒ Object



29
30
31
32
33
34
# File 'lib/legion/identity/broker.rb', line 29

def credentials_for(provider_name, service: nil)
  lease = lease_for(provider_name)
  return nil unless lease&.valid?

  { token: lease.token, provider: provider_name.to_sym, service: service, lease: lease }
end

.emailsObject



105
106
107
108
109
# File 'lib/legion/identity/broker.rb', line 105

def emails
  process_state = Identity::Process.identity_hash
   = process_state[:metadata] || {}
  Array([:emails])
end

.groupsObject



75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/legion/identity/broker.rb', line 75

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



101
102
103
# File 'lib/legion/identity/broker.rb', line 101

def invalidate_groups_cache!
  @groups_cache.set(nil)
end

.lease_for(provider_name) ⇒ Object



16
17
18
19
20
21
22
23
# File 'lib/legion/identity/broker.rb', line 16

def lease_for(provider_name)
  name = provider_name.to_sym
  renewer = renewers[name]
  return renewer.current_lease if renewer

  static_ref = static_leases[name]
  static_ref&.get
end

.leasesObject



115
116
117
118
119
# File 'lib/legion/identity/broker.rb', line 115

def leases
  dynamic = renewers.transform_values { |r| r.current_lease&.to_h }
  static  = static_leases.transform_values { |ref| ref.get&.to_h }
  dynamic.merge(static)
end

.providersObject



111
112
113
# File 'lib/legion/identity/broker.rb', line 111

def providers
  (renewers.keys + static_leases.keys).uniq
end

.refresh_credential(provider_name) ⇒ Object



56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'lib/legion/identity/broker.rb', line 56

def refresh_credential(provider_name)
  name = provider_name.to_sym
  ref  = static_leases[name]
  return false unless ref

  provider = providers_map[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:) ⇒ Object



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/legion/identity/broker.rb', line 36

def register_provider(provider_name, provider:, lease:)
  name = provider_name.to_sym

  renewers[name]&.stop!
  if lease&.expires_at.nil? && !lease&.renewable
    # Static credential — store without a background renewal thread
    renewers.delete(name)
    static_leases[name] = Concurrent::AtomicReference.new(lease)
    providers_map[name] = provider
  else
    # Dynamic credential — create LeaseRenewer
    static_leases.delete(name)
    renewers[name] = LeaseRenewer.new(
      provider_name: name,
      provider:      provider,
      lease:         lease
    )
  end
end

.renewer_for(provider_name) ⇒ Object



25
26
27
# File 'lib/legion/identity/broker.rb', line 25

def renewer_for(provider_name)
  renewers[provider_name.to_sym]
end

.reset!Object



132
133
134
135
136
# File 'lib/legion/identity/broker.rb', line 132

def reset!
  shutdown
  @groups_cache = Concurrent::AtomicReference.new(nil)
  @groups_fetch_in_progress = Concurrent::AtomicBoolean.new(false)
end

.shutdownObject



121
122
123
124
125
126
127
128
129
130
# File 'lib/legion/identity/broker.rb', line 121

def shutdown
  renewers.each_value do |r|
    r.stop!
  rescue Exception # rubocop:disable Lint/RescueException
    nil
  end
  renewers.clear
  static_leases.clear
  providers_map.clear
end

.token_for(provider_name) ⇒ Object



11
12
13
14
# File 'lib/legion/identity/broker.rb', line 11

def token_for(provider_name)
  lease = lease_for(provider_name)
  lease&.valid? ? lease.token : nil
end