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

(-)a/Koha/Auth.pm (+151 lines)
Line 0 Link Here
1
package Koha::Auth;
2
3
use strict;
4
use warnings;
5
6
use C4::Auth qw//;
7
use C4::Context qw//;
8
9
=head2 authenticate
10
11
    my $user = Koha::Auth->authenticate({
12
        sessionID => $sessionID,
13
    });
14
15
Verifies that this user has an authenticated Koha session
16
17
=cut
18
19
#NOTE: This method requires that a Koha session exists
20
sub authenticate {
21
    my ($class,$args) = @_;
22
    my ($auth_user,$auth_session,$auth_cookie);
23
    my $sessionID = $args->{sessionID};
24
    if ($sessionID){
25
        my $session = C4::Auth::get_session($sessionID);
26
        if ($session){
27
            my $id = $session->param('id');
28
            if ( $id ){
29
                my $patrons = Koha::Patrons->search({ userid => $id });
30
                if ($patrons->count){
31
                    $auth_user = $patrons->next;
32
                    $auth_session = $session;
33
                    _set_userenv_compat({ session => $session });
34
                }
35
            }
36
        }
37
    }
38
    if ($auth_user){
39
        #FIXME: Check for timeout
40
    }
41
    #FIXME: Ideally, it would be nice to calculate patron authorizations at login time,
42
    #rather than on each page load (like we do currently)...
43
    return ($auth_user,$auth_session,$auth_cookie);
44
}
45
46
#NOTE: Needed since C4::Context->userenv is so ubiquitous
47
sub _set_userenv_compat {
48
    my ($args) = @_;
49
    my $session = $args->{session};
50
    if ($session){
51
        C4::Context->_new_userenv($session->param('id'));
52
        C4::Context->set_userenv(
53
            $session->param('number'),       $session->param('id'),
54
            $session->param('cardnumber'),   $session->param('firstname'),
55
            $session->param('surname'),      $session->param('branch'),
56
            $session->param('branchname'),   $session->param('flags'),
57
            $session->param('emailaddress'), $session->param('shibboleth'),
58
            $session->param('desk_id'),      $session->param('desk_name')
59
        );
60
    }
61
}
62
63
=head2 authorize
64
65
    my $flags = Koha::Auth->authorize({
66
        session => $session,
67
        flagsrequired => { self_check => 'self_checkout_module' },
68
    });
