Class: Darrrr::RecoveryProvider
- Inherits:
-
Object
- Object
- Darrrr::RecoveryProvider
- Includes:
- CryptoHelper, Provider
- Defined in:
- lib/darrrr/recovery_provider.rb
Constant Summary collapse
- INTEGER_FIELDS =
[:token_max_size]
- BASE64_FIELDS =
[:countersign_pubkeys_secp256r1]
- URL_FIELDS =
[ :issuer, :save_token, :recover_account, :privacy_policy ]
- REQUIRED_FIELDS =
URL_FIELDS + INTEGER_FIELDS + BASE64_FIELDS
Constants included from Constants
Constants::CLOCK_SKEW, Constants::COUNTERSIGNED_RECOVERY_TOKEN_TYPE, Constants::DIGEST, Constants::GROUP, Constants::PRIME_256_V1, Constants::PROTOCOL_VERSION, Constants::RECOVERY_TOKEN_TYPE, Constants::TOKEN_ID_BYTE_LENGTH, Constants::WELL_KNOWN_CONFIG_PATH
Constants included from Provider
Provider::MAX_RECOVERY_PROVIDER_CACHE_LENGTH, Provider::RECOVERY_PROVIDER_CACHE_LENGTH, Provider::REQUIRED_CRYPTO_OPS
Instance Attribute Summary collapse
-
#icon_152px ⇒ Object
optional field.
-
#save_token_async_api_iframe ⇒ Object
optional.
-
#signing_private_key ⇒ Object
writeonly
Sets the attribute signing_private_key.
-
#token_max_size ⇒ Object
writeonly
Sets the attribute token_max_size.
Instance Method Summary collapse
-
#countersign_token(token:, context: nil, options: 0x00) ⇒ Object
Takes a binary representation of a token and signs if for a given account provider.
- #encryptor_key ⇒ Object
-
#recovery_url(token_id) ⇒ Object
The URL representing the location of the token.
-
#to_h ⇒ Object
Used to serve content at /.well-known/delegated-account-recovery/configuration.
-
#unseal_keys(context = nil) ⇒ Object
The CryptoHelper defines an ‘unseal` method that requires us to define a `unseal_keys` method that will return the set of keys that are valid when verifying the signature on a sealed key.
-
#validate_recovery_token!(token, context = {}) ⇒ Object
Validate the token according to the processing instructions for the save-token endpoint.
Methods included from CryptoHelper
Methods included from Provider
#custom_encryptor=, #encryptor, included, #initialize, #load, #with_encryptor
Instance Attribute Details
#icon_152px ⇒ Object
optional field
24 25 26 |
# File 'lib/darrrr/recovery_provider.rb', line 24 def icon_152px @icon_152px end |
#save_token_async_api_iframe ⇒ Object
optional
19 20 21 |
# File 'lib/darrrr/recovery_provider.rb', line 19 def save_token_async_api_iframe @save_token_async_api_iframe end |
#signing_private_key=(value) ⇒ Object (writeonly)
Sets the attribute signing_private_key
18 19 20 |
# File 'lib/darrrr/recovery_provider.rb', line 18 def signing_private_key=(value) @signing_private_key = value end |
#token_max_size=(value) ⇒ Object (writeonly)
Sets the attribute token_max_size
18 19 20 |
# File 'lib/darrrr/recovery_provider.rb', line 18 def token_max_size=(value) @token_max_size = value end |
Instance Method Details
#countersign_token(token:, context: nil, options: 0x00) ⇒ Object
Takes a binary representation of a token and signs if for a given account provider. Do not pass in a RecoveryToken object. The wrapping data structure is identical to the structure it’s wrapping in format.
token: the to_binary_s or binary representation of the recovery token context: an arbitrary object that is passed to lower level crypto operations options: the value to set in the options byte field of the recovery
token (defaults to 0x00)
returns a Base64 encoded representation of the countersigned token and the signature over the token.
75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/darrrr/recovery_provider.rb', line 75 def countersign_token(token:, context: nil, options: 0x00) begin account_provider = RecoveryToken.account_provider_issuer(token) rescue RecoveryTokenSerializationError, UnknownProviderError raise TokenFormatError, "Could not determine provider" end counter_recovery_token = RecoveryToken.build( issuer: self, audience: account_provider, type: COUNTERSIGNED_RECOVERY_TOKEN_TYPE, options: , ) counter_recovery_token.data = token seal(counter_recovery_token, context) end |
#encryptor_key ⇒ Object
60 61 62 |
# File 'lib/darrrr/recovery_provider.rb', line 60 def encryptor_key :darrrr_recovery_provider_encryptor end |
#recovery_url(token_id) ⇒ Object
The URL representing the location of the token. Used to initiate a recovery.
token_id: the shared ID representing a token.
56 57 58 |
# File 'lib/darrrr/recovery_provider.rb', line 56 def recovery_url(token_id) [self.recover_account, "?token_id=", URI.escape(token_id)].join end |
#to_h ⇒ Object
Used to serve content at /.well-known/delegated-account-recovery/configuration
27 28 29 30 31 32 33 34 35 36 37 |
# File 'lib/darrrr/recovery_provider.rb', line 27 def to_h { "issuer" => self.issuer, "countersign-pubkeys-secp256r1" => self.unseal_keys.dup, "token-max-size" => self.token_max_size, "save-token" => self.save_token, "recover-account" => self.recover_account, "save-token-async-api-iframe" => self.save_token_async_api_iframe, "privacy-policy" => self.privacy_policy } end |
#unseal_keys(context = nil) ⇒ Object
The CryptoHelper defines an ‘unseal` method that requires us to define a `unseal_keys` method that will return the set of keys that are valid when verifying the signature on a sealed key.
returns the value of ‘countersign_pubkeys_secp256r1` or executes a proc passing `self` as the first argument.
45 46 47 48 49 50 51 |
# File 'lib/darrrr/recovery_provider.rb', line 45 def unseal_keys(context = nil) if @countersign_pubkeys_secp256r1.respond_to?(:call) @countersign_pubkeys_secp256r1.call(context) else @countersign_pubkeys_secp256r1 end end |
#validate_recovery_token!(token, context = {}) ⇒ Object
Validate the token according to the processing instructions for the save-token endpoint.
Returns a validated token
97 98 99 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 125 126 127 128 129 130 131 |
# File 'lib/darrrr/recovery_provider.rb', line 97 def validate_recovery_token!(token, context = {}) errors = [] # 1. Authenticate the User. The exact nature of how the Recovery Provider authenticates the User is beyond the scope of this specification. # handled in before_filter # 4. Retrieve the Account Provider configuration as described in Section 2 using the issuer field of the token as the subject. begin account_provider = RecoveryToken.account_provider_issuer(token) rescue RecoveryTokenSerializationError, UnknownProviderError, TokenFormatError => e raise RecoveryTokenError, "Could not determine provider: #{e.}" end # 2. Parse the token. # 3. Validate that the version value is 0. # 5. Validate the signature over the token according to processing rules for the algorithm implied by the version. begin recovery_token = account_provider.unseal(token, context) rescue CryptoError => e raise RecoveryTokenError.new("Unable to verify signature of token") rescue TokenFormatError => e raise RecoveryTokenError.new(e.) end # 6. Validate that the audience field of the token identifies an origin which the provider considers itself authoritative for. (Often the audience will be same-origin with the Recovery Provider, but other values may be acceptable, e.g. "https://mail.example.com" and "https://social.example.com" may be acceptable audiences for "https://recovery.example.com".) unless self.origin == recovery_token.audience raise RecoveryTokenError.new("Unnacceptable audience") end if DateTime.parse(recovery_token.issued_time).utc < (Time.now - CLOCK_SKEW).utc raise RecoveryTokenError.new("Issued at time is too far in the past") end recovery_token end |