Skip to content

Commit 7e38478

Browse files
author
Andrew
committed
Add support for puppetdb behind basic auth
We have a moderately unique puppet setup (though remarkably close to github's setup, in some ways). We run puppetdb behind a proxy that is secured with basic auth (and we will eventually be submitting patches upstream to puppet). This commit allows octocatalog-diff to parse basic auth username, and password from a URL.
1 parent 4330554 commit 7e38478

File tree

2 files changed

+75
-1
lines changed

2 files changed

+75
-1
lines changed

lib/octocatalog-diff/puppetdb.rb

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,6 +108,9 @@ def _get(path)
108108

109109
begin
110110
more_options = { headers: { 'Accept' => 'application/json' }, timeout: @timeout }
111+
if connection[:username] || connection[:password]
112+
more_options[:basic_auth] = { username: connection[:username], password: connection[:password] }
113+
end
111114
response = OctocatalogDiff::Util::HTTParty.get(complete_url, @options.merge(more_options), 'puppetdb')
112115

113116
# Handle all non-200's from PuppetDB
@@ -153,7 +156,13 @@ def parse_url(url)
153156
end
154157

155158
raise ArgumentError, "URL #{url} has invalid scheme" unless uri.scheme =~ /^https?$/
156-
{ ssl: uri.scheme == 'https', host: uri.host, port: uri.port }
159+
parsed_url = { ssl: uri.scheme == 'https', host: uri.host, port: uri.port }
160+
if uri.user || uri.password
161+
parsed_url[:username] = uri.user
162+
parsed_url[:password] = uri.password
163+
end
164+
165+
parsed_url
157166
rescue URI::InvalidURIError => exc
158167
raise exc.class, "Invalid URL: #{url} (#{exc.message})"
159168
end

spec/octocatalog-diff/tests/puppetdb_spec.rb

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,24 @@ def ssl_test(server_opts, opts = {})
2525
test_server.stop
2626
end
2727

28+
def basic_auth_test(server_opts, opts = {})
29+
server_opts[:rsa_key] ||= File.read(OctocatalogDiff::Spec.fixture_path('ssl/generated/server.key'))
30+
server_opts[:cert] ||= File.read(OctocatalogDiff::Spec.fixture_path('ssl/generated/server.crt'))
31+
server_opts[:require_header] ||= {}
32+
server_opts[:require_header]['Authorization'] = 'Basic dXNlcm5hbWU6cGFzc3dvcmQ=' # username:password
33+
test_server = nil
34+
3.times do
35+
test_server = SSLTestServer.new(server_opts)
36+
test_server.start
37+
break if test_server.port > 0
38+
end
39+
raise OctocatalogDiff::Spec::FixtureError, 'Unable to instantiate SSLTestServer' unless test_server.port > 0
40+
testobj = OctocatalogDiff::PuppetDB.new(opts.merge(puppetdb_url: "https://username:password@localhost:#{test_server.port}"))
41+
return testobj.get('/foo')
42+
ensure
43+
test_server.stop
44+
end
45+
2846
describe OctocatalogDiff::PuppetDB do
2947
# Test constructor's ability to create @connections
3048
describe '#initialize' do
@@ -272,6 +290,53 @@ def ssl_test(server_opts, opts = {})
272290
expect { testobj.send(:parse_url, test_url) }.to raise_error(URI::InvalidURIError)
273291
end
274292
end
293+
294+
context 'basic auth' do
295+
it 'should detect a username:password combination' do
296+
test_url = 'https://username:[email protected]:8090'
297+
testobj = OctocatalogDiff::PuppetDB.new
298+
result = testobj.send(:parse_url, test_url)
299+
expect(result[:username]).to eq('username')
300+
expect(result[:password]).to eq('password')
301+
end
302+
303+
it 'should allow usernames without passwords' do
304+
test_url = 'https://username:@foo.bar.host:8090'
305+
testobj = OctocatalogDiff::PuppetDB.new
306+
result = testobj.send(:parse_url, test_url)
307+
expect(result[:username]).to eq('username')
308+
expect(result[:password]).to eq('')
309+
end
310+
311+
it 'should allow passwords without usernames' do
312+
test_url = 'https://:[email protected]:8090'
313+
testobj = OctocatalogDiff::PuppetDB.new
314+
result = testobj.send(:parse_url, test_url)
315+
expect(result[:username]).to eq('')
316+
expect(result[:password]).to eq('password')
317+
end
318+
319+
it 'should not parse a username or password when none are provided' do
320+
test_url = 'https://foo.bar.host:8090'
321+
testobj = OctocatalogDiff::PuppetDB.new
322+
result = testobj.send(:parse_url, test_url)
323+
expect(result[:username]).to eq(nil)
324+
expect(result[:password]).to eq(nil)
325+
end
326+
end
327+
end
328+
329+
context 'basic auth connection options' do
330+
context 'with basic auth on' do
331+
let(:server_opts) { {} }
332+
let(:client_opts) { {} }
333+
describe '#get' do
334+
it 'should not fail with basic auth on' do
335+
result = basic_auth_test(server_opts, client_opts)
336+
expect(result.key?('success')).to eq(true)
337+
end
338+
end
339+
end
275340
end
276341

277342
context 'puppetdb ssl connection options' do

0 commit comments

Comments
 (0)