69
70
=cut
71
72
sub authorize {
73
    my ($class,$args) = @_;
74
    my $flags;
75
    my $session = $args->{session};
76
    my $flagsrequired = $args->{flagsrequired};
77
    if ($session && $flagsrequired){
78
        my $userid = $session->param('id');
79
        if ($userid){
80
            $flags = C4::Auth::haspermission($userid,$flagsrequired);
81
        }
82
    }
83
    return $flags;
84
}
85
86
sub get_authz_from_flags {
87
    my ($args) = @_;
88
    my $flags = $args->{flags};
89
    my $authz;
90
91
    #FIXME: This contains a lot of copy/paste from C4::Auth
92
    my $all_perms = C4::Auth::get_all_subpermissions();
93
94
    if ($flags){
95
        if ( $flags->{superlibrarian} == 1 ){
96
            #NOTE: These are similar but slightly different to @flatroots...
97
            my @perms = qw/
98
                circulate
99
                catalogue
100
                parameters
101
                borrowers
102
                permissions
103
                reserveforothers
104
                editcatalogue
105
                updatecharges
106
                acquisition
107
                tools
108
                editauthorities
109
                serials
110
                reports
111
                staffaccess
112
                plugins
113
                coursereserves
114
                clubs
115
                ill
116
                stockrotation
117
                problem_reports
118
            /;
119
            foreach my $perm (@perms){
120
                $authz->{ "CAN_user_${perm}" } = 1;
121
            }
122
            foreach my $module ( keys %$all_perms ) {
123
                foreach my $subperm ( keys %{ $all_perms->{$module} } ) {
124
                    $authz->{ "CAN_user_${module}_${subperm}" } = 1;
125
                }
126
            }
127
        }
128
        else {
129
            foreach my $module ( keys %$all_perms ) {
130
                if ( defined($flags->{$module}) && $flags->{$module} == 1 ) {
131
                    foreach my $subperm ( keys %{ $all_perms->{$module} } ) {
132
                        $authz->{ "CAN_user_${module}_${subperm}" } = 1;
133
                    }
134
                } elsif ( ref( $flags->{$module} ) ) {
135
                    foreach my $subperm ( keys %{ $flags->{$module} } ) {
136
                        $authz->{ "CAN_user_${module}_${subperm}" } = 1;
137
                    }
138
                }
139
            }
140
            foreach my $module ( keys %$flags ) {
141
                if ( $flags->{$module} == 1 or ref( $flags->{$module} ) ) {
142
                    $authz->{ "CAN_user_$module" } = 1;
143
                }
144
            }
145
        }
146
    }
147
148
    return $authz;
149
}
150
151
1;
(-)a/Koha/Staff.pm (+85 lines)
Line 0 Link Here
1
package Koha::Staff;
2
3
use Mojo::Base 'Mojolicious';
4
use Koha::Auth;
5
use Koha::Template;
6
use C4::Context;
7
8
sub startup {
9
    my $self = shift;
10
11
    #FIXME: Move into a plugin?
12
    $self->helper(
13
        staff_authorize => sub {
14
            my ($c,$args) = @_;
15
            my $session = $c->stash->{__koha_session__};
16
            my $flags = Koha::Auth->authorize({
17
                session => $session,
18
                flagsrequired => $args->{flagsrequired},
19
            });
20
            if($flags){
21
                $c->stash->{__koha_flags__} = $flags;
22
                $c->stash->{__koha_authz__} = Koha::Auth::get_authz_from_flags({ flags => $flags });
23
                return ($flags,$c->stash->{__koha__user__});
24
            }
25
            else {
26
                $c->render( text => 'Forbidden', status => 403 );
27
                return;
28
            }
29
        }
30
    );
31
    #FIXME: Move into a plugin?
32
    $self->helper(
33
        prepare_template => sub {
34
            my ($c,$args) = @_;
35
            my $template_filename = $args->{template_filename};
36
            my $interface = $args->{interface};
37
            my $template = Koha::Template::prepare_template({
38
                template_filename => $template_filename,
39
                interface => $interface,
40
                koha_session => $c->stash->{__koha_session__},
41
                koha_user => $c->stash->{__koha_user__},
42
                koha_authz => $c->stash->{__koha_authz__},
43
            });
44
            return $template;
45
        }
46
    );
47
48
    # Router
49
    my $r = $self->routes;
50
51
    #NOTE: The /login route is public and does not require authentication
52
    #FIXME: Implement a Mojolicious login route
53
    #$r->get('/login')->to( controller => 'login', action => 'index' );
54
55
    #NOTE: All other routes require authentication
56
    my $auth = $r->under('/' => sub {
57
        my $c = shift;
58
        my $sessionID = $c->cookie('CGISESSID');
59
        my ($user,$session) = Koha::Auth->authenticate({
60
            sessionID => $sessionID,
61
        });
62
        if ($user && $session){
63
            $c->stash->{__koha_user__} = $user;
64
            $c->stash->{__koha_session__} = $session;
65
            $c->cookie(
66
                'CGISESSID' => $session->id,
67
                {
68
                    httponly => 1,
69
                    secure => ( C4::Context->https_enabled() ? 1 : 0 ),
70
                    path => '/',
71
                }
72
            );
73
            return 1;
74
        }
75
        else {
76
            #FIXME: In future, redirect to a /login route
77
            $c->redirect_to('/index.html');
78
            return;
79
        }
80
    });
81
    my $tools = $auth->under('tools');
82
    $tools->any(['GET','POST'] => '/:controller/:action' => { action => 'index' })->to(namespace => 'Koha::Staff::Controller::Tools');
83
}
84
85
1;
(-)a/Koha/Staff/Controller/Tools/Export.pm (+155 lines)
Line 0 Link Here
1
package Koha::Staff::Controller::Tools::Export;
2
3
use Mojo::Base 'Mojolicious::Controller';
4
5
use Koha::Exporter::Record;
6
use C4::Biblio qw//;
7
use Encode;
8
use Carp;
9
10
use Koha::ItemTypes;
11
use Koha::Authority::Types;
12
use Koha::Libraries;
13
14
use Koha::Auth;
15
16
sub index {
17
    my $c = shift;
18
    my ($flags,$loggedinuser) = $c->staff_authorize({ flagsrequired => { 'tools' => 'export_catalog' } });
19
    my $template = $c->prepare_template({
20
        template_filename => 'tools/export.tt',
21
        interface => 'intranet',
22
    });
23
24
    #FIXME: This is for showing messages about the download...
25
    my @messages = ();
26
    $template->{VARS}->{messages} = \@messages;
27
28
    my $itemtypes = Koha::ItemTypes->search_with_localization;
29
	$template->{VARS}->{itemtypes} = $itemtypes;
30
31
    my $authority_types = Koha::Authority::Types->search( {}, { order_by => ['authtypecode'] } );
32
	$template->{VARS}->{authority_types} = $authority_types;
33
34
    my $branch = $c->every_param('branch');
35
    my $libraries =  Koha::Libraries->search_filtered({}, { order_by => ['branchname'] })->unblessed;
36
    #NOTE: This will only work if we return to this action...
37
    for my $library ( @$libraries ) {
38
        $library->{selected} = 1 if grep { $library->{branchcode} eq $_ } @$branch;
39
    }
40
	$template->{VARS}->{libraries} = $libraries;
41
42
	my $backupdir         = C4::Context->config('backupdir');
43
    if (   $flags->{superlibrarian}
44
        && C4::Context->config('backup_db_via_tools')
45
        && $backupdir
46
        && -d $backupdir )
47
    {
48
        $template->{VARS}->{'allow_db_export'} = 1;
49
        $template->{VARS}->{'dbfiles'}         = _getbackupfilelist(
50
            { directory => "$backupdir", extension => 'sql' } );
51
    }
52
53
    if (   $flags->{superlibrarian}
54
        && C4::Context->config('backup_conf_via_tools')
55
        && $backupdir
56
        && -d $backupdir )
57
    {
58
        $template->{VARS}->{'allow_conf_export'} = 1;
59
        $template->{VARS}->{'conffiles'}         = _getbackupfilelist(
60
            { directory => "$backupdir", extension => 'tar' } );
61
    }
62
63
    $c->render( text => $template->output );
64
}
65
66
sub _getbackupfilelist {
67
    my $args      = shift;
68
    my $directory = $args->{directory};
69
    my $extension = $args->{extension};
70
    my @files;
71
72
    if ( opendir( my $dir, $directory ) ) {
73
        while ( my $file = readdir($dir) ) {
74
            next unless ( $file =~ m/\.$extension(\.(gz|bz2|xz))?/ );
75
            push @files, $file
76
              if ( -f "$directory/$file" && -r "$directory/$file" );
77
        }
78
        closedir($dir);
79
    }
80
    use Data::Dumper;
81
    warn Dumper(\@files);
82
    return \@files;
83
}
84
85
86
sub download {
87
    my $c = shift;
88
    my ($flags,$loggedinuser) = $c->staff_authorize({ flagsrequired => { 'tools' => 'export_catalog' } });
89
90
	my $record_type = $c->param('record_type') || 'bibs'; #FIXME: Remove bibs?
91
	my $backupdir         = C4::Context->config('backupdir');
92
93
    if ( $record_type eq 'bibs' or $record_type eq 'auths' ){
94
        #TODO: Refactor code from export.pl
95
    }
96
    elsif ( $record_type eq 'db' or $record_type eq 'conf' ){
97
        #TODO: Most of this code should go in a model module
98
		if ( $flags->{superlibrarian}
99
		and (
100
                    $record_type eq 'db' and C4::Context->config('backup_db_via_tools')
101
                 or
102
                    $record_type eq 'conf' and C4::Context->config('backup_conf_via_tools')
103
            )
104
        ) {
105
			my $extension = $record_type eq 'db' ? 'sql' : 'tar';
106
			my $filename = $c->param('filename');
107
			$filename =~ s/(\r|\n)//;
108
			my $fh = _get_backup_filehandle({
109
				directory => $backupdir,
110
				extension => $extension,
111
				filename => $filename,
112
			});
113
            my $content_type = 'application/octet-stream';
114
            if ( $filename =~ m/\.gz$/ ){
115
                $content_type = 'application/x-gzip';
116
            }
117
            elsif ( $filename =~ m/\.bz2$/ ){
118
                $content_type = 'application/x-bzip2';
119
            }
120
            #FIXME: Add error handling
121
            $c->res->headers->content_type($content_type);
122
            $c->res->headers->content_disposition("attachment; filename=$filename;");
123
			my $drain;
124
			$drain = sub {
125
				my $c = shift;
126
				read($fh,my $chunk, 64 * 1024);
127
				if ($chunk){
128
					$c->write($chunk,$drain);
129
				}
130
				else {
131
					$c->write('');
132
				}
133
			};
134
			$c->$drain;
135
		}
136
    }
137
}
138
139
#FIXME: Move this into a Koha::Exporter module
140
sub _get_backup_filehandle {
141
	my ($args) = @_;
142
    my $directory = $args->{directory};
143
    my $extension = $args->{extension};
144
    my $filename  = $args->{filename};
145
146
    return unless ( $directory && -d $directory );
147
    return unless ( $filename =~ m/\.$extension(\.(gz|bz2|xz))?$/ );
148
    return if ( $filename =~ m#/# );
149
    $filename = "$directory/$filename";
150
    return unless ( -f $filename && -r $filename );
151
    return unless ( open( my $fh, '<', $filename ) );
152
	return $fh;
153
}
154
155
1;
(-)a/Koha/Template.pm (+40 lines)
Line 0 Link Here
1
package Koha::Template;
2
3
use strict;
4
use warnings;
5
6
use C4::Templates;
7
8
sub prepare_template {
9
    my ($args) = @_;
10
    my $template;
11
    my $session = $args->{koha_session};
12
    my $user = $args->{koha_user};
13
    my $authz = $args->{koha_authz};
14
    my $template_filename = $args->{template_filename};
15
    my $interface = $args->{interface};
16
    if ($template_filename && $interface){
17
        $template = C4::Templates::gettemplate($template_filename,$interface);
18
        if ($template){
19
            if ($session){
20
                $template->{VARS}->{ sessionID } = $session->param('id');
21
            }
22
            if ($user){
23
                $template->{VARS}->{ logged_in_user } = $user;
24
                $template->{VARS}->{ loggedinusernumber } = $user->borrowernumber;
25
                $template->{VARS}->{ loggedinusername } = $user->userid;
26
            }
27
            if ($authz){
28
                foreach my $key ( keys %$authz ){
29
                    $template->{VARS}->{ $key } = $authz->{$key};
30
                }
31
            }
32
33
            #NOTE: You could include all the syspref stuff here that exists in C4::Auth,
34
            #but I rather avoid it, and have templates update to use the Koha.Preference mechanism instead.
35
        }
36
    }
37
    return $template;
38
}
39
40
1;
(-)a/debian/templates/plack.psgi (+20 lines)
Lines 67-72 my $apiv1 = builder { Link Here
67
    $server->to_psgi_app;
67
    $server->to_psgi_app;
68
};
68
};
69
69
70
my $staff_interface = builder {
71
    my $server = Mojo::Server::PSGI->new;
72
    $server->build_app('Koha::Staff');
73
    my $app = $server->app;
74
    $app->hook( before_dispatch => sub {
75
        my $c = shift;
76
        #NOTE: Rewrite the base path to strip off the mount prefix
77
        my $path = $c->req->url->base->path(Mojo::Path->new);
78
79
    });
80
    $server->to_psgi_app;
81
};
82
70
Koha::Logger->_init;
83
Koha::Logger->_init;
71
84
72
builder {
85
builder {
Lines 98-101 builder { Link Here
98
        }
111
        }
99
        $apiv1;
112
        $apiv1;
100
    };
