From 3769c0e71a227283f53baf48e4f4db6c55b4ff40 Mon Sep 17 00:00:00 2001 From: Martin Renvoize Date: Mon, 5 Jan 2015 22:45:44 +0000 Subject: [PATCH] Bug 13499: Tidy of Auth.pm This tidy should only change whitespace and not line breaks, thus retaining history. There are no code changes, and thus there should be no regressions to test for koha wise. To test the non-destrcutive nature of the patch, run a 'git blame -w' on the file before and after the patch. The resulting blame should include a comparabile history of the file, with only some additional blank lines being attributed to this commit. A 'git blame -wM' may also be useful for comparison purposes. --- C4/Auth.pm | 1227 +++++++++++++++++++++++++++++++----------------------------- 1 file changed, 644 insertions(+), 583 deletions(-) diff --git a/C4/Auth.pm b/C4/Auth.pm index b808c66..e7a6ab1 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -28,7 +28,7 @@ require Exporter; use C4::Context; use C4::Templates; # to get the template use C4::Languages; -use C4::Branch; # GetBranches +use C4::Branch; # GetBranches use C4::Search::History; use C4::VirtualShelves; use Koha::AuthUtils qw(hash_password); @@ -40,27 +40,29 @@ use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $cas BEGIN { sub psgi_env { any { /^psgi\./ } keys %ENV } + sub safe_exit { - if ( psgi_env ) { die 'psgi:exit' } - else { exit } + if (psgi_env) { die 'psgi:exit' } + else { exit } } - $VERSION = 3.07.00.049; # set version for version checking - - $debug = $ENV{DEBUG}; - @ISA = qw(Exporter); - @EXPORT = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions); - @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &checkpw_internal &checkpw_hash - &get_all_subpermissions &get_user_subpermissions - ); + $VERSION = 3.07.00.049; # set version for version checking + + $debug = $ENV{DEBUG}; + @ISA = qw(Exporter); + @EXPORT = qw(&checkauth &get_template_and_user &haspermission &get_user_subpermissions); + @EXPORT_OK = qw(&check_api_auth &get_session &check_cookie_auth &checkpw &checkpw_internal &checkpw_hash + &get_all_subpermissions &get_user_subpermissions + ); %EXPORT_TAGS = ( EditPermissions => [qw(get_all_subpermissions get_user_subpermissions)] ); - $ldap = C4::Context->config('useldapserver') || 0; - $cas = C4::Context->preference('casAuthentication'); - $shib = C4::Context->config('useshibboleth') || 0; - $caslogout = C4::Context->preference('casLogout'); - require C4::Auth_with_cas; # no import + $ldap = C4::Context->config('useldapserver') || 0; + $cas = C4::Context->preference('casAuthentication'); + $shib = C4::Context->config('useshibboleth') || 0; + $caslogout = C4::Context->preference('casLogout'); + require C4::Auth_with_cas; # no import + if ($ldap) { - require C4::Auth_with_ldap; - import C4::Auth_with_ldap qw(checkpw_ldap); + require C4::Auth_with_ldap; + import C4::Auth_with_ldap qw(checkpw_ldap); } if ($shib) { require C4::Auth_with_shibboleth; @@ -69,16 +71,18 @@ BEGIN { # Check for good config if ( shib_ok() ) { + # Get shibboleth login attribute $shib_login = get_login_shib(); } + # Bad config, disable shibboleth else { $shib = 0; } } if ($cas) { - import C4::Auth_with_cas qw(check_api_auth_cas checkpw_cas login_cas logout_cas login_cas_url); + import C4::Auth_with_cas qw(check_api_auth_cas checkpw_cas login_cas logout_cas login_cas_url); } } @@ -148,10 +152,10 @@ Output.pm module. sub get_template_and_user { - my $in = shift; + my $in = shift; my ( $user, $cookie, $sessionID, $flags ); - C4::Context->interface($in->{type}); + C4::Context->interface( $in->{type} ); $in->{'authnotrequired'} ||= 0; my $template = C4::Templates::gettemplate( @@ -161,7 +165,7 @@ sub get_template_and_user { $in->{'is_plugin'} ); - if ( $in->{'template_name'} !~m/maintenance/ ) { + if ( $in->{'template_name'} !~ m/maintenance/ ) { ( $user, $cookie, $sessionID, $flags ) = checkauth( $in->{'query'}, $in->{'authnotrequired'}, @@ -173,14 +177,16 @@ sub get_template_and_user { my $borrowernumber; if ($user) { require C4::Members; + # It's possible for $user to be the borrowernumber if they don't have a # userid defined (and are logging in through some other method, such # as SSL certs against an email address) $borrowernumber = getborrowernumber($user) if defined($user); - if (!defined($borrowernumber) && defined($user)) { - my $borrower = C4::Members::GetMember(borrowernumber => $user); + if ( !defined($borrowernumber) && defined($user) ) { + my $borrower = C4::Members::GetMember( borrowernumber => $user ); if ($borrower) { $borrowernumber = $user; + # A bit of a hack, but I don't know there's a nicer way # to do it. $user = $borrower->{firstname} . ' ' . $borrower->{surname}; @@ -188,19 +194,19 @@ sub get_template_and_user { } # user info - $template->param( loggedinusername => $user ); + $template->param( loggedinusername => $user ); $template->param( loggedinusernumber => $borrowernumber ); - $template->param( sessionID => $sessionID ); + $template->param( sessionID => $sessionID ); - my ($total, $pubshelves, $barshelves) = C4::VirtualShelves::GetSomeShelfNames($borrowernumber, 'MASTHEAD'); + my ( $total, $pubshelves, $barshelves ) = C4::VirtualShelves::GetSomeShelfNames( $borrowernumber, 'MASTHEAD' ); $template->param( pubshelves => $total->{pubtotal}, pubshelvesloop => $pubshelves, - barshelves => $total->{bartotal}, - barshelvesloop => $barshelves, + barshelves => $total->{bartotal}, + barshelvesloop => $barshelves, ); - my ( $borr ) = C4::Members::GetMemberDetails( $borrowernumber ); + my ($borr) = C4::Members::GetMemberDetails($borrowernumber); my @bordat; $bordat[0] = $borr; $template->param( "USER_INFO" => \@bordat ); @@ -208,11 +214,12 @@ sub get_template_and_user { my $all_perms = get_all_subpermissions(); my @flagroots = qw(circulate catalogue parameters borrowers permissions reserveforothers borrow - editcatalogue updatecharges management tools editauthorities serials reports acquisition); + editcatalogue updatecharges management tools editauthorities serials reports acquisition); + # We are going to use the $flags returned by checkauth # to create the template's parameters that will indicate # which menus the user can access. - if ( $flags && $flags->{superlibrarian}==1 ) { + if ( $flags && $flags->{superlibrarian} == 1 ) { $template->param( CAN_user_circulate => 1 ); $template->param( CAN_user_catalogue => 1 ); $template->param( CAN_user_parameters => 1 ); @@ -231,21 +238,22 @@ sub get_template_and_user { $template->param( CAN_user_staffaccess => 1 ); $template->param( CAN_user_plugins => 1 ); $template->param( CAN_user_coursereserves => 1 ); - foreach my $module (keys %$all_perms) { - foreach my $subperm (keys %{ $all_perms->{$module} }) { + foreach my $module ( keys %$all_perms ) { + + foreach my $subperm ( keys %{ $all_perms->{$module} } ) { $template->param( "CAN_user_${module}_${subperm}" => 1 ); } } } - if ( $flags ) { - foreach my $module (keys %$all_perms) { - if ( $flags->{$module} == 1) { - foreach my $subperm (keys %{ $all_perms->{$module} }) { + if ($flags) { + foreach my $module ( keys %$all_perms ) { + if ( $flags->{$module} == 1 ) { + foreach my $subperm ( keys %{ $all_perms->{$module} } ) { $template->param( "CAN_user_${module}_${subperm}" => 1 ); } - } elsif ( ref($flags->{$module}) ) { - foreach my $subperm (keys %{ $flags->{$module} } ) { + } elsif ( ref( $flags->{$module} ) ) { + foreach my $subperm ( keys %{ $flags->{$module} } ) { $template->param( "CAN_user_${module}_${subperm}" => 1 ); } } @@ -253,34 +261,36 @@ sub get_template_and_user { } if ($flags) { - foreach my $module (keys %$flags) { - if ( $flags->{$module} == 1 or ref($flags->{$module}) ) { + foreach my $module ( keys %$flags ) { + if ( $flags->{$module} == 1 or ref( $flags->{$module} ) ) { $template->param( "CAN_user_$module" => 1 ); - if ($module eq "parameters") { + if ( $module eq "parameters" ) { $template->param( CAN_user_management => 1 ); } } } } + # Logged-in opac search history # If the requested template is an opac one and opac search history is enabled - if ($in->{type} eq 'opac' && C4::Context->preference('EnableOpacSearchHistory')) { - my $dbh = C4::Context->dbh; + if ( $in->{type} eq 'opac' && C4::Context->preference('EnableOpacSearchHistory') ) { + my $dbh = C4::Context->dbh; my $query = "SELECT COUNT(*) FROM search_history WHERE userid=?"; - my $sth = $dbh->prepare($query); + my $sth = $dbh->prepare($query); $sth->execute($borrowernumber); # If at least one search has already been performed - if ($sth->fetchrow_array > 0) { + if ( $sth->fetchrow_array > 0 ) { + # We show the link in opac $template->param( EnableOpacSearchHistory => 1 ); } # And if there are searches performed when the user was not logged in, # we add them to the logged-in search history - my @recentSearches = C4::Search::History::get_from_session({ cgi => $in->{'query'} }); + my @recentSearches = C4::Search::History::get_from_session( { cgi => $in->{'query'} } ); if (@recentSearches) { - my $dbh = C4::Context->dbh; + my $dbh = C4::Context->dbh; my $query = q{ INSERT INTO search_history(userid, sessionid, query_desc, query_cgi, type, total, time ) VALUES (?, ?, ?, ?, ?, ?, ?) @@ -288,17 +298,17 @@ sub get_template_and_user { my $sth = $dbh->prepare($query); $sth->execute( $borrowernumber, - $in->{query}->cookie("CGISESSID"), - $_->{query_desc}, - $_->{query_cgi}, - $_->{type} || 'biblio', - $_->{total}, - $_->{time}, - ) foreach @recentSearches; + $in->{query}->cookie("CGISESSID"), + $_->{query_desc}, + $_->{query_cgi}, + $_->{type} || 'biblio', + $_->{total}, + $_->{time}, + ) foreach @recentSearches; # clear out the search history from the session now that # we've saved it to the database - C4::Search::History::set_to_session({ cgi => $in->{'query'}, search_history => [] }); + C4::Search::History::set_to_session( { cgi => $in->{'query'}, search_history => [] } ); } } elsif ( $in->{type} eq 'intranet' and C4::Context->preference('EnableSearchHistory') ) { $template->param( EnableSearchHistory => 1 ); @@ -306,39 +316,41 @@ sub get_template_and_user { } else { # if this is an anonymous session, setup to display public lists... - # If shibboleth is enabled, and we're in an anonymous session, we should allow - # the user to attemp login via shibboleth. - if ( $shib ) { - $template->param( shibbolethAuthentication => $shib, - shibbolethLoginUrl => login_shib_url($in->{'query'}), + # If shibboleth is enabled, and we're in an anonymous session, we should allow + # the user to attemp login via shibboleth. + if ($shib) { + $template->param( shibbolethAuthentication => $shib, + shibbolethLoginUrl => login_shib_url( $in->{'query'} ), ); + # If shibboleth is enabled and we have a shibboleth login attribute, # but we are in an anonymous session, then we clearly have an invalid # shibboleth koha account. - if ( $shib_login ) { - $template->param( invalidShibLogin => '1'); + if ($shib_login) { + $template->param( invalidShibLogin => '1' ); } } - $template->param( sessionID => $sessionID ); - - my ($total, $pubshelves) = C4::VirtualShelves::GetSomeShelfNames(undef, 'MASTHEAD'); + $template->param( sessionID => $sessionID ); + + my ( $total, $pubshelves ) = C4::VirtualShelves::GetSomeShelfNames( undef, 'MASTHEAD' ); $template->param( pubshelves => $total->{pubtotal}, pubshelvesloop => $pubshelves, ); } - # Anonymous opac search history - # If opac search history is enabled and at least one search has already been performed - if (C4::Context->preference('EnableOpacSearchHistory')) { - my @recentSearches = C4::Search::History::get_from_session({ cgi => $in->{'query'} }); + + # Anonymous opac search history + # If opac search history is enabled and at least one search has already been performed + if ( C4::Context->preference('EnableOpacSearchHistory') ) { + my @recentSearches = C4::Search::History::get_from_session( { cgi => $in->{'query'} } ); if (@recentSearches) { - $template->param(EnableOpacSearchHistory => 1); + $template->param( EnableOpacSearchHistory => 1 ); } - } + } - if(C4::Context->preference('dateformat')){ - $template->param(dateformat => C4::Context->preference('dateformat')) + if ( C4::Context->preference('dateformat') ) { + $template->param( dateformat => C4::Context->preference('dateformat') ) } # these template parameters are set the same regardless of $in->{'type'} @@ -346,190 +358,195 @@ sub get_template_and_user { # Set the using_https variable for templates # FIXME Under Plack the CGI->https method always returns 'OFF' my $https = $in->{query}->https(); - my $using_https = (defined $https and $https ne 'OFF') ? 1 : 0; + my $using_https = ( defined $https and $https ne 'OFF' ) ? 1 : 0; $template->param( - "BiblioDefaultView".C4::Context->preference("BiblioDefaultView") => 1, - EnhancedMessagingPreferences => C4::Context->preference('EnhancedMessagingPreferences'), - GoogleJackets => C4::Context->preference("GoogleJackets"), - OpenLibraryCovers => C4::Context->preference("OpenLibraryCovers"), - KohaAdminEmailAddress => "" . C4::Context->preference("KohaAdminEmailAddress"), - LoginBranchcode => (C4::Context->userenv?C4::Context->userenv->{"branch"}:undef), - LoginFirstname => (C4::Context->userenv?C4::Context->userenv->{"firstname"}:"Bel"), - LoginSurname => C4::Context->userenv?C4::Context->userenv->{"surname"}:"Inconnu", - emailaddress => C4::Context->userenv?C4::Context->userenv->{"emailaddress"}:undef, - loggedinpersona => C4::Context->userenv?C4::Context->userenv->{"persona"}:undef, - TagsEnabled => C4::Context->preference("TagsEnabled"), - hide_marc => C4::Context->preference("hide_marc"), - item_level_itypes => C4::Context->preference('item-level_itypes'), - patronimages => C4::Context->preference("patronimages"), - singleBranchMode => C4::Context->preference("singleBranchMode"), - XSLTDetailsDisplay => C4::Context->preference("XSLTDetailsDisplay"), - XSLTResultsDisplay => C4::Context->preference("XSLTResultsDisplay"), - using_https => $using_https, - noItemTypeImages => C4::Context->preference("noItemTypeImages"), - marcflavour => C4::Context->preference("marcflavour"), - persona => C4::Context->preference("persona"), + "BiblioDefaultView" . C4::Context->preference("BiblioDefaultView") => 1, + EnhancedMessagingPreferences => C4::Context->preference('EnhancedMessagingPreferences'), + GoogleJackets => C4::Context->preference("GoogleJackets"), + OpenLibraryCovers => C4::Context->preference("OpenLibraryCovers"), + KohaAdminEmailAddress => "" . C4::Context->preference("KohaAdminEmailAddress"), + LoginBranchcode => ( C4::Context->userenv ? C4::Context->userenv->{"branch"} : undef ), + LoginFirstname => ( C4::Context->userenv ? C4::Context->userenv->{"firstname"} : "Bel" ), + LoginSurname => C4::Context->userenv ? C4::Context->userenv->{"surname"} : "Inconnu", + emailaddress => C4::Context->userenv ? C4::Context->userenv->{"emailaddress"} : undef, + loggedinpersona => C4::Context->userenv ? C4::Context->userenv->{"persona"} : undef, + TagsEnabled => C4::Context->preference("TagsEnabled"), + hide_marc => C4::Context->preference("hide_marc"), + item_level_itypes => C4::Context->preference('item-level_itypes'), + patronimages => C4::Context->preference("patronimages"), + singleBranchMode => C4::Context->preference("singleBranchMode"), + XSLTDetailsDisplay => C4::Context->preference("XSLTDetailsDisplay"), + XSLTResultsDisplay => C4::Context->preference("XSLTResultsDisplay"), + using_https => $using_https, + noItemTypeImages => C4::Context->preference("noItemTypeImages"), + marcflavour => C4::Context->preference("marcflavour"), + persona => C4::Context->preference("persona"), ); if ( $in->{'type'} eq "intranet" ) { $template->param( - AmazonCoverImages => C4::Context->preference("AmazonCoverImages"), - AutoLocation => C4::Context->preference("AutoLocation"), - "BiblioDefaultView".C4::Context->preference("IntranetBiblioDefaultView") => 1, - CalendarFirstDayOfWeek => (C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday")?0:1, - CircAutocompl => C4::Context->preference("CircAutocompl"), - FRBRizeEditions => C4::Context->preference("FRBRizeEditions"), - IndependentBranches => C4::Context->preference("IndependentBranches"), - IntranetNav => C4::Context->preference("IntranetNav"), - IntranetmainUserblock => C4::Context->preference("IntranetmainUserblock"), - LibraryName => C4::Context->preference("LibraryName"), - LoginBranchname => (C4::Context->userenv?C4::Context->userenv->{"branchname"}:undef), - advancedMARCEditor => C4::Context->preference("advancedMARCEditor"), - canreservefromotherbranches => C4::Context->preference('canreservefromotherbranches'), - intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), - IntranetFavicon => C4::Context->preference("IntranetFavicon"), - intranetreadinghistory => C4::Context->preference("intranetreadinghistory"), - intranetstylesheet => C4::Context->preference("intranetstylesheet"), - IntranetUserCSS => C4::Context->preference("IntranetUserCSS"), - intranetuserjs => C4::Context->preference("intranetuserjs"), - intranetbookbag => C4::Context->preference("intranetbookbag"), - suggestion => C4::Context->preference("suggestion"), - virtualshelves => C4::Context->preference("virtualshelves"), - StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"), - EasyAnalyticalRecords => C4::Context->preference('EasyAnalyticalRecords'), - LocalCoverImages => C4::Context->preference('LocalCoverImages'), - OPACLocalCoverImages => C4::Context->preference('OPACLocalCoverImages'), - AllowMultipleCovers => C4::Context->preference('AllowMultipleCovers'), - EnableBorrowerFiles => C4::Context->preference('EnableBorrowerFiles'), - UseKohaPlugins => C4::Context->preference('UseKohaPlugins'), - UseCourseReserves => C4::Context->preference("UseCourseReserves"), + AmazonCoverImages => C4::Context->preference("AmazonCoverImages"), + AutoLocation => C4::Context->preference("AutoLocation"), + "BiblioDefaultView" . C4::Context->preference("IntranetBiblioDefaultView") => 1, + CalendarFirstDayOfWeek => ( C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday" ) ? 0 : 1, + CircAutocompl => C4::Context->preference("CircAutocompl"), + FRBRizeEditions => C4::Context->preference("FRBRizeEditions"), + IndependentBranches => C4::Context->preference("IndependentBranches"), + IntranetNav => C4::Context->preference("IntranetNav"), + IntranetmainUserblock => C4::Context->preference("IntranetmainUserblock"), + LibraryName => C4::Context->preference("LibraryName"), + LoginBranchname => ( C4::Context->userenv ? C4::Context->userenv->{"branchname"} : undef ), + advancedMARCEditor => C4::Context->preference("advancedMARCEditor"), + canreservefromotherbranches => C4::Context->preference('canreservefromotherbranches'), + intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), + IntranetFavicon => C4::Context->preference("IntranetFavicon"), + intranetreadinghistory => C4::Context->preference("intranetreadinghistory"), + intranetstylesheet => C4::Context->preference("intranetstylesheet"), + IntranetUserCSS => C4::Context->preference("IntranetUserCSS"), + intranetuserjs => C4::Context->preference("intranetuserjs"), + intranetbookbag => C4::Context->preference("intranetbookbag"), + suggestion => C4::Context->preference("suggestion"), + virtualshelves => C4::Context->preference("virtualshelves"), + StaffSerialIssueDisplayCount => C4::Context->preference("StaffSerialIssueDisplayCount"), + EasyAnalyticalRecords => C4::Context->preference('EasyAnalyticalRecords'), + LocalCoverImages => C4::Context->preference('LocalCoverImages'), + OPACLocalCoverImages => C4::Context->preference('OPACLocalCoverImages'), + AllowMultipleCovers => C4::Context->preference('AllowMultipleCovers'), + EnableBorrowerFiles => C4::Context->preference('EnableBorrowerFiles'), + UseKohaPlugins => C4::Context->preference('UseKohaPlugins'), + UseCourseReserves => C4::Context->preference("UseCourseReserves"), ); } else { warn "template type should be OPAC, here it is=[" . $in->{'type'} . "]" unless ( $in->{'type'} eq 'opac' ); + #TODO : replace LibraryName syspref with 'system name', and remove this html processing my $LibraryNameTitle = C4::Context->preference("LibraryName"); $LibraryNameTitle =~ s/<(?:\/?)(?:br|p)\s*(?:\/?)>/ /sgi; $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg; + # clean up the busc param in the session if the page is not opac-detail and not the "add to list" page - if ( C4::Context->preference("OpacBrowseResults") + if ( C4::Context->preference("OpacBrowseResults") && $in->{'template_name'} =~ /opac-(.+)\.(?:tt|tmpl)$/ ) { my $pagename = $1; - unless ( $pagename =~ /^(?:MARC|ISBD)?detail$/ - or $pagename =~ /^addbybiblionumber$/ ) { - my $sessionSearch = get_session($sessionID || $in->{'query'}->cookie("CGISESSID")); - $sessionSearch->clear(["busc"]) if ($sessionSearch->param("busc")); + unless ( $pagename =~ /^(?:MARC|ISBD)?detail$/ + or $pagename =~ /^addbybiblionumber$/ ) { + my $sessionSearch = get_session( $sessionID || $in->{'query'}->cookie("CGISESSID") ); + $sessionSearch->clear( ["busc"] ) if ( $sessionSearch->param("busc") ); } } + # variables passed from CGI: opac_css_override and opac_search_limits. - my $opac_search_limit = $ENV{'OPAC_SEARCH_LIMIT'}; + my $opac_search_limit = $ENV{'OPAC_SEARCH_LIMIT'}; my $opac_limit_override = $ENV{'OPAC_LIMIT_OVERRIDE'}; - my $opac_name = ''; + my $opac_name = ''; if ( - ($opac_limit_override && $opac_search_limit && $opac_search_limit =~ /branch:(\w+)/) || - ($in->{'query'}->param('limit') && $in->{'query'}->param('limit') =~ /branch:(\w+)/) || - ($in->{'query'}->param('multibranchlimit') && $in->{'query'}->param('multibranchlimit') =~ /multibranchlimit-(\w+)/) - ) { - $opac_name = $1; # opac_search_limit is a branch, so we use it. + ( $opac_limit_override && $opac_search_limit && $opac_search_limit =~ /branch:(\w+)/ ) || + ( $in->{'query'}->param('limit') && $in->{'query'}->param('limit') =~ /branch:(\w+)/ ) || + ( $in->{'query'}->param('multibranchlimit') && $in->{'query'}->param('multibranchlimit') =~ /multibranchlimit-(\w+)/ ) + ) { + $opac_name = $1; # opac_search_limit is a branch, so we use it. } elsif ( $in->{'query'}->param('multibranchlimit') ) { $opac_name = $in->{'query'}->param('multibranchlimit'); - } elsif (C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv && C4::Context->userenv->{'branch'}) { + } elsif ( C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv && C4::Context->userenv->{'branch'} ) { $opac_name = C4::Context->userenv->{'branch'}; } + # FIXME Under Plack the CGI->https method always returns 'OFF' ($using_https will be set to 0 in this case) - my $opac_base_url = C4::Context->preference("OPACBaseURL"); #FIXME uses $using_https below as well - if (!$opac_base_url){ - $opac_base_url = $ENV{'SERVER_NAME'} . ($ENV{'SERVER_PORT'} eq ($using_https ? "443" : "80") ? '' : ":$ENV{'SERVER_PORT'}"); + my $opac_base_url = C4::Context->preference("OPACBaseURL"); #FIXME uses $using_https below as well + if ( !$opac_base_url ) { + $opac_base_url = $ENV{'SERVER_NAME'} . ( $ENV{'SERVER_PORT'} eq ( $using_https ? "443" : "80" ) ? '' : ":$ENV{'SERVER_PORT'}" ); } $template->param( - opaccolorstylesheet => C4::Context->preference("opaccolorstylesheet"), - AnonSuggestions => "" . C4::Context->preference("AnonSuggestions"), - AuthorisedValueImages => C4::Context->preference("AuthorisedValueImages"), - BranchesLoop => GetBranchesLoop($opac_name), - BranchCategoriesLoop => GetBranchCategories( 'searchdomain', 1, $opac_name ), - CalendarFirstDayOfWeek => (C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday")?0:1, - LibraryName => "" . C4::Context->preference("LibraryName"), - LibraryNameTitle => "" . $LibraryNameTitle, - LoginBranchname => C4::Context->userenv?C4::Context->userenv->{"branchname"}:"", - OPACAmazonCoverImages => C4::Context->preference("OPACAmazonCoverImages"), - OPACFRBRizeEditions => C4::Context->preference("OPACFRBRizeEditions"), - OpacHighlightedWords => C4::Context->preference("OpacHighlightedWords"), - OPACItemHolds => C4::Context->preference("OPACItemHolds"), - OPACShelfBrowser => "". C4::Context->preference("OPACShelfBrowser"), - OPACURLOpenInNewWindow => "" . C4::Context->preference("OPACURLOpenInNewWindow"), - OPACUserCSS => "". C4::Context->preference("OPACUserCSS"), - OPACViewOthersSuggestions => "" . C4::Context->preference("OPACViewOthersSuggestions"), - OpacAuthorities => C4::Context->preference("OpacAuthorities"), - OPACBaseURL => ($using_https ? "https://" : "http://") . $opac_base_url, - opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'}, - opac_search_limit => $opac_search_limit, - opac_limit_override => $opac_limit_override, - OpacBrowser => C4::Context->preference("OpacBrowser"), - OpacCloud => C4::Context->preference("OpacCloud"), - OpacKohaUrl => C4::Context->preference("OpacKohaUrl"), - OpacMainUserBlock => "" . C4::Context->preference("OpacMainUserBlock"), - OpacNav => "" . C4::Context->preference("OpacNav"), - OpacNavRight => "" . C4::Context->preference("OpacNavRight"), - OpacNavBottom => "" . C4::Context->preference("OpacNavBottom"), - OpacPasswordChange => C4::Context->preference("OpacPasswordChange"), - OPACPatronDetails => C4::Context->preference("OPACPatronDetails"), - OPACPrivacy => C4::Context->preference("OPACPrivacy"), - OPACFinesTab => C4::Context->preference("OPACFinesTab"), - OpacTopissue => C4::Context->preference("OpacTopissue"), - RequestOnOpac => C4::Context->preference("RequestOnOpac"), - 'Version' => C4::Context->preference('Version'), - hidelostitems => C4::Context->preference("hidelostitems"), - mylibraryfirst => (C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv) ? C4::Context->userenv->{'branch'} : '', - opaclayoutstylesheet => "" . C4::Context->preference("opaclayoutstylesheet"), - opacbookbag => "" . C4::Context->preference("opacbookbag"), - opaccredits => "" . C4::Context->preference("opaccredits"), - OpacFavicon => C4::Context->preference("OpacFavicon"), - opacheader => "" . C4::Context->preference("opacheader"), - opaclanguagesdisplay => "" . C4::Context->preference("opaclanguagesdisplay"), - opacreadinghistory => C4::Context->preference("opacreadinghistory"), - opacuserjs => C4::Context->preference("opacuserjs"), - opacuserlogin => "" . C4::Context->preference("opacuserlogin"), - ShowReviewer => C4::Context->preference("ShowReviewer"), - ShowReviewerPhoto => C4::Context->preference("ShowReviewerPhoto"), - suggestion => "" . C4::Context->preference("suggestion"), - virtualshelves => "" . C4::Context->preference("virtualshelves"), - OPACSerialIssueDisplayCount => C4::Context->preference("OPACSerialIssueDisplayCount"), - OPACXSLTDetailsDisplay => C4::Context->preference("OPACXSLTDetailsDisplay"), - OPACXSLTResultsDisplay => C4::Context->preference("OPACXSLTResultsDisplay"), - SyndeticsClientCode => C4::Context->preference("SyndeticsClientCode"), - SyndeticsEnabled => C4::Context->preference("SyndeticsEnabled"), - SyndeticsCoverImages => C4::Context->preference("SyndeticsCoverImages"), - SyndeticsTOC => C4::Context->preference("SyndeticsTOC"), - SyndeticsSummary => C4::Context->preference("SyndeticsSummary"), - SyndeticsEditions => C4::Context->preference("SyndeticsEditions"), - SyndeticsExcerpt => C4::Context->preference("SyndeticsExcerpt"), - SyndeticsReviews => C4::Context->preference("SyndeticsReviews"), - SyndeticsAuthorNotes => C4::Context->preference("SyndeticsAuthorNotes"), - SyndeticsAwards => C4::Context->preference("SyndeticsAwards"), - SyndeticsSeries => C4::Context->preference("SyndeticsSeries"), - SyndeticsCoverImageSize => C4::Context->preference("SyndeticsCoverImageSize"), - OPACLocalCoverImages => C4::Context->preference("OPACLocalCoverImages"), - PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"), + opaccolorstylesheet => C4::Context->preference("opaccolorstylesheet"), + AnonSuggestions => "" . C4::Context->preference("AnonSuggestions"), + AuthorisedValueImages => C4::Context->preference("AuthorisedValueImages"), + BranchesLoop => GetBranchesLoop($opac_name), + BranchCategoriesLoop => GetBranchCategories( 'searchdomain', 1, $opac_name ), + CalendarFirstDayOfWeek => ( C4::Context->preference("CalendarFirstDayOfWeek") eq "Sunday" ) ? 0 : 1, + LibraryName => "" . C4::Context->preference("LibraryName"), + LibraryNameTitle => "" . $LibraryNameTitle, + LoginBranchname => C4::Context->userenv ? C4::Context->userenv->{"branchname"} : "", + OPACAmazonCoverImages => C4::Context->preference("OPACAmazonCoverImages"), + OPACFRBRizeEditions => C4::Context->preference("OPACFRBRizeEditions"), + OpacHighlightedWords => C4::Context->preference("OpacHighlightedWords"), + OPACItemHolds => C4::Context->preference("OPACItemHolds"), + OPACShelfBrowser => "" . C4::Context->preference("OPACShelfBrowser"), + OPACURLOpenInNewWindow => "" . C4::Context->preference("OPACURLOpenInNewWindow"), + OPACUserCSS => "" . C4::Context->preference("OPACUserCSS"), + OPACViewOthersSuggestions => "" . C4::Context->preference("OPACViewOthersSuggestions"), + OpacAuthorities => C4::Context->preference("OpacAuthorities"), + OPACBaseURL => ( $using_https ? "https://" : "http://" ) . $opac_base_url, + opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'}, + opac_search_limit => $opac_search_limit, + opac_limit_override => $opac_limit_override, + OpacBrowser => C4::Context->preference("OpacBrowser"), + OpacCloud => C4::Context->preference("OpacCloud"), + OpacKohaUrl => C4::Context->preference("OpacKohaUrl"), + OpacMainUserBlock => "" . C4::Context->preference("OpacMainUserBlock"), + OpacNav => "" . C4::Context->preference("OpacNav"), + OpacNavRight => "" . C4::Context->preference("OpacNavRight"), + OpacNavBottom => "" . C4::Context->preference("OpacNavBottom"), + OpacPasswordChange => C4::Context->preference("OpacPasswordChange"), + OPACPatronDetails => C4::Context->preference("OPACPatronDetails"), + OPACPrivacy => C4::Context->preference("OPACPrivacy"), + OPACFinesTab => C4::Context->preference("OPACFinesTab"), + OpacTopissue => C4::Context->preference("OpacTopissue"), + RequestOnOpac => C4::Context->preference("RequestOnOpac"), + 'Version' => C4::Context->preference('Version'), + hidelostitems => C4::Context->preference("hidelostitems"), + mylibraryfirst => ( C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv ) ? C4::Context->userenv->{'branch'} : '', + opaclayoutstylesheet => "" . C4::Context->preference("opaclayoutstylesheet"), + opacbookbag => "" . C4::Context->preference("opacbookbag"), + opaccredits => "" . C4::Context->preference("opaccredits"), + OpacFavicon => C4::Context->preference("OpacFavicon"), + opacheader => "" . C4::Context->preference("opacheader"), + opaclanguagesdisplay => "" . C4::Context->preference("opaclanguagesdisplay"), + opacreadinghistory => C4::Context->preference("opacreadinghistory"), + opacuserjs => C4::Context->preference("opacuserjs"), + opacuserlogin => "" . C4::Context->preference("opacuserlogin"), + ShowReviewer => C4::Context->preference("ShowReviewer"), + ShowReviewerPhoto => C4::Context->preference("ShowReviewerPhoto"), + suggestion => "" . C4::Context->preference("suggestion"), + virtualshelves => "" . C4::Context->preference("virtualshelves"), + OPACSerialIssueDisplayCount => C4::Context->preference("OPACSerialIssueDisplayCount"), + OPACXSLTDetailsDisplay => C4::Context->preference("OPACXSLTDetailsDisplay"), + OPACXSLTResultsDisplay => C4::Context->preference("OPACXSLTResultsDisplay"), + SyndeticsClientCode => C4::Context->preference("SyndeticsClientCode"), + SyndeticsEnabled => C4::Context->preference("SyndeticsEnabled"), + SyndeticsCoverImages => C4::Context->preference("SyndeticsCoverImages"), + SyndeticsTOC => C4::Context->preference("SyndeticsTOC"), + SyndeticsSummary => C4::Context->preference("SyndeticsSummary"), + SyndeticsEditions => C4::Context->preference("SyndeticsEditions"), + SyndeticsExcerpt => C4::Context->preference("SyndeticsExcerpt"), + SyndeticsReviews => C4::Context->preference("SyndeticsReviews"), + SyndeticsAuthorNotes => C4::Context->preference("SyndeticsAuthorNotes"), + SyndeticsAwards => C4::Context->preference("SyndeticsAwards"), + SyndeticsSeries => C4::Context->preference("SyndeticsSeries"), + SyndeticsCoverImageSize => C4::Context->preference("SyndeticsCoverImageSize"), + OPACLocalCoverImages => C4::Context->preference("OPACLocalCoverImages"), + PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"), PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"), ); - $template->param(OpacPublic => '1') if ($user || C4::Context->preference("OpacPublic")); + $template->param( OpacPublic => '1' ) if ( $user || C4::Context->preference("OpacPublic") ); } # Check if we were asked using parameters to force a specific language if ( defined $in->{'query'}->param('language') ) { + # Extract the language, let C4::Languages::getlanguage choose # what to do - my $language = C4::Languages::getlanguage($in->{'query'}); - my $languagecookie = C4::Templates::getlanguagecookie($in->{'query'},$language); + my $language = C4::Languages::getlanguage( $in->{'query'} ); + my $languagecookie = C4::Templates::getlanguagecookie( $in->{'query'}, $language ); if ( ref $cookie eq 'ARRAY' ) { - push @{ $cookie }, $languagecookie; + push @{$cookie}, $languagecookie; } else { - $cookie = [$cookie, $languagecookie]; + $cookie = [ $cookie, $languagecookie ]; } } - return ( $template, $borrowernumber, $cookie, $flags); + return ( $template, $borrowernumber, $cookie, $flags ); } =head2 checkauth @@ -611,13 +628,14 @@ has authenticated. =cut sub _version_check { - my $type = shift; + my $type = shift; my $query = shift; my $version; + # If Version syspref is unavailable, it means Koha is beeing installed, # and so we must redirect to OPAC maintenance page or to the WebInstaller # also, if OpacMaintenance is ON, OPAC should redirect to maintenance - if (C4::Context->preference('OpacMaintenance') && $type eq 'opac') { + if ( C4::Context->preference('OpacMaintenance') && $type eq 'opac' ) { warn "OPAC Install required, redirecting to maintenance"; print $query->redirect("/cgi-bin/koha/maintenance.pl"); safe_exit; @@ -637,17 +655,18 @@ sub _version_check { # there is no DB version, it's a fresh install, # go to web installer # there is a DB version, compare it to the code version - my $kohaversion=C4::Context::KOHAVERSION; + my $kohaversion = C4::Context::KOHAVERSION; + # remove the 3 last . to have a Perl number $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; $debug and print STDERR "kohaversion : $kohaversion\n"; - if ($version < $kohaversion){ + if ( $version < $kohaversion ) { my $warning = "Database update needed, redirecting to %s. Database is $version and Koha is $kohaversion"; - if ($type ne 'opac'){ - warn sprintf($warning, 'Installer'); + if ( $type ne 'opac' ) { + warn sprintf( $warning, 'Installer' ); print $query->redirect("/cgi-bin/koha/installer/install.pl?step=3"); } else { - warn sprintf("OPAC: " . $warning, 'maintenance'); + warn sprintf( "OPAC: " . $warning, 'maintenance' ); print $query->redirect("/cgi-bin/koha/maintenance.pl"); } safe_exit; @@ -657,14 +676,15 @@ sub _version_check { sub _session_log { (@_) or return 0; open my $fh, '>>', "/tmp/sessionlog" or warn "ERROR: Cannot append to /tmp/sessionlog"; - printf $fh join("\n",@_); + printf $fh join( "\n", @_ ); close $fh; } sub _timeout_syspref { my $timeout = C4::Context->preference('timeout') || 600; + # value in days, convert in seconds - if ($timeout =~ /(\d+)[dD]/) { + if ( $timeout =~ /(\d+)[dD]/ ) { $timeout = $1 * 86400; }; return $timeout; @@ -673,6 +693,7 @@ sub _timeout_syspref { sub checkauth { my $query = shift; $debug and warn "Checking Auth"; + # $authnotrequired will be set for scripts which will run without authentication my $authnotrequired = shift; my $flagsrequired = shift; @@ -683,7 +704,8 @@ sub checkauth { my $dbh = C4::Context->dbh; my $timeout = _timeout_syspref(); - _version_check($type,$query); + _version_check( $type, $query ); + # state variables my $loggedin = 0; my %info; @@ -706,7 +728,7 @@ sub checkauth { # Finally, after those tests, we can assume (although if it would be better with # a syspref) that if we get a REMOTE_USER, that's from basic authentication, # and we can affect it to $userid. - if ( !$shib and defined($ENV{'REMOTE_USER'}) and $ENV{'REMOTE_USER'} ne '' and $userid = $ENV{'REMOTE_USER'} ) { + if ( !$shib and defined( $ENV{'REMOTE_USER'} ) and $ENV{'REMOTE_USER'} ne '' and $userid = $ENV{'REMOTE_USER'} ) { # Using Basic Authentication, no cookies required $cookie = $query->cookie( @@ -717,16 +739,17 @@ sub checkauth { ); $loggedin = 1; } - elsif ( $persona ){ - # we dont want to set a session because we are being called by a persona callback + elsif ($persona) { + + # we dont want to set a session because we are being called by a persona callback } elsif ( $sessionID = $query->cookie("CGISESSID") ) { # assignment, not comparison my $session = get_session($sessionID); C4::Context->_new_userenv($sessionID); - my ($ip, $lasttime, $sessiontype); + my ( $ip, $lasttime, $sessiontype ); my $s_userid = ''; - if ($session){ + if ($session) { $s_userid = $session->param('id') // ''; C4::Context::set_userenv( $session->param('number'), $s_userid, @@ -736,17 +759,18 @@ sub checkauth { $session->param('emailaddress'), $session->param('branchprinter'), $session->param('persona'), $session->param('shibboleth') ); - C4::Context::set_shelves_userenv('bar',$session->param('barshelves')); - C4::Context::set_shelves_userenv('pub',$session->param('pubshelves')); - C4::Context::set_shelves_userenv('tot',$session->param('totshelves')); - $debug and printf STDERR "AUTH_SESSION: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ; - $ip = $session->param('ip'); - $lasttime = $session->param('lasttime'); - $userid = $s_userid; + C4::Context::set_shelves_userenv( 'bar', $session->param('barshelves') ); + C4::Context::set_shelves_userenv( 'pub', $session->param('pubshelves') ); + C4::Context::set_shelves_userenv( 'tot', $session->param('totshelves') ); + $debug and printf STDERR "AUTH_SESSION: (%s)\t%s %s - %s\n", map { $session->param($_) } qw(cardnumber firstname surname branch); + $ip = $session->param('ip'); + $lasttime = $session->param('lasttime'); + $userid = $s_userid; $sessiontype = $session->param('sessiontype') || ''; } - if ( ( $query->param('koha_login_context') && ($q_userid ne $s_userid) ) - || ( $cas && $query->param('ticket') ) || ( $shib && $shib_login && !$logout ) ) { + if ( ( $query->param('koha_login_context') && ( $q_userid ne $s_userid ) ) + || ( $cas && $query->param('ticket') ) || ( $shib && $shib_login && !$logout ) ) { + #if a user enters an id ne to the id in the current session, we need to log them in... #first we need to clear the anonymous session... $debug and warn "query id = $q_userid but session id = $s_userid"; @@ -755,30 +779,34 @@ sub checkauth { $session->flush; C4::Context->_unset_userenv($sessionID); $sessionID = undef; - $userid = undef; + $userid = undef; } elsif ($logout) { + # voluntary logout the user - # check wether the user was using their shibboleth session or a local one + # check wether the user was using their shibboleth session or a local one my $shibSuccess = C4::Context->userenv->{'shibboleth'}; $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); + #_session_log(sprintf "%20s from %16s logged out at %30s (manually).\n", $userid,$ip,(strftime "%c",localtime)); $sessionID = undef; $userid = undef; - if ($cas and $caslogout) { + if ( $cas and $caslogout ) { logout_cas($query); } # If we are in a shibboleth session (shibboleth is enabled, a shibboleth match attribute is set and matches koha matchpoint) - if ( $shib and $shib_login and $shibSuccess and $type eq 'opac') { - # (Note: $type eq 'opac' condition should be removed when shibboleth authentication for intranet will be implemented) + if ( $shib and $shib_login and $shibSuccess and $type eq 'opac' ) { + + # (Note: $type eq 'opac' condition should be removed when shibboleth authentication for intranet will be implemented) logout_shib($query); } } - elsif ( !$lasttime || ($lasttime < time() - $timeout) ) { + elsif ( !$lasttime || ( $lasttime < time() - $timeout ) ) { + # timed logout $info{'timed_out'} = 1; if ($session) { @@ -786,11 +814,13 @@ sub checkauth { $session->flush; } C4::Context->_unset_userenv($sessionID); + #_session_log(sprintf "%20s from %16s logged out at %30s (inactivity).\n", $userid,$ip,(strftime "%c",localtime)); $userid = undef; $sessionID = undef; } elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) { + # Different ip than originally logged in from $info{'oldip'} = $ip; $info{'newip'} = $ENV{'REMOTE_ADDR'}; @@ -798,6 +828,7 @@ sub checkauth { $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); + #_session_log(sprintf "%20s from %16s logged out at %30s (ip changed to %16s).\n", $userid,$ip,(strftime "%c",localtime), $info{'newip'}); $sessionID = undef; $userid = undef; @@ -809,8 +840,8 @@ sub checkauth { -HttpOnly => 1 ); $session->param( 'lasttime', time() ); - unless ( $sessiontype && $sessiontype eq 'anon' ) { #if this is an anonymous session, we want to update the session, but not behave as if they are logged in... - $flags = haspermission($userid, $flagsrequired); + unless ( $sessiontype && $sessiontype eq 'anon' ) { #if this is an anonymous session, we want to update the session, but not behave as if they are logged in... + $flags = haspermission( $userid, $flagsrequired ); if ($flags) { $loggedin = 1; } else { @@ -819,7 +850,7 @@ sub checkauth { } } } - unless ($userid || $sessionID) { + unless ( $userid || $sessionID ) { #we initiate a session prior to checking for a username to allow for anonymous sessions... my $session = get_session("") or die "Auth ERROR: Cannot get_session()"; @@ -828,7 +859,7 @@ sub checkauth { # by get_template_and_user to store it in user's search history after # a successful login. if ($anon_search_history) { - $session->param('search_history', $anon_search_history); + $session->param( 'search_history', $anon_search_history ); } my $sessionID = $session->id; @@ -840,111 +871,114 @@ sub checkauth { ); $userid = $q_userid; my $pki_field = C4::Context->preference('AllowPKIAuth'); - if (! defined($pki_field) ) { + if ( !defined($pki_field) ) { print STDERR "ERROR: Missing system preference AllowPKIAuth.\n"; $pki_field = 'None'; } - if ( ( $cas && $query->param('ticket') ) + if ( ( $cas && $query->param('ticket') ) || $userid || ( $shib && $shib_login ) || $pki_field ne 'None' || $persona ) { - my $password = $query->param('password'); - my $shibSuccess = 0; + my $password = $query->param('password'); + my $shibSuccess = 0; my ( $return, $cardnumber ); - # If shib is enabled and we have a shib login, does the login match a valid koha user + + # If shib is enabled and we have a shib login, does the login match a valid koha user if ( $shib && $shib_login && $type eq 'opac' ) { my $retuserid; - # Do not pass password here, else shib will not be checked in checkpw. + + # Do not pass password here, else shib will not be checked in checkpw. ( $return, $cardnumber, $retuserid ) = checkpw( $dbh, $userid, undef, $query ); - $userid = $retuserid; - $shibSuccess = $return; + $userid = $retuserid; + $shibSuccess = $return; $info{'invalidShibLogin'} = 1 unless ($return); } - # If shib login and match were successfull, skip further login methods - unless ( $shibSuccess ) { - if ( $cas && $query->param('ticket') ) { - my $retuserid; - ( $return, $cardnumber, $retuserid ) = - checkpw( $dbh, $userid, $password, $query ); - $userid = $retuserid; - $info{'invalidCasLogin'} = 1 unless ($return); - } - - elsif ($persona) { - my $value = $persona; - # If we're looking up the email, there's a chance that the person - # doesn't have a userid. So if there is none, we pass along the - # borrower number, and the bits of code that need to know the user - # ID will have to be smart enough to handle that. - require C4::Members; - my @users_info = C4::Members::GetBorrowersWithEmail($value); - if (@users_info) { - - # First the userid, then the borrowernum - $value = $users_info[0][1] || $users_info[0][0]; - } - else { - undef $value; - } - $return = $value ? 1 : 0; - $userid = $value; - } - - elsif ( - ( $pki_field eq 'Common Name' && $ENV{'SSL_CLIENT_S_DN_CN'} ) - || ( $pki_field eq 'emailAddress' - && $ENV{'SSL_CLIENT_S_DN_Email'} ) - ) - { - my $value; - if ( $pki_field eq 'Common Name' ) { - $value = $ENV{'SSL_CLIENT_S_DN_CN'}; + # If shib login and match were successfull, skip further login methods + unless ($shibSuccess) { + if ( $cas && $query->param('ticket') ) { + my $retuserid; + ( $return, $cardnumber, $retuserid ) = + checkpw( $dbh, $userid, $password, $query ); + $userid = $retuserid; + $info{'invalidCasLogin'} = 1 unless ($return); } - elsif ( $pki_field eq 'emailAddress' ) { - $value = $ENV{'SSL_CLIENT_S_DN_Email'}; - # If we're looking up the email, there's a chance that the person - # doesn't have a userid. So if there is none, we pass along the - # borrower number, and the bits of code that need to know the user - # ID will have to be smart enough to handle that. + elsif ($persona) { + my $value = $persona; + + # If we're looking up the email, there's a chance that the person + # doesn't have a userid. So if there is none, we pass along the + # borrower number, and the bits of code that need to know the user + # ID will have to be smart enough to handle that. require C4::Members; my @users_info = C4::Members::GetBorrowersWithEmail($value); if (@users_info) { # First the userid, then the borrowernum $value = $users_info[0][1] || $users_info[0][0]; - } else { + } + else { undef $value; } + $return = $value ? 1 : 0; + $userid = $value; } + elsif ( + ( $pki_field eq 'Common Name' && $ENV{'SSL_CLIENT_S_DN_CN'} ) + || ( $pki_field eq 'emailAddress' + && $ENV{'SSL_CLIENT_S_DN_Email'} ) + ) + { + my $value; + if ( $pki_field eq 'Common Name' ) { + $value = $ENV{'SSL_CLIENT_S_DN_CN'}; + } + elsif ( $pki_field eq 'emailAddress' ) { + $value = $ENV{'SSL_CLIENT_S_DN_Email'}; + + # If we're looking up the email, there's a chance that the person + # doesn't have a userid. So if there is none, we pass along the + # borrower number, and the bits of code that need to know the user + # ID will have to be smart enough to handle that. + require C4::Members; + my @users_info = C4::Members::GetBorrowersWithEmail($value); + if (@users_info) { + + # First the userid, then the borrowernum + $value = $users_info[0][1] || $users_info[0][0]; + } else { + undef $value; + } + } - $return = $value ? 1 : 0; - $userid = $value; + $return = $value ? 1 : 0; + $userid = $value; - } - else { - my $retuserid; - ( $return, $cardnumber, $retuserid ) = - checkpw( $dbh, $userid, $password, $query ); - $userid = $retuserid if ( $retuserid ); - $info{'invalid_username_or_password'} = 1 unless ($return); - } } - if ($return) { - #_session_log(sprintf "%20s from %16s logged in at %30s.\n", $userid,$ENV{'REMOTE_ADDR'},(strftime '%c', localtime)); - if ( $flags = haspermission( $userid, $flagsrequired ) ) { + } + else { + my $retuserid; + ( $return, $cardnumber, $retuserid ) = + checkpw( $dbh, $userid, $password, $query ); + $userid = $retuserid if ($retuserid); + $info{'invalid_username_or_password'} = 1 unless ($return); + } } + if ($return) { + + #_session_log(sprintf "%20s from %16s logged in at %30s.\n", $userid,$ENV{'REMOTE_ADDR'},(strftime '%c', localtime)); + if ( $flags = haspermission( $userid, $flagsrequired ) ) { $loggedin = 1; } - else { + else { $info{'nopermission'} = 1; C4::Context->_unset_userenv($sessionID); } - my ($borrowernumber, $firstname, $surname, $userflags, - $branchcode, $branchname, $branchprinter, $emailaddress); + my ( $borrowernumber, $firstname, $surname, $userflags, + $branchcode, $branchname, $branchprinter, $emailaddress ); if ( $return == 1 ) { my $select = " @@ -957,49 +991,52 @@ sub checkauth { "; my $sth = $dbh->prepare("$select where userid=?"); $sth->execute($userid); - unless ($sth->rows) { + unless ( $sth->rows ) { $debug and print STDERR "AUTH_1: no rows for userid='$userid'\n"; $sth = $dbh->prepare("$select where cardnumber=?"); $sth->execute($cardnumber); - unless ($sth->rows) { + unless ( $sth->rows ) { $debug and print STDERR "AUTH_2a: no rows for cardnumber='$cardnumber'\n"; $sth->execute($userid); - unless ($sth->rows) { + unless ( $sth->rows ) { $debug and print STDERR "AUTH_2b: no rows for userid='$userid' AS cardnumber\n"; } } } - if ($sth->rows) { - ($borrowernumber, $firstname, $surname, $userflags, - $branchcode, $branchname, $branchprinter, $emailaddress) = $sth->fetchrow; + if ( $sth->rows ) { + ( $borrowernumber, $firstname, $surname, $userflags, + $branchcode, $branchname, $branchprinter, $emailaddress ) = $sth->fetchrow; $debug and print STDERR "AUTH_3 results: " . - "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress\n"; + "$cardnumber,$borrowernumber,$userid,$firstname,$surname,$userflags,$branchcode,$emailaddress\n"; } else { print STDERR "AUTH_3: no results for userid='$userid', cardnumber='$cardnumber'.\n"; } -# launch a sequence to check if we have a ip for the branch, i -# if we have one we replace the branchcode of the userenv by the branch bound in the ip. + # launch a sequence to check if we have a ip for the branch, i + # if we have one we replace the branchcode of the userenv by the branch bound in the ip. + + my $ip = $ENV{'REMOTE_ADDR'}; - my $ip = $ENV{'REMOTE_ADDR'}; # if they specify at login, use that - if ($query->param('branch')) { - $branchcode = $query->param('branch'); + if ( $query->param('branch') ) { + $branchcode = $query->param('branch'); $branchname = GetBranchName($branchcode); } my $branches = GetBranches(); - if (C4::Context->boolean_preference('IndependentBranches') && C4::Context->boolean_preference('Autolocation')){ + if ( C4::Context->boolean_preference('IndependentBranches') && C4::Context->boolean_preference('Autolocation') ) { + # we have to check they are coming from the right ip range my $domain = $branches->{$branchcode}->{'branchip'}; - if ($ip !~ /^$domain/){ - $loggedin=0; + if ( $ip !~ /^$domain/ ) { + $loggedin = 0; $info{'wrongip'} = 1; } } my @branchesloop; foreach my $br ( keys %$branches ) { + # now we work with the treatment of ip my $domain = $branches->{$br}->{'branchip'}; if ( $domain && $ip =~ /^$domain/ ) { @@ -1010,37 +1047,38 @@ sub checkauth { $branchname = $branches->{$br}->{'branchname'}; } } - $session->param('number',$borrowernumber); - $session->param('id',$userid); - $session->param('cardnumber',$cardnumber); - $session->param('firstname',$firstname); - $session->param('surname',$surname); - $session->param('branch',$branchcode); - $session->param('branchname',$branchname); - $session->param('flags',$userflags); - $session->param('emailaddress',$emailaddress); - $session->param('ip',$session->remote_addr()); - $session->param('lasttime',time()); - $session->param('shibboleth',$shibSuccess); - $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map {$session->param($_)} qw(cardnumber firstname surname branch) ; + $session->param( 'number', $borrowernumber ); + $session->param( 'id', $userid ); + $session->param( 'cardnumber', $cardnumber ); + $session->param( 'firstname', $firstname ); + $session->param( 'surname', $surname ); + $session->param( 'branch', $branchcode ); + $session->param( 'branchname', $branchname ); + $session->param( 'flags', $userflags ); + $session->param( 'emailaddress', $emailaddress ); + $session->param( 'ip', $session->remote_addr() ); + $session->param( 'lasttime', time() ); + $session->param( 'shibboleth', $shibSuccess ); + $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map { $session->param($_) } qw(cardnumber firstname surname branch); } elsif ( $return == 2 ) { + #We suppose the user is the superlibrarian $borrowernumber = 0; - $session->param('number',0); - $session->param('id',C4::Context->config('user')); - $session->param('cardnumber',C4::Context->config('user')); - $session->param('firstname',C4::Context->config('user')); - $session->param('surname',C4::Context->config('user')); - $session->param('branch','NO_LIBRARY_SET'); - $session->param('branchname','NO_LIBRARY_SET'); - $session->param('flags',1); - $session->param('emailaddress', C4::Context->preference('KohaAdminEmailAddress')); - $session->param('ip',$session->remote_addr()); - $session->param('lasttime',time()); + $session->param( 'number', 0 ); + $session->param( 'id', C4::Context->config('user') ); + $session->param( 'cardnumber', C4::Context->config('user') ); + $session->param( 'firstname', C4::Context->config('user') ); + $session->param( 'surname', C4::Context->config('user') ); + $session->param( 'branch', 'NO_LIBRARY_SET' ); + $session->param( 'branchname', 'NO_LIBRARY_SET' ); + $session->param( 'flags', 1 ); + $session->param( 'emailaddress', C4::Context->preference('KohaAdminEmailAddress') ); + $session->param( 'ip', $session->remote_addr() ); + $session->param( 'lasttime', time() ); } - if ($persona){ - $session->param('persona',1); + if ($persona) { + $session->param( 'persona', 1 ); } C4::Context::set_userenv( $session->param('number'), $session->param('id'), @@ -1057,19 +1095,20 @@ sub checkauth { $info{'invalid_username_or_password'} = 1; C4::Context->_unset_userenv($sessionID); } - $session->param('lasttime',time()); - $session->param('ip',$session->remote_addr()); + $session->param( 'lasttime', time() ); + $session->param( 'ip', $session->remote_addr() ); } } # END if ( $userid = $query->param('userid') ) - elsif ($type eq "opac") { + elsif ( $type eq "opac" ) { + # if we are here this is an anonymous session; add public lists to it and a few other items... # anonymous sessions are created only for the OPAC $debug and warn "Initiating an anonymous session..."; # setting a couple of other session vars... - $session->param('ip',$session->remote_addr()); - $session->param('lasttime',time()); - $session->param('sessiontype','anon'); + $session->param( 'ip', $session->remote_addr() ); + $session->param( 'lasttime', time() ); + $session->param( 'sessiontype', 'anon' ); } } # END unless ($userid) @@ -1087,11 +1126,11 @@ sub checkauth { return ( $userid, $cookie, $sessionID, $flags ); } -# -# -# AUTH rejected, show the login/password template, after checking the DB. -# -# + # + # + # AUTH rejected, show the login/password template, after checking the DB. + # + # # get the inputs from the incoming query my @inputs = (); @@ -1106,56 +1145,56 @@ sub checkauth { $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg; my $template_name = ( $type eq 'opac' ) ? 'opac-auth.tt' : 'auth.tt'; - my $template = C4::Templates::gettemplate($template_name, $type, $query ); + my $template = C4::Templates::gettemplate( $template_name, $type, $query ); $template->param( - branchloop => GetBranchesLoop(), - opaccolorstylesheet => C4::Context->preference("opaccolorstylesheet"), - opaclayoutstylesheet => C4::Context->preference("opaclayoutstylesheet"), - login => 1, - INPUTS => \@inputs, - casAuthentication => C4::Context->preference("casAuthentication"), - shibbolethAuthentication => $shib, - suggestion => C4::Context->preference("suggestion"), - virtualshelves => C4::Context->preference("virtualshelves"), - LibraryName => "" . C4::Context->preference("LibraryName"), - LibraryNameTitle => "" . $LibraryNameTitle, - opacuserlogin => C4::Context->preference("opacuserlogin"), - OpacNav => C4::Context->preference("OpacNav"), - OpacNavRight => C4::Context->preference("OpacNavRight"), - OpacNavBottom => C4::Context->preference("OpacNavBottom"), - opaccredits => C4::Context->preference("opaccredits"), - OpacFavicon => C4::Context->preference("OpacFavicon"), - opacreadinghistory => C4::Context->preference("opacreadinghistory"), - opaclanguagesdisplay => C4::Context->preference("opaclanguagesdisplay"), - opacuserjs => C4::Context->preference("opacuserjs"), - opacbookbag => "" . C4::Context->preference("opacbookbag"), - OpacCloud => C4::Context->preference("OpacCloud"), - OpacTopissue => C4::Context->preference("OpacTopissue"), - OpacAuthorities => C4::Context->preference("OpacAuthorities"), - OpacBrowser => C4::Context->preference("OpacBrowser"), - opacheader => C4::Context->preference("opacheader"), - TagsEnabled => C4::Context->preference("TagsEnabled"), - OPACUserCSS => C4::Context->preference("OPACUserCSS"), - intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), - intranetstylesheet => C4::Context->preference("intranetstylesheet"), - intranetbookbag => C4::Context->preference("intranetbookbag"), - IntranetNav => C4::Context->preference("IntranetNav"), - IntranetFavicon => C4::Context->preference("IntranetFavicon"), - intranetuserjs => C4::Context->preference("intranetuserjs"), - IndependentBranches=> C4::Context->preference("IndependentBranches"), - AutoLocation => C4::Context->preference("AutoLocation"), - wrongip => $info{'wrongip'}, - PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"), + branchloop => GetBranchesLoop(), + opaccolorstylesheet => C4::Context->preference("opaccolorstylesheet"), + opaclayoutstylesheet => C4::Context->preference("opaclayoutstylesheet"), + login => 1, + INPUTS => \@inputs, + casAuthentication => C4::Context->preference("casAuthentication"), + shibbolethAuthentication => $shib, + suggestion => C4::Context->preference("suggestion"), + virtualshelves => C4::Context->preference("virtualshelves"), + LibraryName => "" . C4::Context->preference("LibraryName"), + LibraryNameTitle => "" . $LibraryNameTitle, + opacuserlogin => C4::Context->preference("opacuserlogin"), + OpacNav => C4::Context->preference("OpacNav"), + OpacNavRight => C4::Context->preference("OpacNavRight"), + OpacNavBottom => C4::Context->preference("OpacNavBottom"), + opaccredits => C4::Context->preference("opaccredits"), + OpacFavicon => C4::Context->preference("OpacFavicon"), + opacreadinghistory => C4::Context->preference("opacreadinghistory"), + opaclanguagesdisplay => C4::Context->preference("opaclanguagesdisplay"), + opacuserjs => C4::Context->preference("opacuserjs"), + opacbookbag => "" . C4::Context->preference("opacbookbag"), + OpacCloud => C4::Context->preference("OpacCloud"), + OpacTopissue => C4::Context->preference("OpacTopissue"), + OpacAuthorities => C4::Context->preference("OpacAuthorities"), + OpacBrowser => C4::Context->preference("OpacBrowser"), + opacheader => C4::Context->preference("opacheader"), + TagsEnabled => C4::Context->preference("TagsEnabled"), + OPACUserCSS => C4::Context->preference("OPACUserCSS"), + intranetcolorstylesheet => C4::Context->preference("intranetcolorstylesheet"), + intranetstylesheet => C4::Context->preference("intranetstylesheet"), + intranetbookbag => C4::Context->preference("intranetbookbag"), + IntranetNav => C4::Context->preference("IntranetNav"), + IntranetFavicon => C4::Context->preference("IntranetFavicon"), + intranetuserjs => C4::Context->preference("intranetuserjs"), + IndependentBranches => C4::Context->preference("IndependentBranches"), + AutoLocation => C4::Context->preference("AutoLocation"), + wrongip => $info{'wrongip'}, + PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"), PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"), - persona => C4::Context->preference("Persona"), - opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'}, + persona => C4::Context->preference("Persona"), + opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'}, ); - $template->param( OpacPublic => C4::Context->preference("OpacPublic")); + $template->param( OpacPublic => C4::Context->preference("OpacPublic") ); $template->param( loginprompt => 1 ) unless $info{'nopermission'}; - if($type eq 'opac'){ - my ($total, $pubshelves) = C4::VirtualShelves::GetSomeShelfNames(undef, 'MASTHEAD'); + if ( $type eq 'opac' ) { + my ( $total, $pubshelves ) = C4::VirtualShelves::GetSomeShelfNames( undef, 'MASTHEAD' ); $template->param( pubshelves => $total->{pubtotal}, pubshelvesloop => $pubshelves, @@ -1164,32 +1203,32 @@ sub checkauth { if ($cas) { - # Is authentication against multiple CAS servers enabled? - if (C4::Auth_with_cas::multipleAuth && !$casparam) { - my $casservers = C4::Auth_with_cas::getMultipleAuth(); - my @tmplservers; - foreach my $key (keys %$casservers) { - push @tmplservers, {name => $key, value => login_cas_url($query, $key) . "?cas=$key" }; + # Is authentication against multiple CAS servers enabled? + if ( C4::Auth_with_cas::multipleAuth && !$casparam ) { + my $casservers = C4::Auth_with_cas::getMultipleAuth(); + my @tmplservers; + foreach my $key ( keys %$casservers ) { + push @tmplservers, { name => $key, value => login_cas_url( $query, $key ) . "?cas=$key" }; + } + $template->param( + casServersLoop => \@tmplservers + ); + } else { + $template->param( + casServerUrl => login_cas_url($query), + ); } - $template->param( - casServersLoop => \@tmplservers - ); - } else { - $template->param( - casServerUrl => login_cas_url($query), - ); - } - $template->param( + $template->param( invalidCasLogin => $info{'invalidCasLogin'} ); } if ($shib) { - $template->param( - shibbolethAuthentication => $shib, - shibbolethLoginUrl => login_shib_url($query), - ); + $template->param( + shibbolethAuthentication => $shib, + shibbolethLoginUrl => login_shib_url($query), + ); } my $self_url = $query->url( -absolute => 1 ); @@ -1197,13 +1236,14 @@ sub checkauth { url => $self_url, LibraryName => C4::Context->preference("LibraryName"), ); - $template->param( %info ); -# $cookie = $query->cookie(CGISESSID => $session->id -# ); + $template->param(%info); + + # $cookie = $query->cookie(CGISESSID => $session->id + # ); print $query->header( - -type => 'text/html', + -type => 'text/html', -charset => 'utf-8', - -cookie => $cookie + -cookie => $cookie ), $template->output; safe_exit; @@ -1244,23 +1284,25 @@ Possible return values in C<$status> are: =cut sub check_api_auth { - my $query = shift; + my $query = shift; my $flagsrequired = shift; my $dbh = C4::Context->dbh; my $timeout = _timeout_syspref(); - unless (C4::Context->preference('Version')) { + unless ( C4::Context->preference('Version') ) { + # database has not been installed yet - return ("maintenance", undef, undef); + return ( "maintenance", undef, undef ); } - my $kohaversion=C4::Context::KOHAVERSION; + my $kohaversion = C4::Context::KOHAVERSION; $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; - if (C4::Context->preference('Version') < $kohaversion) { + if ( C4::Context->preference('Version') < $kohaversion ) { + # database in need of version update; assume that # no API should be called while databsae is in # this condition. - return ("maintenance", undef, undef); + return ( "maintenance", undef, undef ); } # FIXME -- most of what follows is a copy-and-paste @@ -1275,10 +1317,10 @@ sub check_api_auth { # a form submission, assume that any current cookie # is to be ignored my $sessionID = undef; - unless ($query->param('userid')) { + unless ( $query->param('userid') ) { $sessionID = $query->cookie("CGISESSID"); } - if ($sessionID && not ($cas && $query->param('PT')) ) { + if ( $sessionID && not( $cas && $query->param('PT') ) ) { my $session = get_session($sessionID); C4::Context->_new_userenv($sessionID); if ($session) { @@ -1290,78 +1332,84 @@ sub check_api_auth { $session->param('emailaddress'), $session->param('branchprinter') ); - my $ip = $session->param('ip'); + my $ip = $session->param('ip'); my $lasttime = $session->param('lasttime'); - my $userid = $session->param('id'); + my $userid = $session->param('id'); if ( $lasttime < time() - $timeout ) { + # time out $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); $userid = undef; $sessionID = undef; - return ("expired", undef, undef); + return ( "expired", undef, undef ); } elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) { + # IP address changed $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); $userid = undef; $sessionID = undef; - return ("expired", undef, undef); + return ( "expired", undef, undef ); } else { my $cookie = $query->cookie( - -name => 'CGISESSID', - -value => $session->id, + -name => 'CGISESSID', + -value => $session->id, -HttpOnly => 1, ); - $session->param('lasttime',time()); - my $flags = haspermission($userid, $flagsrequired); + $session->param( 'lasttime', time() ); + my $flags = haspermission( $userid, $flagsrequired ); if ($flags) { - return ("ok", $cookie, $sessionID); + return ( "ok", $cookie, $sessionID ); } else { $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); $userid = undef; $sessionID = undef; - return ("failed", undef, undef); + return ( "failed", undef, undef ); } } } else { - return ("expired", undef, undef); + return ( "expired", undef, undef ); } } else { + # new login - my $userid = $query->param('userid'); + my $userid = $query->param('userid'); my $password = $query->param('password'); - my ($return, $cardnumber); + my ( $return, $cardnumber ); - # Proxy CAS auth - if ($cas && $query->param('PT')) { - my $retuserid; - $debug and print STDERR "## check_api_auth - checking CAS\n"; - # In case of a CAS authentication, we use the ticket instead of the password - my $PT = $query->param('PT'); - ($return,$cardnumber,$userid) = check_api_auth_cas($dbh, $PT, $query); # EXTERNAL AUTH - } else { - # User / password auth - unless ($userid and $password) { - # caller did something wrong, fail the authenticateion - return ("failed", undef, undef); + # Proxy CAS auth + if ( $cas && $query->param('PT') ) { + my $retuserid; + $debug and print STDERR "## check_api_auth - checking CAS\n"; + + # In case of a CAS authentication, we use the ticket instead of the password + my $PT = $query->param('PT'); + ( $return, $cardnumber, $userid ) = check_api_auth_cas( $dbh, $PT, $query ); # EXTERNAL AUTH + } else { + + # User / password auth + unless ( $userid and $password ) { + + # caller did something wrong, fail the authenticateion + return ( "failed", undef, undef ); + } + ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password, $query ); } - ( $return, $cardnumber ) = checkpw( $dbh, $userid, $password, $query ); - } - if ($return and haspermission( $userid, $flagsrequired)) { + if ( $return and haspermission( $userid, $flagsrequired ) ) { my $session = get_session(""); - return ("failed", undef, undef) unless $session; + return ( "failed", undef, undef ) unless $session; my $sessionID = $session->id; C4::Context->_new_userenv($sessionID); my $cookie = $query->cookie( - -name => 'CGISESSID', - -value => $sessionID, + -name => 'CGISESSID', + -value => $sessionID, -HttpOnly => 1, ); if ( $return == 1 ) { @@ -1381,10 +1429,10 @@ sub check_api_auth { $branchprinter, $emailaddress ) = $sth->fetchrow if ( $sth->rows ); - unless ($sth->rows ) { + unless ( $sth->rows ) { my $sth = $dbh->prepare( "select borrowernumber, firstname, surname, flags, borrowers.branchcode, branches.branchname as branchname, branches.branchprinter as branchprinter, email from borrowers left join branches on borrowers.branchcode=branches.branchcode where cardnumber=?" - ); + ); $sth->execute($cardnumber); ( $borrowernumber, $firstname, $surname, @@ -1395,21 +1443,23 @@ sub check_api_auth { unless ( $sth->rows ) { $sth->execute($userid); ( - $borrowernumber, $firstname, $surname, $userflags, - $branchcode, $branchname, $branchprinter, $emailaddress + $borrowernumber, $firstname, $surname, $userflags, + $branchcode, $branchname, $branchprinter, $emailaddress ) = $sth->fetchrow if ( $sth->rows ); } } - my $ip = $ENV{'REMOTE_ADDR'}; + my $ip = $ENV{'REMOTE_ADDR'}; + # if they specify at login, use that - if ($query->param('branch')) { - $branchcode = $query->param('branch'); + if ( $query->param('branch') ) { + $branchcode = $query->param('branch'); $branchname = GetBranchName($branchcode); } my $branches = GetBranches(); my @branchesloop; foreach my $br ( keys %$branches ) { + # now we work with the treatment of ip my $domain = $branches->{$br}->{'branchip'}; if ( $domain && $ip =~ /^$domain/ ) { @@ -1420,30 +1470,31 @@ sub check_api_auth { $branchname = $branches->{$br}->{'branchname'}; } } - $session->param('number',$borrowernumber); - $session->param('id',$userid); - $session->param('cardnumber',$cardnumber); - $session->param('firstname',$firstname); - $session->param('surname',$surname); - $session->param('branch',$branchcode); - $session->param('branchname',$branchname); - $session->param('flags',$userflags); - $session->param('emailaddress',$emailaddress); - $session->param('ip',$session->remote_addr()); - $session->param('lasttime',time()); + $session->param( 'number', $borrowernumber ); + $session->param( 'id', $userid ); + $session->param( 'cardnumber', $cardnumber ); + $session->param( 'firstname', $firstname ); + $session->param( 'surname', $surname ); + $session->param( 'branch', $branchcode ); + $session->param( 'branchname', $branchname ); + $session->param( 'flags', $userflags ); + $session->param( 'emailaddress', $emailaddress ); + $session->param( 'ip', $session->remote_addr() ); + $session->param( 'lasttime', time() ); } elsif ( $return == 2 ) { + #We suppose the user is the superlibrarian - $session->param('number',0); - $session->param('id',C4::Context->config('user')); - $session->param('cardnumber',C4::Context->config('user')); - $session->param('firstname',C4::Context->config('user')); - $session->param('surname',C4::Context->config('user')); - $session->param('branch','NO_LIBRARY_SET'); - $session->param('branchname','NO_LIBRARY_SET'); - $session->param('flags',1); - $session->param('emailaddress', C4::Context->preference('KohaAdminEmailAddress')); - $session->param('ip',$session->remote_addr()); - $session->param('lasttime',time()); + $session->param( 'number', 0 ); + $session->param( 'id', C4::Context->config('user') ); + $session->param( 'cardnumber', C4::Context->config('user') ); + $session->param( 'firstname', C4::Context->config('user') ); + $session->param( 'surname', C4::Context->config('user') ); + $session->param( 'branch', 'NO_LIBRARY_SET' ); + $session->param( 'branchname', 'NO_LIBRARY_SET' ); + $session->param( 'flags', 1 ); + $session->param( 'emailaddress', C4::Context->preference('KohaAdminEmailAddress') ); + $session->param( 'ip', $session->remote_addr() ); + $session->param( 'lasttime', time() ); } C4::Context::set_userenv( $session->param('number'), $session->param('id'), @@ -1452,9 +1503,9 @@ sub check_api_auth { $session->param('branchname'), $session->param('flags'), $session->param('emailaddress'), $session->param('branchprinter') ); - return ("ok", $cookie, $sessionID); + return ( "ok", $cookie, $sessionID ); } else { - return ("failed", undef, undef); + return ( "failed", undef, undef ); } } } @@ -1487,23 +1538,25 @@ Possible return values in C<$status> are: =cut sub check_cookie_auth { - my $cookie = shift; + my $cookie = shift; my $flagsrequired = shift; my $dbh = C4::Context->dbh; my $timeout = _timeout_syspref(); - unless (C4::Context->preference('Version')) { + unless ( C4::Context->preference('Version') ) { + # database has not been installed yet - return ("maintenance", undef); + return ( "maintenance", undef ); } - my $kohaversion=C4::Context::KOHAVERSION; + my $kohaversion = C4::Context::KOHAVERSION; $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; - if (C4::Context->preference('Version') < $kohaversion) { + if ( C4::Context->preference('Version') < $kohaversion ) { + # database in need of version update; assume that # no API should be called while databsae is in # this condition. - return ("maintenance", undef); + return ( "maintenance", undef ); } # FIXME -- most of what follows is a copy-and-paste @@ -1517,11 +1570,11 @@ sub check_cookie_auth { # however, if a userid parameter is present (i.e., from # a form submission, assume that any current cookie # is to be ignored - unless (defined $cookie and $cookie) { - return ("failed", undef); + unless ( defined $cookie and $cookie ) { + return ( "failed", undef ); } my $sessionID = $cookie; - my $session = get_session($sessionID); + my $session = get_session($sessionID); C4::Context->_new_userenv($sessionID); if ($session) { C4::Context::set_userenv( @@ -1532,41 +1585,43 @@ sub check_cookie_auth { $session->param('emailaddress'), $session->param('branchprinter') ); - my $ip = $session->param('ip'); + my $ip = $session->param('ip'); my $lasttime = $session->param('lasttime'); - my $userid = $session->param('id'); + my $userid = $session->param('id'); if ( $lasttime < time() - $timeout ) { + # time out $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); $userid = undef; $sessionID = undef; - return ("expired", undef); + return ( "expired", undef ); } elsif ( $ip ne $ENV{'REMOTE_ADDR'} ) { + # IP address changed $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); $userid = undef; $sessionID = undef; - return ("expired", undef); + return ( "expired", undef ); } else { - $session->param('lasttime',time()); - my $flags = haspermission($userid, $flagsrequired); + $session->param( 'lasttime', time() ); + my $flags = haspermission( $userid, $flagsrequired ); if ($flags) { - return ("ok", $sessionID); + return ( "ok", $sessionID ); } else { $session->delete(); $session->flush; C4::Context->_unset_userenv($sessionID); $userid = undef; $sessionID = undef; - return ("failed", undef); + return ( "failed", undef ); } } } else { - return ("expired", undef); + return ( "expired", undef ); } } @@ -1586,22 +1641,22 @@ will be created. =cut sub get_session { - my $sessionID = shift; + my $sessionID = shift; my $storage_method = C4::Context->preference('SessionStorage'); - my $dbh = C4::Context->dbh; + my $dbh = C4::Context->dbh; my $session; - if ($storage_method eq 'mysql'){ - $session = new CGI::Session("driver:MySQL;serializer:yaml;id:md5", $sessionID, {Handle=>$dbh}); + if ( $storage_method eq 'mysql' ) { + $session = new CGI::Session( "driver:MySQL;serializer:yaml;id:md5", $sessionID, { Handle => $dbh } ); } - elsif ($storage_method eq 'Pg') { - $session = new CGI::Session("driver:PostgreSQL;serializer:yaml;id:md5", $sessionID, {Handle=>$dbh}); + elsif ( $storage_method eq 'Pg' ) { + $session = new CGI::Session( "driver:PostgreSQL;serializer:yaml;id:md5", $sessionID, { Handle => $dbh } ); } - elsif ($storage_method eq 'memcached' && C4::Context->ismemcached){ - $session = new CGI::Session("driver:memcached;serializer:yaml;id:md5", $sessionID, { Memcached => C4::Context->memcached } ); + elsif ( $storage_method eq 'memcached' && C4::Context->ismemcached ) { + $session = new CGI::Session( "driver:memcached;serializer:yaml;id:md5", $sessionID, { Memcached => C4::Context->memcached } ); } else { # catch all defaults to tmp should work on all systems - $session = new CGI::Session("driver:File;serializer:yaml;id:md5", $sessionID, {Directory=>'/tmp'}); + $session = new CGI::Session( "driver:File;serializer:yaml;id:md5", $sessionID, { Directory => '/tmp' } ); } return $session; } @@ -1610,34 +1665,36 @@ sub checkpw { my ( $dbh, $userid, $password, $query ) = @_; if ($ldap) { $debug and print STDERR "## checkpw - checking LDAP\n"; - my ($retval,$retcard,$retuserid) = checkpw_ldap(@_); # EXTERNAL AUTH - return 0 if $retval == -1; # Incorrect password for LDAP login attempt - ($retval) and return ($retval,$retcard,$retuserid); + my ( $retval, $retcard, $retuserid ) = checkpw_ldap(@_); # EXTERNAL AUTH + return 0 if $retval == -1; # Incorrect password for LDAP login attempt + ($retval) and return ( $retval, $retcard, $retuserid ); } - if ($cas && $query && $query->param('ticket')) { + if ( $cas && $query && $query->param('ticket') ) { $debug and print STDERR "## checkpw - checking CAS\n"; - # In case of a CAS authentication, we use the ticket instead of the password + + # In case of a CAS authentication, we use the ticket instead of the password my $ticket = $query->param('ticket'); - $query->delete('ticket'); # remove ticket to come back to original URL - my ($retval,$retcard,$retuserid) = checkpw_cas($dbh, $ticket, $query); # EXTERNAL AUTH - ($retval) and return ($retval,$retcard,$retuserid); + $query->delete('ticket'); # remove ticket to come back to original URL + my ( $retval, $retcard, $retuserid ) = checkpw_cas( $dbh, $ticket, $query ); # EXTERNAL AUTH + ($retval) and return ( $retval, $retcard, $retuserid ); return 0; } # If we are in a shibboleth session (shibboleth is enabled, and a shibboleth match attribute is present) # Check for password to asertain whether we want to be testing against shibboleth or another method this # time around. - if ($shib && $shib_login && !$password) { + if ( $shib && $shib_login && !$password ) { $debug and print STDERR "## checkpw - checking Shibboleth\n"; + # In case of a Shibboleth authentication, we expect a shibboleth user attribute # (defined under shibboleth mapping in koha-conf.xml) to contain the login of the # shibboleth-authenticated user # Then, we check if it matches a valid koha user if ($shib_login) { - my ( $retval, $retcard, $retuserid ) = C4::Auth_with_shibboleth::checkpw_shib( $shib_login ); # EXTERNAL AUTH + my ( $retval, $retcard, $retuserid ) = C4::Auth_with_shibboleth::checkpw_shib($shib_login); # EXTERNAL AUTH ($retval) and return ( $retval, $retcard, $retuserid ); return 0; } @@ -1652,8 +1709,9 @@ sub checkpw_internal { if ( $userid && $userid eq C4::Context->config('user') ) { if ( $password && $password eq C4::Context->config('pass') ) { - # Koha superuser account -# C4::Context->set_userenv(0,0,C4::Context->config('user'),C4::Context->config('user'),C4::Context->config('user'),"",1); + + # Koha superuser account + # C4::Context->set_userenv(0,0,C4::Context->config('user'),C4::Context->config('user'),C4::Context->config('user'),"",1); return 2; } else { @@ -1663,7 +1721,7 @@ sub checkpw_internal { my $sth = $dbh->prepare( -"select password,cardnumber,borrowernumber,userid,firstname,surname,branchcode,flags from borrowers where userid=?" + "select password,cardnumber,borrowernumber,userid,firstname,surname,branchcode,flags from borrowers where userid=?" ); $sth->execute($userid); if ( $sth->rows ) { @@ -1671,7 +1729,7 @@ sub checkpw_internal { $surname, $branchcode, $flags ) = $sth->fetchrow; - if ( checkpw_hash($password, $stored_hash) ) { + if ( checkpw_hash( $password, $stored_hash ) ) { C4::Context->set_userenv( "$borrowernumber", $userid, $cardnumber, $firstname, $surname, $branchcode, $flags ); @@ -1680,7 +1738,7 @@ sub checkpw_internal { } $sth = $dbh->prepare( -"select password,cardnumber,borrowernumber,userid, firstname,surname,branchcode,flags from borrowers where cardnumber=?" + "select password,cardnumber,borrowernumber,userid, firstname,surname,branchcode,flags from borrowers where cardnumber=?" ); $sth->execute($userid); if ( $sth->rows ) { @@ -1688,20 +1746,20 @@ sub checkpw_internal { $surname, $branchcode, $flags ) = $sth->fetchrow; - if ( checkpw_hash($password, $stored_hash) ) { + if ( checkpw_hash( $password, $stored_hash ) ) { C4::Context->set_userenv( $borrowernumber, $userid, $cardnumber, $firstname, $surname, $branchcode, $flags ); return 1, $cardnumber, $userid; } } - if ( $userid && $userid eq 'demo' + if ( $userid && $userid eq 'demo' && "$password" eq 'demo' && C4::Context->config('demo') ) { -# DEMO => the demo user is allowed to do everything (if demo set to 1 in koha.conf -# some features won't be effective : modify systempref, modify MARC structure, + # DEMO => the demo user is allowed to do everything (if demo set to 1 in koha.conf + # some features won't be effective : modify systempref, modify MARC structure, return 2; } return 0; @@ -1714,8 +1772,8 @@ sub checkpw_hash { # check what encryption algorithm was implemented: Bcrypt - if the hash starts with '$2' it is Bcrypt else md5 my $hash; - if ( substr($stored_hash,0,2) eq '$2') { - $hash = hash_password($password, $stored_hash); + if ( substr( $stored_hash, 0, 2 ) eq '$2' ) { + $hash = hash_password( $password, $stored_hash ); } else { $hash = md5_base64($password); } @@ -1735,9 +1793,9 @@ C<$authflags> is a hashref of permissions =cut sub getuserflags { - my $flags = shift; - my $userid = shift; - my $dbh = @_ ? shift : C4::Context->dbh; + my $flags = shift; + my $userid = shift; + my $dbh = @_ ? shift : C4::Context->dbh; my $userflags; { # I don't want to do this, but if someone logs in as the database @@ -1757,10 +1815,11 @@ sub getuserflags { $userflags->{$flag} = 0; } } + # get subpermissions and merge with top-level permissions my $user_subperms = get_user_subpermissions($userid); - foreach my $module (keys %$user_subperms) { - next if $userflags->{$module} == 1; # user already has permission for everything in this module + foreach my $module ( keys %$user_subperms ) { + next if $userflags->{$module} == 1; # user already has permission for everything in this module $userflags->{$module} = $user_subperms->{$module}; } @@ -1796,17 +1855,17 @@ sub get_user_subpermissions { my $userid = shift; my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare("SELECT flag, user_permissions.code + my $sth = $dbh->prepare( "SELECT flag, user_permissions.code FROM user_permissions JOIN permissions USING (module_bit, code) JOIN userflags ON (module_bit = bit) JOIN borrowers USING (borrowernumber) - WHERE userid = ?"); + WHERE userid = ?" ); $sth->execute($userid); my $user_perms = {}; - while (my $perm = $sth->fetchrow_hashref) { - $user_perms->{$perm->{'flag'}}->{$perm->{'code'}} = 1; + while ( my $perm = $sth->fetchrow_hashref ) { + $user_perms->{ $perm->{'flag'} }->{ $perm->{'code'} } = 1; } return $user_perms; } @@ -1825,14 +1884,14 @@ of the subpermission. sub get_all_subpermissions { my $dbh = C4::Context->dbh; - my $sth = $dbh->prepare("SELECT flag, code, description + my $sth = $dbh->prepare( "SELECT flag, code, description FROM permissions - JOIN userflags ON (module_bit = bit)"); + JOIN userflags ON (module_bit = bit)" ); $sth->execute(); my $all_perms = {}; - while (my $perm = $sth->fetchrow_hashref) { - $all_perms->{$perm->{'flag'}}->{$perm->{'code'}} = $perm->{'description'}; + while ( my $perm = $sth->fetchrow_hashref ) { + $all_perms->{ $perm->{'flag'} }->{ $perm->{'code'} } = $perm->{'description'}; } return $all_perms; } @@ -1849,16 +1908,18 @@ Returns member's flags or 0 if a permission is not met. =cut sub haspermission { - my ($userid, $flagsrequired) = @_; + my ( $userid, $flagsrequired ) = @_; my $sth = C4::Context->dbh->prepare("SELECT flags FROM borrowers WHERE userid=?"); $sth->execute($userid); my $row = $sth->fetchrow(); - my $flags = getuserflags($row, $userid); + my $flags = getuserflags( $row, $userid ); if ( $userid eq C4::Context->config('user') ) { + # Super User Account from /etc/koha.conf $flags->{'superlibrarian'} = 1; } elsif ( $userid eq 'demo' && C4::Context->config('demo') ) { + # Demo user that can do "anything" (demo=1 in /etc/koha.conf) $flags->{'superlibrarian'} = 1; } @@ -1867,26 +1928,26 @@ sub haspermission { foreach my $module ( keys %$flagsrequired ) { my $subperm = $flagsrequired->{$module}; - if ($subperm eq '*') { - return 0 unless ( $flags->{$module} == 1 or ref($flags->{$module}) ); + if ( $subperm eq '*' ) { + return 0 unless ( $flags->{$module} == 1 or ref( $flags->{$module} ) ); } else { return 0 unless ( $flags->{$module} == 1 or - ( ref($flags->{$module}) and - exists $flags->{$module}->{$subperm} and - $flags->{$module}->{$subperm} == 1 - ) - ); + ( ref( $flags->{$module} ) and + exists $flags->{$module}->{$subperm} and + $flags->{$module}->{$subperm} == 1 + ) + ); } } return $flags; + #FIXME - This fcn should return the failed permission so a suitable error msg can be delivered. } - sub getborrowernumber { my ($userid) = @_; my $userenv = C4::Context->userenv; - if ( defined( $userenv ) && ref( $userenv ) eq 'HASH' && $userenv->{number} ) { + if ( defined($userenv) && ref($userenv) eq 'HASH' && $userenv->{number} ) { return $userenv->{number}; } my $dbh = C4::Context->dbh; -- 1.7.10.4