Bug 22026: Removed 'use Modern::Perl;' from Koha::REST::classes
[koha.git] / Koha / REST / Plugin / PluginRoutes.pm
1 package Koha::REST::Plugin::PluginRoutes;
2
3 # This file is part of Koha.
4 #
5 # Koha is free software; you can redistribute it and/or modify it under the
6 # terms of the GNU General Public License as published by the Free Software
7 # Foundation; either version 3 of the License, or (at your option) any later
8 # version.
9 #
10 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
11 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
12 # A PARTICULAR PURPOSE.  See the GNU General Public License for more details.
13 #
14 # You should have received a copy of the GNU General Public License along
15 # with Koha; if not, write to the Free Software Foundation, Inc.,
16 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
17
18 use Mojo::Base 'Mojolicious::Plugin';
19
20 use Koha::Exceptions::Plugin;
21 use Koha::Plugins;
22
23 use Clone qw(clone);
24 use Try::Tiny;
25
26 =head1 NAME
27
28 Koha::REST::Plugin::PluginRoutes
29
30 =head1 API
31
32 =head2 Helper methods
33
34 =head3 register
35
36 =cut
37
38 sub register {
39     my ( $self, $app, $config ) = @_;
40
41     my $spec      = $config->{spec};
42     my $validator = $config->{validator};
43
44     my @plugins;
45
46     if (   C4::Context->preference('UseKohaPlugins')
47         && C4::Context->config("enable_plugins") )
48     {
49         @plugins = Koha::Plugins->new()->GetPlugins(
50             {
51                 method => 'api_routes',
52             }
53         );
54         # plugin needs to define a namespace
55         @plugins = grep { $_->api_namespace } @plugins;
56     }
57
58     foreach my $plugin ( @plugins ) {
59         $spec = inject_routes( $spec, $plugin, $validator );
60     }
61
62     return $spec;
63 }
64
65 =head3 inject_routes
66
67 =cut
68
69 sub inject_routes {
70     my ( $spec, $plugin, $validator ) = @_;
71
72     return try {
73
74         my $backup_spec = merge_spec( clone($spec), $plugin );
75         if ( spec_ok( $backup_spec, $validator ) ) {
76             $spec = merge_spec( $spec, $plugin );
77         }
78         else {
79             Koha::Exceptions::Plugin->throw(
80                 "The resulting spec is invalid. Skipping " . $plugin->get_metadata->{name}
81             );
82         }
83
84         return $spec;
85     }
86     catch {
87         warn "$_";
88         return $spec;
89     };
90 }
91
92 =head3 merge_spec
93
94 =cut
95
96 sub merge_spec {
97     my ( $spec, $plugin ) = @_;
98
99     my $plugin_spec = $plugin->api_routes;
100
101     foreach my $route ( keys %{ $plugin_spec } ) {
102
103         my $THE_route = '/contrib/' . $plugin->api_namespace . $route;
104         if ( exists $spec->{ $THE_route } ) {
105             # Route exists, overwriting is forbidden
106             Koha::Exceptions::Plugin::ForbiddenAction->throw(
107                 "Attempted to overwrite $THE_route"
108             );
109         }
110
111         $spec->{'paths'}->{ $THE_route } = $plugin_spec->{ $route };
112     }
113
114     return $spec;
115 }
116
117 =head3 spec_ok
118
119 =cut
120
121 sub spec_ok {
122     my ( $spec, $validator ) = @_;
123
124     return try {
125         $validator->load_and_validate_schema(
126             $spec,
127             {
128                 allow_invalid_ref => 1,
129             }
130         );
131         return 1;
132     }
133     catch {
134         return 0;
135     }
136 }
137
138 1;