Class: CommandTower::Secrets::Generate

Inherits:
Object
  • Object
show all
Includes:
CommandTower::ServiceLogging
Defined in:
app/services/command_tower/secrets/generate.rb

Overview

Issues a single-purpose user secret (email verification, password reset, phone verification). Called from capability services, so it stays a plain domain object with a narrow outcome.

Defined Under Namespace

Classes: Issued

Constant Summary collapse

MAX_RETRY =
10
EXHAUSTED_MSG =
"Failed to generate Secret. Cannot Continue"

Class Method Summary collapse

Instance Method Summary collapse

Methods included from CommandTower::ServiceLogging

included

Constructor Details

#initialize(user:, secret_length:, reason:, type: DEFAULT_SECRET_TYPE, extra: nil, cleanse: false, death_time: nil, use_count_max: nil) ⇒ Generate

Returns a new instance of Generate.



40
41
42
43
44
45
46
47
48
49
# File 'app/services/command_tower/secrets/generate.rb', line 40

def initialize(user:, secret_length:, reason:, type: DEFAULT_SECRET_TYPE, extra: nil, cleanse: false, death_time: nil, use_count_max: nil)
  @user = user
  @secret_length = secret_length
  @reason = reason
  @type = type || DEFAULT_SECRET_TYPE
  @extra = extra
  @cleanse = !!cleanse
  @death_time = death_time
  @use_count_max = use_count_max
end

Class Method Details

.call(**kwargs) ⇒ Object



36
37
38
# File 'app/services/command_tower/secrets/generate.rb', line 36

def self.call(**kwargs)
  new(**kwargs).call
end

Instance Method Details

#callObject



51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
# File 'app/services/command_tower/secrets/generate.rb', line 51

def call
  if cleanse && @attempts.nil?
    # if this fails ... so be it
    Cleanse.(user:, reason:)
  end

  @attempts ||= 1

  Issued.success(record: UserSecret.create!(**db_params))
rescue ActiveRecord::RecordNotUnique
  if @attempts < MAX_RETRY
    @attempts += 1
    log_warn("Duplicate Secret was generated. Attempting to retry: #{@attempts} of #{MAX_RETRY}")
    retry
  end

  log_error("Duplicate Secret was generated. Exhausted Max attempts of #{MAX_RETRY}.")
  Issued.failure(msg: EXHAUSTED_MSG)
end

#generate_secretObject



71
72
73
74
75
76
77
78
79
80
# File 'app/services/command_tower/secrets/generate.rb', line 71

def generate_secret
  case type
  when :numeric
    secret_length.times.map { SecureRandom.rand(0...10) }.join
  when :alphanumeric, :hex
    SecureRandom.public_send(type, secret_length)
  when :uuid
    SecureRandom.public_send(type)
  end
end