113
    };
114
    mount '/intranet/staff' => builder {
115
        if ( Log::Log4perl->get_logger('plack-intranet')->has_appenders ){
116
            enable 'Log4perl', category => 'plack-intranet';
117
            enable 'LogWarn';
118
        }
119
        $staff_interface;
120
    };
101
};
121
};
(-)a/koha-tmpl/intranet-tmpl/prog/en/includes/tools-menu.inc (-1 / +1 lines)
Lines 72-78 Link Here
72
      <li><a href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">Automatic item modifications by age</a></li>
72
      <li><a href="/cgi-bin/koha/tools/automatic_item_modification_by_age.pl">Automatic item modifications by age</a></li>
73
    [% END %]
73
    [% END %]
74
    [% IF ( CAN_user_tools_export_catalog ) %]
74
    [% IF ( CAN_user_tools_export_catalog ) %]
75
    <li><a href="/cgi-bin/koha/tools/export.pl">Export data</a></li>
75
    <li><a href="/cgi-bin/koha/staff/tools/export">Export data</a></li>
76
    [% END %]
76
    [% END %]
77
    [% IF ( CAN_user_tools_inventory ) %]
77
    [% IF ( CAN_user_tools_inventory ) %]
78
        <li><a href="/cgi-bin/koha/tools/inventory.pl">Inventory</a></li>
