Skip to content
Merged
2 changes: 2 additions & 0 deletions app/controllers/concerns/verify_profile_concern.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,8 @@ def account_or_verify_profile_url

def profile_needs_verification?
return false if current_user.blank?
return false if sp_session[:ial2_strict] &&
!IdentityConfig.store.gpo_allowed_for_strict_ial2
current_user.decorate.pending_profile_requires_verification? ||
user_needs_to_reactivate_account?
end
Expand Down
2 changes: 2 additions & 0 deletions app/controllers/idv/doc_auth_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ def redirect_if_mail_bounced
end

def redirect_if_pending_profile
return if sp_session[:ial2_strict] &&
!IdentityConfig.store.gpo_allowed_for_strict_ial2
redirect_to idv_gpo_verify_url if current_user.decorate.pending_profile_requires_verification?
end

Expand Down
7 changes: 7 additions & 0 deletions app/controllers/idv/gpo_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ class GpoController < ApplicationController
before_action :confirm_idv_needed
before_action :confirm_user_completed_idv_profile_step
before_action :confirm_mail_not_spammed
before_action :confirm_gpo_allowed_if_strict_ial2
before_action :max_attempts_reached, only: [:update]

def index
Expand Down Expand Up @@ -65,6 +66,12 @@ def failure
redirect_to idv_gpo_url unless performed?
end

def confirm_gpo_allowed_if_strict_ial2
return unless sp_session[:ial2_strict]
return if IdentityConfig.store.gpo_allowed_for_strict_ial2
redirect_to idv_phone_url
end

def pii(address_pii)
address_pii.dup.merge(non_address_pii)
end
Expand Down
5 changes: 4 additions & 1 deletion app/controllers/idv/otp_delivery_method_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,11 @@ def otp_delivery_selection_form
end

def gpo_letter_available
return @gpo_letter_available if defined?(@gpo_letter_available)
@gpo_letter_available ||= FeatureManagement.enable_gpo_verification? &&
!Idv::GpoMail.new(current_user).mail_spammed?
!Idv::GpoMail.new(current_user).mail_spammed? &&
!(sp_session[:ial2_strict] &&
!IdentityConfig.store.gpo_allowed_for_strict_ial2)
end
end
end
5 changes: 4 additions & 1 deletion app/controllers/idv/phone_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,11 @@ def new_phone_added?
end

def gpo_letter_available
return @gpo_letter_available if defined?(@gpo_letter_available)
@gpo_letter_available ||= FeatureManagement.enable_gpo_verification? &&
!Idv::GpoMail.new(current_user).mail_spammed?
!Idv::GpoMail.new(current_user).mail_spammed? &&
!(sp_session[:ial2_strict] &&
!IdentityConfig.store.gpo_allowed_for_strict_ial2)
end
end
end
11 changes: 11 additions & 0 deletions app/controllers/idv/phone_errors_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ class PhoneErrorsController < ApplicationController

before_action :confirm_two_factor_authenticated
before_action :confirm_idv_phone_step_needed
before_action :set_gpo_letter_available

def warning
@remaining_attempts = throttle.remaining_count
Expand Down Expand Up @@ -45,5 +46,15 @@ def track_event(type:)

analytics.idv_phone_error_visited(**attributes)
end

# rubocop:disable Naming/MemoizedInstanceVariableName
def set_gpo_letter_available
return @gpo_letter_available if defined?(@gpo_letter_available)
@gpo_letter_available ||= FeatureManagement.enable_gpo_verification? &&
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same thing existed previously, but won't this reassign the instance variable if called repeatedly while still false?

Should it be... ?

Suggested change
@gpo_letter_available ||= FeatureManagement.enable_gpo_verification? &&
@gpo_letter_available &&= FeatureManagement.enable_gpo_verification? &&

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yep, happy to fix!

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I ended up going with this because of some quirks with the &&= operator:

[1] pry(main)> a &&= true
=> nil
[2] pry(main)> a
=> nil

!Idv::GpoMail.new(current_user).mail_spammed? &&
!(sp_session[:ial2_strict] &&
!IdentityConfig.store.gpo_allowed_for_strict_ial2)
end
# rubocop:enable Naming/MemoizedInstanceVariableName
end
end
2 changes: 1 addition & 1 deletion app/models/profile.rb
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ def includes_phone_check?
def strict_ial2_proofed?
return false unless active
return false unless includes_liveness_check?
return true if IdentityConfig.store.usps_upload_allowed_for_strict_ial2
return true if IdentityConfig.store.gpo_allowed_for_strict_ial2
includes_phone_check?
end

