@@ -, +, @@ $ apt update ; apt dist-upgrade -y $ kshell k$ prove t/db_dependent/Koha/REST/Plugin/PluginRoutes.t \ t/db_dependent/api/v1 $ koha-plack --restart kohadev ; tail -f /var/log/koha/kohadev/*.log --- Koha/REST/Plugin/PluginRoutes.pm | 33 +++++-------- Koha/REST/V1.pm | 49 +++++++------------ .../Koha/REST/Plugin/PluginRoutes.t | 16 +++--- t/db_dependent/Koha/REST/V1.t | 2 - 4 files changed, 39 insertions(+), 61 deletions(-) --- a/Koha/REST/Plugin/PluginRoutes.pm +++ a/Koha/REST/Plugin/PluginRoutes.pm @@ -24,6 +24,7 @@ use Koha::Plugins; use Koha::Logger; use Clone qw( clone ); +use JSON::Validator::Schema::OpenAPIv2; use Try::Tiny qw( catch try ); =head1 NAME @@ -41,8 +42,8 @@ Koha::REST::Plugin::PluginRoutes sub register { my ( $self, $app, $config ) = @_; - my $spec = $config->{spec}; - my $validator = $config->{validator}; + my $spec = $config->{spec}; + my $validate = $config->{validate}; my @plugins; @@ -58,7 +59,7 @@ sub register { ); foreach my $plugin ( @plugins ) { - $spec = $self->inject_routes( $spec, $plugin, $validator ); + $spec = $self->inject_routes( $spec, $plugin, $validate ); } } @@ -71,14 +72,14 @@ sub register { =cut sub inject_routes { - my ( $self, $spec, $plugin, $validator ) = @_; + my ( $self, $spec, $plugin, $validate ) = @_; - return merge_spec( $spec, $plugin ) unless $validator; + return merge_spec( $spec, $plugin ) unless $validate; return try { my $backup_spec = merge_spec( clone($spec), $plugin ); - if ( $self->spec_ok( $backup_spec, $validator ) ) { + if ( $self->spec_ok( $backup_spec, $validate ) ) { $spec = merge_spec( $spec, $plugin ); } else { @@ -145,23 +146,15 @@ sub merge_spec { =cut sub spec_ok { - my ( $self, $spec, $validator ) = @_; + my ( $self, $spec ) = @_; - my $schema = $self->{'swagger-v2-schema'}; + my $schema = JSON::Validator::Schema::OpenAPIv2->new( $spec ); - return try { - $validator->load_and_validate_schema( - $spec, - { - allow_invalid_ref => 1, - schema => ( $schema ) ? $schema : undef, - } - ); - return 1; - } - catch { - return 0; + if ($schema->is_invalid) { + warn $schema->errors->[0]; } + + return !$schema->is_invalid; } 1; --- a/Koha/REST/V1.pm +++ a/Koha/REST/V1.pm @@ -22,7 +22,8 @@ use Mojo::Base 'Mojolicious'; use C4::Context; use Koha::Logger; -use JSON::Validator::OpenAPI::Mojolicious; +use JSON::Validator::Schema::OpenAPIv2; + use Try::Tiny qw( catch try ); =head1 NAME @@ -68,25 +69,23 @@ sub startup { $self->secrets([$secret_passphrase]); } - my $validator = JSON::Validator::OpenAPI::Mojolicious->new; + my $spec_file = $self->home->rel_file("api/v1/swagger/swagger.yaml"); push @{$self->routes->namespaces}, 'Koha::Plugin'; # Try to load and merge all schemas first and validate the result just once. - my $spec; - my $swagger_schema = $self->home->rel_file("api/swagger-v2-schema.json"); try { - $spec = $validator->bundle( - { - replace => 1, - schema => $self->home->rel_file("api/v1/swagger/swagger.yaml") - } - ); + + my $schema = JSON::Validator::Schema::OpenAPIv2->new; + + $schema->resolve( $spec_file ); + + my $spec = $schema->bundle->data; $self->plugin( 'Koha::REST::Plugin::PluginRoutes' => { - spec => $spec, - validator => undef + spec => $spec, + validate => 0, } ) unless C4::Context->needs_install; # load only if Koha is installed @@ -94,11 +93,6 @@ sub startup { OpenAPI => { spec => $spec, route => $self->routes->under('/api/v1')->to('Auth#under'), - schema => ( $swagger_schema ) ? $swagger_schema : undef, - allow_invalid_ref => - 1, # required by our spec because $ref directly under - # Paths-, Parameters-, Definitions- & Info-object - # is not allowed by the OpenAPI specification. } ); } @@ -111,19 +105,16 @@ sub startup { $logger->error("Warning: Could not load REST API spec bundle: " . $_); try { - $validator->load_and_validate_schema( - $self->home->rel_file("api/v1/swagger/swagger.yaml"), - { - allow_invalid_ref => 1, - schema => ( $swagger_schema ) ? $swagger_schema : undef, - } - ); - $spec = $validator->schema->data; + my $schema = JSON::Validator::Schema::OpenAPIv2->new; + $schema->resolve( $spec_file ); + + my $spec = $schema->bundle->data; + $self->plugin( 'Koha::REST::Plugin::PluginRoutes' => { - spec => $spec, - validator => $validator + spec => $spec, + validate => 1 } ) unless C4::Context->needs_install; # load only if Koha is installed @@ -131,10 +122,6 @@ sub startup { OpenAPI => { spec => $spec, route => $self->routes->under('/api/v1')->to('Auth#under'), - allow_invalid_ref => - 1, # required by our spec because $ref directly under - # Paths-, Parameters-, Definitions- & Info-object - # is not allowed by the OpenAPI specification. } ); } --- a/t/db_dependent/Koha/REST/Plugin/PluginRoutes.t +++ a/t/db_dependent/Koha/REST/Plugin/PluginRoutes.t @@ -25,8 +25,6 @@ use Test::MockModule; use File::Basename; use t::lib::Mocks; -use JSON::Validator::OpenAPI::Mojolicious; - # Dummy app for testing the plugin use Mojolicious::Lite; @@ -72,8 +70,9 @@ subtest 'Bad plugins tests' => sub { my $t; warning_like { $t = Test::Mojo->new('Koha::REST::V1'); } - [qr{Could not load REST API spec bundle: Invalid JSON specification}, - qr{The resulting spec is invalid. Skipping Bad API Route Plugin},], + [qr{Could not load REST API spec bundle: /paths/~0001contrib~0001badass}, + qr{bother_wrong/put/parameters/0: /oneOf/1 Properties not allowed:}, + qr{Plugin Koha::Plugin::BadAPIRoute route injection failed: The resulting spec is invalid. Skipping Bad API Route Plugin},], 'Bad plugins raise warning'; my $routes = get_defined_routes($t); @@ -153,8 +152,9 @@ subtest 'Permissions and access to plugin routes tests' => sub { my $t; warning_like { $t = Test::Mojo->new('Koha::REST::V1'); } - [qr{Could not load REST API spec bundle: Invalid JSON specification}, - qr{The resulting spec is invalid. Skipping Bad API Route Plugin},], + [qr{Could not load REST API spec bundle: /paths/~0001contrib~0001badass}, + qr{bother_wrong/put/parameters/0: /oneOf/1 Properties not allowed:}, + qr{Plugin Koha::Plugin::BadAPIRoute route injection failed: The resulting spec is invalid. Skipping Bad API Route Plugin},], 'Bad plugins raise warning'; my $routes = get_defined_routes($t); @@ -262,8 +262,8 @@ sub traverse_routes { my $path = $route->pattern->unparsed || '/'; # Methods - my $via = $route->via; - my $verb = !$via ? '*' : uc join ',', @$via; + my $methods = $route->methods // []; + my $verb = !$methods ? '*' : uc join ',', @$methods; $routes->{$path}->{$verb} = 1; $depth++; --- a/t/db_dependent/Koha/REST/V1.t +++ a/t/db_dependent/Koha/REST/V1.t @@ -21,8 +21,6 @@ use Test::More tests => 1; use Test::Mojo; use Test::Warn; -use JSON::Validator::OpenAPI::Mojolicious; - subtest 'Type definition tests' => sub { plan tests => 4; --