From 4788de0ddd195b4e6008b0d99a8d08ad08280040 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 | 87 ++++++++++++++ Koha/Mojo/Plugins/Core.pm | 124 ++++++++++++++++++++ Koha/Mojo/Staff.pm | 85 ++++++++++++++ Koha/Mojo/Staff/Controller/Plugins.pm | 52 +++++++++ Koha/Template.pm | 64 ++++++++++ debian/templates/plack.psgi | 32 +++++ staff | 21 ++++ t/db_dependent/Koha/Auth.t | 149 ++++++++++++++++++++++++ t/db_dependent/Koha/Mojo/Plugins/Core.t | 123 +++++++++++++++++++ t/db_dependent/Koha/Template.t | 62 ++++++++++ 10 files changed, 799 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 100644 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..c9d1bc1e5b --- /dev/null +++ b/Koha/Auth.pm @@ -0,0 +1,87 @@ +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..7f570838ad --- /dev/null +++ b/Koha/Mojo/Plugins/Core.pm @@ -0,0 +1,124 @@ +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..31cb22dcd8 --- /dev/null +++ b/Koha/Mojo/Staff.pm @@ -0,0 +1,85 @@ +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..1b2264b911 --- /dev/null +++ b/Koha/Mojo/Staff/Controller/Plugins.pm @@ -0,0 +1,52 @@ +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..dbf253173b --- /dev/null +++ b/Koha/Template.pm @@ -0,0 +1,64 @@ +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..08c3d74209 --- /dev/null +++ b/t/db_dependent/Koha/Auth.t @@ -0,0 +1,149 @@ +#!/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 100644 index 0000000000..338475c611 --- /dev/null +++ b/t/db_dependent/Koha/Mojo/Plugins/Core.t @@ -0,0 +1,123 @@ +#!/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..d1856bcbc0 --- /dev/null +++ b/t/db_dependent/Koha/Template.t @@ -0,0 +1,62 @@ +#!/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