View | Details | Raw Unified | Return to bug 21116
Collapse All | Expand All

(-)a/Koha/Exceptions/Plugin.pm (+84 lines)
Line 0 Link Here
1
package Koha::Exceptions::Plugin;
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 Modern::Perl;
19
20
use Koha::Exceptions::Exception;
21
22
use Exception::Class (
23
    'Koha::Exceptions::Plugin' => {
24
        isa         => 'Koha::Exceptions::Exception',
25
    },
26
    'Koha::Exceptions::Plugin::ForbiddenAction' => {
27
        isa         => 'Koha::Exceptions::Plugin',
28
        description => 'The plugin is trying to do something it is not allowed to'
29
    },
30
    'Koha::Exceptions::Plugin::MissingMethod' => {
31
        isa         => 'Koha::Exceptions::Plugin',
32
        description => 'Required method is missing',
33
        fields      =>  ['plugin_name','method']
34
    }
35
);
36
37
sub full_message {
38
    my $self = shift;
39
40
    my $msg = $self->message;
41
42
    unless ( $msg) {
43
        if ( $self->isa('Koha::Exceptions::Plugin::MissingMethod') ) {
44
            $msg = sprintf("Cannot use plugin (%s) because the it doesn't implement the '%s' method which is required.", $self->plugin_name, $self->method );
45
        }
46
    }
47
48
    return $msg;
49
}
50
51
=head1 NAME
52
53
Koha::Exceptions::Plugin - Base class for Plugin exceptions
54
55
=head1 Exceptions
56
57
=head2 Koha::Exceptions::Plugin
58
59
Generic Plugin exception
60
61
=head2 Koha::Exceptions::Plugin::MissingMethod
62
63
Exception to be used when a plugin is required to implement a specific
64
method and it doesn't.
65
66
=head3 Parameters
67
68
=over
69
70
=item plugin_name: the plugin name for display purposes
71
72
=item method: the missing method
73
74
=back
75
76
=head1 Class methods
77
78
=head2 full_message
79
80
Overloaded method for exception stringifying.
81
82
=cut
83
84
1;
(-)a/Koha/REST/Plugin/PluginRoutes.pm (+140 lines)
Line 0 Link Here
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 Modern::Perl;
19
20
use Mojo::Base 'Mojolicious::Plugin';
21
22
use Koha::Exceptions::Plugin;
23
use Koha::Plugins;
24
25
use Clone qw(clone);
26
use Try::Tiny;
27
28
=head1 NAME
29
30
Koha::REST::Plugin::PluginRoutes
31
32
=head1 API
33
34
=head2 Helper methods
35
36
=head3 register
37
38
=cut
39
40
sub register {
41
    my ( $self, $app, $config ) = @_;
42
43
    my $spec      = $config->{spec};
44
    my $validator = $config->{validator};
45
46
    my @plugins;
47
48
    if (   C4::Context->preference('UseKohaPlugins')
49
        && C4::Context->config("enable_plugins") )
50
    {
51
        @plugins = Koha::Plugins->new()->GetPlugins(
52
            {
53
                method => 'api_routes',
54
            }
55
        );
56
        # plugin needs to define a namespace
57
        @plugins = grep { $_->api_namespace } @plugins;
58
    }
59
60
    foreach my $plugin ( @plugins ) {
61
        $spec = inject_routes( $spec, $plugin, $validator );
62
    }
63
64
    return $spec;
65
}
66
67
=head3 inject_routes
68
69
=cut
70
71
sub inject_routes {
72
    my ( $spec, $plugin, $validator ) = @_;
73
74
    return try {
75
76
        my $backup_spec = merge_spec( clone($spec), $plugin );
77
        if ( spec_ok( $backup_spec, $validator ) ) {
78
            $spec = merge_spec( $spec, $plugin );
79
        }
80
        else {
81
            Koha::Exceptions::Plugin->throw(
82
                "The resulting spec is invalid. Skipping " . $plugin->get_metadata->{name}
83
            );
84
        }
85
86
        return $spec;
87
    }
88
    catch {
89
        warn "$_";
90
        return $spec;
91
    };
92
}
93
94
=head3 merge_spec
95
96
=cut
97
98
sub merge_spec {
99
    my ( $spec, $plugin ) = @_;
100
101
    my $plugin_spec = $plugin->api_routes;
102
103
    foreach my $route ( keys %{ $plugin_spec } ) {
104
105
        my $THE_route = '/contrib/' . $plugin->api_namespace . $route;
106
        if ( exists $spec->{ $THE_route } ) {
107
            # Route exists, overwriting is forbidden
108
            Koha::Exceptions::Plugin::ForbiddenAction->throw(
109
                "Attempted to overwrite $THE_route"
110
            );
111
        }
112
113
        $spec->{'paths'}->{ $THE_route } = $plugin_spec->{ $route };
114
    }
115
116
    return $spec;
117
}
118
119
=head3 spec_ok
120
121
=cut
122
123
sub spec_ok {
124
    my ( $spec, $validator ) = @_;
125
126
    return try {
127
        $validator->load_and_validate_schema(
128
            $spec,
129
            {
130
                allow_invalid_ref => 1,
131
            }
132
        );
133
        return 1;
134
    }
135
    catch {
136
        return 0;
137
    }
138
}
139
140
1;
(-)a/Koha/REST/V1.pm (-8 / +30 lines)
Lines 20-25 use Modern::Perl; Link Here
20
use Mojo::Base 'Mojolicious';
20
use Mojo::Base 'Mojolicious';
21
21
22
use C4::Context;
22
use C4::Context;
23
use JSON::Validator::OpenAPI::Mojolicious;
23
24
24
=head1 NAME
25
=head1 NAME
25
26
Lines 51-63 sub startup { Link Here
51
        $self->secrets([$secret_passphrase]);
52
        $self->secrets([$secret_passphrase]);
52
    }
