Class: RailsBase::Authentication::SingleSignOnSend

Inherits:
ServiceBase
  • Object
show all
Defined in:
app/services/rails_base/authentication/single_sign_on_send.rb

Constant Summary collapse

SSO_DECISION_TWILIO =
:twilio
SSO_DECISION_EMAIL =
:email
VALID_SSO_DECISIONS =
[SSO_DECISION_TWILIO, SSO_DECISION_EMAIL].freeze

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



18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 18

def call
  # :nocov:
  # redundant check, unless user overwrites `sso_decision_type`
  unless VALID_SSO_DECISIONS.include?(sso_decision_type)
    context.fail!(message: "Invalid sso decision. Given [#{sso_decision_type}]. Expected [#{VALID_SSO_DECISIONS}]")
  end
  # :nocov:

  params = {
    user: user,
    token_length: token_length,
    uses: uses,
    expires_at: expires_at,
    reason: reason || RailsBase::Authentication::Constants::SSO_LOGIN_REASON,
    token_type: token_type,
    url_redirect: url_redirect
  }
  datum = SingleSignOnCreate.call(**params)
  context.fail!(message: 'Failed to create SSO token. Try again') if datum.failure?

  url = sso_url(data: datum.data.data)
  case sso_decision_type
  when SSO_DECISION_TWILIO
    context.sso_destination = :sms
    send_to_twilio!(message: message(url: url, full_name: user.full_name))
  when SSO_DECISION_EMAIL
    context.sso_destination = :email
    send_to_email!(message: message(url: url, full_name: user.full_name))
  end
end

#message(url:, full_name:) ⇒ Object

This method is expected to be overridden by the main app This is the default message Might consider shipping this to a locales that can be easily overridden in downstream app



52
53
54
55
56
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 52

def message(url:, full_name:)
  return msg_proc.call(url, full_name) if msg_proc.is_a?(Proc)

  "Hello #{user.full_name}. This is your SSO link to your favorite site.\n#{url}"
end

#send_to_email!(message:) ⇒ Object



81
82
83
84
85
86
87
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 81

def send_to_email!(message:)
  RailsBase::EventMailer.send_sso(user: user, message: message).deliver_me
rescue StandardError => e
  log(level: :error, msg: "Error caught #{e.class.name}")
  log(level: :error, msg: "Failed to send email to #{user.email}")
  context.fail!(message: "Failed to send email to user. Try again.")
end

#send_to_twilio!(message:) ⇒ Object



71
72
73
74
75
76
77
78
79
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 71

def send_to_twilio!(message:)
  TwilioJob.perform_later(message: message, to: user.phone_number)
  log(level: :info, msg: "Sent twilio message to #{user.phone_number}")
rescue StandardError => e
  log(level: :error, msg: "Error caught #{e.class.name}")
  log(level: :error, msg: "Error caught #{e.message}")
  log(level: :error, msg: "Failed to send sms to #{user.phone_number}")
  context.fail!(message: "Failed to send sms to user. Try again.")
end

#sso_decision_typeObject

This method is expected to be overridden by the main app This is expected default behavior if SSO is available



60
61
62
63
64
65
66
67
68
69
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 60

def sso_decision_type
  if user.phone_number.present?
    SSO_DECISION_TWILIO
  elsif user.email_validated
    SSO_DECISION_EMAIL
  else
    log(level: :error, msg: "No SSO will be sent for user #{user.id}. No email/phone available to send to at this time")
    context.fail!(message: "User does not have a validated email nor phone number. Unable to do SSO")
  end
end

#sso_url(data:) ⇒ Object



89
90
91
92
93
94
95
96
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 89

def sso_url(data:)
  params = {
    data: data,
    host: Constants::BASE_URL,
  }
  params[:port] = Constants::BASE_URL_PORT if Constants::BASE_URL_PORT
  Constants::URL_HELPER.sso_retrieve_url(params)
end

#validate!Object



98
99
100
101
102
# File 'app/services/rails_base/authentication/single_sign_on_send.rb', line 98

def validate!
  raise "Expected user to be a User. Received #{user.class}" unless user.is_a? User

  # Other validations take place in SingleSignOnCreate class
end