Commit f7905e64 authored by Stan Hu's avatar Stan Hu

Merge branch 'dblessing-external-auth-gitlab-http' into 'master'

External Authorization Client adheres to local request setting

See merge request gitlab-org/gitlab!37622
parents 462eaa31 626e03f5
---
title: External auth adheres to local request setting
merge_request: 37622
author:
type: changed
...@@ -17,23 +17,28 @@ module Gitlab ...@@ -17,23 +17,28 @@ module Gitlab
end end
def request_access def request_access
response = Excon.post( response = Gitlab::HTTP.post(
service_url, service_url,
post_params post_params
) )
::Gitlab::ExternalAuthorization::Response.new(response) ::Gitlab::ExternalAuthorization::Response.new(response)
rescue Excon::Error => e rescue *Gitlab::HTTP::HTTP_ERRORS => e
raise ::Gitlab::ExternalAuthorization::RequestFailed.new(e) raise ::Gitlab::ExternalAuthorization::RequestFailed.new(e)
end end
private private
def allow_local_requests?
Gitlab::CurrentSettings.allow_local_requests_from_system_hooks?
end
def post_params def post_params
params = { headers: REQUEST_HEADERS, params = { headers: REQUEST_HEADERS,
body: body.to_json, body: body.to_json,
connect_timeout: timeout, connect_timeout: timeout,
read_timeout: timeout, read_timeout: timeout,
write_timeout: timeout } write_timeout: timeout,
allow_local_requests: allow_local_requests? }
if has_tls? if has_tls?
params[:client_cert_data] = client_cert params[:client_cert_data] = client_cert
......
...@@ -5,16 +5,16 @@ module Gitlab ...@@ -5,16 +5,16 @@ module Gitlab
class Response class Response
include ::Gitlab::Utils::StrongMemoize include ::Gitlab::Utils::StrongMemoize
def initialize(excon_response) def initialize(response)
@excon_response = excon_response @response = response
end end
def valid? def valid?
@excon_response && [200, 401, 403].include?(@excon_response.status) @response && [200, 401, 403].include?(@response.code)
end end
def successful? def successful?
valid? && @excon_response.status == 200 valid? && @response.code == 200
end end
def reason def reason
...@@ -28,7 +28,7 @@ module Gitlab ...@@ -28,7 +28,7 @@ module Gitlab
end end
def parse_response! def parse_response!
Gitlab::Json.parse(@excon_response.body) Gitlab::Json.parse(@response.body)
rescue JSON::JSONError rescue JSON::JSONError
# The JSON response is optional, so don't fail when it's missing # The JSON response is optional, so don't fail when it's missing
nil nil
......
...@@ -14,7 +14,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do ...@@ -14,7 +14,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
describe '#request_access' do describe '#request_access' do
it 'performs requests to the configured endpoint' do it 'performs requests to the configured endpoint' do
expect(Excon).to receive(:post).with(dummy_url, any_args) expect(Gitlab::HTTP).to receive(:post).with(dummy_url, any_args)
client.request_access client.request_access
end end
...@@ -25,7 +25,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do ...@@ -25,7 +25,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
project_classification_label: 'dummy_label', project_classification_label: 'dummy_label',
identities: [] identities: []
}.to_json }.to_json
expect(Excon).to receive(:post) expect(Gitlab::HTTP).to receive(:post)
.with(dummy_url, hash_including(body: expected_body)) .with(dummy_url, hash_including(body: expected_body))
client.request_access client.request_access
...@@ -36,7 +36,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do ...@@ -36,7 +36,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
external_authorization_service_timeout: 3 external_authorization_service_timeout: 3
) )
expect(Excon).to receive(:post).with(dummy_url, expect(Gitlab::HTTP).to receive(:post).with(dummy_url,
hash_including( hash_including(
connect_timeout: 3, connect_timeout: 3,
read_timeout: 3, read_timeout: 3,
...@@ -58,25 +58,33 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do ...@@ -58,25 +58,33 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
client_key_pass: 'open sesame' client_key_pass: 'open sesame'
} }
expect(Excon).to receive(:post).with(dummy_url, hash_including(expected_params)) expect(Gitlab::HTTP).to receive(:post).with(dummy_url, hash_including(expected_params))
client.request_access client.request_access
end end
it 'returns an expected response' do it 'returns an expected response' do
expect(Excon).to receive(:post) expect(Gitlab::HTTP).to receive(:post)
expect(client.request_access) expect(client.request_access)
.to be_kind_of(::Gitlab::ExternalAuthorization::Response) .to be_kind_of(::Gitlab::ExternalAuthorization::Response)
end end
it 'wraps exceptions if the request fails' do it 'wraps exceptions if the request fails' do
expect(Excon).to receive(:post) { raise Excon::Error.new('the request broke') } expect(Gitlab::HTTP).to receive(:post) { raise Gitlab::HTTP::BlockedUrlError.new('the request broke') }
expect { client.request_access } expect { client.request_access }
.to raise_error(::Gitlab::ExternalAuthorization::RequestFailed) .to raise_error(::Gitlab::ExternalAuthorization::RequestFailed)
end end
it 'passes local request setting to Gitlab::HTTP' do
stub_application_setting(allow_local_requests_from_system_hooks: false)
expect(Gitlab::HTTP).to receive(:post).with(dummy_url, hash_including(allow_local_requests: false))
client.request_access
end
describe 'for ldap users' do describe 'for ldap users' do
let(:user) do let(:user) do
create(:omniauth_user, create(:omniauth_user,
...@@ -92,7 +100,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do ...@@ -92,7 +100,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
identities: [{ provider: 'ldapprovider', extern_uid: 'external id' }], identities: [{ provider: 'ldapprovider', extern_uid: 'external id' }],
user_ldap_dn: 'external id' user_ldap_dn: 'external id'
}.to_json }.to_json
expect(Excon).to receive(:post) expect(Gitlab::HTTP).to receive(:post)
.with(dummy_url, hash_including(body: expected_body)) .with(dummy_url, hash_including(body: expected_body))
client.request_access client.request_access
...@@ -115,7 +123,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do ...@@ -115,7 +123,7 @@ RSpec.describe Gitlab::ExternalAuthorization::Client do
{ provider: 'facebook', extern_uid: 'facebook_external_id' } { provider: 'facebook', extern_uid: 'facebook_external_id' }
] ]
}.to_json }.to_json
expect(Excon).to receive(:post) expect(Gitlab::HTTP).to receive(:post)
.with(dummy_url, hash_including(body: expected_body)) .with(dummy_url, hash_including(body: expected_body))
client.request_access client.request_access
......
...@@ -3,21 +3,21 @@ ...@@ -3,21 +3,21 @@
require 'spec_helper' require 'spec_helper'
RSpec.describe Gitlab::ExternalAuthorization::Response do RSpec.describe Gitlab::ExternalAuthorization::Response do
let(:excon_response) { double } let(:http_response) { double }
subject(:response) { described_class.new(excon_response) } subject(:response) { described_class.new(http_response) }
describe '#valid?' do describe '#valid?' do
it 'is valid for 200, 401, and 403 responses' do it 'is valid for 200, 401, and 403 responses' do
[200, 401, 403].each do |status| [200, 401, 403].each do |code|
allow(excon_response).to receive(:status).and_return(status) allow(http_response).to receive(:code).and_return(code)
expect(response).to be_valid expect(response).to be_valid
end end
end end
it "is invalid for other statuses" do it "is invalid for other statuses" do
expect(excon_response).to receive(:status).and_return(500) expect(http_response).to receive(:code).and_return(500)
expect(response).not_to be_valid expect(response).not_to be_valid
end end
...@@ -25,13 +25,13 @@ RSpec.describe Gitlab::ExternalAuthorization::Response do ...@@ -25,13 +25,13 @@ RSpec.describe Gitlab::ExternalAuthorization::Response do
describe '#reason' do describe '#reason' do
it 'returns a reason if it was included in the response body' do it 'returns a reason if it was included in the response body' do
expect(excon_response).to receive(:body).and_return({ reason: 'Not authorized' }.to_json) expect(http_response).to receive(:body).and_return({ reason: 'Not authorized' }.to_json)
expect(response.reason).to eq('Not authorized') expect(response.reason).to eq('Not authorized')
end end
it 'returns nil when there was no body' do it 'returns nil when there was no body' do
expect(excon_response).to receive(:body).and_return('') expect(http_response).to receive(:body).and_return('')
expect(response.reason).to eq(nil) expect(response.reason).to eq(nil)
end end
...@@ -39,14 +39,14 @@ RSpec.describe Gitlab::ExternalAuthorization::Response do ...@@ -39,14 +39,14 @@ RSpec.describe Gitlab::ExternalAuthorization::Response do
describe '#successful?' do describe '#successful?' do
it 'is `true` if the status is 200' do it 'is `true` if the status is 200' do
allow(excon_response).to receive(:status).and_return(200) allow(http_response).to receive(:code).and_return(200)
expect(response).to be_successful expect(response).to be_successful
end end
it 'is `false` if the status is 401 or 403' do it 'is `false` if the status is 401 or 403' do
[401, 403].each do |status| [401, 403].each do |code|
allow(excon_response).to receive(:status).and_return(status) allow(http_response).to receive(:code).and_return(code)
expect(response).not_to be_successful expect(response).not_to be_successful
end end
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment