Bugzilla – Attachment 113660 Details for
Bug 26791
Build Mojolicious controller replacement for export.pl
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 26791: Replace export.pl with export Mojolicious controller
Bug-26791-Replace-exportpl-with-export-Mojolicious.patch (text/plain), 20.19 KB, created by
David Cook
on 2020-11-16 11:56:17 UTC
(
hide
)
Description:
Bug 26791: Replace export.pl with export Mojolicious controller
Filename:
MIME Type:
Creator:
David Cook
Created:
2020-11-16 11:56:17 UTC
Size:
20.19 KB
patch
obsolete
>From 590b7f2f2b5e48f3df0161b11e9cb443fc538cde Mon Sep 17 00:00:00 2001 >From: David Cook <dcook@prosentient.com.au> >Date: Mon, 16 Nov 2020 09:59:59 +0000 >Subject: [PATCH] Bug 26791: Replace export.pl with export Mojolicious > controller > >--- > Koha/Auth.pm | 151 ++++++++++++++++++++ > Koha/Staff.pm | 85 +++++++++++ > Koha/Staff/Controller/Tools/Export.pm | 155 +++++++++++++++++++++ > Koha/Template.pm | 40 ++++++ > debian/templates/plack.psgi | 20 +++ > .../intranet-tmpl/prog/en/includes/tools-menu.inc | 2 +- > .../intranet-tmpl/prog/en/modules/tools/export.tt | 8 +- > .../prog/en/modules/tools/tools-home.tt | 2 +- > staff | 21 +++ > 9 files changed, 478 insertions(+), 6 deletions(-) > create mode 100644 Koha/Auth.pm > create mode 100644 Koha/Staff.pm > create mode 100644 Koha/Staff/Controller/Tools/Export.pm > create mode 100644 Koha/Template.pm > create mode 100755 staff > >diff --git a/Koha/Auth.pm b/Koha/Auth.pm >new file mode 100644 >index 0000000000..38e86d150c >--- /dev/null >+++ b/Koha/Auth.pm >@@ -0,0 +1,151 @@ >+package Koha::Auth; >+ >+use strict; >+use warnings; >+ >+use C4::Auth qw//; >+use C4::Context qw//; >+ >+=head2 authenticate >+ >+ my $user = Koha::Auth->authenticate({ >+ sessionID => $sessionID, >+ }); >+ >+Verifies that this user has an authenticated Koha session >+ >+=cut >+ >+#NOTE: This method requires that a Koha session exists >+sub authenticate { >+ my ($class,$args) = @_; >+ my ($auth_user,$auth_session,$auth_cookie); >+ my $sessionID = $args->{sessionID}; >+ if ($sessionID){ >+ my $session = C4::Auth::get_session($sessionID); >+ if ($session){ >+ my $id = $session->param('id'); >+ if ( $id ){ >+ my $patrons = Koha::Patrons->search({ userid => $id }); >+ if ($patrons->count){ >+ $auth_user = $patrons->next; >+ $auth_session = $session; >+ _set_userenv_compat({ session => $session }); >+ } >+ } >+ } >+ } >+ if ($auth_user){ >+ #FIXME: Check for timeout >+ } >+ #FIXME: Ideally, it would be nice to calculate patron authorizations at login time, >+ #rather than on each page load (like we do currently)... >+ return ($auth_user,$auth_session,$auth_cookie); >+} >+ >+#NOTE: Needed since C4::Context->userenv is so ubiquitous >+sub _set_userenv_compat { >+ my ($args) = @_; >+ my $session = $args->{session}; >+ if ($session){ >+ C4::Context->_new_userenv($session->param('id')); >+ C4::Context->set_userenv( >+ $session->param('number'), $session->param('id'), >+ $session->param('cardnumber'), $session->param('firstname'), >+ $session->param('surname'), $session->param('branch'), >+ $session->param('branchname'), $session->param('flags'), >+ $session->param('emailaddress'), $session->param('shibboleth'), >+ $session->param('desk_id'), $session->param('desk_name') >+ ); >+ } >+} >+ >+=head2 authorize >+ >+ my $flags = Koha::Auth->authorize({ >+ session => $session, >+ flagsrequired => { self_check => 'self_checkout_module' }, >+ }); >+ >+=cut >+ >+sub authorize { >+ my ($class,$args) = @_; >+ my $flags; >+ my $session = $args->{session}; >+ my $flagsrequired = $args->{flagsrequired}; >+ if ($session && $flagsrequired){ >+ my $userid = $session->param('id'); >+ if ($userid){ >+ $flags = C4::Auth::haspermission($userid,$flagsrequired); >+ } >+ } >+ return $flags; >+} >+ >+sub get_authz_from_flags { >+ my ($args) = @_; >+ my $flags = $args->{flags}; >+ my $authz; >+ >+ #FIXME: This contains a lot of copy/paste from C4::Auth >+ my $all_perms = C4::Auth::get_all_subpermissions(); >+ >+ if ($flags){ >+ if ( $flags->{superlibrarian} == 1 ){ >+ #NOTE: These are similar but slightly different to @flatroots... >+ my @perms = qw/ >+ circulate >+ catalogue >+ parameters >+ borrowers >+ permissions >+ reserveforothers >+ editcatalogue >+ updatecharges >+ acquisition >+ tools >+ editauthorities >+ serials >+ reports >+ staffaccess >+ plugins >+ coursereserves >+ clubs >+ ill >+ stockrotation >+ problem_reports >+ /; >+ foreach my $perm (@perms){ >+ $authz->{ "CAN_user_${perm}" } = 1; >+ } >+ foreach my $module ( keys %$all_perms ) { >+ foreach my $subperm ( keys %{ $all_perms->{$module} } ) { >+ $authz->{ "CAN_user_${module}_${subperm}" } = 1; >+ } >+ } >+ } >+ else { >+ foreach my $module ( keys %$all_perms ) { >+ if ( defined($flags->{$module}) && $flags->{$module} == 1 ) { >+ foreach my $subperm ( keys %{ $all_perms->{$module} } ) { >+ $authz->{ "CAN_user_${module}_${subperm}" } = 1; >+ } >+ } elsif ( ref( $flags->{$module} ) ) { >+ foreach my $subperm ( keys %{ $flags->{$module} } ) { >+ $authz->{ "CAN_user_${module}_${subperm}" } = 1; >+ } >+ } >+ } >+ foreach my $module ( keys %$flags ) { >+ if ( $flags->{$module} == 1 or ref( $flags->{$module} ) ) { >+ $authz->{ "CAN_user_$module" } = 1; >+ } >+ } >+ } >+ } >+ >+ return $authz; >+} >+ >+1; >diff --git a/Koha/Staff.pm b/Koha/Staff.pm >new file mode 100644 >index 0000000000..8654752292 >--- /dev/null >+++ b/Koha/Staff.pm >@@ -0,0 +1,85 @@ >+package Koha::Staff; >+ >+use Mojo::Base 'Mojolicious'; >+use Koha::Auth; >+use Koha::Template; >+use C4::Context; >+ >+sub startup { >+ my $self = shift; >+ >+ #FIXME: Move into a plugin? >+ $self->helper( >+ staff_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::get_authz_from_flags({ flags => $flags }); >+ return ($flags,$c->stash->{__koha__user__}); >+ } >+ else { >+ $c->render( text => 'Forbidden', status => 403 ); >+ return; >+ } >+ } >+ ); >+ #FIXME: Move into a plugin? >+ $self->helper( >+ prepare_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; >+ } >+ ); >+ >+ # 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; >+ 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 => '/', >+ } >+ ); >+ return 1; >+ } >+ else { >+ #FIXME: In future, redirect to a /login route >+ $c->redirect_to('/index.html'); >+ return; >+ } >+ }); >+ my $tools = $auth->under('tools'); >+ $tools->any(['GET','POST'] => '/:controller/:action' => { action => 'index' })->to(namespace => 'Koha::Staff::Controller::Tools'); >+} >+ >+1; >diff --git a/Koha/Staff/Controller/Tools/Export.pm b/Koha/Staff/Controller/Tools/Export.pm >new file mode 100644 >index 0000000000..1440652094 >--- /dev/null >+++ b/Koha/Staff/Controller/Tools/Export.pm >@@ -0,0 +1,155 @@ >+package Koha::Staff::Controller::Tools::Export; >+ >+use Mojo::Base 'Mojolicious::Controller'; >+ >+use Koha::Exporter::Record; >+use C4::Biblio qw//; >+use Encode; >+use Carp; >+ >+use Koha::ItemTypes; >+use Koha::Authority::Types; >+use Koha::Libraries; >+ >+use Koha::Auth; >+ >+sub index { >+ my $c = shift; >+ my ($flags,$loggedinuser) = $c->staff_authorize({ flagsrequired => { 'tools' => 'export_catalog' } }); >+ my $template = $c->prepare_template({ >+ template_filename => 'tools/export.tt', >+ interface => 'intranet', >+ }); >+ >+ #FIXME: This is for showing messages about the download... >+ my @messages = (); >+ $template->{VARS}->{messages} = \@messages; >+ >+ my $itemtypes = Koha::ItemTypes->search_with_localization; >+ $template->{VARS}->{itemtypes} = $itemtypes; >+ >+ my $authority_types = Koha::Authority::Types->search( {}, { order_by => ['authtypecode'] } ); >+ $template->{VARS}->{authority_types} = $authority_types; >+ >+ my $branch = $c->every_param('branch'); >+ my $libraries = Koha::Libraries->search_filtered({}, { order_by => ['branchname'] })->unblessed; >+ #NOTE: This will only work if we return to this action... >+ for my $library ( @$libraries ) { >+ $library->{selected} = 1 if grep { $library->{branchcode} eq $_ } @$branch; >+ } >+ $template->{VARS}->{libraries} = $libraries; >+ >+ my $backupdir = C4::Context->config('backupdir'); >+ if ( $flags->{superlibrarian} >+ && C4::Context->config('backup_db_via_tools') >+ && $backupdir >+ && -d $backupdir ) >+ { >+ $template->{VARS}->{'allow_db_export'} = 1; >+ $template->{VARS}->{'dbfiles'} = _getbackupfilelist( >+ { directory => "$backupdir", extension => 'sql' } ); >+ } >+ >+ if ( $flags->{superlibrarian} >+ && C4::Context->config('backup_conf_via_tools') >+ && $backupdir >+ && -d $backupdir ) >+ { >+ $template->{VARS}->{'allow_conf_export'} = 1; >+ $template->{VARS}->{'conffiles'} = _getbackupfilelist( >+ { directory => "$backupdir", extension => 'tar' } ); >+ } >+ >+ $c->render( text => $template->output ); >+} >+ >+sub _getbackupfilelist { >+ my $args = shift; >+ my $directory = $args->{directory}; >+ my $extension = $args->{extension}; >+ my @files; >+ >+ if ( opendir( my $dir, $directory ) ) { >+ while ( my $file = readdir($dir) ) { >+ next unless ( $file =~ m/\.$extension(\.(gz|bz2|xz))?/ ); >+ push @files, $file >+ if ( -f "$directory/$file" && -r "$directory/$file" ); >+ } >+ closedir($dir); >+ } >+ use Data::Dumper; >+ warn Dumper(\@files); >+ return \@files; >+} >+ >+ >+sub download { >+ my $c = shift; >+ my ($flags,$loggedinuser) = $c->staff_authorize({ flagsrequired => { 'tools' => 'export_catalog' } }); >+ >+ my $record_type = $c->param('record_type') || 'bibs'; #FIXME: Remove bibs? >+ my $backupdir = C4::Context->config('backupdir'); >+ >+ if ( $record_type eq 'bibs' or $record_type eq 'auths' ){ >+ #TODO: Refactor code from export.pl >+ } >+ elsif ( $record_type eq 'db' or $record_type eq 'conf' ){ >+ #TODO: Most of this code should go in a model module >+ if ( $flags->{superlibrarian} >+ and ( >+ $record_type eq 'db' and C4::Context->config('backup_db_via_tools') >+ or >+ $record_type eq 'conf' and C4::Context->config('backup_conf_via_tools') >+ ) >+ ) { >+ my $extension = $record_type eq 'db' ? 'sql' : 'tar'; >+ my $filename = $c->param('filename'); >+ $filename =~ s/(\r|\n)//; >+ my $fh = _get_backup_filehandle({ >+ directory => $backupdir, >+ extension => $extension, >+ filename => $filename, >+ }); >+ my $content_type = 'application/octet-stream'; >+ if ( $filename =~ m/\.gz$/ ){ >+ $content_type = 'application/x-gzip'; >+ } >+ elsif ( $filename =~ m/\.bz2$/ ){ >+ $content_type = 'application/x-bzip2'; >+ } >+ #FIXME: Add error handling >+ $c->res->headers->content_type($content_type); >+ $c->res->headers->content_disposition("attachment; filename=$filename;"); >+ my $drain; >+ $drain = sub { >+ my $c = shift; >+ read($fh,my $chunk, 64 * 1024); >+ if ($chunk){ >+ $c->write($chunk,$drain); >+ } >+ else { >+ $c->write(''); >+ } >+ }; >+ $c->$drain; >+ } >+ } >+} >+ >+#FIXME: Move this into a Koha::Exporter module >+sub _get_backup_filehandle { >+ my ($args) = @_; >+ my $directory = $args->{directory}; >+ my $extension = $args->{extension}; >+ my $filename = $args->{filename}; >+ >+ return unless ( $directory && -d $directory ); >+ return unless ( $filename =~ m/\.$extension(\.(gz|bz2|xz))?$/ ); >+ return if ( $filename =~ m#/# ); >+ $filename = "$directory/$filename"; >+ return unless ( -f $filename && -r $filename ); >+ return unless ( open( my $fh, '<', $filename ) ); >+ return $fh; >+} >+ >+1; >diff --git a/Koha/Template.pm b/Koha/Template.pm >new file mode 100644 >index 0000000000..fa0b629369 >--- /dev/null >+++ b/Koha/Template.pm >@@ -0,0 +1,40 @@ >+package Koha::Template; >+ >+use strict; >+use warnings; >+ >+use C4::Templates; >+ >+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->param('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: You could include all the syspref stuff here that exists in C4::Auth, >+ #but I rather avoid it, and have templates update to use the Koha.Preference mechanism instead. >+ } >+ } >+ return $template; >+} >+ >+1; >diff --git a/debian/templates/plack.psgi b/debian/templates/plack.psgi >index 99438c595a..fc20ed1f40 100644 >--- a/debian/templates/plack.psgi >+++ b/debian/templates/plack.psgi >@@ -67,6 +67,19 @@ my $apiv1 = builder { > $server->to_psgi_app; > }; > >+my $staff_interface = builder { >+ my $server = Mojo::Server::PSGI->new; >+ $server->build_app('Koha::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 { >@@ -98,4 +111,11 @@ builder { > } > $apiv1; > }; >+ mount '/intranet/staff' => builder { >+ if ( Log::Log4perl->get_logger('plack-intranet')->has_appenders ){ >+ enable 'Log4perl', category => 'plack-intranet'; >+ enable 'LogWarn'; >+ } >+ $staff_interface; >+ }; > }; >diff --git a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >index ba3f54a281..b0d7deddaa 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >+++ b/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc >@@ -72,7 +72,7 @@ > <li><a href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">Automatic item modifications by age</a></li> > [% END %] > [% IF ( CAN_user_tools_export_catalog ) %] >- <li><a href="/cgi-bin/koha/tools/export.pl">Export data</a></li> >+ <li><a href="/cgi-bin/koha/staff/tools/export">Export data</a></li> > [% END %] > [% IF ( CAN_user_tools_inventory ) %] > <li><a href="/cgi-bin/koha/tools/inventory.pl">Inventory</a></li> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt >index 4e9a992c04..f65cafce39 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt >@@ -48,7 +48,7 @@ > <strong>Note : The items are exported by this tool unless specified.</strong> > </p> > >-<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/tools/export.pl"> >+<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/staff/tools/export/download"> > <fieldset class="rows"> > <legend> Select records to export </legend> > <ol> >@@ -167,7 +167,7 @@ > </div> > > <div id="auths"> >-<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/tools/export.pl"> >+<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/staff/tools/export/download"> > <fieldset class="rows"> > <legend> Select records to export </legend> > <ol><li> >@@ -229,7 +229,7 @@ > > [% IF ( allow_db_export ) %] > <div id="db"> >-<form method="post" action="/cgi-bin/koha/tools/export.pl"> >+<form method="post" action="/cgi-bin/koha/staff/tools/export/download"> > <p><strong>Note : This export file will be very large, and is generated nightly.</strong></p> > <fieldset class="rows"> > <legend> Choose a file </legend> >@@ -255,7 +255,7 @@ > > [% IF ( allow_conf_export ) %] > <div id="conf"> >-<form method="post" action="/cgi-bin/koha/tools/export.pl"> >+<form method="post" action="/cgi-bin/koha/staff/tools/export/download"> > <p><strong>Note : This export file will be very large, and is generated nightly.</strong></p> > <fieldset class="rows"> > <legend> Choose a file </legend> >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >index c8d7f7d567..61a42c3e26 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt >@@ -195,7 +195,7 @@ > [% END %] > > [% IF ( CAN_user_tools_export_catalog ) %] >- <dt><a href="/cgi-bin/koha/tools/export.pl">Export data</a></dt> >+ <dt><a href="/cgi-bin/koha/staff/tools/export">Export data</a></dt> > <dd>Export bibliographic, holdings, and authority records</dd> > [% END %] > >diff --git a/staff b/staff >new file mode 100755 >index 0000000000..f5b4a97808 >--- /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 <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+ >+require Mojolicious::Commands; >+Mojolicious::Commands->start_app('Koha::Staff'); >-- >2.11.0
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 26791
: 113660 |
114587