Class: Darrrr::RecoveryToken

Inherits:
Object
  • Object
show all
Extended by:
Forwardable
Defined in:
lib/darrrr/recovery_token.rb

Constant Summary collapse

BASE64_CHARACTERS =
/\A[0-9a-zA-Z+\/=]+\z/

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(token_object) ⇒ RecoveryToken

Typically, you would not call ‘new` directly but instead use `build` and `parse`

token_object: a RecoveryTokenWriter/RecoveryTokenReader instance



22
23
24
# File 'lib/darrrr/recovery_token.rb', line 22

def initialize(token_object)
  @token_object = token_object
end

Instance Attribute Details

#token_objectObject (readonly)

Returns the value of attribute token_object.



10
11
12
# File 'lib/darrrr/recovery_token.rb', line 10

def token_object
  @token_object
end

Class Method Details

.account_provider_issuer(serialized_data) ⇒ Object

Extract an account provider from a token based on the token type.

serialized_data: a binary string representation of a RecoveryToken.

returns the account provider for the recovery token or raises an error

if the token is a countersigned token


91
92
93
# File 'lib/darrrr/recovery_token.rb', line 91

def (serialized_data)
  issuer(serialized_data, Darrrr::RECOVERY_TOKEN_TYPE)
end

.build(issuer:, audience:, type:, options: 0x00) ⇒ Object

data: the value that will be encrypted by EncryptedData. audience: the provider for which we are building the token. type: Either 0 (recovery token) or 1 (countersigned recovery token) options: the value to set for the options byte

returns a RecoveryToken.



43
44
45
46
47
48
49
50
51
52
53
54
# File 'lib/darrrr/recovery_token.rb', line 43

def build(issuer:, audience:, type:, options: 0x00)
  token = RecoveryTokenWriter.new.tap do |token|
    token.token_id = token_id
    token.issuer = issuer.origin
    token.issued_time = Time.now.utc.iso8601
    token.options = options
    token.audience = audience.origin
    token.version = Darrrr::PROTOCOL_VERSION
    token.token_type = type
  end
  new(token)
end

.parse(serialized_data) ⇒ Object

serialized_data: a binary string representation of a RecoveryToken.

returns a RecoveryToken.



65
66
67
68
69
70
71
72
73
# File 'lib/darrrr/recovery_token.rb', line 65

def parse(serialized_data)
  new RecoveryTokenReader.new.read(serialized_data)
rescue IOError => e
  message = e.message
  if serialized_data =~ BASE64_CHARACTERS
    message = "#{message}: did you forget to Base64.strict_decode64 this value?"
  end
  raise RecoveryTokenSerializationError, message
end

.recovery_provider_issuer(serialized_data) ⇒ Object

Extract a recovery provider from a token based on the token type.

serialized_data: a binary string representation of a RecoveryToken.

returns the recovery provider for the coutnersigned token or raises an

error if the token is a recovery token


81
82
83
# File 'lib/darrrr/recovery_token.rb', line 81

def recovery_provider_issuer(serialized_data)
  issuer(serialized_data, Darrrr::COUNTERSIGNED_RECOVERY_TOKEN_TYPE)
end

.token_idObject

token ID generates a random array of bytes. this method only exists so that it can be stubbed.



58
59
60
# File 'lib/darrrr/recovery_token.rb', line 58

def token_id
  SecureRandom.random_bytes(16).bytes.to_a
end

Instance Method Details

#decode(context = nil) ⇒ Object



27
28
29
# File 'lib/darrrr/recovery_token.rb', line 27

def decode(context = nil)
  Darrrr..encryptor.decrypt(self.data, Darrrr., context)
end

#state_urlObject

A globally known location of the token, used to initiate a recovery



32
33
34
# File 'lib/darrrr/recovery_token.rb', line 32

def state_url
  [Darrrr.recovery_provider(self.audience)., "id=#{CGI::escape(token_id.to_hex)}"].join("?")
end