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 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.4'
VERSION = '0.7.5'
end
4 changes: 4 additions & 0 deletions source/aws-ruby-sdk/s3_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

module IdentityIdpFunctions
class S3Helper
def s3_url?(url)
URI.parse(url).host.split('.').include?('s3')
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Not sure how concerned we are for accuracy of this check, but alternatively:

Suggested change
URI.parse(url).host.split('.').include?('s3')
URI.parse(url).host =~ /\.?s3\.amazonaws\.com$/

Could maybe do for a test case or two as well?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

My thinking was, if any subdomain was exactly equal to s3 then it was probably an actual S3 URL, or at least a fake that was trying hard enough to be an S3 URL that it would count?

For simplicity's sake I'd like to leave this as-is for now, but happy to re-evaluate if we run into issues with it.

I've added a few test cases, including how this can be "fooled" in 57e971b

end

def download(url)
uri = URI.parse(url)
if uri.host.start_with?('s3.')
Expand Down
9 changes: 5 additions & 4 deletions source/proof_document/lib/proof_document.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'bundler/setup' if !defined?(Bundler)
require 'base64'
require 'faraday'
require 'identity-doc-auth'
require 'json'
Expand Down Expand Up @@ -31,10 +32,10 @@ def initialize(encryption_key:,
liveness_checking_enabled:,
callback_url:,
trace_id: nil)
@encryption_key = encryption_key
@front_image_iv = front_image_iv
@back_image_iv = back_image_iv
@selfie_image_iv = selfie_image_iv
@encryption_key = Base64.decode64(encryption_key.to_s)
@front_image_iv = Base64.decode64(front_image_iv.to_s)
@back_image_iv = Base64.decode64(back_image_iv.to_s)
@selfie_image_iv = Base64.decode64(selfie_image_iv.to_s)
@front_image_url = front_image_url
@back_image_url = back_image_url
@selfie_image_url = selfie_image_url
Expand Down
14 changes: 7 additions & 7 deletions source/proof_document/spec/proof_document_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -8,10 +8,10 @@
let(:trace_id) { SecureRandom.uuid }
let(:event) do
{
encryption_key: encryption_key,
front_image_iv: front_image_iv,
back_image_iv: back_image_iv,
selfie_image_iv: selfie_image_iv,
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,
Expand All @@ -25,9 +25,9 @@
let(:front_image_iv) { '123456789012' }
let(:back_image_iv) { '123456789012' }
let(:selfie_image_iv) { '123456789012' }
let(:front_image_url) { 'http://foo.com/bar1' }
let(:back_image_url) { 'http://foo.com/bar2' }
let(:selfie_image_url) { 'http://foo.com/bar3' }
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(:applicant_pii) do
{
Expand Down
17 changes: 12 additions & 5 deletions source/proof_document_mock/lib/proof_document_mock.rb
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
require 'bundler/setup' if !defined?(Bundler)
require 'base64'
require 'faraday'
require 'identity-doc-auth'
require 'json'
Expand Down Expand Up @@ -32,10 +33,10 @@ def initialize(encryption_key:,
callback_url:,
trace_id: nil)
@callback_url = callback_url
@encryption_key = encryption_key
@front_image_iv = front_image_iv
@back_image_iv = back_image_iv
@selfie_image_iv = selfie_image_iv
@encryption_key = Base64.decode64(encryption_key.to_s)
@front_image_iv = Base64.decode64(front_image_iv.to_s)
@back_image_iv = Base64.decode64(back_image_iv.to_s)
@selfie_image_iv = Base64.decode64(selfie_image_iv.to_s)
@front_image_url = front_image_url
@back_image_url = back_image_url
@selfie_image_url = selfie_image_url
Expand Down Expand Up @@ -122,7 +123,13 @@ def doc_auth_client
end

def decrypt_from_s3(name, url, iv)
encrypted_image = timer.time("download.#{name}") { s3_helper.download(url) }
encrypted_image = timer.time("download.#{name}") do
if s3_helper.s3_url?(url)
s3_helper.download(url)
else
build_faraday.get(url).body.b
end
end
timer.time("decrypt.#{name}") do
encryption_helper.decrypt(data: encrypted_image, iv: iv, key: encryption_key)
end
Expand Down
56 changes: 42 additions & 14 deletions source/proof_document_mock/spec/proof_document_mock_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,10 @@

let(:event) do
{
encryption_key: encryption_key,
front_image_iv: front_image_iv,
back_image_iv: back_image_iv,
selfie_image_iv: selfie_image_iv,
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,
Expand All @@ -33,12 +33,12 @@
end

let(:encryption_key) { '12345678901234567890123456789012' }
let(:front_image_iv) { '111111111111' }
let(:back_image_iv) { '222222222222' }
let(:selfie_image_iv) { '333333333333' }
let(:front_image_url) { 'http://foo.com/bar1' }
let(:back_image_url) { 'http://foo.com/bar2' }
let(:selfie_image_url) { 'http://foo.com/bar3' }
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(: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' }

before do
body = applicant_pii.to_json
Expand Down Expand Up @@ -100,10 +100,10 @@
subject(:function) do
IdentityIdpFunctions::ProofDocumentMock.new(
callback_url: callback_url,
encryption_key: encryption_key,
front_image_iv: front_image_iv,
back_image_iv: back_image_iv,
selfie_image_iv: selfie_image_iv,
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,
Expand Down Expand Up @@ -188,5 +188,33 @@
expect(WebMock).to have_requested(:post, callback_url)
end
end

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
stub_request(:get, front_image_url).to_return(
body: encrypt(data: applicant_pii.to_json, key: encryption_key, iv: front_image_iv),
)
stub_request(:get, back_image_url).to_return(
body: encrypt(data: applicant_pii.to_json, key: encryption_key, iv: back_image_iv),
)
stub_request(:get, selfie_image_url).to_return(
body: encrypt(data: applicant_pii.to_json, key: encryption_key, iv: selfie_image_iv),
)
end

it 'still downloads and decrypts the content' do
function.proof

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

expect(a_request(:post, callback_url)).to have_been_made
end
end
end
end
26 changes: 26 additions & 0 deletions spec/lib/s3_helper_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,32 @@
RSpec.describe IdentityIdpFunctions::S3Helper do
subject(:s3_helper) { IdentityIdpFunctions::S3Helper.new }

describe '#s3_url?' do
subject(:s3_url?) { s3_helper.s3_url?(url) }

context 'with a subdomain bucket format url' do
let(:url) { 'https://s3.region-name.amazonaws.com/bucket/key' }
it { is_expected.to eq(true) }
end

context 'with a path bucket format url' do
let(:url) { 'https://bucket.s3.region-name.amazonaws.com/key' }
it { is_expected.to eq(true) }
end

context 'with a non-s3 url' do
let(:url) { 'https://example.com' }
it { is_expected.to eq(false) }
end

context 'with a non-s3 url that has an s3 subdomain' do
let(:url) { 'https://s3.example.com' }
it 'gets fooled and returns true' do
expect(s3_url?).to eq(true)
end
end
end

describe '#download' do
let(:bucket_name) { 'bucket123456' }
let(:prefix) { SecureRandom.uuid }
Expand Down