Class: Authn::TokenField::Encrypted

Inherits:
Base
  • Object
show all
Defined in:
lib/authn/token_field/encrypted.rb

Constant Summary

Constants inherited from Base

Base::TRUE_PROC

Instance Attribute Summary

Attributes inherited from Base

#expires_at_field, #klass, #options, #token_field

Instance Method Summary collapse

Methods inherited from Base

#ensure_token!, #expirable?, #expired?, #expires_at, fabricate, #initialize, #relation, #reset_token!, #sensitive_fields, #token_with_expiration, #write_new_token

Constructor Details

This class inherits a constructor from Authn::TokenField::Base

Instance Method Details

#encode(token) ⇒ Object



53
54
55
# File 'lib/authn/token_field/encrypted.rb', line 53

def encode(token)
  Authn::TokenField::EncryptionHelper.encrypt_token(token)
end

#encrypted_fieldObject



78
79
80
# File 'lib/authn/token_field/encrypted.rb', line 78

def encrypted_field
  @encrypted_field ||= "#{@token_field}_encrypted"
end

#ensure_token(token_owner_record) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/authn/token_field/encrypted.rb', line 26

def ensure_token(token_owner_record)
  # TODO, tech debt, because some specs are testing migrations, but are still
  # using factory bot to create resources, it might happen that a database
  # schema does not have "#{token_name}_encrypted" field yet, however a bunch
  # of models call `ensure_#{token_name}` in `before_save`.
  #
  # In that case we are using insecure strategy, but this should only happen
  # in tests, because otherwise `encrypted_field` is going to exist.
  #
  # Another use case is when we are caching resources / columns, like we do
  # in case of ApplicationSetting.

  return super if token_owner_record.has_attribute?(encrypted_field)

  if required? # rubocop:disable Style/GuardClause -- Multiple guard clauses + guard clause with `if` modifier is messy
    raise ArgumentError, _('Using required encryption strategy when encrypted field is missing!')
  else
    insecure_strategy.ensure_token(token_owner_record)
  end
end

#find_token_authenticatable(token, unscoped = false) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
# File 'lib/authn/token_field/encrypted.rb', line 10

def find_token_authenticatable(token, unscoped = false)
  return if token.blank?

  token_owner_record =
    if required?
      find_by_encrypted_token(token, unscoped)
    elsif optional?
      find_by_encrypted_token(token, unscoped) ||
        find_by_plaintext_token(token, unscoped)
    elsif migrating?
      find_by_plaintext_token(token, unscoped)
    end

  token_owner_record if token_owner_record && matches_prefix?(token_owner_record, token)
end

#get_token(token_owner_record) ⇒ Object



47
48
49
50
51
# File 'lib/authn/token_field/encrypted.rb', line 47

def get_token(token_owner_record)
  return insecure_strategy.get_token(token_owner_record) if migrating?

  get_encrypted_token(token_owner_record)
end

#migrating?Boolean

Returns:

  • (Boolean)


70
71
72
# File 'lib/authn/token_field/encrypted.rb', line 70

def migrating?
  encrypted_strategy == :migrating
end

#optional?Boolean

Returns:

  • (Boolean)


74
75
76
# File 'lib/authn/token_field/encrypted.rb', line 74

def optional?
  encrypted_strategy == :optional
end

#required?Boolean

Returns:

  • (Boolean)


66
67
68
# File 'lib/authn/token_field/encrypted.rb', line 66

def required?
  encrypted_strategy == :required
end

#set_token(token_owner_record, token) ⇒ Object

Raises:

  • (ArgumentError)


57
58
59
60
61
62
63
64
# File 'lib/authn/token_field/encrypted.rb', line 57

def set_token(token_owner_record, token)
  raise ArgumentError unless token.present?

  token_owner_record[encrypted_field] = encode(token)
  token_owner_record[token_field] = token if migrating?
  token_owner_record[token_field] = nil if optional?
  token
end

#token_fieldsObject



6
7
8
# File 'lib/authn/token_field/encrypted.rb', line 6

def token_fields
  super + [encrypted_field]
end