diff --git a/app/controllers/idv/capture_doc_controller.rb b/app/controllers/idv/capture_doc_controller.rb index a7dabc2b6f9..d9a4874746f 100644 --- a/app/controllers/idv/capture_doc_controller.rb +++ b/app/controllers/idv/capture_doc_controller.rb @@ -69,17 +69,19 @@ def process_result(result) reset_session session[:doc_capture_user_id] = result.extra[:for_user_id] session[:document_capture_session_uuid] = document_capture_session_uuid - if FeatureManagement.document_capture_step_enabled? - session[:sp] ||= {} - session[:sp][:ial2_strict] = document_capture_session.ial2_strict - session[:sp][:issuer] = document_capture_session.issuer - end + update_sp_session_with_result(result) else flash[:error] = t('errors.capture_doc.invalid_link') redirect_to root_url end end + def update_sp_session_with_result(result) + session[:sp] ||= {} + session[:sp][:ial2_strict] = result.extra[:ial2_strict] + session[:sp][:issuer] = result.extra[:sp_issuer] + end + def token params[:token] end @@ -87,9 +89,5 @@ def token def document_capture_session_uuid params['document-capture-session'] end - - def document_capture_session - DocumentCaptureSession.find_by(uuid: document_capture_session_uuid) - end end end diff --git a/app/services/capture_doc/create_request.rb b/app/services/capture_doc/create_request.rb index bd43e4b6cda..8ed36d57f30 100644 --- a/app/services/capture_doc/create_request.rb +++ b/app/services/capture_doc/create_request.rb @@ -1,15 +1,23 @@ module CaptureDoc class CreateRequest - def self.call(user_id) + def self.call(user_id, sp_session) doc_capture = DocCapture.find_by(user_id: user_id) - token = SecureRandom.uuid - now = Time.zone.now + if doc_capture - doc_capture.update!(request_token: token, requested_at: now, acuant_token: nil) + doc_capture.update!(acuant_token: nil, **doc_capture_attributes(sp_session)) doc_capture else - DocCapture.create(user_id: user_id, request_token: token, requested_at: now) + DocCapture.create(user_id: user_id, **doc_capture_attributes(sp_session)) end end + + def self.doc_capture_attributes(sp_session) + { + request_token: SecureRandom.uuid, + requested_at: Time.zone.now, + issuer: sp_session[:issuer], + ial2_strict: sp_session[:ial2_strict], + } + end end end diff --git a/app/services/capture_doc/validate_document_capture_session.rb b/app/services/capture_doc/validate_document_capture_session.rb index a313910f563..0592c462c04 100644 --- a/app/services/capture_doc/validate_document_capture_session.rb +++ b/app/services/capture_doc/validate_document_capture_session.rb @@ -22,6 +22,8 @@ def extra_analytics_attributes for_user_id: document_capture_session&.user_id, user_id: 'anonymous-uuid', event: 'Document capture session validation', + ial2_strict: document_capture_session&.ial2_strict?, + sp_issuer: document_capture_session&.issuer, } end end diff --git a/app/services/capture_doc/validate_request_token.rb b/app/services/capture_doc/validate_request_token.rb index 425bec86e30..f15e27968bd 100644 --- a/app/services/capture_doc/validate_request_token.rb +++ b/app/services/capture_doc/validate_request_token.rb @@ -22,6 +22,8 @@ def extra_analytics_attributes for_user_id: capture_doc_request&.user_id, user_id: 'anonymous-uuid', event: 'Request token validation', + ial2_strict: capture_doc_request&.ial2_strict?, + sp_issuer: capture_doc_request&.issuer, } end end diff --git a/app/services/flow/base_flow.rb b/app/services/flow/base_flow.rb index acd5baaabce..6b314fe001c 100644 --- a/app/services/flow/base_flow.rb +++ b/app/services/flow/base_flow.rb @@ -35,7 +35,7 @@ def mark_step_complete(step) return if step.nil? klass = steps[step] - retun if klass.nil? + return if klass.nil? flow_session[klass.to_s] = true end diff --git a/app/services/idv/steps/send_link_step.rb b/app/services/idv/steps/send_link_step.rb index f85606571db..69660050ca6 100644 --- a/app/services/idv/steps/send_link_step.rb +++ b/app/services/idv/steps/send_link_step.rb @@ -10,7 +10,7 @@ def call private def send_link - capture_doc = CaptureDoc::CreateRequest.call(user_id) + capture_doc = CaptureDoc::CreateRequest.call(user_id, sp_session) session_uuid = flow_session[:document_capture_session_uuid] update_document_capture_session_requested_at(session_uuid) Telephony.send_doc_auth_link( @@ -32,7 +32,11 @@ def update_document_capture_session_requested_at(session_uuid) return unless FeatureManagement.document_capture_step_enabled? document_capture_session = DocumentCaptureSession.find_by(uuid: session_uuid) return unless document_capture_session - document_capture_session.update!(requested_at: Time.zone.now) + document_capture_session.update!( + requested_at: Time.zone.now, + issuer: sp_session[:issuer], + ial2_strict: sp_session[:ial2_strict], + ) end def link(token, session_uuid) diff --git a/db/migrate/20200922144112_add_liveness_enabled_fields_to_doc_captures.rb b/db/migrate/20200922144112_add_liveness_enabled_fields_to_doc_captures.rb new file mode 100644 index 00000000000..dbdf28ca2b0 --- /dev/null +++ b/db/migrate/20200922144112_add_liveness_enabled_fields_to_doc_captures.rb @@ -0,0 +1,6 @@ +class AddLivenessEnabledFieldsToDocCaptures < ActiveRecord::Migration[5.2] + def change + add_column :doc_captures, :ial2_strict, :boolean + add_column :doc_captures, :issuer, :string + end +end diff --git a/db/schema.rb b/db/schema.rb index a21ac25dc21..b3ad3f3f243 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -10,7 +10,7 @@ # # It's strongly recommended that you check this file into your version control system. -ActiveRecord::Schema.define(version: 2020_09_18_154850) do +ActiveRecord::Schema.define(version: 2020_09_22_144112) do # These are extensions that must be enabled in order to support this database enable_extension "plpgsql" @@ -168,12 +168,12 @@ t.integer "choose_method_view_count", default: 0 t.datetime "present_cac_view_at" t.integer "present_cac_view_count", default: 0 - t.integer "present_cac_submit_count", default: 0 - t.integer "present_cac_error_count", default: 0 t.datetime "enter_info_view_at" t.integer "enter_info_view_count", default: 0 t.datetime "success_view_at" t.integer "success_view_count", default: 0 + t.integer "present_cac_submit_count", default: 0 + t.integer "present_cac_error_count", default: 0 t.datetime "selfie_view_at" t.integer "selfie_view_count", default: 0 t.integer "selfie_submit_count", default: 0 @@ -202,6 +202,8 @@ t.string "acuant_token" t.datetime "created_at", null: false t.datetime "updated_at", null: false + t.boolean "ial2_strict" + t.string "issuer" t.index ["request_token"], name: "index_doc_captures_on_request_token", unique: true t.index ["user_id"], name: "index_doc_captures_on_user_id", unique: true end diff --git a/spec/controllers/idv/capture_doc_controller_spec.rb b/spec/controllers/idv/capture_doc_controller_spec.rb index 08dde52699d..02c94afcba6 100644 --- a/spec/controllers/idv/capture_doc_controller_spec.rb +++ b/spec/controllers/idv/capture_doc_controller_spec.rb @@ -25,7 +25,7 @@ token = nil before do allow(FeatureManagement).to receive(:document_capture_step_enabled?).and_return(false) - capture_doc = CaptureDoc::CreateRequest.call(user.id) + capture_doc = CaptureDoc::CreateRequest.call(user.id, {}) token = capture_doc.request_token end diff --git a/spec/features/idv/doc_capture/mobile_back_image_step_spec.rb b/spec/features/idv/doc_capture/mobile_back_image_step_spec.rb index 825c95666dd..3378c9a471d 100644 --- a/spec/features/idv/doc_capture/mobile_back_image_step_spec.rb +++ b/spec/features/idv/doc_capture/mobile_back_image_step_spec.rb @@ -5,9 +5,18 @@ include DocAuthHelper include DocCaptureHelper + let(:sp_requested_ial2_strict) { false } + before do allow(FeatureManagement).to receive(:document_capture_step_enabled?).and_return(false) + + if sp_requested_ial2_strict + visit_idp_from_oidc_sp_with_ial2_strict + else + visit_idp_from_oidc_sp_with_ial2 + end complete_doc_capture_steps_before_mobile_back_image_step + allow_any_instance_of(DeviceDetector).to receive(:device_type).and_return('mobile') end @@ -46,17 +55,39 @@ expect(page).to have_current_path(idv_capture_doc_capture_mobile_back_image_step) end - it 'does not attempt to verify the document if selfie checking is enabled' do - allow(Figaro.env).to receive(:liveness_checking_enabled).and_return('true') + context 'with liveness enabled' do + before do + allow(Figaro.env).to receive(:liveness_checking_enabled).and_return('true') + end - mock_client = DocAuth::Mock::DocAuthMockClient.new - allow(DocAuth::Mock::DocAuthMockClient).to receive(:new).and_return(mock_client) + context 'the SP requested IAL2 strict' do + let(:sp_requested_ial2_strict) { true } - expect(mock_client).to_not receive(:get_results) + it 'does not attempt to verify the document until the selfie step' do + mock_client = DocAuth::Mock::DocAuthMockClient.new + allow(DocAuth::Mock::DocAuthMockClient).to receive(:new).and_return(mock_client) - attach_image - click_idv_continue + expect(mock_client).to_not receive(:get_results) + + attach_image + click_idv_continue + + expect(page).to have_current_path(idv_capture_doc_capture_selfie_step) + end + end + + context 'the SP does not request IAL2 strict' do + let(:sp_requested_ial2_strict) { false } + + it 'does not redirect to the selfie step' do + attach_image_data_url + click_idv_continue - expect(page).to have_current_path(idv_capture_doc_capture_selfie_step) + expect(page).to have_current_path(idv_capture_doc_capture_complete_step) + expect(DocAuth::Mock::DocAuthMockClient.last_uploaded_back_image).to eq( + doc_auth_image_data_url_data, + ) + end + end end end diff --git a/spec/services/capture_doc/create_request_spec.rb b/spec/services/capture_doc/create_request_spec.rb index bab44142613..d3c447acd9c 100644 --- a/spec/services/capture_doc/create_request_spec.rb +++ b/spec/services/capture_doc/create_request_spec.rb @@ -3,10 +3,16 @@ describe CaptureDoc::CreateRequest do let(:subject) { described_class } let(:user_id) { 1 } + let(:sp_session) do + { + ial2_strict: true, + issuer: 'fake-sp-issuer', + } + end let(:old_timestamp) { Time.zone.now - 1.year } it 'creates a new request if one does not exist' do - result = subject.call(user_id) + result = subject.call(user_id, sp_session) expect(result).to be_kind_of(DocCapture) doc_capture = DocCapture.find_by(user_id: user_id) @@ -14,6 +20,8 @@ expect(doc_capture.request_token).to be_present expect(doc_capture.requested_at).to be_present expect(doc_capture.acuant_token).to be_nil + expect(doc_capture.ial2_strict).to eq(true) + expect(doc_capture.issuer).to eq 'fake-sp-issuer' end it 'update a request if one already exists' do @@ -24,7 +32,7 @@ acuant_token: 'foo', ) - result = subject.call(user_id) + result = subject.call(user_id, sp_session) expect(result).to be_kind_of(DocCapture) doc_capture = DocCapture.find_by(user_id: user_id) @@ -33,5 +41,7 @@ expect(doc_capture.request_token).to be_present expect(doc_capture.requested_at).to_not eq(old_timestamp) expect(doc_capture.acuant_token).to be_nil + expect(doc_capture.ial2_strict).to eq(true) + expect(doc_capture.issuer).to eq 'fake-sp-issuer' end end diff --git a/spec/services/capture_doc/find_user_id_spec.rb b/spec/services/capture_doc/find_user_id_spec.rb index bb1dc5562bf..3f0390eeacd 100644 --- a/spec/services/capture_doc/find_user_id_spec.rb +++ b/spec/services/capture_doc/find_user_id_spec.rb @@ -5,7 +5,7 @@ let(:user_id) { 1 } it 'finds the user_id if it exists and is not expired' do - doc_capture = CaptureDoc::CreateRequest.call(user_id) + doc_capture = CaptureDoc::CreateRequest.call(user_id, {}) result = subject.call(doc_capture.request_token) expect(result).to eq(user_id) @@ -14,7 +14,7 @@ it 'does not find the user_id if it the token is expired' do doc_capture = nil Timecop.travel(Time.zone.now - 1.day) do - doc_capture = CaptureDoc::CreateRequest.call(user_id) + doc_capture = CaptureDoc::CreateRequest.call(user_id, {}) end result = subject.call(doc_capture.request_token) diff --git a/spec/services/capture_doc/update_acuant_token_spec.rb b/spec/services/capture_doc/update_acuant_token_spec.rb index a5e81792079..61baecc425b 100644 --- a/spec/services/capture_doc/update_acuant_token_spec.rb +++ b/spec/services/capture_doc/update_acuant_token_spec.rb @@ -6,7 +6,7 @@ let(:token) { 'foo' } it 'updates the token if the entry exists' do - CaptureDoc::CreateRequest.call(user_id) + CaptureDoc::CreateRequest.call(user_id, {}) result = subject.call(user_id, token) expect(result).to be_truthy diff --git a/spec/support/features/doc_capture_helper.rb b/spec/support/features/doc_capture_helper.rb index 5227196c45c..375d11402ab 100644 --- a/spec/support/features/doc_capture_helper.rb +++ b/spec/support/features/doc_capture_helper.rb @@ -74,7 +74,7 @@ def mock_doc_captured(user_id) response = DocAuth::Response.new(success: true) user.document_capture_sessions.last.store_result_from_response(response) else - doc_capture = CaptureDoc::CreateRequest.call(user_id) + doc_capture = CaptureDoc::CreateRequest.call(user_id, {}) doc_capture.acuant_token = 'foo' doc_capture.save! end