Class: SAML::URLService

Inherits:
Object
  • Object
show all
Defined in:
lib/saml/url_service.rb

Overview

This class is responsible for providing the URLs for the various SSO and SLO endpoints

Direct Known Subclasses

PostURLService

Constant Summary collapse

VIRTUAL_HOST_MAPPINGS =
{
  'https://api.vets.gov' => { base_redirect: 'https://www.vets.gov' },
  'https://staging-api.vets.gov' => { base_redirect: 'https://staging.vets.gov' },
  'https://dev-api.vets.gov' => { base_redirect: 'https://dev.vets.gov' },
  'https://api.va.gov' => { base_redirect: 'https://www.va.gov' },
  'https://staging-api.va.gov' => { base_redirect: 'https://staging.va.gov' },
  'https://dev-api.va.gov' => { base_redirect: 'https://dev.va.gov' },
  'http://localhost:3000' => { base_redirect: "http://#{localhost_redirect}:3001" },
  'http://127.0.0.1:3000' => { base_redirect: "http://#{localhost_ip_redirect}:3001" }
}.freeze
LOGIN_REDIRECT_PARTIAL =
'/auth/login/callback'
LOGOUT_REDIRECT_PARTIAL =
'/logout/'
BROKER_CODE =
'iam'
WEB_CLIENT_ID =
'web'
MOBILE_CLIENT_ID =
'mobile'
UNIFIED_SIGN_IN_CLIENTS =
%w[vaweb mhv myvahealth ebenefits vamobile vaoccmobile].freeze
TERMS_OF_USE_ENABLED_CLIENTS =
%w[vaweb mhv].freeze
TERMS_OF_USE_DECLINED_PATH =
'/terms-of-use/declined'

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(saml_settings, session: nil, user: nil, params: {}, loa3_context: LOA::IDME_LOA3_VETS) ⇒ URLService

Returns a new instance of URLService.



33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/saml/url_service.rb', line 33

def initialize(saml_settings, session: nil, user: nil, params: {}, loa3_context: LOA::IDME_LOA3_VETS)
  unless %w[new saml_callback saml_logout_callback ssoe_slo_callback].include?(params[:action])
    raise Common::Exceptions::RoutingError, params[:path]
  end

  if session.present?
    @session = session
    @user = user
    @authn_context = user&.authn_context
  end

  @saml_settings = saml_settings
  @loa3_context = loa3_context

  if (params[:action] == 'saml_callback') && params[:RelayState].present?
    @type = JSON.parse(CGI.unescapeHTML(params[:RelayState]))['type']
  end
  @query_params = {}
  @tracker = initialize_tracker(params)

  Raven.extra_context(params:)
  Raven.user_context(session:, user:)
end

Instance Attribute Details

#authn_contextObject (readonly)

Returns the value of attribute authn_context.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def authn_context
  @authn_context
end

#query_paramsObject (readonly)

Returns the value of attribute query_params.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def query_params
  @query_params
end

#saml_settingsObject (readonly)

Returns the value of attribute saml_settings.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def saml_settings
  @saml_settings
end

#sessionObject (readonly)

Returns the value of attribute session.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def session
  @session
end

#trackerObject (readonly)

Returns the value of attribute tracker.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def tracker
  @tracker
end

#typeObject (readonly)

Returns the value of attribute type.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def type
  @type
end

#userObject (readonly)

Returns the value of attribute user.



31
32
33
# File 'lib/saml/url_service.rb', line 31

def user
  @user
end

Instance Method Details

#base_redirect_urlObject

REDIRECT_URLS



58
59
60
# File 'lib/saml/url_service.rb', line 58

def base_redirect_url
  VIRTUAL_HOST_MAPPINGS[current_host][:base_redirect]
end

#callback_verify_urlObject



132
133
134
135
136
137
138
139
140
141
142
143
144
# File 'lib/saml/url_service.rb', line 132

def callback_verify_url
  link_authn_context =
    case type
    when 'logingov'
      build_authn_context([IAL::LOGIN_GOV_IAL2, AAL::LOGIN_GOV_AAL2], AuthnContext::LOGIN_GOV)
    when 'mhv', 'mhv_verified'
      build_authn_context('myhealthevet_loa3', AuthnContext::MHV)
    when 'dslogon'
      build_authn_context('dslogon_loa3', AuthnContext::DSLOGON)
    end

  build_sso_url(link_authn_context)
end

#custom_url(authn) ⇒ Object



104
105
106
107
# File 'lib/saml/url_service.rb', line 104

def custom_url(authn)
  @type = 'custom'
  build_sso_url(authn)
end

#idme_signup_url(authn_context) ⇒ Object



91
92
93
94
95
# File 'lib/saml/url_service.rb', line 91

