diff --git a/app/controllers/concerns/billable_event_trackable.rb b/app/controllers/concerns/billable_event_trackable.rb index 2d57483272b..cf2fdb5542d 100644 --- a/app/controllers/concerns/billable_event_trackable.rb +++ b/app/controllers/concerns/billable_event_trackable.rb @@ -13,20 +13,16 @@ def track_billing_events private def create_sp_return_log(billable:) - user_ial_context = IalContext.new( - ial: ial_context.ial, service_provider: current_sp, user: current_user, - ) - SpReturnLog.create( request_id: request_id, user: current_user, billable: billable, - ial: user_ial_context.bill_for_ial_1_or_2, + ial: ial_context.bill_for_ial_1_or_2, issuer: current_sp.issuer, - profile_id: user_ial_context.bill_for_ial_1_or_2 > 1 ? current_user.active_profile&.id : nil, - profile_verified_at: user_ial_context.bill_for_ial_1_or_2 > 1 ? + profile_id: ial_context.bill_for_ial_1_or_2 > 1 ? current_user.active_profile&.id : nil, + profile_verified_at: ial_context.bill_for_ial_1_or_2 > 1 ? current_user.active_profile&.verified_at : nil, - profile_requested_issuer: user_ial_context.bill_for_ial_1_or_2 > 1 ? + profile_requested_issuer: ial_context.bill_for_ial_1_or_2 > 1 ? current_user.active_profile&.initiating_service_provider_issuer : nil, requested_at: session[:session_started_at], returned_at: Time.zone.now, diff --git a/app/controllers/openid_connect/authorization_controller.rb b/app/controllers/openid_connect/authorization_controller.rb index 3862b699ef5..fa34a72a59d 100644 --- a/app/controllers/openid_connect/authorization_controller.rb +++ b/app/controllers/openid_connect/authorization_controller.rb @@ -28,7 +28,7 @@ class AuthorizationController < ApplicationController before_action :prompt_for_password_if_ial2_request_and_pii_locked, only: [:index] def index - if @authorize_form.ial2_or_greater? + if resolved_authn_context_result.identity_proofing? return redirect_to reactivate_account_url if user_needs_to_reactivate_account? return redirect_to url_for_pending_profile_reason if user_has_pending_profile? return redirect_to idv_url if identity_needs_verification? @@ -97,7 +97,11 @@ def link_identity_to_service_provider end def ial_context - @authorize_form.ial_context + IalContext.new( + ial: @authorize_form.ial, + service_provider: @authorize_form.service_provider, + user: current_user, + ) end def handle_successful_handoff @@ -122,7 +126,7 @@ def track_handoff_analytics(result, attributes = {}) end def identity_needs_verification? - (@authorize_form.ial2_requested? && + (resolved_authn_context_result.identity_proofing? && (current_user.identity_not_verified? || decorated_sp_session.requested_more_recent_verification?)) || current_user.reproof_for_irs?(service_provider: current_sp) @@ -211,14 +215,9 @@ def store_request end def track_events - event_ial_context = IalContext.new( - ial: @authorize_form.ial, - service_provider: @authorize_form.service_provider, - user: current_user, - ) analytics.sp_redirect_initiated( - ial: event_ial_context.ial, - billed_ial: event_ial_context.bill_for_ial_1_or_2, + ial: ial_context.ial, + billed_ial: ial_context.bill_for_ial_1_or_2, sign_in_flow: session[:sign_in_flow], vtr: sp_session[:vtr], acr_values: sp_session[:acr_values], diff --git a/app/forms/openid_connect_authorize_form.rb b/app/forms/openid_connect_authorize_form.rb index 51a9bb4f276..bd3970803cd 100644 --- a/app/forms/openid_connect_authorize_form.rb +++ b/app/forms/openid_connect_authorize_form.rb @@ -96,7 +96,7 @@ def link_identity_to_service_provider(current_user, rails_session_id) @identity = identity_linker.link_identity( nonce: nonce, rails_session_id: rails_session_id, - ial: ial_context.ial, + ial: ial, aal: aal, acr_values: acr_values&.join(' '), vtr: vtr, @@ -117,10 +117,6 @@ def ial_values acr_values.filter { |acr| acr.include?('ial') || acr.include?('loa') } end - def ial_context - @ial_context ||= IalContext.new(ial: ial, service_provider: service_provider) - end - def ial if parsed_vector_of_trust&.identity_proofing? 2 @@ -150,10 +146,6 @@ def requested_aal_value Saml::Idp::Constants::DEFAULT_AAL_AUTHN_CONTEXT_CLASSREF end - def_delegators :ial_context, - :ial2_or_greater?, - :ial2_requested? - def biometric_comparison_required? parsed_vector_of_trust&.biometric_comparison? end @@ -180,8 +172,8 @@ def code def check_for_unauthorized_scope(params) param_value = params[:scope] - return false if ial2_or_greater? || param_value.blank? - return true if verified_at_requested? && !ial_context.ial2_service_provider? + return false if identity_proofing_requested_or_default? || param_value.blank? + return true if verified_at_requested? && !identity_proofing_service_provider? @scope != param_value.split(' ').compact end @@ -317,16 +309,15 @@ def error_redirect_uri end def scopes - if ial_context.ialmax_requested? || ial2_or_greater? + if identity_proofing_requested_or_default? return OpenidConnectAttributeScoper::VALID_SCOPES end OpenidConnectAttributeScoper::VALID_IAL1_SCOPES end def validate_privileges - if (ial2_requested? && !ial_context.ial2_service_provider?) || - (ial_context.ialmax_requested? && - !IdentityConfig.store.allowed_ialmax_providers.include?(client_id)) + if (identity_proofing_requested? && !identity_proofing_service_provider?) || + (ialmax_requested? && !ialmax_allowed_for_sp?) errors.add( :acr_values, t('openid_connect.authorization.errors.no_auth'), type: :no_auth @@ -334,6 +325,32 @@ def validate_privileges end end + def identity_proofing_requested_or_default? + identity_proofing_requested? || + ialmax_requested? || + sp_defaults_to_identity_proofing? + end + + def sp_defaults_to_identity_proofing? + vtr.blank? && ial_values.blank? && identity_proofing_service_provider? + end + + def identity_proofing_requested? + ial == 2 + end + + def identity_proofing_service_provider? + service_provider&.ial.to_i >= 2 + end + + def ialmax_allowed_for_sp? + IdentityConfig.store.allowed_ialmax_providers.include?(client_id) + end + + def ialmax_requested? + ial == 0 + end + def highest_level_aal(aal_values) AALS_BY_PRIORITY.find { |aal| aal_values.include?(aal) } end diff --git a/spec/forms/openid_connect_authorize_form_spec.rb b/spec/forms/openid_connect_authorize_form_spec.rb index 59a13a585db..7b7bedbcb25 100644 --- a/spec/forms/openid_connect_authorize_form_spec.rb +++ b/spec/forms/openid_connect_authorize_form_spec.rb @@ -758,53 +758,6 @@ end end - describe '#ial2_requested?' do - subject(:ial2_requested?) { form.ial2_requested? } - - context 'with vtr params' do - let(:acr_values) { nil } - - context 'when identity proofing is requested' do - let(:vtr) { ['P1'].to_json } - it { expect(ial2_requested?).to eq(true) } - end - - context 'when identity proofing is not requested' do - let(:vtr) { ['C1'].to_json } - it { expect(ial2_requested?).to eq(false) } - end - end - - context 'with acr_values param' do - let(:vtr) { nil } - - context 'with ial1' do - let(:acr_values) { Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF } - it { expect(ial2_requested?).to eq(false) } - end - - context 'with ial2' do - let(:acr_values) { Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF } - it { expect(ial2_requested?).to eq(true) } - end - - context 'with ial1 and ial2' do - let(:acr_values) do - [ - Saml::Idp::Constants::IAL1_AUTHN_CONTEXT_CLASSREF, - Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, - ].join(' ') - end - it { expect(ial2_requested?).to eq(true) } - end - - context 'with a malformed ial' do - let(:acr_values) { 'foobarbaz' } - it { expect(ial2_requested?).to eq(false) } - end - end - end - describe '#client_id' do it 'returns the form client_id' do form = OpenidConnectAuthorizeForm.new(client_id: 'foobar')