Class: TokenAuthenticatableStrategies::Encrypted

Inherits:
Base
  • Object
show all
Defined in:
app/models/concerns/token_authenticatable_strategies/encrypted.rb

Instance Attribute Summary

Attributes inherited from Base

#klass, #options, #token_field

Instance Method Summary collapse

Methods inherited from Base

#ensure_token!, fabricate, #initialize, #reset_token!

Constructor Details

This class inherits a constructor from TokenAuthenticatableStrategies::Base

Instance Method Details

#ensure_token(instance) ⇒ Object


20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 20

def ensure_token(instance)
  # 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 instance.has_attribute?(encrypted_field)

  if required?
    raise ArgumentError, _('Using required encryption strategy when encrypted field is missing!')
  else
    insecure_strategy.ensure_token(instance)
  end
end

#find_token_authenticatable(token, unscoped = false) ⇒ Object


5
6
7
8
9
10
11
12
13
14
15
16
17
18
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 5

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

  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)
  else
    raise ArgumentError, _("Unknown encryption strategy: %{encrypted_strategy}!") % { encrypted_strategy: encrypted_strategy }
  end
end

#get_token(instance) ⇒ Object


41
42
43
44
45
46
47
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 41

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

  encrypted_token = instance.read_attribute(encrypted_field)
  token = Gitlab::CryptoHelper.aes256_gcm_decrypt(encrypted_token)
  token || (insecure_strategy.get_token(instance) if optional?)
end

#migrating?Boolean

Returns:

  • (Boolean)

62
63
64
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 62

def migrating?
  encrypted_strategy == :migrating
end

#optional?Boolean

Returns:

  • (Boolean)

66
67
68
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 66

def optional?
  encrypted_strategy == :optional
end

#required?Boolean

Returns:

  • (Boolean)

58
59
60
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 58

def required?
  encrypted_strategy == :required
end

#set_token(instance, token) ⇒ Object

Raises:

  • (ArgumentError)

49
50
51
52
53
54
55
56
# File 'app/models/concerns/token_authenticatable_strategies/encrypted.rb', line 49

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

  instance[encrypted_field] = Gitlab::CryptoHelper.aes256_gcm_encrypt(token)
  instance[token_field] = token if migrating?
  instance[token_field] = nil if optional?
  token
end