53
    }
53
54
54
    $self->plugin(OpenAPI => {
55
    my $validator = JSON::Validator::OpenAPI::Mojolicious->new;
55
        url => $self->home->rel_file("api/v1/swagger/swagger.json"),
56
    $validator->load_and_validate_schema(
56
        route => $self->routes->under('/api/v1')->to('Auth#under'),
57
        $self->home->rel_file("api/v1/swagger/swagger.json"),
57
        allow_invalid_ref => 1, # required by our spec because $ref directly under
58
        {
58
                                # Paths-, Parameters-, Definitions- & Info-object
59
          allow_invalid_ref  => 1,
59
                                # is not allowed by the OpenAPI specification.
60
        }
60
    });
61
      );
62
63
    push @{$self->routes->namespaces}, 'Koha::Plugin';
64
65
    my $spec = $validator->schema->data;
66
    $self->plugin(
67
        'Koha::REST::Plugin::PluginRoutes' => {
68
            spec      => $spec,
69
            validator => $validator
70
        }
71
    );
72
73
    $self->plugin(
74
        OpenAPI => {
75
            spec  => $spec,
76
            route => $self->routes->under('/api/v1')->to('Auth#under'),
77
            allow_invalid_ref =>
78
              1,    # required by our spec because $ref directly under
79
                    # Paths-, Parameters-, Definitions- & Info-object
80
                    # is not allowed by the OpenAPI specification.
81
        }
82
    );
83
61
    $self->plugin( 'Koha::REST::Plugin::Pagination' );
84
    $self->plugin( 'Koha::REST::Plugin::Pagination' );
62
    $self->plugin( 'Koha::REST::Plugin::Query' );
85
    $self->plugin( 'Koha::REST::Plugin::Query' );
63
    $self->plugin( 'Koha::REST::Plugin::Objects' );
86
    $self->plugin( 'Koha::REST::Plugin::Objects' );
64
- 

Return to bug 21116