diff --git a/lib/App/Netdisco/Web.pm b/lib/App/Netdisco/Web.pm index e50d167e..307e7c58 100644 --- a/lib/App/Netdisco/Web.pm +++ b/lib/App/Netdisco/Web.pm @@ -112,29 +112,6 @@ eval { }; Dancer::Session::Cookie::init(session); -# setup for swagger API -my $swagger = Dancer::Plugin::Swagger->instance->doc; -$swagger->{schemes} = ['http','https']; -$swagger->{consumes} = 'application/json'; -$swagger->{produces} = 'application/json'; -$swagger->{tags} = [ - {name => 'General', - description => 'Log in and Log out'}, - {name => 'Search', - description => 'Search Operations'}, - {name => 'Objects', - description => 'Retrieve Device, Port, and associated Node Data'}, - {name => 'Reports', - description => 'Canned and Custom Reports'}, -]; -$swagger->{securityDefinitions} = { - APIKeyHeader => - { type => 'apiKey', name => 'Authorization', in => 'header' }, - BasicAuth => - { type => 'basic' }, -}; -$swagger->{security} = [ { APIKeyHeader => [] } ]; - # workaround for https://github.com/PerlDancer/Dancer/issues/935 hook after_error_render => sub { setting('layout' => 'main') }; @@ -279,7 +256,7 @@ hook before_layout_render => sub { hook 'after' => sub { my $r = shift; # a Dancer::Response - if (request->path eq '/swagger.json') { + if (request->path eq uri_for('/swagger.json')->path) { $r->content( to_json( $r->content ) ); header('Content-Type' => 'application/json'); } @@ -292,6 +269,55 @@ hook 'after' => sub { } }; +# setup for swagger API +my $swagger = Dancer::Plugin::Swagger->instance; +my $swagger_doc = $swagger->doc; + +$swagger_doc->{schemes} = ['http','https']; +$swagger_doc->{consumes} = 'application/json'; +$swagger_doc->{produces} = 'application/json'; +$swagger_doc->{tags} = [ + {name => 'General', + description => 'Log in and Log out'}, + {name => 'Search', + description => 'Search Operations'}, + {name => 'Objects', + description => 'Retrieve Device, Port, and associated Node Data'}, + {name => 'Reports', + description => 'Canned and Custom Reports'}, +]; +$swagger_doc->{securityDefinitions} = { + APIKeyHeader => + { type => 'apiKey', name => 'Authorization', in => 'header' }, + BasicAuth => + { type => 'basic' }, +}; +$swagger_doc->{security} = [ { APIKeyHeader => [] } ]; + +# manually install Swagger UI routes because plugin doesn't handle non-root +# hosting, so we cannot use show_ui(1) +my $swagger_base = config->{plugins}->{Swagger}->{ui_url}; + +get $swagger_base => sub { + redirect uri_for($swagger_base)->path + . '/?url=' . uri_for('/swagger.json')->path; +}; + +get $swagger_base.'/' => sub { + # user might request /swagger-ui/ initially (Plugin doesn't handle this) + params->{url} or redirect $swagger_base; + + my $file = $swagger->ui_dir->child('index.html'); + send_error "file not found", 404 unless -f $file; + return $file->slurp; +}; + +get $swagger_base.'/**' => sub { + my $file = $swagger->ui_dir->child( @{ (splat())[0] } ); + send_error "file not found", 404 unless -f $file; + send_file $file, system_path => 1; +}; + # remove empty lines from CSV response # this makes writing templates much more straightforward! hook 'after' => sub { diff --git a/share/config.yml b/share/config.yml index db6fb71d..01470dcd 100644 --- a/share/config.yml +++ b/share/config.yml @@ -499,6 +499,7 @@ plugins: Swagger: main_api_module: 'App::Netdisco' ui_url: '/swagger-ui' + show_ui: false Auth::Extensible: no_api_change_warning: true no_default_pages: true