Expand Down
2 changes: 1 addition & 1 deletion app/views/idv/phone_errors/_warning.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ locals:
text: t('idv.troubleshooting.options.contact_support', app_name: APP_NAME),
new_tab: true,
},
FeatureManagement.enable_gpo_verification? && {
@gpo_letter_available && {
text: t('idv.troubleshooting.options.verify_by_mail'),
url: idv_gpo_path,
},
Expand Down
2 changes: 1 addition & 1 deletion app/views/idv/phone_errors/failure.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
title: t('titles.failure.phone_verification'),
heading: t('idv.failure.phone.heading'),
options: [
FeatureManagement.enable_gpo_verification? && {
@gpo_letter_available && {
text: t('idv.troubleshooting.options.verify_by_mail'),
url: idv_gpo_path,
},
Expand Down
2 changes: 1 addition & 1 deletion config/application.yml.default
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ usps_ipp_root_url: ''
usps_ipp_request_timeout: 10
usps_ipp_sponsor_id: ''
usps_ipp_username: ''
usps_upload_allowed_for_strict_ial2: true
gpo_allowed_for_strict_ial2: true
voice_otp_pause_time: '0.5s'
voice_otp_speech_rate: 'slow'
voip_check: true
Expand Down
2 changes: 1 addition & 1 deletion lib/identity_config.rb
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,7 @@ def self.build_store(config_map)
config.add(:usps_ipp_username, type: :string)
config.add(:usps_ipp_request_timeout, type: :integer)
config.add(:usps_upload_enabled, type: :boolean)
config.add(:usps_upload_allowed_for_strict_ial2, type: :boolean)
config.add(:gpo_allowed_for_strict_ial2, type: :boolean)
config.add(:usps_upload_sftp_directory, type: :string)
config.add(:usps_upload_sftp_host, type: :string)
config.add(:usps_upload_sftp_password, type: :string)
Expand Down
2 changes: 1 addition & 1 deletion spec/features/idv/strict_ial2/upgrade_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@
context 'strict IAL2 does not allow a phone check' do
before do
allow(IdentityConfig.store).to receive(
:usps_upload_allowed_for_strict_ial2,
:gpo_allowed_for_strict_ial2,
).and_return(false)
end

Expand Down
76 changes: 76 additions & 0 deletions spec/features/idv/strict_ial2/usps_upload_disallowed_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
require 'rails_helper'

feature 'Strict IAL2 with usps upload disallowed' do
include IdvHelper
include OidcAuthHelper
include IdvHelper
include IdvStepHelper

before do
allow(IdentityConfig.store).to receive(:liveness_checking_enabled).and_return(true)
allow(IdentityConfig.store).to receive(
:gpo_allowed_for_strict_ial2,
).and_return(false)
end

it 'does not allow the user to select the letter flow during proofing' do
user = create(:user, :signed_up)
visit_idp_from_oidc_sp_with_ial2_strict
sign_in_user(user)
fill_in_code_with_last_phone_otp
click_submit_default
complete_idv_steps_before_phone_step

# Link is not present on the phone page
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))

# Link is not present on the OTP delivery selection page
fill_out_phone_form_ok('7032231234')
click_idv_continue
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))

# Link is not visible on the OTP entry page
choose_idv_otp_delivery_method_sms
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))

# Link is not visible on error or warning page
visit idv_phone_errors_warning_path
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))
visit idv_phone_errors_jobfail_path
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))
visit idv_phone_errors_timeout_path
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))
visit idv_phone_errors_failure_path
expect(page).to_not have_content(t('idv.troubleshooting.options.verify_by_mail'))

# Visiting the GPO page redirects
visit idv_gpo_path
expect(current_path).to eq(idv_phone_path)
end

it 'does not prompt a pending user for a mailed code' do
user = create(
:profile,
deactivation_reason: :verification_pending,
pii: { first_name: 'John', ssn: '111223333' },
).user

visit_idp_from_oidc_sp_with_ial2_strict
sign_in_user(user)
fill_in_code_with_last_phone_otp
click_submit_default

