Class: RailsBase::Mfa::Sms::Validate

Inherits:
ServiceBase show all
Defined in:
app/services/rails_base/mfa/sms/validate.rb

Instance Method Summary collapse

Methods inherited from ServiceBase

inherited, #internal_validate, #service_base_logging

Methods included from ServiceLogging

#aletered_message, #class_name, #log, #log_prefix, #logger, #service_id

Instance Method Details

#callObject



12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'app/services/rails_base/mfa/sms/validate.rb', line 12

def call
  if sms_code.present?
    log(level: :info, msg: "Raw sms code was passed in")
    mfa_code = sms_code
  else
    log(level: :info, msg: "Code Array was passed in. Manipulating Data first")
    array = convert_to_array
    if array.length != RailsBase::Authentication::Constants::MFA_LENGTH
      log(level: :warn, msg: "Not enough params for MFA code. Given #{array}. Expected of length #{RailsBase::Authentication::Constants::MFA_LENGTH}")
      context.fail!(message: RailsBase::Authentication::Constants::MV_FISHY, redirect_url: RailsBase.url_routes.new_user_session_path, level: :alert)
    end

    mfa_code = array.join
  end


  log(level: :info, msg: "mfa code received: #{mfa_code}")
  datum = get_short_lived_datum(mfa_code)
  log(level: :info, msg: "Datum returned with: #{datum}")

  validate_datum?(datum)
  validate_user_consistency?(datum)
  validate_current_user?(datum) if current_user

  context.user = datum[:user]
end

#convert_to_arrayObject



79
80
81
82
83
84
85
86
87
88
89
# File 'app/services/rails_base/mfa/sms/validate.rb', line 79

def convert_to_array
  array = []
  return array unless params.dig(:mfa).respond_to? :keys

  RailsBase::Authentication::Constants::MFA_LENGTH.times do |index|
    var_name = "#{RailsBase::Authentication::Constants::MV_BASE_NAME}#{index}".to_sym
    array << params[:mfa][var_name]
  end

  array.compact
end

#get_short_lived_datum(mfa_code) ⇒ Object



74
75
76
77
# File 'app/services/rails_base/mfa/sms/validate.rb', line 74

def get_short_lived_datum(mfa_code)
  log(level: :debug, msg: "Looking for #{mfa_code} with reason #{reason}")
  ShortLivedData.find_datum(data: mfa_code, reason: reason)
end

#reasonObject



91
92
93
# File 'app/services/rails_base/mfa/sms/validate.rb', line 91

def reason
  input_reason || RailsBase::Authentication::Constants::MFA_REASON
end

#validate!Object



95
96
97
98
99
100
101
102
103
# File 'app/services/rails_base/mfa/sms/validate.rb', line 95

def validate!
  if sms_code.nil?
    raise 'params is not present' if params.nil?
  end

  raise 'mfa_event is expected to be a RailsBase::MfaEvent' unless RailsBase::MfaEvent === mfa_event

  raise 'session_mfa_user_id is not present' if session_mfa_user_id.nil?
end

#validate_current_user?(datum) ⇒ Boolean

Returns:

  • (Boolean)


39
40
41
42
43
44
45
46
47
# File 'app/services/rails_base/mfa/sms/validate.rb', line 39

def validate_current_user?(datum)
  return true if current_user.id == datum[:user].id

  # User MFA for a different user matched the session token
  # However, those did not match the current user signed in
  # Something is very 🐟
  log(level: :error, msg: "Someone is a teapot. Current logged in user does not equal mfa code.")
  context.fail!(message: 'You are a teapot', redirect_url: RailsBase.url_routes.signout_path, level: :warn)
end

#validate_datum?(datum) ⇒ Boolean

Returns:

  • (Boolean)


49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
# File 'app/services/rails_base/mfa/sms/validate.rb', line 49

def validate_datum?(datum)
  return true if datum[:valid]

  if datum[:found]
    # MFA is either expired or the incorrect reason. Either way it does not match
    msg = "Errors with MFA: #{datum[:invalid_reason].join(", ")}. Please login again"
    log(level: :warn, msg: msg)
    context.fail!(message: msg, redirect_url: RailsBase.url_routes.new_user_session_path, level: :warn)
  end

  # MFA does not exist for any reason type
  log(level: :warn, msg: "Could not find MFA code. Incorrect MFA code")

  context.fail!(message: "Incorrect SMS code.", redirect_url: RailsBase.url_routes.mfa_with_event_path(mfa_event: mfa_event.event, type: RailsBase::Mfa::SMS), level: :warn)
end

#validate_user_consistency?(datum) ⇒ Boolean

Returns:

  • (Boolean)


65
66
67
68
69
70
71
72
# File 'app/services/rails_base/mfa/sms/validate.rb', line 65

def validate_user_consistency?(datum)
  return true if datum[:user].id == session_mfa_user_id.to_i
  log(level: :warn, msg: "Datum user does not match session user. [#{datum[:user].id}, #{session_mfa_user_id.to_i}]")

  # MFA session token user does not match the datum user
  # Something is very 🐟
  context.fail!(message: RailsBase::Authentication::Constants::MV_FISHY, redirect_url: RailsBase.url_routes.new_user_session_path, level: :alert)
end