Skip to content

Commit

Permalink
Use faraday to handle basic auth (#396)
Browse files Browse the repository at this point in the history
Use faraday to handle basic auth
  • Loading branch information
mjgiarlo committed Sep 11, 2019
2 parents 5d12515 + 4a94d67 commit b08ac11
Show file tree
Hide file tree
Showing 5 changed files with 64 additions and 36 deletions.
40 changes: 23 additions & 17 deletions app/controllers/sdr_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,39 +13,45 @@ def cm_inv_diff
query_params = { subset: params[:subset].to_s }
query_params[:version] = params[:version].to_s unless params[:version].nil?
query_string = URI.encode_www_form(query_params)
url = "#{Settings.sdr_url}/objects/#{params[:druid]}/cm-inv-diff?#{query_string}"
sdr_response = Faraday.post(url, current_content, 'Content-Type' => 'application/xml')
path = "/objects/#{params[:druid]}/cm-inv-diff"
uri = sdr_uri(path)
sdr_response = sdr_conn(uri).post("#{uri.path}?#{query_string}", current_content, 'Content-Type' => 'application/xml')

proxy_faraday_response(sdr_response)
end

def ds_manifest
url = "#{Settings.sdr_url}/objects/#{params[:druid]}/manifest/#{params[:dsname]}"
sdr_response = Faraday.get url

proxy_faraday_response(sdr_response)
proxy_faraday_response(sdr_get("/objects/#{params[:druid]}/manifest/#{params[:dsname]}"))
end

def ds_metadata
url = "#{Settings.sdr_url}/objects/#{params[:druid]}/metadata/#{params[:dsname]}"
sdr_response = Faraday.get url

proxy_faraday_response(sdr_response)
proxy_faraday_response(sdr_get("/objects/#{params[:druid]}/metadata/#{params[:dsname]}"))
end

def current_version
url = "#{Settings.sdr_url}/objects/#{params[:druid]}/current_version"
sdr_response = Faraday.get url

proxy_faraday_response(sdr_response)
proxy_faraday_response(sdr_get("/objects/#{params[:druid]}/current_version"))
end

def file_content
query_string = URI.encode_www_form(version: params[:version].to_s)
encoded_filename = URI.encode(params[:filename])
url = "#{Settings.sdr_url}/objects/#{params[:druid]}/content/#{encoded_filename}?#{query_string}"
sdr_response = Faraday.get url
proxy_faraday_response(sdr_get("/objects/#{params[:druid]}/content/#{encoded_filename}?#{query_string}"))
end

proxy_faraday_response(sdr_response)
private

def sdr_uri(path)
URI("#{Settings.sdr_url}#{path}")
end

def sdr_conn(uri)
Faraday.new("#{uri.scheme}://#{uri.host}").tap do |conn|
conn.basic_auth(uri.user, uri.password)
end
end

def sdr_get(path)
uri = sdr_uri(path)
sdr_conn(uri).get("#{uri.path}?#{uri.query}")
end
end
8 changes: 5 additions & 3 deletions app/services/sdr_client.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,10 @@ class SdrClient
# @raises [Dor::Exception] if SDR doesn't know about the object (i.e. 404 response code)
# @raises [StandardError] if the response from SDR can't be parsed
def self.current_version(druid)
url = "#{Settings.sdr_url}/objects/#{druid}/current_version"
response = Faraday.get "#{Settings.sdr_url}/objects/#{druid}/current_version"
uri = URI("#{Settings.sdr_url}/objects/#{druid}/current_version")
conn = Faraday.new "#{uri.scheme}://#{uri.host}"
conn.basic_auth(uri.user, uri.password)
response = conn.get uri.path

if response.status == 404
raise Dor::Exception, 'SDR is not yet answering queries about this object. ' \
Expand All @@ -19,7 +21,7 @@ def self.current_version(druid)

return Integer(doc.text)
rescue StandardError
raise "Unable to parse XML from SDR current_version API call.\n\turl: #{url}\n\tstatus: #{response.status}\n\tbody: #{response.body}"
raise "Unable to parse XML from SDR current_version API call.\n\turl: #{uri}\n\tstatus: #{response.status}\n\tbody: #{response.body}"
end
end
end
2 changes: 1 addition & 1 deletion config/settings.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ solr:
url: 'https://solr.example.com/solr/collection'

workflow_url: 'https://workflow.example.com/workflow'
sdr_url: 'http://sdr-services.example.com/sdr'
sdr_url: 'http://user:password@sdr-services.example.com/sdr'
purl_services_url: ~

cleanup:
Expand Down
44 changes: 31 additions & 13 deletions spec/controllers/sdr_controller_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,9 @@
let(:mock_response) { '<currentVersion>1</currentVersion>' }

it 'retrieves the current version from SDR' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/current_version").to_return(body: mock_response, headers: { 'Content-Type' => 'application/xml' })
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/current_version")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: mock_response, headers: { 'Content-Type' => 'application/xml' })

get :current_version, params: { druid: item.pid }

Expand All @@ -27,7 +29,9 @@
end

it 'passes through error codes' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/current_version").to_return(status: 404, body: '')
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/current_version")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(status: 404, body: '')

get :current_version, params: { druid: item.pid }

Expand All @@ -42,8 +46,13 @@
let(:mock_response_txt) { 'some file content' }

it 'passes through errors' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/content/no_such_file?version=2").to_return(status: 404)
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/content/unexpected_error?version=2").to_return(status: 500)
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/content/no_such_file?version=2")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(status: 404)

stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/content/unexpected_error?version=2")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(status: 500)

get :file_content, params: { druid: item.pid, filename: 'no_such_file', version: 2 }
expect(response.status).to eq 404
Expand All @@ -57,7 +66,8 @@
let(:uri_encoded_filename) { URI.encode(filename_with_spaces) }

it 'handles file names with characters that need URI encoding' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/content/#{uri_encoded_filename}?version=#{item_version}")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/content/#{uri_encoded_filename}?version=#{item_version}")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: mock_response_txt, headers: { 'Content-Type' => content_type_txt })

get :file_content, params: { druid: item.pid, filename: filename_with_spaces, version: item_version }
Expand All @@ -70,7 +80,8 @@

context 'text file type' do
it 'retrieves the content for a version of a text file from SDR' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/content/#{content_file_name_txt}?version=#{item_version}")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/content/#{content_file_name_txt}?version=#{item_version}")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: mock_response_txt, headers: { 'Content-Type' => content_type_txt })

get :file_content, params: { druid: item.pid, filename: content_file_name_txt, version: item_version }
Expand All @@ -89,7 +100,8 @@
let(:mock_response_jpg) { URI.encode_www_form_component(File.binread(img_fixture_filename)) }

it 'retrieves the content for a version of a text file from SDR' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/content/#{content_file_name_jpg}?version=#{item_version}")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/content/#{content_file_name_jpg}?version=#{item_version}")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: mock_response_jpg, headers: { 'Content-Type' => content_type_jpg })

get :file_content, params: { druid: item.pid, filename: content_file_name_jpg, version: item_version }
Expand All @@ -113,7 +125,8 @@

context 'with an explicit version' do
it 'passes the version to SDR' do
stub_request(:post, "#{Settings.sdr_url}/objects/#{item.pid}/cm-inv-diff?subset=all&version=5")
stub_request(:post, "http://sdr-services.example.com/sdr/objects/#{item.pid}/cm-inv-diff?subset=all&version=5")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: mock_response, headers: { 'Content-Type' => 'application/xml' })

