Skip to content
This repository was archived by the owner on Apr 22, 2021. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all 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
2 changes: 1 addition & 1 deletion Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ gemspec

gem 'aamva', github: '18F/identity-aamva-api-client-gem', tag: 'v3.4.1'
gem 'identity-doc-auth', github: '18F/identity-doc-auth', tag: 'v0.3.1'
gem 'lexisnexis', github: '18F/identity-lexisnexis-api-client-gem', tag: 'v2.4.1'
gem 'lexisnexis', github: '18F/identity-lexisnexis-api-client-gem', tag: 'v2.5.0'
gem 'proofer', github: '18F/identity-proofer-gem', tag: 'v2.7.1'

group :test do
Expand Down
2 changes: 1 addition & 1 deletion lib/identity-idp-functions/version.rb
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# frozen_string_literal: true

module IdentityIdpFunctions
VERSION = '0.7.8'
VERSION = '0.8.0'
end
2 changes: 1 addition & 1 deletion source/proof_address/lib/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,6 @@ ruby '~> 2.7.0'

gem 'aws-sdk-ssm', '~> 1.55'
gem 'faraday'
gem 'lexisnexis', github: '18F/identity-lexisnexis-api-client-gem', tag: 'v2.4.1'
gem 'lexisnexis', github: '18F/identity-lexisnexis-api-client-gem', tag: 'v2.5.0'
gem 'proofer', github: '18F/identity-proofer-gem', tag: 'v2.7.1'
gem 'retries'
2 changes: 1 addition & 1 deletion source/proof_resolution/lib/Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ ruby '~> 2.7.0'
gem 'aamva', github: '18F/identity-aamva-api-client-gem', tag: 'v3.4.1'
gem 'aws-sdk-ssm', '~> 1.55'
gem 'faraday'
gem 'lexisnexis', github: '18F/identity-lexisnexis-api-client-gem', tag: 'v2.4.1'
gem 'lexisnexis', github: '18F/identity-lexisnexis-api-client-gem', tag: 'v2.5.0'
gem 'proofer', github: '18F/identity-proofer-gem', tag: 'v2.7.1'
gem 'retries'
114 changes: 98 additions & 16 deletions source/proof_resolution/lib/proof_resolution.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,21 +16,75 @@ def self.handle(event:, context:, &callback_block) # rubocop:disable Lint/Unused
new(**params).proof(&callback_block)
end

attr_reader :applicant_pii, :callback_url, :should_proof_state_id, :trace_id, :timer

def initialize(applicant_pii:, callback_url:, should_proof_state_id:, trace_id: nil)
attr_reader :applicant_pii,
:callback_url,
:trace_id,
:timer

def initialize(
applicant_pii:,
callback_url:,
should_proof_state_id:,
dob_year_only: false,
trace_id: nil
)
@applicant_pii = applicant_pii
@callback_url = callback_url
@should_proof_state_id = should_proof_state_id
@dob_year_only = dob_year_only
@trace_id = trace_id
@timer = IdentityIdpFunctions::Timer.new
end

def should_proof_state_id?
@should_proof_state_id
end

def dob_year_only?
@dob_year_only
end

CallbackLogData = Struct.new(
:result,
:resolution_success,
:state_id_success,
keyword_init: true,
)

# rubocop:disable Metrics/PerceivedComplexity
def proof
set_up_env!

raise Errors::MisconfiguredLambdaError if !block_given? && api_auth_token.to_s.empty?

callback_log_data = if dob_year_only? && should_proof_state_id?
proof_aamva_then_lexisnexis_dob_only
else
proof_lexisnexis_then_aamva
end

callback_body = {
resolution_result: callback_log_data.result,
}

if block_given?
yield callback_body
else
post_callback(callback_body: callback_body)
end
ensure
log_event(
name: 'ProofResolution',
trace_id: trace_id,
resolution_success: callback_log_data&.resolution_success,
state_id_success: callback_log_data&.state_id_success,
timing: timer.results,
)
end
# rubocop:enable Metrics/PerceivedComplexity

# @return [CallbackLogData]
def proof_lexisnexis_then_aamva
proofer_result = timer.time('resolution') do
with_retries(**faraday_retry_options) do
lexisnexis_proofer.proof(applicant_pii)
Expand All @@ -47,29 +101,57 @@ def proof
result[:exception] = proofer_result.exception.inspect if proofer_result.exception

state_id_success = nil
if should_proof_state_id && result[:success]
if should_proof_state_id? && result[:success]
timer.time('state_id') do
proof_state_id(result)
end
state_id_success = result[:success]
end

callback_body = {
resolution_result: result,
}
CallbackLogData.new(
result: result,
resolution_success: resolution_success,
state_id_success: state_id_success,
)
end