78
        <li><a href="/cgi-bin/koha/tools/inventory.pl">Inventory</a></li>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/export.tt (-4 / +4 lines)
Lines 48-54 Link Here
48
    <strong>Note : The items are exported by this tool unless specified.</strong>
48
    <strong>Note : The items are exported by this tool unless specified.</strong>
49
</p>
49
</p>
50
50
51
<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/tools/export.pl">
51
<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/staff/tools/export/download">
52
    <fieldset class="rows">
52
    <fieldset class="rows">
53
    <legend> Select records to export </legend>
53
    <legend> Select records to export </legend>
54
        <ol>
54
        <ol>
Lines 167-173 Link Here
167
</div>
167
</div>
168
168
169
<div id="auths">
169
<div id="auths">
170
<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/tools/export.pl">
170
<form method="post" enctype="multipart/form-data" action="/cgi-bin/koha/staff/tools/export/download">
171
    <fieldset class="rows">
171
    <fieldset class="rows">
172
    <legend> Select records to export </legend>
172
    <legend> Select records to export </legend>
173
        <ol><li>
173
        <ol><li>
Lines 229-235 Link Here
229
229
230
[% IF ( allow_db_export ) %]
230
[% IF ( allow_db_export ) %]
231
<div id="db">
231
<div id="db">
232
<form method="post" action="/cgi-bin/koha/tools/export.pl">
232
<form method="post" action="/cgi-bin/koha/staff/tools/export/download">
233
    <p><strong>Note : This export file will be very large, and is generated nightly.</strong></p>
