From caed3d5b8fd2766513c3be513c332f8da44d6005 Mon Sep 17 00:00:00 2001 From: David Cook Date: Wed, 12 May 2021 07:30:24 +0000 Subject: [PATCH] Bug 31380: Allow Koha Plugins to run using Mojolicious controllers This patch adds a new mount point in plack.psgi, which makes Koha able to run Mojolicious controllers. For example: http://localhost:8081/cgi-bin/koha/staff/plugins/run 0a) Apply patch 0b) cp debian/templates/plack.psgi /etc/koha/sites/kohadev/plack.psgi 0c) koha-plack --restart kohadev 1) Upload Koha Plugin koha-plugin-mojolicious.kpz 2) koha-plack --restart kohadev 3) Go to http://localhost:8081/cgi-bin/koha/plugins/plugins-home.pl 4) Next to "Mojolicious Test", click "Actions", then click "Run tool" 5) Note that the web page looks perfect 6) Note that the URL is a bit different to normal: http://localhost:8081/cgi-bin/koha/staff/plugins/run?class=Koha%3A%3APlugin%3A%3AProsentient%3A%3AMojolicious&method=tool instead of: http://localhost:8081/cgi-bin/koha/plugins/run.pl?class=Koha%3A%3APlugin%3A%3AProsentient%3A%3AMojolicious&method=tool Note: The test Koha plugin will only work with a Mojolicious controller, but it could be easily made to work with both 7) Run the above test using an unauthenticated user, use a staff user without plugin permissions, try with a staff user with plugin permissions, and try with a superlibrarian 8) Run tests prove t/db_dependent/Koha/Auth.t prove t/db_dependent/Koha/Mojo/Plugins/Core.t prove t/db_dependent/Koha/Template.t --- Koha/Auth.pm | 88 +++++++++++++ Koha/Mojo/Plugins/Core.pm | 131 +++++++++++++++++++ Koha/Mojo/Staff.pm | 90 +++++++++++++ Koha/Mojo/Staff/Controller/Plugins.pm | 54 ++++++++ Koha/Template.pm | 65 ++++++++++ debian/templates/plack.psgi | 32 +++++ staff | 21 +++ t/db_dependent/Koha/Auth.t | 163 ++++++++++++++++++++++++ t/db_dependent/Koha/Mojo/Plugins/Core.t | 119 +++++++++++++++++ t/db_dependent/Koha/Template.t | 65 ++++++++++ 10 files changed, 828 insertions(+) create mode 100644 Koha/Auth.pm create mode 100644 Koha/Mojo/Plugins/Core.pm create mode 100644 Koha/Mojo/Staff.pm create mode 100644 Koha/Mojo/Staff/Controller/Plugins.pm create mode 100644 Koha/Template.pm create mode 100755 staff create mode 100755 t/db_dependent/Koha/Auth.t create mode 100755 t/db_dependent/Koha/Mojo/Plugins/Core.t create mode 100755 t/db_dependent/Koha/Template.t diff --git a/Koha/Auth.pm b/Koha/Auth.pm new file mode 100644 index 0000000000..4673ce4cb9 --- /dev/null +++ b/Koha/Auth.pm @@ -0,0 +1,88 @@ +package Koha::Auth; + +# 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 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, see . + +use Modern::Perl; + +use C4::Auth qw//; +use Koha::Patrons; + +=head1 NAME + +Koha::Auth - Koha class for handling authentication and authorization + +=head1 SYNOPSIS + +=head2 METHODS + +=head3 authenticate + + my $user = Koha::Auth->authenticate({ + sessionID => $sessionID, + }); + +Verifies that this user has an authenticated Koha session + +=cut + +sub authenticate { + my ( $class, $args ) = @_; + my ( $auth_user, $auth_session ); + my $sessionID = $args->{sessionID}; + if ($sessionID) { + my $flags; + my ( $return, $session, $more_info ) = C4::Auth::check_cookie_auth( + $sessionID, $flags, + { remote_addr => $ENV{REMOTE_ADDR}, skip_version_check => 1 } + ); + if ( $return && $return eq 'ok' && $session ) { + my $userid = $session->param('id'); + if ($userid) { + my $patron = Koha::Patrons->find( { userid => $userid } ); + if ($patron) { + $auth_user = $patron; + $auth_session = $session; + } + } + } + } + return ( $auth_user, $auth_session ); +} + +=head3 authorize + + my $flags = Koha::Auth->authorize({ + session => $session, + flagsrequired => { self_check => 'self_checkout_module' }, + }); + +=cut + +sub authorize { + my ( $class, $args ) = @_; + my $flags = 0; + my $session = $args->{session}; + my $flagsrequired = $args->{flagsrequired}; + if ($session) { + my $userid = $session->param('id'); + if ($userid) { + $flags = C4::Auth::haspermission( $userid, $flagsrequired ); + } + } + return $flags; +} + +1; diff --git a/Koha/Mojo/Plugins/Core.pm b/Koha/Mojo/Plugins/Core.pm new file mode 100644 index 0000000000..0c22cb51b6 --- /dev/null +++ b/Koha/Mojo/Plugins/Core.pm @@ -0,0 +1,131 @@ +package Koha::Mojo::Plugins::Core; + +# 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 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, see . + +use Modern::Perl; + +use Mojo::Base 'Mojolicious::Plugin'; + +use Koha::Auth; +use Koha::Auth::Permissions; +use Koha::Template; + +use Koha::Exceptions; +use Koha::Exceptions::Authorization; + +=head1 NAME + +Koha::Mojo::Plugins::Core - Mojolicious plugin that adds AuthZ and + template helpers for Koha Mojolicious controllers + +=head1 SYNOPSIS + +=head2 METHODS + +=head3 register + +=cut + +sub register { + my ( $self, $app, $conf ) = @_; + + $app->helper( + 'koha.authenticate' => sub { + my ( $c, $args ) = @_; + my $authenticated = 0; + my $sessionID = $c->cookie('CGISESSID'); + my ( $user, $session ) = Koha::Auth->authenticate( + { + sessionID => $sessionID, + } + ); + if ( $user && $session ) { + $c->stash->{__koha_user__} = $user; + $c->stash->{__koha_session__} = $session; + $c->cookie( + 'CGISESSID' => $session->id, + { + httponly => 1, + secure => ( C4::Context->https_enabled() ? 1 : 0 ), + path => '/', + } + ); + $authenticated = 1; + } + return $authenticated; + } + ); + + $app->helper( + 'koha.authorize' => sub { + my ( $c, $args ) = @_; + my $session = $c->stash->{__koha_session__}; + my $flags = Koha::Auth->authorize( + { + session => $session, + flagsrequired => $args->{flagsrequired}, + } + ); + if ($flags) { + $c->stash->{__koha_flags__} = $flags; + $c->stash->{__koha_authz__} = Koha::Auth::Permissions->get_authz_from_flags( { flags => $flags } ); + return ( $flags, $c->stash->{__koha_user__} ); + } else { + Koha::Exceptions::Authorization::Unauthorized->throw( + error => "Authorization failure. Missing required permission(s).", + required_permissions => $args->{flagsrequired}, + ); + } + } + ); + + $app->helper( + 'koha.template' => sub { + my ( $c, $args ) = @_; + my $template_filename = $args->{template_filename}; + my $interface = $args->{interface}; + my $template = Koha::Template::prepare_template( + { + template_filename => $template_filename, + interface => $interface, + koha_session => $c->stash->{__koha_session__}, + koha_user => $c->stash->{__koha_user__}, + koha_authz => $c->stash->{__koha_authz__}, + } + ); + return $template; + } + ); + + $app->helper( + 'koha.render_staff_error' => sub { + my ( $c, $args ) = @_; + my $status = $args->{status} // 500; + my ( $flags, $loggedinuser ) = $c->koha->authorize( { flagsrequired => { catalogue => 1, } } ); + my $template = $c->koha->template( + { + template_filename => 'errors/errorpage.tt', + interface => 'intranet', + } + ); + $template->{VARS}->{errno} = $status; + $template->{VARS}->{admin} = C4::Context->preference('KohaAdminEmailAddress'); + return $c->render( text => $template->output(), status => $status ); + } + ); +} + +1; diff --git a/Koha/Mojo/Staff.pm b/Koha/Mojo/Staff.pm new file mode 100644 index 0000000000..8497ee73c3 --- /dev/null +++ b/Koha/Mojo/Staff.pm @@ -0,0 +1,90 @@ +package Koha::Mojo::Staff; + +# 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 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, see . + +use Mojo::Base 'Mojolicious'; + +use C4::Context; +use Try::Tiny qw( catch try ); + +=head1 NAME + +Koha::Mojo::Staff - Mojolicious application for Koha staff interface + +=head1 SYNOPSIS + +=head2 METHODS + +=head3 startup + +=cut + +sub startup { + my $self = shift; + + #NOTE: Load plugin which sets up core helper methods needed for any Koha app + $self->plugin('Koha::Mojo::Plugins::Core'); + + #NOTE: Customize application-wide exception handling + $self->hook( + around_dispatch => sub { + my ( $next, $c ) = @_; + try { + $next->(); + } catch { + my $status = 500; + if ( $_->isa('Koha::Exceptions::Authorization::Unauthorized') ) { + $status = 403; + } + $c->koha->render_staff_error( { status => $status } ); + }; + } + ); + + # Router + my $r = $self->routes; + + #NOTE: The /login route is public and does not require authentication + #FIXME: Implement a Mojolicious login route + #$r->get('/login')->to( controller => 'login', action => 'index' ); + + #NOTE: All other routes require authentication + my $auth = $r->under( + '/' => sub { + my $c = shift; + if ( $c->koha->authenticate ) { + return 1; + } else { + + #FIXME: In future, redirect to a /login route, or prompt for login here + $c->redirect_to('/index.html'); + return; + } + } + ); + my $plugins = $auth->under('plugins'); + $plugins->any( [ 'GET', 'POST' ] => '/run' )->to( controller => 'Plugins', action => 'run' ); + + #NOTE: Catch-all route to redirect to CGI 404 handler for any unmatched routes + $auth->any( + '/*' => sub { + my $c = shift; + $c->koha->render_staff_error( { status => 404 } ); + } + ); +} + +1; diff --git a/Koha/Mojo/Staff/Controller/Plugins.pm b/Koha/Mojo/Staff/Controller/Plugins.pm new file mode 100644 index 0000000000..5ec435ead4 --- /dev/null +++ b/Koha/Mojo/Staff/Controller/Plugins.pm @@ -0,0 +1,54 @@ +package Koha::Mojo::Staff::Controller::Plugins; + +# 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 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, see . + +use Mojo::Base 'Mojolicious::Controller'; + +use C4::Context; +use Koha::Plugins::Handler; + +=head1 NAME + +Koha::Mojo::Staff::Controller::Plugins - Mojolicious controller for running Koha plugins + +=head1 SYNOPSIS + +=head2 METHODS + +=head3 run + +=cut + +sub run { + my $c = shift; + my $class = $c->param('class'); + my $method = $c->param('method'); + my ( $flags, $loggedinuser ) = $c->koha->authorize( { flagsrequired => { 'plugins' => $method } } ); + my $plugins_enabled = C4::Context->config("enable_plugins"); + if ($plugins_enabled) { + my $plugin = Koha::Plugins::Handler->run( { class => $class, method => $method, cgi => $c } ); + } else { + my $template = $c->koha->template( + { + template_filename => 'plugins/plugins-disabled.tt', + interface => 'intranet', + } + ); + $c->render( text => $template->output ); + } +} + +1; diff --git a/Koha/Template.pm b/Koha/Template.pm new file mode 100644 index 0000000000..088ca44d44 --- /dev/null +++ b/Koha/Template.pm @@ -0,0 +1,65 @@ +package Koha::Template; + +# 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 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, see . + +use Modern::Perl; + +use C4::Templates; + +=head1 NAME + +Koha::Template - Koha class for preparing a template for any Koha web view + +=head1 SYNOPSIS + +=head2 METHODS + +=head3 prepare_template + +=cut + +sub prepare_template { + my ($args) = @_; + my $template; + my $session = $args->{koha_session}; + my $user = $args->{koha_user}; + my $authz = $args->{koha_authz}; + my $template_filename = $args->{template_filename}; + my $interface = $args->{interface}; + if ( $template_filename && $interface ) { + $template = C4::Templates::gettemplate( $template_filename, $interface ); + if ($template) { + if ($session) { + $template->{VARS}->{sessionID} = $session->id; + } + if ($user) { + $template->{VARS}->{logged_in_user} = $user; + $template->{VARS}->{loggedinusernumber} = $user->borrowernumber; + $template->{VARS}->{loggedinusername} = $user->userid; + } + if ($authz) { + foreach my $key ( keys %$authz ) { + $template->{VARS}->{$key} = $authz->{$key}; + } + } + + #NOTE: Instead of including syspref code here like in C4::Auth, start switching to Koha.Preference in templates + } + } + return $template; +} + +1; diff --git a/debian/templates/plack.psgi b/debian/templates/plack.psgi index 89cd6ef48f..fd4beb397f 100644 --- a/debian/templates/plack.psgi +++ b/debian/templates/plack.psgi @@ -66,6 +66,19 @@ my $apiv1 = builder { $server->to_psgi_app; }; +my $staff_interface = builder { + my $server = Mojo::Server::PSGI->new; + $server->build_app('Koha::Mojo::Staff'); + my $app = $server->app; + $app->hook( before_dispatch => sub { + my $c = shift; + #NOTE: Rewrite the base path to strip off the mount prefix + my $path = $c->req->url->base->path(Mojo::Path->new); + + }); + $server->to_psgi_app; +}; + Koha::Logger->_init; builder { @@ -114,6 +127,25 @@ builder { } $intranet; }; + mount '/intranet/staff' => builder { + #NOTE: it is important that these are relative links + enable 'ErrorDocument', + 400 => 'errors/400.pl', + 401 => 'errors/401.pl', + 402 => 'errors/402.pl', + 403 => 'errors/403.pl', + 404 => 'errors/404.pl', + 500 => 'errors/500.pl', + subrequest => 1; + #NOTE: Without this middleware to catch fatal errors, ErrorDocument won't be able to render a 500 document + #NOTE: This middleware must be closer to the PSGI app than ErrorDocument + enable "HTTPExceptions"; + if ( Log::Log4perl->get_logger('plack-intranet')->has_appenders ){ + enable 'Log4perl', category => 'plack-intranet'; + enable 'LogWarn'; + } + $staff_interface; + }; mount '/api/v1/app.pl' => builder { if ( Log::Log4perl->get_logger('plack-api')->has_appenders ){ enable 'Log4perl', category => 'plack-api'; diff --git a/staff b/staff new file mode 100755 index 0000000000..8be89e4bf7 --- /dev/null +++ b/staff @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +# 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 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, see . + +use Modern::Perl; + +require Mojolicious::Commands; +Mojolicious::Commands->start_app('Koha::Mojo::Staff'); diff --git a/t/db_dependent/Koha/Auth.t b/t/db_dependent/Koha/Auth.t new file mode 100755 index 0000000000..0b4fb2b651 --- /dev/null +++ b/t/db_dependent/Koha/Auth.t @@ -0,0 +1,163 @@ +#!/usr/bin/perl + +use Modern::Perl; +use C4::Auth qw( get_session ); +use Test::More tests => 8; +use t::lib::TestBuilder; +use t::lib::Mocks; + +use Data::Dumper; +use Koha::Database; + +use_ok('Koha::Auth'); + +t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); + +my $schema = Koha::Database->new->schema; +$schema->storage->txn_begin; + +subtest 'Successful authentication' => sub { + plan tests => 2; + + $ENV{REMOTE_ADDR} = '127.0.0.1'; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower' } ); + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + my $sessionID = $session->id; + + my ( $user, $user_session ) = Koha::Auth->authenticate( + { + sessionID => $sessionID, + } + ); + is( ref $user, 'Koha::Patron', 'User found' ); + is( ref $user_session, 'CGI::Session', 'User session found' ); + + $session->delete; +}; + +subtest 'Failed authentication' => sub { + plan tests => 2; + + $ENV{REMOTE_ADDR} = '127.0.0.1'; + my $session = C4::Auth::get_session; + $session->flush; + $session->param( 'ip', '127.0.0.1' ); + my $sessionID = $session->id; + + my ( $user, $user_session ) = Koha::Auth->authenticate( + { + sessionID => $sessionID, + } + ); + is( $user, undef, 'User not found' ); + is( $user_session, undef, 'User session not found' ); + + $session->delete; +}; + +subtest 'Superlibrarian authorization' => sub { + plan tests => 1; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => 1, } } ); + + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + + my $flags = Koha::Auth->authorize( + { + session => $session, + flagsrequired => { circulate => 1 }, + } + ); + is( $flags->{superlibrarian}, 1, 'Got superlibrarian authorization' ); +}; + +subtest 'Circulation staff authorization' => sub { + plan tests => 2; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => 2, } } ); + + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + + my $flags = Koha::Auth->authorize( + { + session => $session, + flagsrequired => { circulate => 1 }, + } + ); + is( $flags->{superlibrarian}, 0, 'Did not get superlibrarian authorization' ); + is( $flags->{circulate}, 1, 'Did get circulate authorization' ); +}; + +subtest 'Public user not authorized for circulate authorization requirement' => sub { + plan tests => 1; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => undef, } } ); + + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + + my $flags = Koha::Auth->authorize( + { + session => $session, + flagsrequired => { circulate => 1 }, + } + ); + is( $flags, 0, 'Flags returned 0' ); +}; + +subtest 'Staff user not authorized for circulate authorization requirement' => sub { + plan tests => 1; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => 4, } } ); + + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + + my $flags = Koha::Auth->authorize( + { + session => $session, + flagsrequired => { circulate => 1 }, + } + ); + is( $flags, 0, 'Flags returned 0' ); +}; + +subtest 'No authorization required' => sub { + plan tests => 1; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => undef, } } ); + + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + + my $flags = Koha::Auth->authorize( + { + session => $session, + } + ); + is( ref $flags, 'HASH', 'When no flags are required, a hashref is returned' ); +}; + +$schema->storage->txn_rollback; diff --git a/t/db_dependent/Koha/Mojo/Plugins/Core.t b/t/db_dependent/Koha/Mojo/Plugins/Core.t new file mode 100755 index 0000000000..a405d542ae --- /dev/null +++ b/t/db_dependent/Koha/Mojo/Plugins/Core.t @@ -0,0 +1,119 @@ +#!/usr/bin/perl + +# 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 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, see . + +use Modern::Perl; + +# Dummy app for testing the plugin +use Mojolicious::Lite; +use Try::Tiny; + +use C4::Auth qw//; +use Koha::Patrons; +use t::lib::TestBuilder; +use t::lib::Mocks; +t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); + +my $schema = Koha::Database->new->schema; + +app->log->level('error'); + +plugin 'Koha::Mojo::Plugins::Core'; + +get '/get_helper_details' => sub { + my $c = shift; + try { + my $authenticated = $c->koha->authenticate(); + my ( $flags, $loggedinuser ) = $c->koha->authorize(); + my $template = $c->koha->template( + { + template_filename => 'about.tt', + interface => 'intranet', + } + ); + $c->render( + json => { + authenticated => $authenticated, + flags => $flags, + borrowernumber => $loggedinuser->borrowernumber, + template => { + output => $template->output, + sessionID => $template->{VARS}->{sessionID}, + loggedinusernumber => $template->{VARS}->{loggedinusernumber}, + loggedinusername => $template->{VARS}->{loggedinusername}, + CAN_user_circulate => $template->{VARS}->{CAN_user_circulate}, + }, + }, + status => 200, + ); + } catch { + my $status = 500; + if ( $_->isa('Koha::Exceptions::Authorization::Unauthorized') ) { + $status = 403; + } + $c->render( status => $status, text => '' ); + }; +}; + +sub to_model { + my ($args) = @_; + return $args; +} + +# The tests + +use Test::More tests => 2; +use Test::Mojo; + +subtest 'Test core plugins with no session' => sub { + + plan tests => 2; + + my $t = Test::Mojo->new; + $t->get_ok('/get_helper_details')->status_is(403); +}; + +subtest 'Test core plugins with superlibrarian' => sub { + plan tests => 10; + $schema->storage->txn_begin; + + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => 1, } } ); + my $patron = Koha::Patrons->find( $borrower->{borrowernumber} ); + + my $remote_address = '127.0.0.1'; + $ENV{REMOTE_ADDR} = $remote_address; + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', $remote_address ); + $session->flush; + + my $t = Test::Mojo->new; + my $tx = $t->ua->build_tx( GET => '/get_helper_details' ); + $tx->req->cookies( { name => 'CGISESSID', value => $session->id } ); + $tx->req->env( { REMOTE_ADDR => $remote_address } ); + $t->request_ok($tx)->status_is(200)->json_is( '/authenticated' => 1, 'authenticated' ) + ->json_is( '/flags/superlibrarian' => 1, 'superlibrarian flag set' ) + ->json_is( '/borrowernumber' => $patron->borrowernumber, 'Borrower found' ) + ->json_has( '/template/output', 'template output set' ) + ->json_is( '/template/sessionID' => $session->id, 'sesssionID set' ) + ->json_is( '/template/loggedinusernumber' => $patron->borrowernumber, 'loggedinusernumber set' ) + ->json_is( '/template/loggedinusername' => $patron->userid, 'loggedinusername set' ) + ->json_is( '/template/CAN_user_circulate' => 1, 'template permissions set' ); + + $schema->storage->txn_rollback; +}; diff --git a/t/db_dependent/Koha/Template.t b/t/db_dependent/Koha/Template.t new file mode 100755 index 0000000000..4531764916 --- /dev/null +++ b/t/db_dependent/Koha/Template.t @@ -0,0 +1,65 @@ +#!/usr/bin/perl + +use Modern::Perl; +use C4::Auth qw( get_session ); +use Test::More tests => 2; +use t::lib::TestBuilder; +use t::lib::Mocks; + +use Koha::Database; +use Data::Dumper; +use Koha::Auth; +use Koha::Auth::Permissions; +use Koha::Patrons; +use_ok('Koha::Template'); + +t::lib::Mocks::mock_preference( 'SessionStorage', 'tmp' ); + +my $schema = Koha::Database->new->schema; +$schema->storage->txn_begin; + +subtest 'Prepare template' => sub { + plan tests => 6; + + $ENV{REMOTE_ADDR} = '127.0.0.1'; + my $builder = t::lib::TestBuilder->new; + my $borrower = $builder->build( { source => 'Borrower', value => { flags => 2, } } ); + my $session = C4::Auth::get_session; + $session->param( 'id', $borrower->{userid} ); + $session->param( 'lasttime', time() ); + $session->param( 'ip', '127.0.0.1' ); + $session->flush; + my $sessionID = $session->id; + my $flags = Koha::Auth->authorize( + { + session => $session, + flagsrequired => { circulate => 1 }, + } + ); + my $koha_authz = Koha::Auth::Permissions->get_authz_from_flags( { flags => $flags } ); + my $koha_user = Koha::Patrons->find( $borrower->{borrowernumber} ); + + my $htdocs = C4::Context->config('intrahtdocs'); + my $template_filename = $htdocs . '/prog/en/modules/about.tt'; + my $interface = "intranet"; + my $template = Koha::Template::prepare_template( + { + template_filename => $template_filename, + interface => $interface, + koha_session => $session, + koha_user => $koha_user, + koha_authz => $koha_authz, + } + ); + + ok( $template->output, 'Template generates output' ); + is( $template->{VARS}->{sessionID}, $session->id, 'sessionID set' ); + is( $template->{VARS}->{logged_in_user}, $koha_user, 'logged_in_user set' ); + is( $template->{VARS}->{loggedinusernumber}, $koha_user->borrowernumber, 'loggedinusernumber set' ); + is( $template->{VARS}->{loggedinusername}, $koha_user->userid, 'loggedinusername set' ); + is( $template->{VARS}->{CAN_user_circulate}, 1, 'CAN_user_circulate set' ); + + $session->delete; +}; + +$schema->storage->txn_rollback; -- 2.30.2