improvements to login/logout for API

This commit is contained in:
Oliver Gorwits
2019-01-01 10:56:09 +00:00
parent 3b0a9f6310
commit f362b0aee3
2 changed files with 33 additions and 7 deletions

View File

@@ -77,8 +77,12 @@ my $swagger = Dancer::Plugin::Swagger->instance->doc;
$swagger->{schemes} = ['http','https'];
$swagger->{consumes} = 'application/json';
$swagger->{produces} = 'application/json';
$swagger->{securityDefinitions} = { APIKeyHeader =>
{ type => 'apiKey', name => 'Authorization', in => 'header' } };
$swagger->{securityDefinitions} = {
APIKeyHeader =>
{ type => 'apiKey', name => 'Authorization', in => 'header' },
BasicAuth =>
{ type => 'basic' },
};
$swagger->{security} = [ { APIKeyHeader => [] } ];
# workaround for https://github.com/PerlDancer/Dancer/issues/935

View File

@@ -3,6 +3,7 @@ package App::Netdisco::Web::AuthN;
use Dancer ':syntax';
use Dancer::Plugin::DBIC;
use Dancer::Plugin::Auth::Extensible;
use Dancer::Plugin::Swagger;
use MIME::Base64;
@@ -13,7 +14,11 @@ hook 'before' => sub {
# from the internals of Dancer::Plugin::Auth::Extensible
my $provider = Dancer::Plugin::Auth::Extensible::auth_provider('users');
if (! session('logged_in_user') && request->path ne uri_for('/login')->path) {
if (! session('logged_in_user')
and request->path ne uri_for('/login')->path
and request->path ne uri_for('/swagger.json')->path
and index(request->path, uri_for('/swagger-ui')->path) != 0) {
if (setting('trust_x_remote_user')
and scalar request->header('X-REMOTE_USER')
and length scalar request->header('X-REMOTE_USER')) {
@@ -61,7 +66,7 @@ hook 'before' => sub {
get qr{^/(?:login(?:/denied)?)?} => sub {
# FIXME not sure this is the right approach
if (param('return_url') and param('return_url') =~ m{^/api/}) {
status('unauthorized')
status('unauthorized');
return to_json {
error => 'not authorized',
return_url => param('return_url'),
@@ -73,6 +78,15 @@ get qr{^/(?:login(?:/denied)?)?} => sub {
};
# override default login_handler so we can log access in the database
swagger_path {
description => 'Obtain an API Key using HTTP BasicAuth',
parameters => [],
responses => {
default => {
examples => {
'application/json' => { api_key => 'cc9d5c02d8898e5728b7d7a0339c0785' } } },
},
},
post '/login' => sub {
my $mode = (request->is_ajax ? 'WebData'
: request->header('Authorization') ? 'API'
@@ -112,7 +126,7 @@ post '/login' => sub {
token_from => time,
token => \'md5(random()::text)',
})->discard_changes();
return 'api_key:'. $user->token;
return to_json { api_key => $user->token };
}
redirect param('return_url');
@@ -127,9 +141,13 @@ post '/login' => sub {
details => param('return_url'),
});
if ($mode ne 'WebUI') {
if ($mode eq 'WebData') {
status('unauthorized');
}
elsif ($mode ne 'API') {
status('unauthorized');
return to_json { error => 'authentication failed' };
}
else {
vars->{login_failed}++;
forward uri_for('/login'),
@@ -139,6 +157,10 @@ post '/login' => sub {
}
};
# ugh, *puke*, but D::P::Swagger has no way to set this with swagger_path
Dancer::Plugin::Swagger->instance->doc->{paths}->{'/login'}
->{post}->{security}->[0]->{BasicAuth} = [];
# we override the default login_handler, so logout has to be handled as well
any ['get', 'post'] => '/logout' => sub {
schema('netdisco')->resultset('UserLog')->create({