daemon: move authorization check to daemon making it testable

This commit is contained in:
cn 2018-02-05 15:29:12 +01:00
parent 26bf1ee3fd
commit 599fa2b718
2 changed files with 21 additions and 13 deletions

View File

@ -45,6 +45,15 @@ module Dyndnsd
(@db.save; @updater.update(@db)) if @db.changed? (@db.save; @updater.update(@db)) if @db.changed?
end end
def is_authorized?(username, password)
allow = ((@users.has_key? username) and (@users[username]['password'] == password))
if not allow
Dyndnsd.logger.warn "Login failed for #{username}"
Metriks.meter('requests.auth_failed').mark
end
allow
end
def call(env) def call(env)
return [422, {'X-DynDNS-Response' => 'method_forbidden'}, []] if env["REQUEST_METHOD"] != "GET" return [422, {'X-DynDNS-Response' => 'method_forbidden'}, []] if env["REQUEST_METHOD"] != "GET"
return [422, {'X-DynDNS-Response' => 'not_found'}, []] if env["PATH_INFO"] != "/nic/update" return [422, {'X-DynDNS-Response' => 'not_found'}, []] if env["PATH_INFO"] != "/nic/update"
@ -219,17 +228,10 @@ module Dyndnsd
# configure daemon # configure daemon
db = Database.new(config['db']) db = Database.new(config['db'])
updater = Updater::CommandWithBindZone.new(config['domain'], config['updater']['params']) if config['updater']['name'] == 'command_with_bind_zone' updater = Updater::CommandWithBindZone.new(config['domain'], config['updater']['params']) if config['updater']['name'] == 'command_with_bind_zone'
daemon = Daemon.new(config, db, updater)
# configure rack # configure rack
app = Daemon.new(config, db, updater) app = Rack::Auth::Basic.new(daemon, "DynDNS", &daemon.method(:is_authorized?))
app = Rack::Auth::Basic.new(app, "DynDNS") do |user,pass|
allow = ((config['users'].has_key? user) and (config['users'][user]['password'] == pass))
if not allow
Dyndnsd.logger.warn "Login failed for #{user}"
Metriks.meter('requests.auth_failed').mark
end
allow
end
if config['responder'] == 'RestStyle' if config['responder'] == 'RestStyle'
app = Responder::RestStyle.new(app) app = Responder::RestStyle.new(app)

View File

@ -18,11 +18,9 @@ describe Dyndnsd::Daemon do
} }
db = Dyndnsd::DummyDatabase.new({}) db = Dyndnsd::DummyDatabase.new({})
updater = Dyndnsd::Updater::Dummy.new updater = Dyndnsd::Updater::Dummy.new
app = Dyndnsd::Daemon.new(config, db, updater) daemon = Dyndnsd::Daemon.new(config, db, updater)
app = Rack::Auth::Basic.new(app, "DynDNS") do |user,pass| app = Rack::Auth::Basic.new(daemon, "DynDNS", &daemon.method(:is_authorized?))
(config['users'].has_key? user) and (config['users'][user]['password'] == pass)
end
app = Dyndnsd::Responder::DynDNSStyle.new(app) app = Dyndnsd::Responder::DynDNSStyle.new(app)
end end
@ -33,6 +31,13 @@ describe Dyndnsd::Daemon do
expect(last_response.body).to eq('badauth') expect(last_response.body).to eq('badauth')
end end
it 'requires configured correct credentials' do
authorize 'test', 'wrongsecret'
get '/'
expect(last_response.status).to eq(401)
expect(last_response.body).to eq('badauth')
end
it 'only supports GET requests' do it 'only supports GET requests' do
authorize 'test', 'secret' authorize 'test', 'secret'
post '/nic/update' post '/nic/update'
@ -94,6 +99,7 @@ describe Dyndnsd::Daemon do
it 'rejects request if user does not own one hostname' do it 'rejects request if user does not own one hostname' do
authorize 'test', 'secret' authorize 'test', 'secret'
get '/nic/update?hostname=notmyhost.example.org' get '/nic/update?hostname=notmyhost.example.org'
expect(last_response).to be_ok expect(last_response).to be_ok
expect(last_response.body).to eq('nohost') expect(last_response.body).to eq('nohost')