233
    <p><strong>Note : This export file will be very large, and is generated nightly.</strong></p>
234
    <fieldset class="rows">
234
    <fieldset class="rows">
235
    <legend> Choose a file </legend>
235
    <legend> Choose a file </legend>
Lines 255-261 Link Here
255
255
256
[% IF ( allow_conf_export ) %]
256
[% IF ( allow_conf_export ) %]
257
<div id="conf">
257
<div id="conf">
258
<form method="post" action="/cgi-bin/koha/tools/export.pl">
258
<form method="post" action="/cgi-bin/koha/staff/tools/export/download">
259
    <p><strong>Note : This export file will be very large, and is generated nightly.</strong></p>
259
    <p><strong>Note : This export file will be very large, and is generated nightly.</strong></p>
260
    <fieldset class="rows">
260
    <fieldset class="rows">
261
    <legend> Choose a file </legend>
261
    <legend> Choose a file </legend>
(-)a/koha-tmpl/intranet-tmpl/prog/en/modules/tools/tools-home.tt (-1 / +1 lines)
Lines 195-201 Link Here
195
    [% END %]
195
    [% END %]
196
196
197
    [% IF ( CAN_user_tools_export_catalog ) %]
197
    [% IF ( CAN_user_tools_export_catalog ) %]
198
    <dt><a href="/cgi-bin/koha/tools/export.pl">Export data</a></dt>
198
    <dt><a href="/cgi-bin/koha/staff/tools/export">Export data</a></dt>
199
    <dd>Export bibliographic, holdings, and authority records</dd>
199
    <dd>Export bibliographic, holdings, and authority records</dd>
200
    [% END %]
200
    [% END %]
201
201
(-)a/staff (-1 / +21 lines)
Line 0 Link Here
0
- 
1
#!/usr/bin/perl
2
3
# This file is part of Koha.
4
#
5
# Koha is free software; you can redistribute it and/or modify it
6
# under the terms of the GNU General Public License as published by
7
# the Free Software Foundation; either version 3 of the License, or
8
# (at your option) any later version.
9
#
10
# Koha is distributed in the hope that it will be useful, but
11
# WITHOUT ANY WARRANTY; without even the implied warranty of
12
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
# GNU General Public License for more details.
14
#
15
# You should have received a copy of the GNU General Public License
16
# along with Koha; if not, see <http://www.gnu.org/licenses>.
17
18
use Modern::Perl;
19
20
require Mojolicious::Commands;
21
Mojolicious::Commands->start_app('Koha::Staff');

Return to bug 26791