[MT2343] Renamed Quit button Cancel, and removed the table in delete confirm
[koha.git] / installer / InstallAuth.pm
blob2b2ccd5b895e8d40e20fe09b8ad322a18c14853c
1 # -*- tab-width: 8 -*-
2 # NOTE: This file uses 8-character tabs; do not change the tab size!
4 package InstallAuth;
6 # Copyright 2000-2002 Katipo Communications
8 # This file is part of Koha.
10 # Koha is free software; you can redistribute it and/or modify it under the
11 # terms of the GNU General Public License as published by the Free Software
12 # Foundation; either version 2 of the License, or (at your option) any later
13 # version.
15 # Koha is distributed in the hope that it will be useful, but WITHOUT ANY
16 # WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
17 # A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19 # You should have received a copy of the GNU General Public License along with
20 # Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
21 # Suite 330, Boston, MA 02111-1307 USA
23 use strict;
24 use Digest::MD5 qw(md5_base64);
26 require Exporter;
27 use C4::Context;
28 use C4::Output;
29 use C4::Koha;
30 use CGI::Session;
32 use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS);
34 # set the version for version checking
35 $VERSION = 3.00;
37 =head1 NAME
39 InstallAuth - Authenticates Koha users for Install process
41 =head1 SYNOPSIS
43 use CGI;
44 use InstallAuth;
45 use C4::Output;
47 my $query = new CGI;
49 my ($template, $borrowernumber, $cookie)
50 = get_template_and_user({template_name => "opac-main.tmpl",
51 query => $query,
52 type => "opac",
53 authnotrequired => 1,
54 flagsrequired => {borrow => 1},
55 });
57 output_html_with_http_headers $query, $cookie, $template->output;
59 =head1 DESCRIPTION
61 The main function of this module is to provide
62 authentification. However the get_template_and_user function has
63 been provided so that a users login information is passed along
64 automatically. This gets loaded into the template.
65 This package is different from C4::Auth in so far as
66 C4::Auth uses many preferences which are supposed NOT to be obtainable when installing the database.
68 As in C4::Auth, Authentication is based on cookies.
70 =head1 FUNCTIONS
72 =over 2
74 =cut
76 @ISA = qw(Exporter);
77 @EXPORT = qw(
78 &checkauth
79 &get_template_and_user
82 =item get_template_and_user
84 my ($template, $borrowernumber, $cookie)
85 = get_template_and_user({template_name => "opac-main.tmpl",
86 query => $query,
87 type => "opac",
88 authnotrequired => 1,
89 flagsrequired => {borrow => 1},
90 });
92 This call passes the C<query>, C<flagsrequired> and C<authnotrequired>
93 to C<&checkauth> (in this module) to perform authentification.
94 See C<&checkauth> for an explanation of these parameters.
96 The C<template_name> is then used to find the correct template for
97 the page. The authenticated users details are loaded onto the
98 template in the HTML::Template LOOP variable C<USER_INFO>. Also the
99 C<sessionID> is passed to the template. This can be used in templates
100 if cookies are disabled. It needs to be put as and input to every
101 authenticated page.
103 More information on the C<gettemplate> sub can be found in the
104 Output.pm module.
106 =cut
108 sub get_template_and_user {
109 my $in = shift;
110 my $query = $in->{'query'};
111 my $language = $query->cookie('KohaOpacLanguage');
112 my $path =
113 C4::Context->config('intrahtdocs') . "/prog/"
114 . ( $language ? $language : "en" );
115 my $template = HTML::Template::Pro->new(
116 filename => "$path/modules/" . $in->{template_name},
117 die_on_bad_params => 1,
118 global_vars => 1,
119 case_sensitive => 1,
120 path => ["$path/includes"]
123 my ( $user, $cookie, $sessionID, $flags ) = checkauth(
124 $in->{'query'},
125 $in->{'authnotrequired'},
126 $in->{'flagsrequired'},
127 $in->{'type'}
130 # use Data::Dumper;warn "utilisateur $user cookie : ".Dumper($cookie);
132 my $borrowernumber;
133 if ($user) {
134 $template->param( loggedinusername => $user );
135 $template->param( sessionID => $sessionID );
137 # We are going to use the $flags returned by checkauth
138 # to create the template's parameters that will indicate
139 # which menus the user can access.
140 if ( ( $flags && $flags->{superlibrarian} == 1 ) ) {
141 $template->param( CAN_user_circulate => 1 );
142 $template->param( CAN_user_catalogue => 1 );
143 $template->param( CAN_user_parameters => 1 );
144 $template->param( CAN_user_borrowers => 1 );
145 $template->param( CAN_user_permission => 1 );
146 $template->param( CAN_user_reserveforothers => 1 );
147 $template->param( CAN_user_borrow => 1 );
148 $template->param( CAN_user_editcatalogue => 1 );
149 $template->param( CAN_user_updatecharges => 1 );
150 $template->param( CAN_user_acquisition => 1 );
151 $template->param( CAN_user_management => 1 );
152 $template->param( CAN_user_tools => 1 );
153 $template->param( CAN_user_editauthorities => 1 );
154 $template->param( CAN_user_serials => 1 );
155 $template->param( CAN_user_reports => 1 );
158 return ( $template, $borrowernumber, $cookie );
161 =item checkauth
163 ($userid, $cookie, $sessionID) = &checkauth($query, $noauth, $flagsrequired, $type);
165 Verifies that the user is authorized to run this script. If
166 the user is authorized, a (userid, cookie, session-id, flags)
167 quadruple is returned. If the user is not authorized but does
168 not have the required privilege (see $flagsrequired below), it
169 displays an error page and exits. Otherwise, it displays the
170 login page and exits.
172 Note that C<&checkauth> will return if and only if the user
173 is authorized, so it should be called early on, before any
174 unfinished operations (e.g., if you've opened a file, then
175 C<&checkauth> won't close it for you).
177 C<$query> is the CGI object for the script calling C<&checkauth>.
179 The C<$noauth> argument is optional. If it is set, then no
180 authorization is required for the script.
182 C<&checkauth> fetches user and session information from C<$query> and
183 ensures that the user is authorized to run scripts that require
184 authorization.
186 The C<$flagsrequired> argument specifies the required privileges
187 the user must have if the username and password are correct.
188 It should be specified as a reference-to-hash; keys in the hash
189 should be the "flags" for the user, as specified in the Members
190 intranet module. Any key specified must correspond to a "flag"
191 in the userflags table. E.g., { circulate => 1 } would specify
192 that the user must have the "circulate" privilege in order to
193 proceed. To make sure that access control is correct, the
194 C<$flagsrequired> parameter must be specified correctly.
196 The C<$type> argument specifies whether the template should be
197 retrieved from the opac or intranet directory tree. "opac" is
198 assumed if it is not specified; however, if C<$type> is specified,
199 "intranet" is assumed if it is not "opac".
201 If C<$query> does not have a valid session ID associated with it
202 (i.e., the user has not logged in) or if the session has expired,
203 C<&checkauth> presents the user with a login page (from the point of
204 view of the original script, C<&checkauth> does not return). Once the
205 user has authenticated, C<&checkauth> restarts the original script
206 (this time, C<&checkauth> returns).
208 The login page is provided using a HTML::Template, which is set in the
209 systempreferences table or at the top of this file. The variable C<$type>
210 selects which template to use, either the opac or the intranet
211 authentification template.
213 C<&checkauth> returns a user ID, a cookie, and a session ID. The
214 cookie should be sent back to the browser; it verifies that the user
215 has authenticated.
217 =cut
219 sub checkauth {
220 my $query = shift;
222 # $authnotrequired will be set for scripts which will run without authentication
223 my $authnotrequired = shift;
224 my $flagsrequired = shift;
225 my $type = shift;
226 $type = 'intranet' unless $type;
228 my $dbh = C4::Context->dbh();
229 my $template_name;
230 $template_name = "installer/auth.tmpl";
232 # state variables
233 my $loggedin = 0;
234 my %info;
235 my ( $userid, $cookie, $sessionID, $flags, $envcookie );
236 my $logout = $query->param('logout.x');
237 if ( $sessionID = $query->cookie("CGISESSID") ) {
238 C4::Context->_new_userenv($sessionID);
239 my $session =
240 new CGI::Session( "driver:File;serializer:yaml", $sessionID,
241 { Directory => '/tmp' } );
242 if ( $session->param('cardnumber') ) {
243 C4::Context::set_userenv(
244 $session->param('number'),
245 $session->param('id'),
246 $session->param('cardnumber'),
247 $session->param('firstname'),
248 $session->param('surname'),
249 $session->param('branch'),
250 $session->param('branchname'),
251 $session->param('flags'),
252 $session->param('emailaddress'),
253 $session->param('branchprinter')
255 $cookie = $query->cookie( CGISESSID => $session->id );
256 $loggedin = 1;
257 $userid = $session->param('cardnumber');
259 my ( $ip, $lasttime );
261 if ($logout) {
263 # voluntary logout the user
264 C4::Context->_unset_userenv($sessionID);
265 $sessionID = undef;
266 $userid = undef;
267 open L, ">>/tmp/sessionlog";
268 my $time = localtime( time() );
269 printf L "%20s from %16s logged out at %30s (manually).\n", $userid,
270 $ip, $time;
271 close L;
274 unless ($userid) {
275 my $session =
276 new CGI::Session( "driver:File;serializer:yaml", undef, { Directory => '/tmp' } );
277 $sessionID = $session->id;
278 $userid = $query->param('userid');
279 C4::Context->_new_userenv($sessionID);
280 my $password = $query->param('password');
281 C4::Context->_new_userenv($sessionID);
282 my ( $return, $cardnumber ) = checkpw( $userid, $password );
283 if ($return) {
284 $loggedin = 1;
285 open L, ">>/tmp/sessionlog";
286 my $time = localtime( time() );
287 printf L "%20s from %16s logged in at %30s.\n", $userid,
288 $ENV{'REMOTE_ADDR'}, $time;
289 close L;
290 $cookie = $query->cookie( CGISESSID => $sessionID );
291 if ( $return == 2 ) {
293 #Only superlibrarian should have access to this page.
294 #Since if it is a user, it is supposed that there is a borrower table
295 #And thus that data structure is loaded.
296 my $hash = C4::Context::set_userenv(
297 0, 0,
298 C4::Context->config('user'), C4::Context->config('user'),
299 C4::Context->config('user'), "",
300 "NO_LIBRARY_SET", 1,
303 $session->param( 'number', 0 );
304 $session->param( 'id', C4::Context->config('user') );
305 $session->param( 'cardnumber', C4::Context->config('user') );
306 $session->param( 'firstname', C4::Context->config('user') );
307 $session->param( 'surname', C4::Context->config('user'), );
308 $session->param( 'branch', 'NO_LIBRARY_SET' );
309 $session->param( 'branchname', 'NO_LIBRARY_SET' );
310 $session->param( 'flags', 1 );
311 $session->param( 'emailaddress',
312 C4::Context->preference('KohaAdminEmailAddress') );
313 $session->param( 'ip', $session->remote_addr() );
314 $session->param( 'lasttime', time() );
315 $userid = C4::Context->config('user');
318 else {
319 if ($userid) {
320 $info{'invalid_username_or_password'} = 1;
321 C4::Context->_unset_userenv($sessionID);
326 # finished authentification, now respond
327 if ($loggedin) {
329 # successful login
330 unless ($cookie) {
331 $cookie = $query->cookie(
332 -name => 'CGISESSID',
333 -value => '',
334 -expires => ''
337 if ($envcookie) {
338 return ( $userid, [ $cookie, $envcookie ], $sessionID, $flags );
340 else {
341 return ( $userid, $cookie, $sessionID, $flags );
345 # else we have a problem...
346 # get the inputs from the incoming query
347 my @inputs = ();
348 foreach my $name ( param $query) {
349 (next) if ( $name eq 'userid' || $name eq 'password' );
350 my $value = $query->param($name);
351 push @inputs, { name => $name, value => $value };
354 my $path =
355 C4::Context->config('intrahtdocs') . "/prog/"
356 . ( $query->param('language') ? $query->param('language') : "en" );
357 my $template = HTML::Template::Pro->new(
358 filename => "$path/modules/$template_name",
359 die_on_bad_params => 1,
360 global_vars => 1,
361 case_sensitive => 1,
362 path => ["$path/includes"]
364 $template->param(
365 INPUTS => \@inputs,
368 $template->param( login => 1 );
369 $template->param( loginprompt => 1 ) unless $info{'nopermission'};
371 my $self_url = $query->url( -absolute => 1 );
372 $template->param( url => $self_url, );
373 $template->param( \%info );
374 $cookie = $query->cookie(
375 -name => 'CGISESSID',
376 -value => $sessionID,
377 -expires => ''
379 print $query->header(
380 -type => 'text/html; charset=utf-8',
381 -cookie => $cookie
383 $template->output;
384 exit;
387 sub checkpw {
389 my ( $userid, $password ) = @_;
391 if ( $userid
392 && $userid eq C4::Context->config('user')
393 && "$password" eq C4::Context->config('pass') )
396 # Koha superuser account
397 C4::Context->set_userenv(
398 0, 0,
399 C4::Context->config('user'),
400 C4::Context->config('user'),
401 C4::Context->config('user'),
402 "", 1
404 return 2;
406 if ( $userid
407 && $userid eq 'demo'
408 && "$password" eq 'demo'
409 && C4::Context->config('demo') )
412 # DEMO => the demo user is allowed to do everything (if demo set to 1 in koha.conf
413 # some features won't be effective : modify systempref, modify MARC structure,
414 return 2;
416 return 0;
419 END { } # module clean-up code here (global destructor)
421 __END__
423 =back
425 =head1 SEE ALSO
427 CGI(3)
429 C4::Output(3)
431 Digest::MD5(3)
433 =cut