From b9c002477b044c82af30c4099155e5365b54df2a Mon Sep 17 00:00:00 2001 From: Oliver Gorwits Date: Sun, 19 Apr 2020 18:00:15 +0100 Subject: [PATCH] allow swagger_path installed routes to be relocated --- Build.PL | 1 + lib/App/Netdisco/Configuration.pm | 8 ++++++++ lib/App/Netdisco/Web.pm | 1 + lib/App/Netdisco/Web/API/Objects.pm | 10 +++++++--- lib/App/Netdisco/Web/AuthN.pm | 5 ++++- lib/App/Netdisco/Web/Plugin.pm | 2 ++ 6 files changed, 23 insertions(+), 4 deletions(-) diff --git a/Build.PL b/Build.PL index 43f1a851..704a297e 100644 --- a/Build.PL +++ b/Build.PL @@ -89,6 +89,7 @@ Module::Build->new( 'Term::UI' => '0', 'Try::Tiny' => '0', 'URI' => '0', + 'URI::Based' => '0', 'URL::Encode' => '0.03', 'URL::Encode::XS' => '0', 'YAML' => '0.84', diff --git a/lib/App/Netdisco/Configuration.pm b/lib/App/Netdisco/Configuration.pm index 8c2e6620..060dc37d 100644 --- a/lib/App/Netdisco/Configuration.pm +++ b/lib/App/Netdisco/Configuration.pm @@ -7,6 +7,7 @@ use Dancer ':script'; use Path::Class 'dir'; use Net::Domain 'hostdomain'; use File::ShareDir 'dist_dir'; +use URI::Based; BEGIN { if (setting('include_paths') and ref [] eq ref setting('include_paths')) { @@ -224,4 +225,11 @@ config->{'reports'} = [ @{setting('system_reports')}, @{setting('reports')} ]; #config->{plugins}->{Swagger}->{ui_dir} = #dir(dist_dir('App-Netdisco'), 'share', 'public', 'swagger-ui')->absolute; +# setup helpers for when request->uri_for() isn't available +# (for example when inside swagger_path()) +config->{url_base} + = URI::Based->new((config->{path} eq '/') ? '' : config->{path}); +config->{api_base} + = config->{url_base}->with('/api/v1')->path; + true; diff --git a/lib/App/Netdisco/Web.pm b/lib/App/Netdisco/Web.pm index 5344d167..cb0b0c01 100644 --- a/lib/App/Netdisco/Web.pm +++ b/lib/App/Netdisco/Web.pm @@ -32,6 +32,7 @@ BEGIN { $response->status($status || 302); $response->headers('Location' => $destination); }; + # neater than using Dancer::Plugin::Res to handle JSON differently *Dancer::send_error = sub { my ($body, $status) = @_; diff --git a/lib/App/Netdisco/Web/API/Objects.pm b/lib/App/Netdisco/Web/API/Objects.pm index 341520f6..95c7b52e 100644 --- a/lib/App/Netdisco/Web/API/Objects.pm +++ b/lib/App/Netdisco/Web/API/Objects.pm @@ -9,6 +9,7 @@ use Try::Tiny; swagger_path { tags => ['Objects'], + path => setting('api_base').'/object/device/{ip}', description => 'Returns a row from the device table', parameters => [ ip => { @@ -27,6 +28,7 @@ swagger_path { foreach my $rel (qw/device_ips vlans ports modules port_vlans wireless_ports ssids powered_ports/) { swagger_path { tags => ['Objects'], + path => setting('api_base')."/object/device/{ip}/$rel", description => "Returns $rel rows for a given device", parameters => [ ip => { @@ -46,7 +48,7 @@ foreach my $rel (qw/device_ips vlans ports modules port_vlans wireless_ports ssi swagger_path { tags => ['Objects'], description => 'Returns a row from the device_port table', - path => '/api/v1/object/device/{ip}/port/{port}', + path => setting('api_base').'/object/device/{ip}/port/{port}', parameters => [ ip => { description => 'Canonical IP of the Device. Use Search methods to find this.', @@ -72,7 +74,7 @@ foreach my $rel (qw/nodes active_nodes nodes_with_age active_nodes_with_age vlan swagger_path { tags => ['Objects'], description => "Returns $rel rows for a given port", - path => "/api/v1/object/device/{ip}/port/{port}/$rel", + path => setting('api_base')."/object/device/{ip}/port/{port}/$rel", parameters => [ ip => { description => 'Canonical IP of the Device. Use Search methods to find this.', @@ -99,7 +101,7 @@ foreach my $rel (qw/power properties ssid wireless agg_master neighbor last_node swagger_path { tags => ['Objects'], description => "Returns the related $rel table entry for a given port", - path => "/api/v1/object/device/{ip}/port/{port}/$rel", + path => setting('api_base')."/object/device/{ip}/port/{port}/$rel", parameters => [ ip => { description => 'Canonical IP of the Device. Use Search methods to find this.', @@ -124,6 +126,7 @@ foreach my $rel (qw/power properties ssid wireless agg_master neighbor last_node swagger_path { tags => ['Objects'], + path => setting('api_base').'/object/device/{ip}/nodes', description => "Returns the nodes found on a given Device", parameters => [ ip => { @@ -149,6 +152,7 @@ swagger_path { swagger_path { tags => ['Objects'], + path => setting('api_base').'/object/vlan/{vlan}/nodes', description => "Returns the nodes found in a given VLAN", parameters => [ vlan => { diff --git a/lib/App/Netdisco/Web/AuthN.pm b/lib/App/Netdisco/Web/AuthN.pm index e8b0b7d8..1a980473 100644 --- a/lib/App/Netdisco/Web/AuthN.pm +++ b/lib/App/Netdisco/Web/AuthN.pm @@ -85,6 +85,7 @@ hook 'before' => sub { swagger_path { description => 'Obtain an API Key', tags => ['General'], + path => setting('url_base')->with('/login')->path, parameters => [], responses => { default => { examples => { 'application/json' => { api_key => 'cc9d5c02d8898e5728b7d7a0339c0785' } } }, @@ -157,13 +158,15 @@ post '/login' => sub { # ugh, *puke*, but D::P::Swagger has no way to set this with swagger_path # must be after the path is declared, above. -Dancer::Plugin::Swagger->instance->doc->{paths}->{'/login'} +Dancer::Plugin::Swagger->instance->doc + ->{paths}->{ setting('url_base')->with('/login')->path } ->{post}->{security}->[0]->{BasicAuth} = []; # we override the default login_handler, so logout has to be handled as well swagger_path { description => 'Destroy user API Key and session cookie', tags => ['General'], + path => setting('url_base')->with('/logout')->path, parameters => [], responses => { default => { examples => { 'application/json' => {} } } }, }, diff --git a/lib/App/Netdisco/Web/Plugin.pm b/lib/App/Netdisco/Web/Plugin.pm index e14ec2ae..24e5db99 100644 --- a/lib/App/Netdisco/Web/Plugin.pm +++ b/lib/App/Netdisco/Web/Plugin.pm @@ -157,6 +157,7 @@ register 'register_search_tab' => sub { my $tag = $config->{tag}; swagger_path { tags => ['Search'], + path => setting('api_base')."/search/$tag", description => $config->{label} .' Search', parameters => $config->{api_parameters}, responses => @@ -197,6 +198,7 @@ register 'register_report' => sub { (my $category_path = lc $config->{category}) =~ s/ /-/g; swagger_path { tags => ['Reports'], + path => setting('api_base')."/report/$category_path/$tag", description => $config->{label} .' Report', parameters => ($config->{api_parameters} ||