def (authn_context)
  @type = 'signup'
  @query_params[:op] = 'signup'
  build_sso_url(build_authn_context(authn_context, AuthnContext::ID_ME))
end

#login_redirect_url(auth: 'success', code: nil) ⇒ Object



62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
# File 'lib/saml/url_service.rb', line 62

def (auth: 'success', code: nil)
  return verify_url if auth == 'success' && user.loa[:current] < user.loa[:highest]

  # if the original auth request was an inbound ssoe autologin (type custom)
  # and authentication failed, set 'force-needed' so the FE can silently fail
  # authentication and NOT show the user an error page
  auth = 'force-needed' if auth != 'success' && @tracker&.payload_attr(:type) == 'custom'

  @query_params[:type] = type if type
  @query_params[:auth] = auth if auth != 'success'
  @query_params[:code] = code if code

  if Settings.saml_ssoe.relay.present?
    add_query(Settings.saml_ssoe.relay, query_params)
  else
    add_query("#{base_redirect_url}#{LOGIN_REDIRECT_PARTIAL}", query_params)
  end
end

#login_url(type, authn_context, identity_provider, authn_con_compare = AuthnContext::EXACT) ⇒ Object

SIGN ON URLS



86
87
88
89
# File 'lib/saml/url_service.rb', line 86

def (type, authn_context, identity_provider, authn_con_compare = AuthnContext::EXACT)
  @type = type
  build_sso_url(build_authn_context(authn_context, identity_provider), authn_con_compare)
end

#logingov_signup_url(authn_context) ⇒ Object



97
98
99
100
101
102
# File 'lib/saml/url_service.rb', line 97

def (authn_context)
  @type = 'signup'
  build_sso_url(
    build_authn_context(authn_context, AuthnContext::LOGIN_GOV)
  )
end

#logout_redirect_urlObject



81
82
83
# File 'lib/saml/url_service.rb', line 81

def logout_redirect_url
  "#{base_redirect_url}#{LOGOUT_REDIRECT_PARTIAL}"
end

#mfa_urlObject



146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# File 'lib/saml/url_service.rb', line 146

def mfa_url
  @type = 'mfa'
  link_authn_context =
    case authn_context
    when LOA::IDME_LOA1_VETS, LOA::IDME_LOA3_VETS, LOA::IDME_LOA3
      build_authn_context('multifactor', AuthnContext::ID_ME)
    when 'myhealthevet', 'myhealthevet_loa3'
      build_authn_context('myhealthevet_multifactor', AuthnContext::MHV)
    when 'dslogon', 'dslogon_loa3'
      build_authn_context('dslogon_multifactor', AuthnContext::DSLOGON)
    when SAML::UserAttributes::SSOe::INBOUND_AUTHN_CONTEXT
      "#{@user.identity.[:service_name]}_multifactor"
    end
  build_sso_url(link_authn_context)
end

#slo_urlObject

SIGN OFF URLS



163
164
165
166
167
168
169
170
# File 'lib/saml/url_service.rb', line 163

def slo_url
  @type = 'slo'
  logout_request = OneLogin::RubySaml::Logoutrequest.new
  # cache the request for session.token lookup when we receive the response
  SingleLogoutRequest.create(uuid: logout_request.uuid, token: session.token)
  Rails.logger.info "New SP SLO having logout_request '#{logout_request.uuid}' for userid '#{session.uuid}'"
  logout_request.create(url_settings, RelayState: relay_state_params)
end

#ssoe_slo_urlObject

logout URL for SSOe



173
174
175
# File 'lib/saml/url_service.rb', line 173

def ssoe_slo_url
  Settings.saml_ssoe.logout_url
end

#verify_urlObject



109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
# File 'lib/saml/url_service.rb', line 109

def verify_url
  # For verification from a login callback, type should be the initial login policy.
  # In that case, it will have been set to the type from RelayState.
  @type ||= 'verify'
  return callback_verify_url if %w[logingov mhv dslogon].include?(type)

  link_authn_context =
    case authn_context
    when LOA::IDME_LOA1_VETS, 'multifactor'
      build_authn_context(@loa3_context, AuthnContext::ID_ME)
    when IAL::LOGIN_GOV_IAL1
      build_authn_context([IAL::LOGIN_GOV_IAL2, AAL::LOGIN_GOV_AAL2], AuthnContext::LOGIN_GOV)
    when 'myhealthevet', 'myhealthevet_multifactor'
      build_authn_context('myhealthevet_loa3', AuthnContext::MHV)
    when 'dslogon', 'dslogon_multifactor'
      build_authn_context('dslogon_loa3', AuthnContext::DSLOGON)
    when SAML::UserAttributes::SSOe::INBOUND_AUTHN_CONTEXT
      "#{@user.identity.[:service_name]}_loa3"
    end

  build_sso_url(link_authn_context, AuthnContext::EXACT)
end