X-Git-Url: http://git.rot13.org/?a=blobdiff_plain;ds=sidebyside;f=C4%2FAuth.pm;h=fcf7c486735209d9c505e32c36aa87f1b45e74e6;hb=3cf4d92a5f2b7cd4a15913e96108f79323978000;hp=345fd44ac84668ffe53c2dc37b9ddb19a0e7d7e1;hpb=0c6ba2d0c4dde4237de9bcd3995254a4387b1fbe;p=koha.git diff --git a/C4/Auth.pm b/C4/Auth.pm index 345fd44ac8..fcf7c48673 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -4,22 +4,23 @@ package C4::Auth; # # This file is part of Koha. # -# Koha is free software; you can redistribute it and/or modify it under the -# terms of the GNU General Public License as published by the Free Software -# Foundation; either version 2 of the License, or (at your option) any later -# version. +# Koha is free software; you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 3 of the License, or +# (at your option) any later version. # -# Koha is distributed in the hope that it will be useful, but WITHOUT ANY -# WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR -# A PARTICULAR PURPOSE. See the GNU General Public License for more details. +# Koha is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# You should have received a copy of the GNU General Public License along -# with Koha; if not, write to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. +# You should have received a copy of the GNU General Public License +# along with Koha; if not, see . use strict; use warnings; use Digest::MD5 qw(md5_base64); +use File::Spec; use JSON qw/encode_json/; use URI::Escape; use CGI::Session; @@ -28,16 +29,18 @@ require Exporter; use C4::Context; use C4::Templates; # to get the template use C4::Languages; -use C4::Branch; # GetBranches use C4::Search::History; -use C4::VirtualShelves; -use Koha::AuthUtils qw(hash_password); +use Koha; +use Koha::Caches; +use Koha::AuthUtils qw(get_script_name hash_password); +use Koha::Libraries; +use Koha::LibraryCategories; use POSIX qw/strftime/; use List::MoreUtils qw/ any /; use Encode qw( encode is_utf8); # use utf8; -use vars qw($VERSION @ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $caslogout $shib $shib_login); +use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $caslogout $shib $shib_login); BEGIN { sub psgi_env { any { /^psgi\./ } keys %ENV } @@ -46,7 +49,6 @@ BEGIN { if (psgi_env) { die 'psgi:exit' } else { exit } } - $VERSION = 3.07.00.049; # set version for version checking $debug = $ENV{DEBUG}; @ISA = qw(Exporter); @@ -107,7 +109,7 @@ C4::Auth - Authenticates Koha users query => $query, type => "opac", authnotrequired => 0, - flagsrequired => {borrow => 1, catalogue => '*', tools => 'import_patrons' }, + flagsrequired => { catalogue => '*', tools => 'import_patrons' }, } ); @@ -131,7 +133,7 @@ automatically. This gets loaded into the template. query => $query, type => "opac", authnotrequired => 0, - flagsrequired => {borrow => 1, catalogue => '*', tools => 'import_patrons' }, + flagsrequired => { catalogue => '*', tools => 'import_patrons' }, } ); @@ -158,6 +160,9 @@ sub get_template_and_user { C4::Context->interface( $in->{type} ); + my $safe_chars = 'a-zA-Z0-9_\-\/'; + die "bad template path" unless $in->{'template_name'} =~ m/^[$safe_chars]+\.tt$/ig; #sanitize input + $in->{'authnotrequired'} ||= 0; my $template = C4::Templates::gettemplate( $in->{'template_name'}, @@ -175,6 +180,34 @@ sub get_template_and_user { ); } + + # If the user logged in is the SCO user and he tries to go out the SCO module, log the user out removing the CGISESSID cookie + if ( $in->{type} eq 'opac' and $in->{template_name} !~ m|sco/| ) { + if ( C4::Context->preference('AutoSelfCheckID') && $user eq C4::Context->preference('AutoSelfCheckID') ) { + $template = C4::Templates::gettemplate( 'opac-auth.tt', 'opac', $in->{query} ); + my $cookie = $in->{query}->cookie( + -name => 'CGISESSID', + -value => '', + -expires => '', + -HttpOnly => 1, + ); + + $template->param( + loginprompt => 1, + script_name => get_script_name(), + ); + print $in->{query}->header( + { type => 'text/html', + charset => 'utf-8', + cookie => $cookie, + 'X-Frame-Options' => 'SAMEORIGIN' + } + ), + $template->output; + safe_exit; + } + } + my $borrowernumber; if ($user) { require C4::Members; @@ -182,9 +215,10 @@ sub get_template_and_user { # 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) + my $borrower; $borrowernumber = getborrowernumber($user) if defined($user); if ( !defined($borrowernumber) && defined($user) ) { - my $borrower = C4::Members::GetMember( borrowernumber => $user ); + $borrower = C4::Members::GetMember( borrowernumber => $user ); if ($borrower) { $borrowernumber = $user; @@ -192,6 +226,8 @@ sub get_template_and_user { # to do it. $user = $borrower->{firstname} . ' ' . $borrower->{surname}; } + } else { + $borrower = C4::Members::GetMember( borrowernumber => $borrowernumber ); } # user info @@ -199,18 +235,26 @@ sub get_template_and_user { $template->param( loggedinusernumber => $borrowernumber ); $template->param( sessionID => $sessionID ); - my ( $total, $pubshelves, $barshelves ) = C4::VirtualShelves::GetSomeShelfNames( $borrowernumber, 'MASTHEAD' ); - $template->param( - pubshelves => $total->{pubtotal}, - pubshelvesloop => $pubshelves, - barshelves => $total->{bartotal}, - barshelvesloop => $barshelves, - ); + if ( $in->{'type'} eq 'opac' ) { + require Koha::Virtualshelves; + my $some_private_shelves = Koha::Virtualshelves->get_some_shelves( + { + borrowernumber => $borrowernumber, + category => 1, + } + ); + my $some_public_shelves = Koha::Virtualshelves->get_some_shelves( + { + category => 2, + } + ); + $template->param( + some_private_shelves => $some_private_shelves, + some_public_shelves => $some_public_shelves, + ); + } - my ($borr) = C4::Members::GetMemberDetails($borrowernumber); - my @bordat; - $bordat[0] = $borr; - $template->param( "USER_INFO" => \@bordat ); + $template->param( "USER_INFO" => $borrower ); my $all_perms = get_all_subpermissions(); @@ -227,7 +271,6 @@ sub get_template_and_user { $template->param( CAN_user_borrowers => 1 ); $template->param( CAN_user_permissions => 1 ); $template->param( CAN_user_reserveforothers => 1 ); - $template->param( CAN_user_borrow => 1 ); $template->param( CAN_user_editcatalogue => 1 ); $template->param( CAN_user_updatecharges => 1 ); $template->param( CAN_user_acquisition => 1 ); @@ -249,7 +292,7 @@ sub get_template_and_user { if ($flags) { foreach my $module ( keys %$all_perms ) { - if ( $flags->{$module} == 1 ) { + if ( defined($flags->{$module}) && $flags->{$module} == 1 ) { foreach my $subperm ( keys %{ $all_perms->{$module} } ) { $template->param( "CAN_user_${module}_${subperm}" => 1 ); } @@ -318,7 +361,7 @@ 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. + # the user to attempt login via shibboleth. if ($shib) { $template->param( shibbolethAuthentication => $shib, shibbolethLoginUrl => login_shib_url( $in->{'query'} ), @@ -334,11 +377,17 @@ sub get_template_and_user { $template->param( sessionID => $sessionID ); - my ( $total, $pubshelves ) = C4::VirtualShelves::GetSomeShelfNames( undef, 'MASTHEAD' ); - $template->param( - pubshelves => $total->{pubtotal}, - pubshelvesloop => $pubshelves, - ); + if ( $in->{'type'} eq 'opac' ){ + require Koha::Virtualshelves; + my $some_public_shelves = Koha::Virtualshelves->get_some_shelves( + { + category => 2, + } + ); + $template->param( + some_public_shelves => $some_public_shelves, + ); + } } # Anonymous opac search history @@ -354,6 +403,8 @@ sub get_template_and_user { $template->param( dateformat => C4::Context->preference('dateformat') ); } + $template->param(auth_forwarded_hash => scalar $in->{'query'}->param('auth_forwarded_hash')); + # these template parameters are set the same regardless of $in->{'type'} # Set the using_https variable for templates @@ -376,20 +427,20 @@ sub get_template_and_user { 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"), + singleBranchMode => ( Koha::Libraries->search->count == 1 ), 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"), + OPACBaseURL => C4::Context->preference('OPACBaseURL'), ); 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"), @@ -404,7 +455,7 @@ sub get_template_and_user { intranetreadinghistory => C4::Context->preference("intranetreadinghistory"), intranetstylesheet => C4::Context->preference("intranetstylesheet"), IntranetUserCSS => C4::Context->preference("IntranetUserCSS"), - intranetuserjs => C4::Context->preference("intranetuserjs"), + IntranetUserJS => C4::Context->preference("IntranetUserJS"), intranetbookbag => C4::Context->preference("intranetbookbag"), suggestion => C4::Context->preference("suggestion"), virtualshelves => C4::Context->preference("virtualshelves"), @@ -416,6 +467,7 @@ sub get_template_and_user { EnableBorrowerFiles => C4::Context->preference('EnableBorrowerFiles'), UseKohaPlugins => C4::Context->preference('UseKohaPlugins'), UseCourseReserves => C4::Context->preference("UseCourseReserves"), + useDischarge => C4::Context->preference('useDischarge'), ); } else { @@ -426,12 +478,15 @@ sub get_template_and_user { $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 + # clean up the busc param in the session + # if the page is not opac-detail and not the "add to list" page + # and not the "edit comments" page if ( C4::Context->preference("OpacBrowseResults") && $in->{'template_name'} =~ /opac-(.+)\.(?:tt|tmpl)$/ ) { my $pagename = $1; unless ( $pagename =~ /^(?:MARC|ISBD)?detail$/ - or $pagename =~ /^addbybiblionumber$/ ) { + or $pagename =~ /^addbybiblionumber$/ + or $pagename =~ /^review$/ ) { my $sessionSearch = get_session( $sessionID || $in->{'query'}->cookie("CGISESSID") ); $sessionSearch->clear( ["busc"] ) if ( $sessionSearch->param("busc") ); } @@ -453,18 +508,12 @@ sub get_template_and_user { $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 $library_categories = Koha::LibraryCategories->search({categorytype => 'searchdomain', show_in_pulldown => 1}, { order_by => ['categorytype', 'categorycode']}); $template->param( - opaccolorstylesheet => C4::Context->preference("opaccolorstylesheet"), + OpacAdditionalStylesheet => C4::Context->preference("OpacAdditionalStylesheet"), 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, + BranchCategoriesLoop => $library_categories, + opac_name => $opac_name, LibraryName => "" . C4::Context->preference("LibraryName"), LibraryNameTitle => "" . $LibraryNameTitle, LoginBranchname => C4::Context->userenv ? C4::Context->userenv->{"branchname"} : "", @@ -474,9 +523,7 @@ sub get_template_and_user { 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, @@ -503,8 +550,9 @@ sub get_template_and_user { opacheader => "" . C4::Context->preference("opacheader"), opaclanguagesdisplay => "" . C4::Context->preference("opaclanguagesdisplay"), opacreadinghistory => C4::Context->preference("opacreadinghistory"), - opacuserjs => C4::Context->preference("opacuserjs"), + OPACUserJS => C4::Context->preference("OPACUserJS"), opacuserlogin => "" . C4::Context->preference("opacuserlogin"), + OpenLibrarySearch => C4::Context->preference("OpenLibrarySearch"), ShowReviewer => C4::Context->preference("ShowReviewer"), ShowReviewerPhoto => C4::Context->preference("ShowReviewerPhoto"), suggestion => "" . C4::Context->preference("suggestion"), @@ -527,6 +575,7 @@ sub get_template_and_user { OPACLocalCoverImages => C4::Context->preference("OPACLocalCoverImages"), PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"), PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"), + useDischarge => C4::Context->preference('useDischarge'), ); $template->param( OpacPublic => '1' ) if ( $user || C4::Context->preference("OpacPublic") ); @@ -632,7 +681,7 @@ sub _version_check { my $query = shift; my $version; - # If Version syspref is unavailable, it means Koha is beeing installed, + # If version syspref is unavailable, it means Koha is being 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' ) { @@ -655,7 +704,7 @@ 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 = Koha::version(); # remove the 3 last . to have a Perl number $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; @@ -664,7 +713,7 @@ sub _version_check { my $warning = "Database update needed, redirecting to %s. Database is $version and Koha is $kohaversion"; if ( $type ne 'opac' ) { warn sprintf( $warning, 'Installer' ); - print $query->redirect("/cgi-bin/koha/installer/install.pl?step=3"); + print $query->redirect("/cgi-bin/koha/installer/install.pl?step=1&op=updatestructure"); } else { warn sprintf( "OPAC: " . $warning, 'maintenance' ); print $query->redirect("/cgi-bin/koha/maintenance.pl"); @@ -709,7 +758,7 @@ sub checkauth { # state variables my $loggedin = 0; my %info; - my ( $userid, $cookie, $sessionID, $flags, $barshelves, $pubshelves ); + my ( $userid, $cookie, $sessionID, $flags ); my $logout = $query->param('logout.x'); my $anon_search_history; @@ -741,7 +790,7 @@ sub checkauth { } elsif ($persona) { - # we dont want to set a session because we are being called by a persona callback + # we don't want to set a session because we are being called by a persona callback } elsif ( $sessionID = $query->cookie("CGISESSID") ) { # assignment, not comparison @@ -769,7 +818,9 @@ sub checkauth { $sessiontype = $session->param('sessiontype') || ''; } if ( ( $query->param('koha_login_context') && ( $q_userid ne $s_userid ) ) - || ( $cas && $query->param('ticket') && !C4::Context->userenv->{'id'} ) || ( $shib && $shib_login && !$logout ) ) { + || ( $cas && $query->param('ticket') && !C4::Context->userenv->{'id'} ) + || ( $shib && $shib_login && !$logout && !C4::Context->userenv->{'id'} ) + ) { #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... @@ -794,8 +845,8 @@ sub checkauth { $sessionID = undef; $userid = undef; - if ( $cas and $caslogout ) { - logout_cas($query); + if ($cas and $caslogout) { + logout_cas($query, $type); } # If we are in a shibboleth session (shibboleth is enabled, a shibboleth match attribute is set and matches koha matchpoint) @@ -897,12 +948,12 @@ sub checkauth { $info{'invalidShibLogin'} = 1 unless ($return); } - # If shib login and match were successfull, skip further login methods + # If shib login and match were successful, skip further login methods unless ($shibSuccess) { if ( $cas && $query->param('ticket') ) { my $retuserid; ( $return, $cardnumber, $retuserid ) = - checkpw( $dbh, $userid, $password, $query ); + checkpw( $dbh, $userid, $password, $query, $type ); $userid = $retuserid; $info{'invalidCasLogin'} = 1 unless ($return); } @@ -963,7 +1014,7 @@ sub checkauth { else { my $retuserid; ( $return, $cardnumber, $retuserid ) = - checkpw( $dbh, $userid, $password, $query ); + checkpw( $dbh, $userid, $password, $query, $type ); $userid = $retuserid if ($retuserid); $info{'invalid_username_or_password'} = 1 unless ($return); } @@ -1024,9 +1075,10 @@ sub checkauth { # if they specify at login, use that if ( $query->param('branch') ) { $branchcode = $query->param('branch'); - $branchname = GetBranchName($branchcode); + my $library = Koha::Libraries->find($branchcode); + $branchname = $library? $library->branchname: ''; } - my $branches = GetBranches(); + my $branches = { map { $_->branchcode => $_->unblessed } Koha::Libraries->search }; if ( C4::Context->boolean_preference('IndependentBranches') && C4::Context->boolean_preference('Autolocation') ) { # we have to check they are coming from the right ip range @@ -1037,7 +1089,6 @@ sub checkauth { } } - my @branchesloop; foreach my $br ( keys %$branches ) { # now we work with the treatment of ip @@ -1154,11 +1205,11 @@ sub checkauth { my $template_name = ( $type eq 'opac' ) ? 'opac-auth.tt' : 'auth.tt'; my $template = C4::Templates::gettemplate( $template_name, $type, $query ); $template->param( - branchloop => GetBranchesLoop(), - opaccolorstylesheet => C4::Context->preference("opaccolorstylesheet"), + OpacAdditionalStylesheet => C4::Context->preference("OpacAdditionalStylesheet"), opaclayoutstylesheet => C4::Context->preference("opaclayoutstylesheet"), login => 1, INPUTS => \@inputs, + script_name => get_script_name(), casAuthentication => C4::Context->preference("casAuthentication"), shibbolethAuthentication => $shib, SessionRestrictionByIP => C4::Context->preference("SessionRestrictionByIP"), @@ -1174,7 +1225,7 @@ sub checkauth { OpacFavicon => C4::Context->preference("OpacFavicon"), opacreadinghistory => C4::Context->preference("opacreadinghistory"), opaclanguagesdisplay => C4::Context->preference("opaclanguagesdisplay"), - opacuserjs => C4::Context->preference("opacuserjs"), + OPACUserJS => C4::Context->preference("OPACUserJS"), opacbookbag => "" . C4::Context->preference("opacbookbag"), OpacCloud => C4::Context->preference("OpacCloud"), OpacTopissue => C4::Context->preference("OpacTopissue"), @@ -1188,7 +1239,8 @@ sub checkauth { intranetbookbag => C4::Context->preference("intranetbookbag"), IntranetNav => C4::Context->preference("IntranetNav"), IntranetFavicon => C4::Context->preference("IntranetFavicon"), - intranetuserjs => C4::Context->preference("intranetuserjs"), + IntranetUserCSS => C4::Context->preference("IntranetUserCSS"), + IntranetUserJS => C4::Context->preference("IntranetUserJS"), IndependentBranches => C4::Context->preference("IndependentBranches"), AutoLocation => C4::Context->preference("AutoLocation"), wrongip => $info{'wrongip'}, @@ -1198,14 +1250,19 @@ sub checkauth { opac_css_override => $ENV{'OPAC_CSS_OVERRIDE'}, ); + $template->param( SCO_login => 1 ) if ( $query->param('sco_user_login') ); $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' ); + require Koha::Virtualshelves; + my $some_public_shelves = Koha::Virtualshelves->get_some_shelves( + { + category => 2, + } + ); $template->param( - pubshelves => $total->{pubtotal}, - pubshelvesloop => $pubshelves, + some_public_shelves => $some_public_shelves, ); } @@ -1216,14 +1273,14 @@ sub checkauth { 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" }; + push @tmplservers, { name => $key, value => login_cas_url( $query, $key, $type ) . "?cas=$key" }; } $template->param( casServersLoop => \@tmplservers ); } else { $template->param( - casServerUrl => login_cas_url($query), + casServerUrl => login_cas_url($query, undef, $type), ); } @@ -1239,9 +1296,14 @@ sub checkauth { ); } - my $self_url = $query->url( -absolute => 1 ); + if (C4::Context->preference('GoogleOpenIDConnect')) { + if ($query->param("OpenIDConnectFailed")) { + my $reason = $query->param('OpenIDConnectFailed'); + $template->param(invalidGoogleOpenIDConnectLogin => $reason); + } + } + $template->param( - url => $self_url, LibraryName => C4::Context->preference("LibraryName"), ); $template->param(%info); @@ -1249,9 +1311,11 @@ sub checkauth { # $cookie = $query->cookie(CGISESSID => $session->id # ); print $query->header( - -type => 'text/html', - -charset => 'utf-8', - -cookie => $cookie + { type => 'text/html', + charset => 'utf-8', + cookie => $cookie, + 'X-Frame-Options' => 'SAMEORIGIN' + } ), $template->output; safe_exit; @@ -1303,7 +1367,7 @@ sub check_api_auth { # database has not been installed yet return ( "maintenance", undef, undef ); } - my $kohaversion = C4::Context::KOHAVERSION; + my $kohaversion = Koha::version(); $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; if ( C4::Context->preference('Version') < $kohaversion ) { @@ -1462,10 +1526,10 @@ sub check_api_auth { # if they specify at login, use that if ( $query->param('branch') ) { $branchcode = $query->param('branch'); - $branchname = GetBranchName($branchcode); + my $library = Koha::Libraries->find($branchcode); + $branchname = $library? $library->branchname: ''; } - my $branches = GetBranches(); - my @branchesloop; + my $branches = { map { $_->branchcode => $_->unblessed } Koha::Libraries->search }; foreach my $br ( keys %$branches ) { # now we work with the treatment of ip @@ -1548,7 +1612,9 @@ Possible return values in C<$status> are: sub check_cookie_auth { my $cookie = shift; my $flagsrequired = shift; + my $params = shift; + my $remote_addr = $params->{remote_addr} || $ENV{REMOTE_ADDR}; my $dbh = C4::Context->dbh; my $timeout = _timeout_syspref(); @@ -1557,7 +1623,7 @@ sub check_cookie_auth { # database has not been installed yet return ( "maintenance", undef ); } - my $kohaversion = C4::Context::KOHAVERSION; + my $kohaversion = Koha::version(); $kohaversion =~ s/(.*\..*)\.(.*)\.(.*)/$1$2$3/; if ( C4::Context->preference('Version') < $kohaversion ) { @@ -1605,7 +1671,7 @@ sub check_cookie_auth { $userid = undef; $sessionID = undef; return ("expired", undef); - } elsif ( C4::Context->preference('SessionRestrictionByIP') && $ip ne $ENV{'REMOTE_ADDR'} ) { + } elsif ( C4::Context->preference('SessionRestrictionByIP') && $ip ne $remote_addr ) { # IP address changed $session->delete(); @@ -1659,18 +1725,27 @@ sub get_session { 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' && Koha::Caches->get_instance->memcached_cache ) { + my $memcached = Koha::Caches->get_instance()->memcached_cache; + $session = new CGI::Session( "driver:memcached;serializer:yaml;id:md5", $sessionID, { Memcached => $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' } ); + my $dir = File::Spec->tmpdir; + my $instance = C4::Context->config( 'database' ); #actually for packages not exactly the instance name, but generally safer to leave it as it is + $session = new CGI::Session( "driver:File;serializer:yaml;id:md5", $sessionID, { Directory => "$dir/cgisess_$instance" } ); } return $session; } + +# FIXME no_set_userenv may be replaced with force_branchcode_for_userenv +# (or something similar) +# Currently it's only passed from C4::SIP::ILS::Patron::check_password, but +# not having a userenv defined could cause a crash. sub checkpw { - my ( $dbh, $userid, $password, $query ) = @_; + my ( $dbh, $userid, $password, $query, $type, $no_set_userenv ) = @_; + $type = 'opac' unless $type; if ($ldap) { $debug and print STDERR "## checkpw - checking LDAP\n"; my ( $retval, $retcard, $retuserid ) = checkpw_ldap(@_); # EXTERNAL AUTH @@ -1684,7 +1759,7 @@ sub checkpw { # 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 + my ( $retval, $retcard, $retuserid ) = checkpw_cas( $dbh, $ticket, $query, $type ); # EXTERNAL AUTH ($retval) and return ( $retval, $retcard, $retuserid ); return 0; } @@ -1709,11 +1784,11 @@ sub checkpw { } # INTERNAL AUTH - return checkpw_internal(@_) + return checkpw_internal( $dbh, $userid, $password, $no_set_userenv); } sub checkpw_internal { - my ( $dbh, $userid, $password ) = @_; + my ( $dbh, $userid, $password, $no_set_userenv ) = @_; $password = Encode::encode( 'UTF-8', $password ) if Encode::is_utf8($password); @@ -1743,7 +1818,7 @@ sub checkpw_internal { if ( checkpw_hash( $password, $stored_hash ) ) { C4::Context->set_userenv( "$borrowernumber", $userid, $cardnumber, - $firstname, $surname, $branchcode, $branchname, $flags ); + $firstname, $surname, $branchcode, $branchname, $flags ) unless $no_set_userenv; return 1, $cardnumber, $userid; } } @@ -1760,7 +1835,7 @@ sub checkpw_internal { if ( checkpw_hash( $password, $stored_hash ) ) { C4::Context->set_userenv( $borrowernumber, $userid, $cardnumber, - $firstname, $surname, $branchcode, $branchname, $flags ); + $firstname, $surname, $branchcode, $branchname, $flags ) unless $no_set_userenv; return 1, $cardnumber, $userid; } } @@ -1895,14 +1970,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 FROM permissions 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'}; + $all_perms->{ $perm->{'flag'} }->{ $perm->{'code'} } = 1; } return $all_perms; } @@ -1942,11 +2017,13 @@ sub haspermission { if ( $subperm eq '*' ) { return 0 unless ( $flags->{$module} == 1 or ref( $flags->{$module} ) ); } else { - return 0 unless ( $flags->{$module} == 1 or + return 0 unless ( + ( defined $flags->{$module} and + $flags->{$module} == 1 ) + or ( ref( $flags->{$module} ) and exists $flags->{$module}->{$subperm} and - $flags->{$module}->{$subperm} == 1 - ) + $flags->{$module}->{$subperm} == 1 ) ); } }