# Directed to the start of the proofing flow instead of GPO code verification
expect(current_path).to eq(idv_doc_auth_step_path(step: :welcome))

complete_all_doc_auth_steps
click_continue
fill_in 'Password', with: user.password
click_continue
click_acknowledge_personal_key
click_agree_and_continue

expect(current_url).to start_with('http://localhost:7654/auth/result')
expect(user.active_profile.strict_ial2_proofed?).to be_truthy
end
end
4 changes: 2 additions & 2 deletions spec/models/profile_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@
context 'the letter flow is allowed for strict IAL2' do
before do
allow(IdentityConfig.store).to receive(
:usps_upload_allowed_for_strict_ial2,
:gpo_allowed_for_strict_ial2,
).and_return(true)
end

Expand All @@ -124,7 +124,7 @@
context 'the letter flow is not allowed for strict IAL2' do
before do
allow(IdentityConfig.store).to receive(
:usps_upload_allowed_for_strict_ial2,
:gpo_allowed_for_strict_ial2,
).and_return(false)
end

Expand Down
1 change: 1 addition & 0 deletions spec/views/idv/phone_errors/failure.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
before do
decorated_session = instance_double(ServiceProviderSessionDecorator, sp_name: sp_name)
allow(view).to receive(:decorated_session).and_return(decorated_session)
assign(:gpo_letter_available, true)
allow(IdentityConfig.store).to receive(:idv_attempt_window_in_hours).and_return(timeout_hours)

@expires_at = Time.zone.now + timeout_hours.hours
Expand Down
8 changes: 3 additions & 5 deletions spec/views/idv/phone_errors/jobfail.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

describe 'idv/phone_errors/jobfail.html.erb' do
let(:sp_name) { 'Example SP' }
let(:enable_gpo_verification) { false }
let(:gpo_letter_available) { false }

before do
allow(FeatureManagement).to receive(:enable_gpo_verification?).
and_return(enable_gpo_verification)

decorated_session = instance_double(ServiceProviderSessionDecorator, sp_name: sp_name)
allow(view).to receive(:decorated_session).and_return(decorated_session)
assign(:gpo_letter_available, gpo_letter_available)

render
end
Expand Down Expand Up @@ -43,7 +41,7 @@
end

context 'gpo verification enabled' do
let(:enable_gpo_verification) { true }
let(:gpo_letter_available) { true }

it 'renders a list of troubleshooting options' do
expect(rendered).to have_link(
Expand Down
8 changes: 3 additions & 5 deletions spec/views/idv/phone_errors/timeout.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,12 @@

describe 'idv/phone_errors/timeout.html.erb' do
let(:sp_name) { 'Example SP' }
let(:enable_gpo_verification) { false }
let(:gpo_letter_available) { false }

before do
allow(FeatureManagement).to receive(:enable_gpo_verification?).
and_return(enable_gpo_verification)

decorated_session = instance_double(ServiceProviderSessionDecorator, sp_name: sp_name)
allow(view).to receive(:decorated_session).and_return(decorated_session)
assign(:gpo_letter_available, gpo_letter_available)

render
end
Expand Down Expand Up @@ -43,7 +41,7 @@
end

context 'gpo verification enabled' do
let(:enable_gpo_verification) { true }
let(:gpo_letter_available) { true }

it 'renders a list of troubleshooting options' do
expect(rendered).to have_link(
Expand Down
8 changes: 3 additions & 5 deletions spec/views/idv/phone_errors/warning.html.erb_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,12 @@
describe 'idv/phone_errors/warning.html.erb' do
let(:sp_name) { 'Example SP' }
let(:remaining_attempts) { 5 }
let(:enable_gpo_verification) { false }
let(:gpo_letter_available) { false }

before do
allow(FeatureManagement).to receive(:enable_gpo_verification?).
and_return(enable_gpo_verification)

decorated_session = instance_double(ServiceProviderSessionDecorator, sp_name: sp_name)
allow(view).to receive(:decorated_session).and_return(decorated_session)
assign(:gpo_letter_available, gpo_letter_available)

assign(:remaining_attempts, remaining_attempts)

Expand Down Expand Up @@ -43,7 +41,7 @@
end

context 'gpo verification enabled' do
let(:enable_gpo_verification) { true }
let(:gpo_letter_available) { true }

it 'renders a list of troubleshooting options' do
expect(rendered).to have_link(
Expand Down