Class: Kameleoon::Network::AccessTokenSource

Inherits:
Object
  • Object
show all
Defined in:
lib/kameleoon/network/access_token_source.rb

Defined Under Namespace

Classes: FetchError

Constant Summary collapse

SILENCE_PERIOD =

in seconds

300
TOKEN_EXPIRATION_GAP =

in seconds

60
TOKEN_OBSOLESCENCE_GAP =

in seconds

1800
JWT_ACCESS_TOKEN_FIELD =
'access_token'
JWT_EXPIRES_IN_FIELD =
'expires_in'
BASIC_AUTHORIZATION_PREFIX =
'Basic '

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(network_manager, client_id, client_secret) ⇒ AccessTokenSource

Returns a new instance of AccessTokenSource.



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
# File 'lib/kameleoon/network/access_token_source.rb', line 21

def initialize(network_manager, client_id, client_secret)
  Logging::KameleoonLogger.debug(lambda {
    format("CALL: AccessTokenSource.new(network_manager, client_id: '%s', client_secret: '%s')",
           Utils::Strval.secret(client_id), Utils::Strval.secret(client_secret))
  })
  @network_manager = network_manager
  @client_id = client_id
  @client_secret = client_secret
  @cached_token = nil
  @silent_after_fetch_failure_until = 0.0 # 0 = never silenced
  @fetching = nil # Concurrent::Event of the in-flight fetch, shared by all concurrent callers; nil when idle
  @fetching_mutex = Mutex.new
  @basic_auth_token = AccessTokenSource.construct_basic_token(client_id, client_secret)
  Logging::KameleoonLogger.debug(lambda {
    format("RETURN: AccessTokenSource.new(network_manager, client_id: '%s', client_secret: '%s')",
           Utils::Strval.secret(client_id), Utils::Strval.secret(client_secret))
  })
end

Class Method Details

.construct_basic_token(client_id, client_secret) ⇒ Object



40
41
42
43
# File 'lib/kameleoon/network/access_token_source.rb', line 40

def self.construct_basic_token(client_id, client_secret)
  basic_token_content = "#{client_id}:#{client_secret}"
  "#{BASIC_AUTHORIZATION_PREFIX}#{Base64.strict_encode64(basic_token_content)}"
end

Instance Method Details

#discard_token(token) ⇒ Object



65
66
67
68
69
70
# File 'lib/kameleoon/network/access_token_source.rb', line 65

def discard_token(token)
  Logging::KameleoonLogger.debug("CALL: AccessTokenSource.discard_token(token: '%s')", token)
  @cached_token = nil if @cached_token&.value == token
  Logging::KameleoonLogger.debug("RETURN: AccessTokenSource.discard_token(token: '%s')", token)
  @cached_token
end

#get_token(timeout = nil) ⇒ Object

Returns the access token, or nil if it cannot be obtained. Fetches a new token if the cached one is expired or obsolete, unless a recent fetch failure has put the source in the silence period.



47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'lib/kameleoon/network/access_token_source.rb', line 47

def get_token(timeout = nil)
  Logging::KameleoonLogger.debug('CALL: AccessTokenSource.get_token(timeout: %s)', timeout)
  now = Process.clock_gettime(Process::CLOCK_REALTIME)
  token = @cached_token
  silent = now < @silent_after_fetch_failure_until
  if !token.nil? && !token.expired?(now)
    refresh_token_in_background(timeout) if token.obsolete?(now) && !silent
    value = token.value
  elsif silent
    value = nil
  else
    value = fetch_token(timeout)
  end
  Logging::KameleoonLogger.debug("RETURN: AccessTokenSource.get_token(timeout: %s) -> (token: '%s')",
                                 timeout, value)
  value
end