diff --git a/app/controllers/openid_connect/authorization_controller.rb b/app/controllers/openid_connect/authorization_controller.rb index e35fe9164a9..f355665a61a 100644 --- a/app/controllers/openid_connect/authorization_controller.rb +++ b/app/controllers/openid_connect/authorization_controller.rb @@ -10,6 +10,7 @@ class AuthorizationController < ApplicationController include BillableEventTrackable include ForcedReauthenticationConcern + before_action :block_biometric_requests_in_production, only: [:index] before_action :build_authorize_form_from_params, only: [:index] before_action :pre_validate_authorize_form, only: [:index] before_action :sign_out_if_prompt_param_is_login_and_user_is_signed_in, only: [:index] @@ -44,6 +45,13 @@ def index private + def block_biometric_requests_in_production + if params['biometric_comparison_required'] == 'true' && + FeatureManagement.idv_block_biometrics_requests? + render_not_acceptable + end + end + def check_sp_active return if @authorize_form.service_provider&.active? redirect_to sp_inactive_error_url diff --git a/lib/feature_management.rb b/lib/feature_management.rb index 664f6466f10..db78c5efbac 100644 --- a/lib/feature_management.rb +++ b/lib/feature_management.rb @@ -162,4 +162,9 @@ def self.idv_by_mail_only? outage_status.any_phone_vendor_outage? || outage_status.phone_finder_outage? end + + def self.idv_block_biometrics_requests? + (Identity::Hostdata.in_datacenter? && Identity::Hostdata.env == 'prod') || + !IdentityConfig.store.doc_auth_selfie_capture_enabled + end end diff --git a/spec/controllers/openid_connect/authorization_controller_spec.rb b/spec/controllers/openid_connect/authorization_controller_spec.rb index 6b362094969..6d46fc45f57 100644 --- a/spec/controllers/openid_connect/authorization_controller_spec.rb +++ b/spec/controllers/openid_connect/authorization_controller_spec.rb @@ -999,12 +999,82 @@ ) end - it 'sets biometric_comparison_required to true if biometric comparison is required' do - params[:biometric_comparison_required] = true + describe 'handling the :biometric_comparison_required parameter' do + before do + allow(IdentityConfig.store).to receive(:doc_auth_selfie_capture_enabled).and_return(true) + allow(Identity::Hostdata).to receive(:in_datacenter?).and_return(in_datacenter) + allow(Identity::Hostdata).to receive(:env).and_return(env) + end - action + context 'when the param value :biometric_comparison_required is "true"' do + before do + params[:biometric_comparison_required] = 'true' + action + end + + context 'and we are not in production' do + context 'because we are not deployed' do + let(:in_datacenter) { false } + let(:env) { 'prod' } + + it 'sets the session :biometric_comparison_required value to true' do + expect(session[:sp][:biometric_comparison_required]).to eq(true) + end + end + + context 'because the environment is not set to "prod"' do + let(:in_datacenter) { true } + let(:env) { 'test' } + + it 'sets the session :biometric_comparison_required value to true' do + expect(session[:sp][:biometric_comparison_required]).to eq(true) + end + end + end + + # Temporary barrier to public presentation. Update or remove + # when we are ready to accept :biometric_comparison_required + # in production. See LG-11962. + context 'in production' do + let(:in_datacenter) { true } + let(:env) { 'prod' } + + it 'does not set the :sp value' do + expect(session).not_to include(:sp) + end - expect(session[:sp][:biometric_comparison_required]).to eq(true) + it 'renders the unacceptable page' do + expect(controller).to render_template('pages/not_acceptable') + end + end + end + + context 'when the param value :biometric_comparison_required is not set' do + before do + # Should be a no-op, but let's be paranoid. + params.delete(:biometric_comparison_required) + + action + end + + context 'in production' do + let(:in_datacenter) { true } + let(:env) { 'prod' } + + it 'sets the session :biometric_comparison_required value to false' do + expect(session[:sp][:biometric_comparison_required]).to eq(false) + end + end + + context 'not in production' do + let(:in_datacenter) { false } + let(:env) { 'test' } + + it 'sets the session :biometric_comparison_required value to false' do + expect(session[:sp][:biometric_comparison_required]).to eq(false) + end + end + end end end end diff --git a/spec/features/openid_connect/authorization_confirmation_spec.rb b/spec/features/openid_connect/authorization_confirmation_spec.rb index 25bafb60992..40e1aeccb17 100644 --- a/spec/features/openid_connect/authorization_confirmation_spec.rb +++ b/spec/features/openid_connect/authorization_confirmation_spec.rb @@ -105,4 +105,15 @@ def create_user_and_remember_device end end end + + context 'when asked for selfie verification in production' do + before do + allow(Rails.env).to receive(:production?).and_return(true) + visit visit_idp_from_ial2_oidc_sp(biometric_comparison_required: true) + end + + it 'redirects to the 406 (unacceptable) page' do + expect(page.status_code).to eq(406) + end + end end diff --git a/spec/lib/feature_management_spec.rb b/spec/lib/feature_management_spec.rb index c428a837382..ed19e29701d 100644 --- a/spec/lib/feature_management_spec.rb +++ b/spec/lib/feature_management_spec.rb @@ -540,4 +540,38 @@ end end end + + describe '#idv_block_biometrics_requests?' do + before do + allow(IdentityConfig.store).to receive(:doc_auth_selfie_capture_enabled). + and_return(selfie_capture_enabled) + end + + context 'selfies are disabled' do + let(:selfie_capture_enabled) { false } + + it 'says to block biometric requests' do + expect(FeatureManagement.idv_block_biometrics_requests?).to eq(true) + end + end + + context 'selfies are enabled' do + let(:selfie_capture_enabled) { true } + + it 'says to not block biometric requests' do + expect(FeatureManagement.idv_block_biometrics_requests?).to eq(false) + end + + context 'in production' do + before do + allow(Identity::Hostdata).to receive(:in_datacenter?).and_return(true) + allow(Identity::Hostdata).to receive(:env).and_return('prod') + end + + it 'says to block biometric requests' do + expect(FeatureManagement.idv_block_biometrics_requests?).to eq(true) + end + end + end + end end diff --git a/spec/support/oidc_auth_helper.rb b/spec/support/oidc_auth_helper.rb index 0aa6ad7beb6..6613f936174 100644 --- a/spec/support/oidc_auth_helper.rb +++ b/spec/support/oidc_auth_helper.rb @@ -79,7 +79,8 @@ def ial2_params(prompt: nil, nonce: SecureRandom.hex, client_id: OIDC_ISSUER, acr_values: Saml::Idp::Constants::IAL2_AUTHN_CONTEXT_CLASSREF, - tid: nil) + tid: nil, + biometric_comparison_required: false) ial2_params = { client_id: client_id, response_type: 'code', @@ -91,6 +92,9 @@ def ial2_params(prompt: nil, } ial2_params[:tid] = tid if tid ial2_params[:prompt] = prompt if prompt + if biometric_comparison_required + ial2_params[:biometric_comparison_required] = 'true' + end ial2_params end