Bug 17600: Standardize our EXPORT_OK
[srvgit] / Koha / REST / V1.pm
index b692a38..1c22a76 100644 (file)
@@ -2,56 +2,152 @@ package Koha::REST::V1;
 
 # This file is part of Koha.
 #
-# Koha is free software; you can redistribute it and/or modify it under the
-# terms of the GNU General Public License as published by the Free Software
-# Foundation; either version 3 of the License, or (at your option) any later
-# version.
+# Koha is free software; you can redistribute it and/or modify it
+# under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
 #
-# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
-# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
-# A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
+# Koha is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
 #
-# You should have received a copy of the GNU General Public License along
-# with Koha; if not, write to the Free Software Foundation, Inc.,
-# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+# You should have received a copy of the GNU General Public License
+# along with Koha; if not, see <http://www.gnu.org/licenses>.
 
 use Modern::Perl;
+
 use Mojo::Base 'Mojolicious';
 
-use C4::Auth qw( check_cookie_auth get_session );
 use C4::Context;
-use Koha::Patrons;
+use Koha::Logger;
+
+use JSON::Validator::OpenAPI::Mojolicious;
+use Try::Tiny qw( catch try );
+
+=head1 NAME
+
+Koha::REST::V1 - Main v.1 REST api class
+
+=head1 API
+
+=head2 Class Methods
+
+=head3 startup
+
+Overloaded Mojolicious->startup method. It is called at application startup.
+
+=cut
 
 sub startup {
     my $self = shift;
 
-    my $route = $self->routes->under->to(
-        cb => sub {
+    $self->hook(
+        before_dispatch => sub {
             my $c = shift;
 
-            my ($status, $sessionID) = check_cookie_auth($c->cookie('CGISESSID'));
-            if ($status eq "ok") {
-                my $session = get_session($sessionID);
-                my $user = Koha::Patrons->find($session->param('number'));
-                $c->stash('koha.user' => $user);
-            }
+            # Remove /api/v1/app.pl/ from the path
+            $c->req->url->base->path('/');
 
-            return 1;
+            # Handle CORS
+            $c->res->headers->header( 'Access-Control-Allow-Origin' =>
+                  C4::Context->preference('AccessControlAllowOrigin') )
+              if C4::Context->preference('AccessControlAllowOrigin');
         }
     );
 
     # Force charset=utf8 in Content-Type header for JSON responses
-    $self->types->type(json => 'application/json; charset=utf8');
+    $self->types->type( json    => 'application/json; charset=utf8' );
+    # MARC-related types
+    $self->types->type( marcxml => 'application/marcxml+xml' );
+    $self->types->type( mij     => 'application/marc-in-json' );
+    $self->types->type( marc    => 'application/marc' );
 
     my $secret_passphrase = C4::Context->config('api_secret_passphrase');
     if ($secret_passphrase) {
         $self->secrets([$secret_passphrase]);
     }
 
-    $self->plugin(Swagger2 => {
-        route => $route,
-        url => $self->home->rel_file("api/v1/swagger.json"),
-    });
+    my $validator = JSON::Validator::OpenAPI::Mojolicious->new;
+
+    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")
+            }
+        );
+
+        $self->plugin(
+            'Koha::REST::Plugin::PluginRoutes' => {
+                spec               => $spec,
+                validator          => undef
+            }
+        ) unless C4::Context->needs_install; # load only if Koha is installed
+
+        $self->plugin(
+            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.
+            }
+        );
+    }
+    catch {
+        # Validation of the complete spec failed. Resort to validation one-by-one
+        # to catch bad ones.
+
+        # JSON::Validator uses confess, so trim call stack from the message.
+        my $logger = Koha::Logger->get({ interface => 'api' });
+        $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;
+            $self->plugin(
+                'Koha::REST::Plugin::PluginRoutes' => {
+                    spec      => $spec,
+                    validator => $validator
+                }
+            )  unless C4::Context->needs_install; # load only if Koha is installed
+
+            $self->plugin(
+                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.
+                }
+            );
+        }
+        catch {
+            # JSON::Validator uses confess, so trim call stack from the message.
+            $logger->error("Warning: Could not load REST API spec bundle: " . $_);
+        };
+    };
+
+    $self->plugin( 'Koha::REST::Plugin::Pagination' );
+    $self->plugin( 'Koha::REST::Plugin::Query' );
+    $self->plugin( 'Koha::REST::Plugin::Objects' );
+    $self->plugin( 'Koha::REST::Plugin::Exceptions' );
 }
 
 1;