Module: Himari::TokenString

Included in:
AccessToken, RefreshToken, SessionData
Defined in:
lib/himari/token_string.rb

Defined Under Namespace

Modules: ClassMethods Classes: Error, Format, InvalidFormat, SecretIncorrect, SecretMissing, TokenExpired, Verification

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#verificationObject (readonly)

The Verification from the last successful verify_secret!, or nil. Used for logging (#via) and to let a rotating token keep the just-presented secret valid (#secret_hash).



97
98
99
# File 'lib/himari/token_string.rb', line 97

def verification
  @verification
end

Class Method Details

.hash_secret(secret) ⇒ Object



47
48
49
# File 'lib/himari/token_string.rb', line 47

def self.hash_secret(secret)
  Base64.urlsafe_encode64(Digest::SHA384.digest(secret), padding: false)
end

.included(k) ⇒ Object



43
44
45
# File 'lib/himari/token_string.rb', line 43

def self.included(k)
  k.extend(ClassMethods)
end

Instance Method Details

#expiryObject



55
56
57
# File 'lib/himari/token_string.rb', line 55

def expiry
  @expiry
end

#formatObject



128
129
130
# File 'lib/himari/token_string.rb', line 128

def format
  Format.new(header: magic_header, handle: handle, secret: secret)
end

#handleObject



51
52
53
# File 'lib/himari/token_string.rb', line 51

def handle
  @handle
end

#magic_headerObject



124
125
126
# File 'lib/himari/token_string.rb', line 124

def magic_header
  self.class.magic_header
end

#secretObject

Raises:



59
60
61
62
63
# File 'lib/himari/token_string.rb', line 59

def secret
  raise SecretMissing unless @secret

  @secret
end

#secret_hashObject



65
66
67
# File 'lib/himari/token_string.rb', line 65

def secret_hash
  @secret_hash ||= TokenString.hash_secret(secret)
end

#secret_hash_prevObject

Optional second valid secret hash. Tokens that rotate in place (RefreshToken) keep the previously-issued secret valid for one more turn so a client whose rotation response was lost can retry. nil for single-secret tokens (AccessToken, SessionData).



72
73
74
# File 'lib/himari/token_string.rb', line 72

def secret_hash_prev
  @secret_hash_prev
end

#verify!(secret:, now: Time.now) ⇒ Object



76
77
78
79
# File 'lib/himari/token_string.rb', line 76

def verify!(secret:, now: Time.now)
  verify_expiry!(now)
  verify_secret!(secret)
end

#verify_expiry!(now = Time.now) ⇒ Object

Raises:



106
107
108
# File 'lib/himari/token_string.rb', line 106

def verify_expiry!(now = Time.now)
  raise TokenExpired if @expiry <= now.to_i
end

#verify_secret!(given_secret) ⇒ Object

Raises:



81
82
83
84
85
86
87
88
89
90
91
92
93
# File 'lib/himari/token_string.rb', line 81

def verify_secret!(given_secret)
  given_dgst = Digest::SHA384.digest(given_secret)
  @verification =
    if secret_hash_match(secret_hash, given_dgst)
      Verification.new(via: :current, secret_hash: secret_hash)
    elsif secret_hash_prev && secret_hash_match(secret_hash_prev, given_dgst)
      Verification.new(via: :previous, secret_hash: secret_hash_prev)
    end
  raise SecretIncorrect unless @verification

  @secret = given_secret
  true
end