post :cm_inv_diff, params: { druid: item.pid, subset: 'all', version: 5 }
Expand All @@ -124,7 +137,8 @@
end

it 'retrieves the diff from SDR' do
stub_request(:post, "#{Settings.sdr_url}/objects/#{item.pid}/cm-inv-diff?subset=all")
stub_request(:post, "http://sdr-services.example.com/sdr/objects/#{item.pid}/cm-inv-diff?subset=all")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: mock_response, headers: { 'Content-Type' => 'application/xml' })

post :cm_inv_diff, params: { druid: item.pid, subset: 'all' }
Expand All @@ -136,7 +150,8 @@

describe 'signatureCatalog' do
it 'retrieves the catalog from SDR' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/manifest/signatureCatalog.xml")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/manifest/signatureCatalog.xml")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: '<catalog />', headers: { 'Content-Type' => 'application/xml' })

get :ds_manifest, params: { druid: item.pid, dsname: 'signatureCatalog.xml' }
Expand All @@ -147,7 +162,8 @@
end

it 'passes through errors' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/manifest/signatureCatalog.xml")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/manifest/signatureCatalog.xml")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(status: 428)

get :ds_manifest, params: { druid: item.pid, dsname: 'signatureCatalog.xml' }
Expand All @@ -158,7 +174,8 @@

describe 'metadata services' do
it 'retrieves the datastream from SDR' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/metadata/whatever")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/metadata/whatever")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: 'content', headers: { 'Content-Type' => 'application/xml' })

get :ds_metadata, params: { druid: item.pid, dsname: 'whatever' }
Expand All @@ -169,7 +186,8 @@
end

it 'passes through errors' do
stub_request(:get, "#{Settings.sdr_url}/objects/#{item.pid}/metadata/whatever")
stub_request(:get, "http://sdr-services.example.com/sdr/objects/#{item.pid}/metadata/whatever")
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(status: 428)

get :ds_metadata, params: { druid: item.pid, dsname: 'whatever' }
Expand Down
6 changes: 4 additions & 2 deletions spec/services/sdr_client_spec.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
subject(:current_version) { described_class.current_version('druid:ab123cd4567') }

let(:url) { 'http://sdr-services.example.com/sdr/objects/druid:ab123cd4567/current_version' }
let(:url_with_basic_auth) { url.sub('http://', 'http://user:password@') }

it 'returns the current of the object from SDR' do
stub_request(:get, url)
.with(headers: { 'Authorization' => 'Basic dXNlcjpwYXNzd29yZA==' })
.to_return(body: '<currentVersion>2</currentVersion>')
expect(current_version).to eq 2
end
Expand All @@ -19,7 +21,7 @@
stub_request(:get, url)
.to_return(body: '<wrongRoot>2</wrongRoot>')
expect { current_version }.to raise_error(RuntimeError,
"Unable to parse XML from SDR current_version API call.\n\turl: #{url}\n\tstatus: 200\n\tbody: <wrongRoot>2</wrongRoot>")
"Unable to parse XML from SDR current_version API call.\n\turl: #{url_with_basic_auth}\n\tstatus: 200\n\tbody: <wrongRoot>2</wrongRoot>")
end
end

Expand All @@ -28,7 +30,7 @@
stub_request(:get, url)
.to_return(body: '<currentVersion>two</currentVersion>')
expect { current_version }.to raise_error(RuntimeError,
"Unable to parse XML from SDR current_version API call.\n\turl: #{url}\n\tstatus: 200\n\tbody: <currentVersion>two</currentVersion>")
"Unable to parse XML from SDR current_version API call.\n\turl: #{url_with_basic_auth}\n\tstatus: 200\n\tbody: <currentVersion>two</currentVersion>")
end
end

Expand Down

0 comments on commit b08ac11

Please sign in to comment.