Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion app/controllers/api/verify/document_capture_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@ def enqueue_job
}
Idv::Agent.new(applicant).proof_document(
verify_document_capture_session,
liveness_checking_enabled: false,
trace_id: amzn_trace_id,
image_metadata: image_metadata,
analytics_data: {
Expand Down
13 changes: 2 additions & 11 deletions app/jobs/document_proofing_job.rb
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ def perform(
result_id:,
encrypted_arguments:,
trace_id:,
liveness_checking_enabled:,
Comment thread
jmhooper marked this conversation as resolved.
image_metadata:,
analytics_data:,
flow_path:
Expand All @@ -32,23 +31,15 @@ def perform(
encryption_key = Base64.decode64(document_args[:encryption_key].to_s)
front_image_iv = Base64.decode64(document_args[:front_image_iv].to_s)
back_image_iv = Base64.decode64(document_args[:back_image_iv].to_s)
selfie_image_iv = Base64.decode64(document_args[:selfie_image_iv].to_s)
front_image_url = document_args[:front_image_url]
back_image_url = document_args[:back_image_url]
selfie_image_url = document_args[:selfie_image_url]

front_image = decrypt_image_from_s3(
timer: timer, name: :front, url: front_image_url, iv: front_image_iv, key: encryption_key,
)
back_image = decrypt_image_from_s3(
timer: timer, name: :back, url: back_image_url, iv: back_image_iv, key: encryption_key,
)
if liveness_checking_enabled
selfie_image = decrypt_image_from_s3(
timer: timer, name: :selfie, url: selfie_image_url, iv: selfie_image_iv,
key: encryption_key
)
end

analytics = build_analytics(dcs)
doc_auth_client = build_doc_auth_client(analytics, dcs)
Expand All @@ -57,9 +48,9 @@ def perform(
doc_auth_client.post_images(
front_image: front_image,
back_image: back_image,
selfie_image: selfie_image || '',
selfie_image: nil,
Comment thread
jmhooper marked this conversation as resolved.
image_source: image_source(image_metadata),
liveness_checking_enabled: liveness_checking_enabled,
liveness_checking_enabled: false,
user_uuid: user_uuid,
uuid_prefix: uuid_prefix,
)
Expand Down
2 changes: 0 additions & 2 deletions app/services/idv/agent.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,6 @@ def proof_address(document_capture_session, user_id:, issuer:, trace_id:)

def proof_document(
document_capture_session,
liveness_checking_enabled:,
trace_id:,
image_metadata:,
analytics_data:,
Expand All @@ -73,7 +72,6 @@ def proof_document(

DocumentProofingJob.perform_later(
encrypted_arguments: encrypted_arguments,
liveness_checking_enabled: liveness_checking_enabled,
result_id: document_capture_session.result_id,
trace_id: trace_id,
image_metadata: image_metadata,
Expand Down
170 changes: 42 additions & 128 deletions spec/jobs/document_proofing_job_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,14 @@
RSpec.describe DocumentProofingJob, type: :job do
let(:front_image_url) { 'http://bucket.s3.amazonaws.com/bar1' }
let(:back_image_url) { 'http://bucket.s3.amazonaws.com/bar2' }
let(:selfie_image_url) { 'http://bucket.s3.amazonaws.com/bar3' }
let(:encryption_key) { SecureRandom.random_bytes(32) }
let(:front_image_iv) { SecureRandom.random_bytes(12) }
let(:back_image_iv) { SecureRandom.random_bytes(12) }
let(:selfie_image_iv) { SecureRandom.random_bytes(12) }
let(:trace_id) { SecureRandom.uuid }
let(:source) { nil }
let(:front_image_metadata) { { mimeType: 'image/png', source: source } }
let(:back_image_metadata) { { mimeType: 'image/png', source: source } }
let(:image_metadata) { { front: front_image_metadata, back: back_image_metadata } }
let(:liveness_checking_enabled) { true }

let(:applicant_pii) do
{
Expand All @@ -33,7 +30,6 @@
before do
encrypt_and_stub_s3(body: body, url: front_image_url, iv: front_image_iv, key: encryption_key)
encrypt_and_stub_s3(body: body, url: back_image_url, iv: back_image_iv, key: encryption_key)
encrypt_and_stub_s3(body: body, url: selfie_image_url, iv: selfie_image_iv, key: encryption_key)
end

let(:encrypted_arguments) do
Expand All @@ -43,10 +39,8 @@
encryption_key: Base64.encode64(encryption_key),
front_image_iv: Base64.encode64(front_image_iv),
back_image_iv: Base64.encode64(back_image_iv),
selfie_image_iv: Base64.encode64(selfie_image_iv),
front_image_url: front_image_url,
back_image_url: back_image_url,
selfie_image_url: selfie_image_url,
},
}.to_json,
)
Expand All @@ -62,7 +56,6 @@
it 'stores results' do
DocumentProofingJob.perform_later(
result_id: document_capture_session.result_id,
liveness_checking_enabled: liveness_checking_enabled,
encrypted_arguments: encrypted_arguments,
trace_id: trace_id,
image_metadata: image_metadata,
Expand All @@ -81,7 +74,6 @@
subject(:perform) do
instance.perform(
result_id: document_capture_session.result_id,
liveness_checking_enabled: liveness_checking_enabled,
encrypted_arguments: encrypted_arguments,
trace_id: trace_id,
image_metadata: image_metadata,
Expand All @@ -106,129 +98,58 @@
stub_request(:post, "#{doc_url}/Image?light=0&side=1").to_return(body: '')
stub_request(:get, doc_url).to_return(body: '{"Result":1}')
stub_request(:get, "#{doc_url}/Field/Image?key=Photo").to_return(body: '')
stub_request(:post, 'https://facial_match.example.com/api/v1/facematch').
to_return(body: '{"IsMatch":true}')
stub_request(:post, 'https://liveness.example.com/api/v1/liveness').
to_return(body: '{"LivenessResult":{"LivenessAssessment": "Live"}}')
stub_request(:post, 'https://example.login.gov/api/callbacks/proof-document/:token').
to_return(body: '')

allow_any_instance_of(DocAuth::Acuant::Responses::GetResultsResponse).
to receive(:pii_from_doc).and_return(applicant_pii)
end

context 'liveness checking disabled' do
let(:liveness_checking_enabled) { false }

it 'returns a response' do
perform

result = document_capture_session.load_doc_auth_async_result

expect(result.result).to eq(
alert_failure_count: 0,
vendor: 'Acuant',
doc_auth_result: 'Passed',
billed: true,
errors: {},
log_alert_results: {},
attention_with_barcode: false,
image_metrics: {},
processed_alerts: { failed: [], passed: [] },
success: true,
exception: nil,
tamper_result: nil,
)

expect(job_analytics).to have_logged_event(
'IdV: doc auth image upload vendor submitted',
success: true,
errors: {},
attention_with_barcode: false,
exception: nil,
vendor: 'Acuant',
billed: true,
doc_auth_result: 'Passed',
processed_alerts: { failed: [], passed: [] },
alert_failure_count: 0,
image_metrics: {},
state: 'MT',
state_id_type: 'drivers_license',
async: true,
attempts: 0,
remaining_attempts: IdentityConfig.store.doc_auth_max_attempts,
client_image_metrics: {
front: front_image_metadata,
back: back_image_metadata,
},
tamper_result: nil,
)

expect(result.pii_from_doc).to eq(applicant_pii)
end
end

context 'liveness checking enabled' do
let(:liveness_checking_enabled) { true }

it 'returns a response' do
perform
it 'returns a successful response' do
perform

result = document_capture_session.load_doc_auth_async_result

expect(result.result).to eq(
alert_failure_count: 0,
vendor: 'Acuant',
billed: true,
errors: {},
log_alert_results: {},
attention_with_barcode: false,
face_match_results: { is_match: true, match_score: nil },
image_metrics: {},
processed_alerts: { failed: [], passed: [] },
doc_auth_result: 'Passed',
selfie_liveness_results: {
acuant_error: { code: nil, message: nil },
liveness_assessment: 'Live',
liveness_score: nil,
},
success: true,
exception: nil,
tamper_result: nil,
)
result = document_capture_session.load_doc_auth_async_result

expect(result.result).to eq(
alert_failure_count: 0,
vendor: 'Acuant',
doc_auth_result: 'Passed',
billed: true,
errors: {},
log_alert_results: {},
attention_with_barcode: false,
image_metrics: {},
processed_alerts: { failed: [], passed: [] },
success: true,
exception: nil,
tamper_result: nil,
)

expect(job_analytics).to have_logged_event(
'IdV: doc auth image upload vendor submitted',
success: true,
errors: {},
attention_with_barcode: false,
exception: nil,
vendor: 'Acuant',
billed: true,
doc_auth_result: 'Passed',
processed_alerts: { failed: [], passed: [] },
alert_failure_count: 0,
image_metrics: {},
state: 'MT',
state_id_type: 'drivers_license',
async: true,
attempts: 0,
remaining_attempts: IdentityConfig.store.doc_auth_max_attempts,
face_match_results: { is_match: true, match_score: nil },
selfie_liveness_results: {
acuant_error: { code: nil, message: nil },
liveness_assessment: 'Live',
liveness_score: nil,
},
client_image_metrics: {
front: front_image_metadata,
back: back_image_metadata,
},
tamper_result: nil,
)
expect(job_analytics).to have_logged_event(
'IdV: doc auth image upload vendor submitted',
success: true,
errors: {},
attention_with_barcode: false,
exception: nil,
vendor: 'Acuant',
billed: true,
doc_auth_result: 'Passed',
processed_alerts: { failed: [], passed: [] },
alert_failure_count: 0,
image_metrics: {},
state: 'MT',
state_id_type: 'drivers_license',
async: true,
attempts: 0,
remaining_attempts: IdentityConfig.store.doc_auth_max_attempts,
client_image_metrics: {
front: front_image_metadata,
back: back_image_metadata,
},
tamper_result: nil,
)

expect(result.pii_from_doc).to eq(applicant_pii)
end
expect(result.pii_from_doc).to eq(applicant_pii)
end

it 'logs the trace_id and timing info' do
Expand All @@ -238,10 +159,8 @@
timing: hash_including(
'decrypt.back': kind_of(Float),
'decrypt.front': kind_of(Float),
'decrypt.selfie': kind_of(Float),
'download.back': kind_of(Float),
'download.front': kind_of(Float),
'download.selfie': kind_of(Float),
),
)
end
Expand All @@ -253,7 +172,6 @@
context 'with local image URLs instead of S3 URLs' do
let(:front_image_url) { 'http://example.com/bar1' }
let(:back_image_url) { 'http://example.com/bar2' }
let(:selfie_image_url) { 'http://example.com/bar3' }

before do
data = { document: applicant_pii }.to_json
Expand All @@ -265,17 +183,13 @@
stub_request(:get, back_image_url).to_return(
body: encryption_helper.encrypt(data: data, key: encryption_key, iv: back_image_iv),
)
stub_request(:get, selfie_image_url).to_return(
body: encryption_helper.encrypt(data: data, key: encryption_key, iv: selfie_image_iv),
)
end

it 'still downloads and decrypts the content' do
perform

expect(a_request(:get, front_image_url)).to have_been_made
expect(a_request(:get, back_image_url)).to have_been_made
expect(a_request(:get, selfie_image_url)).to have_been_made
end
end

Expand Down