← Index
Performance Profile   « block view • line view • sub view »
For opac/opac-main.pl
  Run on Fri Jul 18 13:58:34 2008
Reported on Fri Jul 18 13:58:41 2008

FileC4/Auth.pm
Statements Executed78
Total Time0.000783 seconds

Subroutines — ordered by inclusive time then name
CallsInclusive
Time
Subroutine
10.05004C4::Auth::get_template_and_user
10.01454C4::Auth::checkauth
10.00670C4::Auth::get_session
10.00147C4::Auth::_version_check
00C4::Auth::BEGIN
00C4::Auth::END
00C4::Auth::_session_log
00C4::Auth::check_api_auth
00C4::Auth::check_cookie_auth
00C4::Auth::checkpw
00C4::Auth::get_all_subpermissions
00C4::Auth::get_user_subpermissions
00C4::Auth::getborrowernumber
00C4::Auth::getuserflags
00C4::Auth::haspermission

LineStmts.Exclusive
Time
Avg.Code
1
2# -*- tab-width: 8 -*-
3# NOTE: This file uses 8-character tabs; do not change the tab size!
4
5package C4::Auth;
6
7# Copyright 2000-2002 Katipo Communications
8#
9# This file is part of Koha.
10#
11# Koha is free software; you can redistribute it and/or modify it under the
12# terms of the GNU General Public License as published by the Free Software
13# Foundation; either version 2 of the License, or (at your option) any later
14# version.
15#
16# Koha is distributed in the hope that it will be useful, but WITHOUT ANY
17# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
18# A PARTICULAR PURPOSE. See the GNU General Public License for more details.
19#
20# You should have received a copy of the GNU General Public License along with
21# Koha; if not, write to the Free Software Foundation, Inc., 59 Temple Place,
22# Suite 330, Boston, MA 02111-1307 USA
23
24use strict;
25use Digest::MD5 qw(md5_base64);
26use CGI::Session;
27
28require Exporter;
29use C4::Context;
30use C4::Output; # to get the template
31use C4::Members;
32use C4::Koha;
33use C4::Branch; # GetBranches
34use C4::VirtualShelves 3.02 qw(GetShelvesSummary);
35
36# use utf8;
37use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap);
38
39BEGIN {
40 $VERSION = 3.02; # set version for version checking
41 $debug = $ENV{DEBUG} || 0 ;
42 @ISA = qw(Exporter);
43 @EXPORT = qw(&checkauth &get_template_and_user);
44 @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &get_all_subpermissions &get_user_subpermissions);
45 %EXPORT_TAGS = (EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)]);
46 $ldap = C4::Context->config('useldapserver') || 0;
47 if ($ldap) {
48 require C4::Auth_with_ldap; # no import
49 import C4::Auth_with_ldap qw(checkpw_ldap);
50 }
51}
52
53=head1 NAME
54
55C4::Auth - Authenticates Koha users
56
57=head1 SYNOPSIS
58
59 use CGI;
60 use C4::Auth;
61 use C4::Output;
62
63 my $query = new CGI;
64
65 my ($template, $borrowernumber, $cookie)
66 = get_template_and_user(
67 {
68 template_name => "opac-main.tmpl",
69 query => $query,
70 type => "opac",
71 authnotrequired => 1,
72 flagsrequired => {borrow => 1, catalogue => '*', tools => 'import_patrons' },
73 }
74 );
75
76 output_html_with_http_headers $query, $cookie, $template->output;
77
78=head1 DESCRIPTION
79
80 The main function of this module is to provide
81 authentification. However the get_template_and_user function has
82 been provided so that a users login information is passed along
83 automatically. This gets loaded into the template.
84
85=head1 FUNCTIONS
86
87=over 2
88
89=item get_template_and_user
90
91 my ($template, $borrowernumber, $cookie)
92 = get_template_and_user(
93 {
94 template_name => "opac-main.tmpl",
95 query => $query,
96 type => "opac",
97 authnotrequired => 1,
98 flagsrequired => {borrow => 1, catalogue => '*', tools => 'import_patrons' },
99 }
100 );
101
102 This call passes the C<query>, C<flagsrequired> and C<authnotrequired>
103 to C<&checkauth> (in this module) to perform authentification.
104 See C<&checkauth> for an explanation of these parameters.
105
106 The C<template_name> is then used to find the correct template for
107 the page. The authenticated users details are loaded onto the
108 template in the HTML::Template LOOP variable C<USER_INFO>. Also the
109 C<sessionID> is passed to the template. This can be used in templates
110 if cookies are disabled. It needs to be put as and input to every
111 authenticated page.
112
113 More information on the C<gettemplate> sub can be found in the
114 Output.pm module.
115
116=cut
117
118
# spent 0.05004s within C4::Auth::get_template_and_user which was called: # 1 times (0.05004s) at line 37 of opac/opac-main.pl
sub get_template_and_user {
119100.000150.00001 my $in = shift;
120 my $template =
# spent 0.02097s making 1 calls to C4::Output::gettemplate
121 gettemplate( $in->{'template_name'}, $in->{'type'}, $in->{'query'} );
122 my ( $user, $cookie, $sessionID, $flags ) = checkauth(
# spent 0.01454s making 1 calls to C4::Auth::checkauth
123 $in->{'query'},
124 $in->{'authnotrequired'},
125 $in->{'flagsrequired'},
126 $in->{'type'}
127 ) unless ($in->{'template_name'}=~/maintenance/);
128
129 my $borrowernumber;
130 my $insecure = C4::Context->preference('insecure');
# spent 0.00028s making 1 calls to C4::Context::preference
131110.000077e-06 if ($user or $insecure) {
132
133 # load the template variables for stylesheets and JavaScript
134 $template->param( css_libs => $in->{'css_libs'} );
135 $template->param( css_module => $in->{'css_module'} );
136 $template->param( css_page => $in->{'css_page'} );
137 $template->param( css_widgets => $in->{'css_widgets'} );
138
139 $template->param( js_libs => $in->{'js_libs'} );
140 $template->param( js_module => $in->{'js_module'} );
141 $template->param( js_page => $in->{'js_page'} );
142 $template->param( js_widgets => $in->{'js_widgets'} );
143
144 # user info
145 $template->param( loggedinusername => $user );
146 $template->param( sessionID => $sessionID );
147
148 my ($pubshelves, $barshelves) = C4::Context->get_shelves_userenv();
149 if (defined($pubshelves)) {
150 $template->param( pubshelves => scalar (@$pubshelves));
151 $template->param( pubshelvesloop => $pubshelves);
152 }
153 if (defined($barshelves)) {
154 $template->param( barshelves => scalar (@$barshelves));
155 $template->param( barshelvesloop => $barshelves);
156 }
157
158 $borrowernumber = getborrowernumber($user);
159 my ( $borr ) = GetMemberDetails( $borrowernumber );
160 my @bordat;
161 $bordat[0] = $borr;
162 $template->param( "USER_INFO" => \@bordat );
163
164 my $all_perms = get_all_subpermissions();
165
166 my @flagroots = qw(circulate catalogue parameters borrowers permissions reserveforothers borrow
167 editcatalogue updatecharges management tools editauthorities serials reports);
168 # We are going to use the $flags returned by checkauth
169 # to create the template's parameters that will indicate
170 # which menus the user can access.
171 if (( $flags && $flags->{superlibrarian}==1) or $insecure==1) {
172 $template->param( CAN_user_circulate => 1 );
173 $template->param( CAN_user_catalogue => 1 );
174 $template->param( CAN_user_parameters => 1 );
175 $template->param( CAN_user_borrowers => 1 );
176 $template->param( CAN_user_permissions => 1 );
177 $template->param( CAN_user_reserveforothers => 1 );
178 $template->param( CAN_user_borrow => 1 );
179 $template->param( CAN_user_editcatalogue => 1 );
180 $template->param( CAN_user_updatecharges => 1 );
181 $template->param( CAN_user_acquisition => 1 );
182 $template->param( CAN_user_management => 1 );
183 $template->param( CAN_user_tools => 1 );
184 $template->param( CAN_user_editauthorities => 1 );
185 $template->param( CAN_user_serials => 1 );
186 $template->param( CAN_user_reports => 1 );
187 $template->param( CAN_user_staffaccess => 1 );
188 foreach my $module (keys %$all_perms) {
189 foreach my $subperm (keys %{ $all_perms->{$module} }) {
190 $template->param( "CAN_user_${module}_${subperm}" => 1 );
191 }
192 }
193 }
194
195 if (C4::Context->preference('GranularPermissions')) {
196 if ( $flags ) {
197 foreach my $module (keys %$all_perms) {
198 if ( $flags->{$module} == 1) {
199 foreach my $subperm (keys %{ $all_perms->{$module} }) {
200 $template->param( "CAN_user_${module}_${subperm}" => 1 );
201 }
202 } elsif ( ref($flags->{$module}) ) {
203 foreach my $subperm (keys %{ $flags->{$module} } ) {
204 $template->param( "CAN_user_${module}_${subperm}" => 1 );
205 }
206 }
207 }
208 }
209 } else {
210 foreach my $module (keys %$all_perms) {
211 foreach my $subperm (keys %{ $all_perms->{$module} }) {
212 $template->param( "CAN_user_${module}_${subperm}" => 1 );
213 }
214 }
215 }
216
217 if ($flags) {
218 foreach my $module (keys %$flags) {
219 if ( $flags->{$module} == 1 or ref($flags->{$module}) ) {
220 $template->param( "CAN_user_$module" => 1 );
221 if ($module eq "parameters") {
222 $template->param( CAN_user_management => 1 );
223 }
224 }
225 }
226 }
227 }
228 else { # if this is an anonymous session, setup to display public lists...
229
230 # load the template variables for stylesheets and JavaScript
231 $template->param( css_libs => $in->{'css_libs'} );
# spent 0.00003s making 1 calls to HTML::Template::Pro::param
232 $template->param( css_module => $in->{'css_module'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
233 $template->param( css_page => $in->{'css_page'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
234 $template->param( css_widgets => $in->{'css_widgets'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
235
236 $template->param( js_libs => $in->{'js_libs'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
237 $template->param( js_module => $in->{'js_module'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
238 $template->param( js_page => $in->{'js_page'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
239 $template->param( js_widgets => $in->{'js_widgets'} );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
240
241 $template->param( sessionID => $sessionID );
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
242
243 my ($pubshelves) = C4::Context->get_shelves_userenv(); # an anonymous user has no 'barshelves'...
# spent 0.00002s making 1 calls to C4::Context::get_shelves_userenv
24420.000017e-06 if (defined(($pubshelves))) {
245 $template->param( pubshelves => scalar (@$pubshelves));
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
246 $template->param( pubshelvesloop => $pubshelves);
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
247 }
248
249 }
250
251 # these template parameters are set the same regardless of $in->{'type'}
252 $template->param(
# spent 0.00247s making 9 calls to C4::Context::preference, avg 0.00027s/call # spent 0.00009s making 1 calls to HTML::Template::Pro::param # spent 0.00004s making 6 calls to C4::Context::userenv, avg 7e-06s/call
253 "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1,
254 EnhancedMessagingPreferences => C4::Context->preference('EnhancedMessagingPreferences'),
255 GoogleJackets => C4::Context->preference("GoogleJackets"),
256 KohaAdminEmailAddress => "" . C4::Context->preference("KohaAdminEmailAddress"),
257 LoginBranchcode => (C4::Context->userenv?C4::Context->userenv->{"branch"}:"insecure"),
258 LoginFirstname => (C4::Context->userenv?C4::Context->userenv->{"firstname"}:"Bel"),
259 LoginSurname => C4::Context->userenv?C4::Context->userenv->{"surname"}:"Inconnu",
260 TagsEnabled => C4::Context->preference("TagsEnabled"),
261 hide_marc => C4::Context->preference("hide_marc"),
262 'item-level_itypes' => C4::Context->preference('item-level_itypes'),
263 patronimages => C4::Context->preference("patronimages"),
264 singleBranchMode => C4::Context->preference("singleBranchMode"),
265 );
266
26750.000250.00005 if ( $in->{'type'} eq "intranet" ) {
268 $template->param(
269 AmazonContent => C4::Context->preference("AmazonContent"),
270 AmazonSimilarItems => C4::Context->preference("AmazonSimilarItems"),
271 AutoLocation => C4::Context->preference("AutoLocation"),
272 "BiblioDefaultView".C4::Context->preference("IntranetBiblioDefaultView") => 1,
273 CircAutocompl => C4::Context->preference("CircAutocompl"),
274 FRBRizeEditions => C4::Context->preference("FRBRizeEditions"),
275 IndependantBranches => C4::Context->preference("IndependantBranches"),
276 IntranetNav => C4::Context->preference("IntranetNav"),
277 IntranetmainUserblock => C4::Context->preference("IntranetmainUserblock"),
278 LibraryName => C4::Context->preference("LibraryName"),
279 LoginBranchname => (C4::Context->userenv?C4::Context->userenv->{"branchname"}:"insecure"),
280 TemplateEncoding => C4::Context->preference("TemplateEncoding"),
281 advancedMARCEditor => C4::Context->preference("advancedMARCEditor"),
282 canreservefromotherbranches => C4::Context->preference('canreservefromotherbranches'),
283 intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"),
284 intranetreadinghistory => C4::Context->preference("intranetreadinghistory"),
285 intranetstylesheet => C4::Context->preference("intranetstylesheet"),
286 intranetuserjs => C4::Context->preference("intranetuserjs"),
287 noItemTypeImages => C4::Context->preference("noItemTypeImages"),
288 suggestion => C4::Context->preference("suggestion"),
289 virtualshelves => C4::Context->preference("virtualshelves"),
290 );
291 }
292 else {
293 warn "template type should be OPAC, here it is=[" . $in->{'type'} . "]" unless ( $in->{'type'} eq 'opac' );
294 my $LibraryNameTitle = C4::Context->preference("LibraryName");
# spent 0.00027s making 1 calls to C4::Context::preference
295 $LibraryNameTitle =~ s/<(?:\/?)(?:br|p)\s*(?:\/?)>/ /sgi;
296 $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg;
297 $template->param(
# spent 0.01029s making 38 calls to C4::Context::preference, avg 0.00027s/call # spent 0.00026s making 1 calls to CGI::AUTOLOAD # spent 0.00022s making 1 calls to HTML::Template::Pro::param # spent 0.00002s making 1 calls to CGI::https # spent 0.00002s making 2 calls to C4::Context::userenv, avg 8e-06s/call
298 AmazonContent => "" . C4::Context->preference("AmazonContent"),
299 AnonSuggestions => "" . C4::Context->preference("AnonSuggestions"),
300 AuthorisedValueImages => C4::Context->preference("AuthorisedValueImages"),
301 LibraryName => "" . C4::Context->preference("LibraryName"),
302 LibraryNameTitle => "" . $LibraryNameTitle,
303 LoginBranchname => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"",
304 OPACAmazonSimilarItems => "" . C4::Context->preference("OPACAmazonSimilarItems"),
305 OPACFRBRizeEditions => C4::Context->preference("OPACFRBRizeEditions"),
306 OPACItemHolds => C4::Context->preference("OPACItemHolds"),
307 OPACShelfBrowser => "". C4::Context->preference("OPACShelfBrowser"),
308 OPACURLOpenInNewWindow => "" . C4::Context->preference("OPACURLOpenInNewWindow"),
309 OPACUserCSS => "". C4::Context->preference("OPACUserCSS"),
310 OPACViewOthersSuggestions => "" . C4::Context->preference("OPACViewOthersSuggestions"),
311 OpacAuthorities => C4::Context->preference("OpacAuthorities"),
312 OPACBaseURL => ($in->{'query'}->https() ? "https://" : "http://") .
313 $ENV{'SERVER_NAME'} .
314 ($ENV{'SERVER_PORT'} eq ($in->{'query'}->https() ? "443" : "80") ? '' : ":$ENV{'SERVER_PORT'}"),
315 OpacBrowser => C4::Context->preference("OpacBrowser"),
316 OpacCloud => C4::Context->preference("OpacCloud"),
317 OpacMainUserBlock => "" . C4::Context->preference("OpacMainUserBlock"),
318 OpacNav => "" . C4::Context->preference("OpacNav"),
319 OpacPasswordChange => C4::Context->preference("OpacPasswordChange"),
320 OpacTopissue => C4::Context->preference("OpacTopissue"),
321 RequestOnOpac => C4::Context->preference("RequestOnOpac"),
322 TemplateEncoding => "". C4::Context->preference("TemplateEncoding"),
323 'Version' => C4::Context->preference('Version'),
324 XSLTDetailsDisplay => C4::Context->preference("XSLTDetailsDisplay"),
325 XSLTResultsDisplay => C4::Context->preference("XSLTResultsDisplay"),
326 hidelostitems => C4::Context->preference("hidelostitems"),
327 mylibraryfirst => C4::Context->preference("SearchMyLibraryFirst"),
328 opacbookbag => "" . C4::Context->preference("opacbookbag"),
329 opaccolorstylesheet => "". C4::Context->preference("opaccolorstylesheet"),
330 opaccredits => "" . C4::Context->preference("opaccredits"),
331 opacheader => "" . C4::Context->preference("opacheader"),
332 opaclanguagesdisplay => "". C4::Context->preference("opaclanguagesdisplay"),
333 opaclayoutstylesheet => "". C4::Context->preference("opaclayoutstylesheet"),
334 opacreadinghistory => C4::Context->preference("opacreadinghistory"),
335 opacsmallimage => "" . C4::Context->preference("opacsmallimage"),
336 opacuserjs => C4::Context->preference("opacuserjs"),
337 opacuserlogin => "" . C4::Context->preference("opacuserlogin"),
338 reviewson => C4::Context->preference("reviewson"),
339 suggestion => "" . C4::Context->preference("suggestion"),
340 virtualshelves => "" . C4::Context->preference("virtualshelves"),
341 );
342 }
343 $template->param(listloop=>[{shelfname=>"Freelist", shelfnumber=>110}]);
# spent 0.00002s making 1 calls to HTML::Template::Pro::param
344 return ( $template, $borrowernumber, $cookie, $flags);
345}
346
347=item checkauth
348
349 ($userid, $cookie, $sessionID) = &checkauth($query, $noauth, $flagsrequired, $type);
350
351Verifies that the user is authorized to run this script. If
352the user is authorized, a (userid, cookie, session-id, flags)
353quadruple is returned. If the user is not authorized but does
354not have the required privilege (see $flagsrequired below), it
355displays an error page and exits. Otherwise, it displays the
356login page and exits.
357
358Note that C<&checkauth> will return if and only if the user
359is authorized, so it should be called early on, before any
360unfinished operations (e.g., if you've opened a file, then
361C<&checkauth> won't close it for you).
362
363C<$query> is the CGI object for the script calling C<&checkauth>.
364
365The C<$noauth> argument is optional. If it is set, then no
366authorization is required for the script.
367
368C<&checkauth> fetches user and session information from C<$query> and
369ensures that the user is authorized to run scripts that require
370authorization.
371
372The C<$flagsrequired> argument specifies the required privileges
373the user must have if the username and password are correct.
374It should be specified as a reference-to-hash; keys in the hash
375should be the "flags" for the user, as specified in the Members
376intranet module. Any key specified must correspond to a "flag"
377in the userflags table. E.g., { circulate => 1 } would specify
378that the user must have the "circulate" privilege in order to
379proceed. To make sure that access control is correct, the
380C<$flagsrequired> parameter must be specified correctly.
381
382If the GranularPermissions system preference is ON, the
383value of each key in the C<flagsrequired> hash takes on an additional
384meaning, e.g.,
385
386=item 1
387
388The user must have access to all subfunctions of the module
389specified by the hash key.
390
391=item *
392
393The user must have access to at least one subfunction of the module
394specified by the hash key.
395
396=item specific permission, e.g., 'export_catalog'
397
398The user must have access to the specific subfunction list, which
399must correspond to a row in the permissions table.
400
401The C<$type> argument specifies whether the template should be
402retrieved from the opac or intranet directory tree. "opac" is
403assumed if it is not specified; however, if C<$type> is specified,
404"intranet" is assumed if it is not "opac".
405
406If C<$query> does not have a valid session ID associated with it
407(i.e., the user has not logged in) or if the session has expired,
408C<&checkauth> presents the user with a login page (from the point of
409view of the original script, C<&checkauth> does not return). Once the
410user has authenticated, C<&checkauth> restarts the original script
411(this time, C<&checkauth> returns).
412
413The login page is provided using a HTML::Template, which is set in the
414systempreferences table or at the top of this file. The variable C<$type>
415selects which template to use, either the opac or the intranet
416authentification template.
417
418C<&checkauth> returns a user ID, a cookie, and a session ID. The
419cookie should be sent back to the browser; it verifies that the user
420has authenticated.
421
422=cut
423
424
# spent 0.00147s within C4::Auth::_version_check which was called: # 1 times (0.00147s) by C4::Auth::checkauth at line 492 of C4/Auth.pm
sub _version_check ($$) {
42590.000055e-06 my $type = shift;
426 my $query = shift;
427 my $version;
428 # If Version syspref is unavailable, it means Koha is beeing installed,
429 # and so we must redirect to OPAC maintenance page or to the WebInstaller
430 # also, if OpacMaintenance is ON, OPAC should redirect to maintenance
431 if (C4::Context->preference('OpacMaintenance') && $type eq 'opac') {
# spent 0.00081s making 1 calls to C4::Context::preference
432 warn "OPAC Install required, redirecting to maintenance";
433 print $query->redirect("/cgi-bin/koha/maintenance.pl");
434 }
435 unless ($version = C4::Context->preference('Version')) { # assignment, not comparison
# spent 0.00029s making 1 calls to C4::Context::preference
436 if ($type ne 'opac') {
437 warn "Install required, redirecting to Installer";
438 print $query->redirect("/cgi-bin/koha/installer/install.pl");
439 }
440 else {
441 warn "OPAC Install required, redirecting to maintenance";
442 print $query->redirect("/cgi-bin/koha/maintenance.pl");
443 }
444 exit;
445 }
446
447 # check that database and koha version are the same
448 # there is no DB version, it's a fresh install,
449 # go to web installer
450 # there is a DB version, compare it to the code version
451 my $kohaversion=C4::Context::KOHAVERSION;
# spent 0.00032s making 1 calls to C4::Context::KOHAVERSION
452 # remove the 3 last . to have a Perl number
453 $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/;
454 $debug and print STDERR "kohaversion : $kohaversion\n";
455 if ($version < $kohaversion){
456 my $warning = "Database update needed, redirecting to %s. Database is $version and Koha is $kohaversion";
457 if ($type ne 'opac'){
458 warn sprintf($warning, 'Installer');
459 print $query->redirect("/cgi-bin/koha/installer/install.pl?step=3");
460 } else {
461 warn sprintf("OPAC: " . $warning, 'maintenance');
462 print $query->redirect("/cgi-bin/koha/maintenance.pl");
463 }
464 exit;
465 }
466}
467
468sub _session_log {
469 (@_) or return 0;
470 open L, ">>/tmp/sessionlog" or warn "ERROR: Cannot append to /tmp/sessionlog";
471 printf L join("\n",@_);
472 close L;
473}
474
475
# spent 0.01454s within C4::Auth::checkauth which was called: # 1 times (0.01454s) by C4::Auth::get_template_and_user at line 122 of C4/Auth.pm
sub checkauth {
476190.000084e-06 my $query = shift;
477 $debug and warn "Checking Auth";
478 # $authnotrequired will be set for scripts which will run without authentication
479 my $authnotrequired = shift;
480 my $flagsrequired = shift;
481 my $type = shift;
482 $type = 'opac' unless $type;
483
484 my $dbh = C4::Context->dbh;
# spent 0.00026s making 1 calls to C4::Context::dbh
485 my $timeout = C4::Context->preference('timeout');
# spent 0.00030s making 1 calls to C4::Context::preference
486 # days
487 if ($timeout =~ /(\d+)[dD]/) {
488 $timeout = $1 * 86400;
489 };
490 $timeout = 600 unless $timeout;
491
492 _version_check($type,$query);
# spent 0.00147s making 1 calls to C4::Auth::_version_check
493 # state variables
494 my $loggedin = 0;
495 my %info;
496 my ( $userid, $cookie, $sessionID, $flags, $barshelves, $pubshelves );
497 my $logout = $query->param('logout.x');
# spent 0.00003s making 1 calls to CGI::param
498
499 if ( $userid = $ENV{'REMOTE_USER'} ) {
# spent 0.00007s making 1 calls to CGI::cookie
500 # Using Basic Authentication, no cookies required
501 $cookie = $query->cookie(
502 -name => 'CGISESSID',
503 -value => '',
504 -expires => ''
505 );
506 $loggedin = 1;
507 }
508 elsif ( $sessionID = $query->cookie("CGISESSID")) { # assignment, not comparison
509 my $session = get_session($sessionID);
510 C4::Context->_new_userenv($sessionID);
511 my ($ip, $lasttime, $sessiontype);
512 if ($session){
513 C4::Context::set_userenv(
514 $session->param('number'), $session->param('id'),
515 $session->param('cardnumber'), $session->param('firstname'),
516 $session->param('surname'), $session->param('branch'),
517 $session->param('branchname'), $session->param('flags'),
518 $session->param('emailaddress'), $session->param('branchprinter')
519 );
520 C4::Context::set_shelves_userenv('bar',$session->param('barshelves'));
521 C4::Context::set_shelves_userenv('pub',$session->param('pubshelves'));
522 $debug and printf STDERR "AUTH_SESSION: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ;
523 $ip = $session->param('ip');
524 $lasttime = $session->param('lasttime');
525 $userid = $session->param('id');
526 $sessiontype = $session->param('sessiontype');
527 }
528
529 if ( ($query->param('koha_login_context')) && ($query->param('userid') ne $session->param('id')) ) {
530 #if a user enters an id ne to the id in the current session, we need to log them in...
531 #first we need to clear the anonymous session...
532 $debug and warn "query id = " . $query->param('userid') . " but session id = " . $session->param('id');
533 $session->flush;
534 $session->delete();
535 C4::Context->_unset_userenv($sessionID);
536 $sessionID = undef;
537 $userid = undef;
538 }
539 elsif ($logout) {
540 # voluntary logout the user
541 $session->flush;
542 $session->delete();
543 C4::Context->_unset_userenv($sessionID);
544 _session_log(sprintf "%20s from %16s logged out at %30s (manually).\n", $userid,$ip,localtime);
545 $sessionID = undef;
546 $userid = undef;
547 }
548 elsif ( $lasttime < time() - $timeout ) {
549 # timed logout
550 $info{'timed_out'} = 1;
551 $session->delete();
552 C4::Context->_unset_userenv($sessionID);
553 _session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,localtime);
554 $userid = undef;
555 $sessionID = undef;
556 }
557 elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) {
558 # Different ip than originally logged in from
559 $info{'oldip'} = $ip;
560 $info{'newip'} = $ENV{'REMOTE_ADDR'};
561 $info{'different_ip'} = 1;
562 $session->delete();
563 C4::Context->_unset_userenv($sessionID);
564 _session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,localtime, $info{'newip'});
565 $sessionID = undef;
566 $userid = undef;
567 }
568 else {
569 $cookie = $query->cookie( CGISESSID => $session->id );
570 $session->param('lasttime',time());
571 unless ( $sessiontype eq 'anon' ) { #if this is an anonymous session, we want to update the session, but not behave as if they are logged in...
572 $flags = haspermission( $dbh, $userid, $flagsrequired );
573 if ($flags) {
574 $loggedin = 1;
575 } else {
576 $info{'nopermission'} = 1;
577 }
578 }
579 }
580 }
58150.000070.00001 unless ($userid || $sessionID) {
582 #we initiate a session prior to checking for a username to allow for anonymous sessions...
583 my $session = get_session("") or die "Auth ERROR: Cannot get_session()";
# spent 0.00670s making 1 calls to C4::Auth::get_session
584 my $sessionID = $session->id;
# spent 0.00003s making 1 calls to CGI::Session::id
585 C4::Context->_new_userenv($sessionID);
# spent 0.00002s making 1 calls to C4::Context::_new_userenv
586 $cookie = $query->cookie(CGISESSID => $sessionID);
# spent 0.00025s making 1 calls to CGI::cookie
58770.000058e-06 if ( $userid = $query->param('userid') ) {
# spent 0.00003s making 1 calls to CGI::param
588 my $password = $query->param('password');
589 my ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password );
590 if ($return) {
591 _session_log(sprintf "%20s from %16s logged in at %30s.\n", $userid,$ENV{'REMOTE_ADDR'},localtime);
592 if ( $flags = haspermission( $dbh, $userid, $flagsrequired ) ) {
593 $loggedin = 1;
594 }
595 else {
596 $info{'nopermission'} = 1;
597 C4::Context->_unset_userenv($sessionID);
598 }
599
600 my ($borrowernumber, $firstname, $surname, $userflags,
601 $branchcode, $branchname, $branchprinter, $emailaddress);
602
603 if ( $return == 1 ) {
604 my $select = "
605 SELECT borrowernumber, firstname, surname, flags, borrowers.branchcode,
606 branches.branchname as branchname,
607 branches.branchprinter as branchprinter,
608 email
609 FROM borrowers
610 LEFT JOIN branches on borrowers.branchcode=branches.branchcode
611 ";
612 my $sth = $dbh->prepare("$select where userid=?");
613 $sth->execute($userid);
614 unless ($sth->rows) {
615 $debug and print STDERR "AUTH_1: no rows for userid='$userid'\n";
616 $sth = $dbh->prepare("$select where cardnumber=?");
617 $sth->execute($cardnumber);
618 unless ($sth->rows) {
619 $debug and print STDERR "AUTH_2a: no rows for cardnumber='$cardnumber'\n";
620 $sth->execute($userid);
621 unless ($sth->rows) {
622 $debug and print STDERR "AUTH_2b: no rows for userid='$userid' AS cardnumber\n";
623 }
624 }
625 }
626 if ($sth->rows) {
627 ($borrowernumber, $firstname, $surname, $userflags,
628 $branchcode, $branchname, $branchprinter, $emailaddress) = $sth->fetchrow;
629 $debug and print STDERR "AUTH_3 results: " .
630 "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress\n";
631 } else {
632 print STDERR "AUTH_3: no results for userid='$userid', cardnumber='$cardnumber'.\n";
633 }
634
635# launch a sequence to check if we have a ip for the branch, i
636# if we have one we replace the branchcode of the userenv by the branch bound in the ip.
637
638 my $ip = $ENV{'REMOTE_ADDR'};
639 # if they specify at login, use that
640 if ($query->param('branch')) {
641 $branchcode = $query->param('branch');
642 $branchname = GetBranchName($branchcode);
643 }
644 my $branches = GetBranches();
645 if (C4::Context->boolean_preference('IndependantBranches') && C4::Context->boolean_preference('Autolocation')){
646 # we have to check they are coming from the right ip range
647 my $domain = $branches->{$branchcode}->{'branchip'};
648 if ($ip !~ /^$domain/){
649 $loggedin=0;
650 $info{'wrongip'} = 1;
651 }
652 }
653
654 my @branchesloop;
655 foreach my $br ( keys %$branches ) {
656 # now we work with the treatment of ip
657 my $domain = $branches->{$br}->{'branchip'};
658 if ( $domain && $ip =~ /^$domain/ ) {
659 $branchcode = $branches->{$br}->{'branchcode'};
660
661 # new op dev : add the branchprinter and branchname in the cookie
662 $branchprinter = $branches->{$br}->{'branchprinter'};
663 $branchname = $branches->{$br}->{'branchname'};
664 }
665 }
666 $session->param('number',$borrowernumber);
667 $session->param('id',$userid);
668 $session->param('cardnumber',$cardnumber);
669 $session->param('firstname',$firstname);
670 $session->param('surname',$surname);
671 $session->param('branch',$branchcode);
672 $session->param('branchname',$branchname);
673 $session->param('flags',$userflags);
674 $session->param('emailaddress',$emailaddress);
675 $session->param('ip',$session->remote_addr());
676 $session->param('lasttime',time());
677 $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ;
678 }
679 elsif ( $return == 2 ) {
680 #We suppose the user is the superlibrarian
681 $borrowernumber = 0;
682 $session->param('number',0);
683 $session->param('id',C4::Context->config('user'));
684 $session->param('cardnumber',C4::Context->config('user'));
685 $session->param('firstname',C4::Context->config('user'));
686 $session->param('surname',C4::Context->config('user'));
687 $session->param('branch','NO_LIBRARY_SET');
688 $session->param('branchname','NO_LIBRARY_SET');
689 $session->param('flags',1);
690 $session->param('emailaddress', C4::Context->preference('KohaAdminEmailAddress'));
691 $session->param('ip',$session->remote_addr());
692 $session->param('lasttime',time());
693 }
694 C4::Context::set_userenv(
695 $session->param('number'), $session->param('id'),
696 $session->param('cardnumber'), $session->param('firstname'),
697 $session->param('surname'), $session->param('branch'),
698 $session->param('branchname'), $session->param('flags'),
699 $session->param('emailaddress'), $session->param('branchprinter')
700 );
701
702 # Grab borrower's shelves and add to the session...
703 $barshelves = GetShelvesSummary($borrowernumber,2,10);
704 $session->param('barshelves', $barshelves);
705 C4::Context::set_shelves_userenv('bar',$barshelves);
706
707 # Grab the public shelves and add to the session...
708 $pubshelves = GetShelvesSummary(0,2,10);
709 $session->param('pubshelves', $pubshelves);
710 C4::Context::set_shelves_userenv('pub',$pubshelves);
711 }
712 else {
713 if ($userid) {
714 $info{'invalid_username_or_password'} = 1;
715 C4::Context->_unset_userenv($sessionID);
716 }
717 }
718 } # END if ( $userid = $query->param('userid') )
719 elsif ($type eq "opac") {
720 # if we are here this is an anonymous session; add public lists to it and a few other items...
721 # anonymous sessions are created only for the OPAC
722 $debug and warn "Initiating an anonymous session...";
723
724 # Grab the public shelves and add to the session...
725 $pubshelves = GetShelvesSummary(0,2,10);
# spent 0.00039s making 1 calls to C4::VirtualShelves::GetShelvesSummary
726 $session->param('pubshelves', $pubshelves);
# spent 0.00006s making 1 calls to CGI::Session::param
727 C4::Context::set_shelves_userenv('pub',$pubshelves);
# spent 0.00002s making 1 calls to C4::Context::set_shelves_userenv
728
729 # setting a couple of other session vars...
730 $session->param('ip',$session->remote_addr());
# spent 0.00005s making 1 calls to CGI::Session::param # spent 9e-06s making 1 calls to CGI::Session::remote_addr
731 $session->param('lasttime',time());
# spent 0.00005s making 1 calls to CGI::Session::param
732 $session->param('sessiontype','anon');
# spent 0.00005s making 1 calls to CGI::Session::param
733 }
734 } # END unless ($userid)
735 my $insecure = C4::Context->boolean_preference('insecure');
# spent 0.00039s making 1 calls to C4::Context::boolean_preference
736
737 # finished authentification, now respond
73828e-064e-06 if ( $loggedin || $authnotrequired || ( defined($insecure) && $insecure ) )
739 {
740 # successful login
74111e-061e-06 unless ($cookie) {
742 $cookie = $query->cookie( CGISESSID => '' );
743 }
744 return ( $userid, $cookie, $sessionID, $flags );
745 }
746
747#
748#
749# AUTH rejected, show the login/password template, after checking the DB.
750#
751#
752
753 # get the inputs from the incoming query
754 my @inputs = ();
755 foreach my $name ( param $query) {
756 (ne