if block_given?
yield callback_body
else
post_callback(callback_body: callback_body)
# @return [CallbackLogData]
def proof_aamva_then_lexisnexis_dob_only
proofer_result = timer.time('state_id') do
with_retries(**faraday_retry_options) do
aamva_proofer.proof(applicant_pii)
end
end
ensure
log_event(
name: 'ProofResolution',
trace_id: trace_id,

result = proofer_result.to_h
state_id_success = proofer_result.success?
resolution_success = nil

result[:context] = { stages: [{ state_id: Aamva::Proofer.vendor_name }] }

if state_id_success
lexisnexis_result = timer.time('resolution') do
with_retries(**faraday_retry_options) do
lexisnexis_proofer.proof(applicant_pii.merge(dob_year_only: dob_year_only?))
end
end

resolution_success = lexisnexis_result.success?

result.merge(lexisnexis_result.to_h) do |key, orig, current|
key == :messages ? orig + current : current
end

result[:context][:stages].push(resolution: LexisNexis::InstantVerify::Proofer.vendor_name)
result[:transaction_id] = lexisnexis_result.transaction_id
result[:timed_out] = lexisnexis_result.timed_out?
result[:exception] = lexisnexis_result.exception.inspect if lexisnexis_result.exception
end

CallbackLogData.new(
result: result,
resolution_success: resolution_success,
state_id_success: state_id_success,
timing: timer.results,
)
end

Expand Down
43 changes: 43 additions & 0 deletions source/proof_resolution/spec/proof_resolution_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -123,13 +123,15 @@
let(:should_proof_state_id) { true }
let(:lexisnexis_proofer) { instance_double(LexisNexis::InstantVerify::Proofer) }
let(:aamva_proofer) { instance_double(Aamva::Proofer) }
let(:dob_year_only) { false }

subject(:function) do
IdentityIdpFunctions::ProofResolution.new(
callback_url: callback_url,
applicant_pii: applicant_pii,
should_proof_state_id: should_proof_state_id,
trace_id: trace_id,
dob_year_only: dob_year_only,
)
end

Expand Down Expand Up @@ -204,6 +206,47 @@
end
end

context 'checking DOB year only' do
let(:dob_year_only) { true }

it 'only sends the birth year to LexisNexis (extra applicant attribute)' do
expect(aamva_proofer).to receive(:proof).and_return(Proofer::Result.new)
expect(lexisnexis_proofer).to receive(:proof).
with(hash_including(dob_year_only: true)).
Copy link
Contributor

Choose a reason for hiding this comment

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

dob_year_only: dob_year_only

and_return(Proofer::Result.new)

function.proof
end

it 'does not check LexisNexis when AAMVA proofing does not match' do
expect(aamva_proofer).to receive(:proof).and_return(Proofer::Result.new(exception: 'error'))
expect(lexisnexis_proofer).to_not receive(:proof)

function.proof
end

it 'logs the correct context' do
transaction_id = SecureRandom.uuid

expect(aamva_proofer).to receive(:proof).and_return(Proofer::Result.new)
expect(lexisnexis_proofer).to receive(:proof).
and_return(Proofer::Result.new(transaction_id: transaction_id))

function.proof

expect(WebMock).to(have_requested(:post, callback_url).with do |request|
body = JSON.parse(request.body, symbolize_names: true)

expect(body.dig(:resolution_result, :context, :stages)).to eq [
{ state_id: 'aamva:state_id' },
{ resolution: 'lexisnexis:instant_verify' },
]

expect(body.dig(:resolution_result, :transaction_id)).to eq(transaction_id)
end)
end
end

context 'when IDP auth token is blank' do
it_behaves_like 'misconfigured proofer'
end
Expand Down
23 changes: 19 additions & 4 deletions source/proof_resolution_mock/lib/proof_resolution_mock.rb
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,31 @@ def self.handle(event:, context:, &callback_block) # rubocop:disable Lint/Unused
new(**params).proof(&callback_block)
end

attr_reader :applicant_pii, :callback_url, :should_proof_state_id, :trace_id, :timer

def initialize(applicant_pii:, callback_url:, should_proof_state_id:, trace_id: nil)
attr_reader :applicant_pii, :callback_url, :trace_id, :timer

def initialize(
applicant_pii:,
callback_url:,
should_proof_state_id:,
dob_year_only: false,
trace_id: nil
)
@applicant_pii = applicant_pii
@callback_url = callback_url
@should_proof_state_id = should_proof_state_id
@dob_year_only = dob_year_only
@trace_id = trace_id
@timer = IdentityIdpFunctions::Timer.new
end

def should_proof_state_id?
@should_proof_state_id
end

def dob_year_only?
@dob_year_only
end

def proof
raise Errors::MisconfiguredLambdaError if !block_given? && api_auth_token.to_s.empty?

Expand All @@ -46,7 +61,7 @@ def proof
result[:exception] = proofer_result.exception.inspect if proofer_result.exception

state_id_success = nil
if should_proof_state_id && result[:success]
if should_proof_state_id? && result[:success]
timer.time('state_id') do
proof_state_id(result)
end
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,14 @@

describe '#proof' do
let(:should_proof_state_id) { true }
let(:dob_year_only) { false }

subject(:function) do
IdentityIdpFunctions::ProofResolutionMock.new(
callback_url: callback_url,
applicant_pii: applicant_pii,
should_proof_state_id: should_proof_state_id,
dob_year_only: dob_year_only,
trace_id: trace_id,
)
end
Expand Down