Bug 23653: use local copy of swagger v2 schema
[koha.git] / Koha / REST / V1.pm
1 package Koha::REST::V1;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it
6 # under the terms of the GNU General Public License as published by
7 # the Free Software Foundation; either version 3 of the License, or
8 # (at your option) any later version.
9 #
10 # Koha is distributed in the hope that it will be useful, but
11 # WITHOUT ANY WARRANTY; without even the implied warranty of
12 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 # GNU General Public License for more details.
14 #
15 # You should have received a copy of the GNU General Public License
16 # along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18 use Modern::Perl;
19
20 use Mojo::Base 'Mojolicious';
21
22 use C4::Context;
23 use JSON::Validator::OpenAPI::Mojolicious;
24 use Try::Tiny;
25
26 =head1 NAME
27
28 Koha::REST::V1 - Main v.1 REST api class
29
30 =head1 API
31
32 =head2 Class Methods
33
34 =head3 startup
35
36 Overloaded Mojolicious->startup method. It is called at application startup.
37
38 =cut
39
40 sub startup {
41     my $self = shift;
42
43     $self->hook(
44         before_dispatch => sub {
45             my $c = shift;
46
47             # Remove /api/v1/app.pl/ from the path
48             $c->req->url->base->path('/');
49
50             # Handle CORS
51             $c->res->headers->header( 'Access-Control-Allow-Origin' =>
52                   C4::Context->preference('AccessControlAllowOrigin') )
53               if C4::Context->preference('AccessControlAllowOrigin');
54         }
55     );
56
57     # Force charset=utf8 in Content-Type header for JSON responses
58     $self->types->type( json    => 'application/json; charset=utf8' );
59     # MARC-related types
60     $self->types->type( marcxml => 'application/marcxml+xml' );
61     $self->types->type( mij     => 'application/marc-in-json' );
62     $self->types->type( marc    => 'application/marc' );
63
64     my $secret_passphrase = C4::Context->config('api_secret_passphrase');
65     if ($secret_passphrase) {
66         $self->secrets([$secret_passphrase]);
67     }
68
69     my $validator = JSON::Validator::OpenAPI::Mojolicious->new;
70
71     push @{$self->routes->namespaces}, 'Koha::Plugin';
72
73     # Try to load and merge all schemas first and validate the result just once.
74     my $spec;
75     my $swagger_schema = $self->home->rel_file("api/swagger-v2-schema.json");
76     try {
77         $spec = $validator->bundle(
78             {
79                 replace => 1,
80                 schema => $self->home->rel_file("api/v1/swagger/swagger.json")
81             }
82         );
83
84         $self->plugin(
85             'Koha::REST::Plugin::PluginRoutes' => {
86                 spec               => $spec,
87                 validator          => undef
88             }
89         ) unless C4::Context->needs_install; # load only if Koha is installed
90
91         $self->plugin(
92             OpenAPI => {
93                 spec  => $spec,
94                 route => $self->routes->under('/api/v1')->to('Auth#under'),
95                 schema => ( $swagger_schema ) ? $swagger_schema : undef,
96                 allow_invalid_ref =>
97                 1,    # required by our spec because $ref directly under
98                         # Paths-, Parameters-, Definitions- & Info-object
99                         # is not allowed by the OpenAPI specification.
100             }
101         );
102     }
103     catch {
104         # Validation of the complete spec failed. Resort to validation one-by-one
105         # to catch bad ones.
106         $validator->load_and_validate_schema(
107             $self->home->rel_file("api/v1/swagger/swagger.json"),
108             {
109                 allow_invalid_ref  => 1,
110                 schema => ( $swagger_schema ) ? $swagger_schema : undef,
111             }
112         );
113
114         $spec = $validator->schema->data;
115         $self->plugin(
116             'Koha::REST::Plugin::PluginRoutes' => {
117                 spec      => $spec,
118                 validator => $validator
119             }
120         )  unless C4::Context->needs_install; # load only if Koha is installed
121
122         $self->plugin(
123             OpenAPI => {
124                 spec  => $spec,
125                 route => $self->routes->under('/api/v1')->to('Auth#under'),
126                 allow_invalid_ref =>
127                 1,    # required by our spec because $ref directly under
128                         # Paths-, Parameters-, Definitions- & Info-object
129                         # is not allowed by the OpenAPI specification.
130             }
131         );
132     };
133
134     $self->plugin( 'Koha::REST::Plugin::Pagination' );
135     $self->plugin( 'Koha::REST::Plugin::Query' );
136     $self->plugin( 'Koha::REST::Plugin::Objects' );
137     $self->plugin( 'Koha::REST::Plugin::Exceptions' );
138 }
139
140 1;