X-Git-Url: http://koha-dev.rot13.org:8081/gitweb/?a=blobdiff_plain;f=C4%2FAuth.pm;h=f281def2ce009a76e0d656aaa61b796f37ac50d3;hb=cb90cbf4eb42e2ac63363a113cb5eb7f33459ac0;hp=f3089f2ac9eadb670c79a1ebd70121d4088544a8;hpb=619d6362ce895ba4da543dcd809b162ed7a9b6b5;p=koha-ffzg.git diff --git a/C4/Auth.pm b/C4/Auth.pm index f3089f2ac9..f281def2ce 100644 --- a/C4/Auth.pm +++ b/C4/Auth.pm @@ -38,6 +38,8 @@ use Koha::Checkouts; use Koha::DateUtils qw(dt_from_string); use Koha::Library::Groups; use Koha::Libraries; +use Koha::Cash::Registers; +use Koha::Desks; use Koha::Patrons; use Koha::Patron::Consents; use POSIX qw/strftime/; @@ -45,6 +47,7 @@ use List::MoreUtils qw/ any /; use Encode qw( encode is_utf8); use C4::Auth_with_shibboleth; use Net::CIDR; +use C4::Log qw/logaction/; # use utf8; use vars qw(@ISA @EXPORT @EXPORT_OK %EXPORT_TAGS $debug $ldap $cas $caslogout); @@ -91,7 +94,7 @@ C4::Auth - Authenticates Koha users use C4::Auth; use C4::Output; - my $query = new CGI; + my $query = CGI->new; my ($template, $borrowernumber, $cookie) = get_template_and_user( @@ -169,7 +172,9 @@ sub get_template_and_user { $in->{'query'}, $in->{'authnotrequired'}, $in->{'flagsrequired'}, - $in->{'type'} + $in->{'type'}, + undef, + $in->{template_name}, ); } @@ -228,6 +233,7 @@ sub get_template_and_user { -value => '', -expires => '', -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); $template->param( @@ -298,7 +304,7 @@ sub get_template_and_user { my $all_perms = get_all_subpermissions(); my @flagroots = qw(circulate catalogue parameters borrowers permissions reserveforothers borrow - editcatalogue updatecharges tools editauthorities serials reports acquisition clubs); + editcatalogue updatecharges tools editauthorities serials reports acquisition clubs problem_reports); # We are going to use the $flags returned by checkauth # to create the template's parameters that will indicate @@ -313,16 +319,20 @@ sub get_template_and_user { $template->param( CAN_user_editcatalogue => 1 ); $template->param( CAN_user_updatecharges => 1 ); $template->param( CAN_user_acquisition => 1 ); + $template->param( CAN_user_suggestions => 1 ); $template->param( CAN_user_tools => 1 ); $template->param( CAN_user_editauthorities => 1 ); $template->param( CAN_user_serials => 1 ); $template->param( CAN_user_reports => 1 ); $template->param( CAN_user_staffaccess => 1 ); - $template->param( CAN_user_plugins => 1 ); $template->param( CAN_user_coursereserves => 1 ); + $template->param( CAN_user_plugins => 1 ); + $template->param( CAN_user_lists => 1 ); $template->param( CAN_user_clubs => 1 ); $template->param( CAN_user_ill => 1 ); $template->param( CAN_user_stockrotation => 1 ); + $template->param( CAN_user_cash_management => 1 ); + $template->param( CAN_user_problem_reports => 1 ); foreach my $module ( keys %$all_perms ) { foreach my $subperm ( keys %{ $all_perms->{$module} } ) { @@ -430,6 +440,25 @@ sub get_template_and_user { } } + # Sysprefs disabled via URL param + # Note that value must be defined in order to override via ENV + foreach my $syspref ( + qw( + OPACUserCSS + OPACUserJS + IntranetUserCSS + IntranetUserJS + OpacAdditionalStylesheet + opaclayoutstylesheet + intranetcolorstylesheet + intranetstylesheet + ) + ) + { + $ENV{"OVERRIDE_SYSPREF_$syspref"} = q{} + if $in->{'query'}->param("DISABLE_SYSPREF_$syspref"); + } + # Anonymous opac search history # If opac search history is enabled and at least one search has already been performed if ( C4::Context->preference('EnableOpacSearchHistory') ) { @@ -447,11 +476,6 @@ sub get_template_and_user { # these template parameters are set the same regardless of $in->{'type'} - # 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 $minPasswordLength = C4::Context->preference('minPasswordLength'); $minPasswordLength = 3 if not $minPasswordLength or $minPasswordLength < 3; $template->param( @@ -460,7 +484,6 @@ sub get_template_and_user { 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, @@ -471,7 +494,6 @@ sub get_template_and_user { 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"), OPACBaseURL => C4::Context->preference('OPACBaseURL'), @@ -488,7 +510,6 @@ sub get_template_and_user { 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"), @@ -497,7 +518,6 @@ sub get_template_and_user { 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"), @@ -506,7 +526,6 @@ sub get_template_and_user { 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"), useDischarge => C4::Context->preference('useDischarge'), pending_checkout_notes => scalar Koha::Checkouts->search({ noteseen => 0 }), @@ -557,7 +576,6 @@ sub get_template_and_user { opac_name => $opac_name, 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"), @@ -571,7 +589,6 @@ sub get_template_and_user { 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"), OpacNavBottom => "" . C4::Context->preference("OpacNavBottom"), OpacPasswordChange => C4::Context->preference("OpacPasswordChange"), @@ -584,7 +601,6 @@ sub get_template_and_user { hidelostitems => C4::Context->preference("hidelostitems"), mylibraryfirst => ( C4::Context->preference("SearchMyLibraryFirst") && C4::Context->userenv ) ? C4::Context->userenv->{'branch'} : '', opacbookbag => "" . C4::Context->preference("opacbookbag"), - opaccredits => "" . C4::Context->preference("opaccredits"), OpacFavicon => C4::Context->preference("OpacFavicon"), opaclanguagesdisplay => "" . C4::Context->preference("opaclanguagesdisplay"), opacreadinghistory => C4::Context->preference("opacreadinghistory"), @@ -768,12 +784,22 @@ sub _session_log { } sub _timeout_syspref { - my $timeout = C4::Context->preference('timeout') || 600; + my $default_timeout = 600; + my $timeout = C4::Context->preference('timeout') || $default_timeout; # value in days, convert in seconds - if ( $timeout =~ /(\d+)[dD]/ ) { + if ( $timeout =~ /^(\d+)[dD]$/ ) { $timeout = $1 * 86400; } + # value in hours, convert in seconds + elsif ( $timeout =~ /^(\d+)[hH]$/ ) { + $timeout = $1 * 3600; + } + elsif ( $timeout !~ m/^\d+$/ ) { + warn "The value of the system preference 'timeout' is not correct, defaulting to $default_timeout"; + $timeout = $default_timeout; + } + return $timeout; } @@ -790,8 +816,21 @@ sub checkauth { my $flagsrequired = shift; my $type = shift; my $emailaddress = shift; + my $template_name = shift; $type = 'opac' unless $type; + unless ( C4::Context->preference("OpacPublic") ) { + my @allowed_scripts_for_private_opac = qw( + opac-memberentry.tt + opac-registration-email-sent.tt + opac-registration-confirmation.tt + opac-memberentry-update-submitted.tt + opac-password-recovery.tt + ); + $authnotrequired = 0 unless grep { $_ eq $template_name } + @allowed_scripts_for_private_opac; + } + my $dbh = C4::Context->dbh; my $timeout = _timeout_syspref(); @@ -829,6 +868,7 @@ sub checkauth { -value => '', -expires => '', -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); $loggedin = 1; } @@ -848,8 +888,9 @@ sub checkauth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress'), - $session->param('shibboleth') + $session->param('emailaddress'), $session->param('shibboleth'), + $session->param('desk_id'), $session->param('desk_name'), + $session->param('register_id'), $session->param('register_name') ); C4::Context::set_shelves_userenv( 'bar', $session->param('barshelves') ); C4::Context::set_shelves_userenv( 'pub', $session->param('pubshelves') ); @@ -929,7 +970,8 @@ sub checkauth { $cookie = $query->cookie( -name => 'CGISESSID', -value => $session->id, - -HttpOnly => 1 + -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); $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... @@ -958,7 +1000,8 @@ sub checkauth { $cookie = $query->cookie( -name => 'CGISESSID', -value => $session->id, - -HttpOnly => 1 + -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); my $pki_field = C4::Context->preference('AllowPKIAuth'); if ( !defined($pki_field) ) { @@ -1050,13 +1093,33 @@ sub checkauth { } else { my $retuserid; - ( $return, $cardnumber, $retuserid, $cas_ticket ) = - checkpw( $dbh, $q_userid, $password, $query, $type ); - $userid = $retuserid if ($retuserid); - $info{'invalid_username_or_password'} = 1 unless ($return); + my $request_method = $query->request_method(); + if ($request_method eq 'POST'){ + ( $return, $cardnumber, $retuserid, $cas_ticket ) = + checkpw( $dbh, $q_userid, $password, $query, $type ); + $userid = $retuserid if ($retuserid); + $info{'invalid_username_or_password'} = 1 unless ($return); + } } } + # If shib configured and shibOnly enabled, we should ignore anything other than a shibboleth type login. + if ( + $shib + && !$shibSuccess + && ( + ( + ( $type eq 'opac' ) + && C4::Context->preference('OPACShibOnly') + ) + || ( ( $type ne 'opac' ) + && C4::Context->preference('staffShibOnly') ) + ) + ) + { + $return = 0; + } + # $return: 1 = valid user if ($return) { @@ -1069,7 +1132,8 @@ sub checkauth { C4::Context->_unset_userenv($sessionID); } my ( $borrowernumber, $firstname, $surname, $userflags, - $branchcode, $branchname, $emailaddress ); + $branchcode, $branchname, $emailaddress, $desk_id, + $desk_name, $register_id, $register_name ); if ( $return == 1 ) { my $select = " @@ -1113,8 +1177,23 @@ sub checkauth { my $library = Koha::Libraries->find($branchcode); $branchname = $library? $library->branchname: ''; } + if ( $query->param('desk_id') ) { + $desk_id = $query->param('desk_id'); + my $desk = Koha::Desks->find($desk_id); + $desk_name = $desk ? $desk->desk_name : ''; + } + if ( C4::Context->preference('UseCashRegisters') ) { + my $register = + $query->param('register_id') + ? Koha::Cash::Registers->find($query->param('register_id')) + : Koha::Cash::Registers->search( + { branch => $branchcode, branch_default => 1 }, + { rows => 1 } )->single; + $register_id = $register->id if ($register); + $register_name = $register->name if ($register); + } my $branches = { map { $_->branchcode => $_->unblessed } Koha::Libraries->search }; - if ( $type ne 'opac' and C4::Context->boolean_preference('AutoLocation') ) { + if ( $type ne 'opac' and C4::Context->preference('AutoLocation') ) { # we have to check they are coming from the right ip range my $domain = $branches->{$branchcode}->{'branchip'}; @@ -1124,7 +1203,8 @@ sub checkauth { $cookie = $query->cookie( -name => 'CGISESSID', -value => '', - -HttpOnly => 1 + -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); $info{'wrongip'} = 1; } @@ -1148,12 +1228,16 @@ sub checkauth { $session->param( 'surname', $surname ); $session->param( 'branch', $branchcode ); $session->param( 'branchname', $branchname ); + $session->param( 'desk_id', $desk_id); + $session->param( 'desk_name', $desk_name); $session->param( 'flags', $userflags ); $session->param( 'emailaddress', $emailaddress ); $session->param( 'ip', $session->remote_addr() ); $session->param( 'lasttime', time() ); $session->param( 'interface', $type); $session->param( 'shibboleth', $shibSuccess ); + $session->param( 'register_id', $register_id ); + $session->param( 'register_name', $register_name ); $debug and printf STDERR "AUTH_4: (%s)\t%s %s - %s\n", map { $session->param($_) } qw(cardnumber firstname surname branch); } $session->param('cas_ticket', $cas_ticket) if $cas_ticket; @@ -1162,7 +1246,9 @@ sub checkauth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress'), $session->param('shibboleth') + $session->param('emailaddress'), $session->param('shibboleth'), + $session->param('desk_id'), $session->param('desk_name'), + $session->param('register_id'), $session->param('register_name') ); } @@ -1202,10 +1288,13 @@ sub checkauth { $cookie = $query->cookie( -name => 'CGISESSID', -value => '', - -HttpOnly => 1 + -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); } + track_login_daily( $userid ); + # In case, that this request was a login attempt, we want to prevent that users can repost the opac login # request. We therefore redirect the user to the requested page again without the login parameters. # See Post/Redirect/Get (PRG) design pattern: https://en.wikipedia.org/wiki/Post/Redirect/Get @@ -1218,8 +1307,6 @@ sub checkauth { exit; } - track_login_daily( $userid ); - return ( $userid, $cookie, $sessionID, $flags ); } @@ -1243,8 +1330,8 @@ sub checkauth { $LibraryNameTitle =~ s/<(?:\/?)(?:br|p)\s*(?:\/?)>/ /sgi; $LibraryNameTitle =~ s/<(?:[^<>'"]|'(?:[^']*)'|"(?:[^"]*)")*>//sg; - my $template_name = ( $type eq 'opac' ) ? 'opac-auth.tt' : 'auth.tt'; - my $template = C4::Templates::gettemplate( $template_name, $type, $query ); + my $auth_template_name = ( $type eq 'opac' ) ? 'opac-auth.tt' : 'auth.tt'; + my $template = C4::Templates::gettemplate( $auth_template_name, $type, $query ); $template->param( login => 1, INPUTS => \@inputs, @@ -1259,7 +1346,6 @@ sub checkauth { opacuserlogin => C4::Context->preference("opacuserlogin"), OpacNav => C4::Context->preference("OpacNav"), 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"), @@ -1273,7 +1359,6 @@ sub checkauth { 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"), IntranetUserCSS => C4::Context->preference("IntranetUserCSS"), @@ -1328,6 +1413,13 @@ sub checkauth { } if ($shib) { + #If shibOnly is enabled just go ahead and redirect directly + if ( (($type eq 'opac') && C4::Context->preference('OPACShibOnly')) || (($type ne 'opac') && C4::Context->preference('staffShibOnly')) ) { + my $redirect_url = login_shib_url( $query ); + print $query->redirect( -uri => "$redirect_url", -status => 303 ); + safe_exit; + } + $template->param( shibbolethAuthentication => $shib, shibbolethLoginUrl => login_shib_url($query), @@ -1440,7 +1532,9 @@ sub check_api_auth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress') + $session->param('emailaddress'), $session->param('shibboleth'), + $session->param('desk_id'), $session->param('desk_name'), + $session->param('register_id'), $session->param('register_name') ); my $ip = $session->param('ip'); @@ -1469,6 +1563,7 @@ sub check_api_auth { -name => 'CGISESSID', -value => $session->id, -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); $session->param( 'lasttime', time() ); my $flags = haspermission( $userid, $flagsrequired ); @@ -1523,6 +1618,7 @@ sub check_api_auth { -name => 'CGISESSID', -value => $sessionID, -HttpOnly => 1, + -secure => ( C4::Context->https_enabled() ? 1 : 0 ), ); if ( $return == 1 ) { my ( @@ -1600,7 +1696,9 @@ sub check_api_auth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress') + $session->param('emailaddress'), $session->param('shibboleth'), + $session->param('desk_id'), $session->param('desk_name'), + $session->param('register_id'), $session->param('register_name') ); return ( "ok", $cookie, $sessionID ); } else { @@ -1688,7 +1786,9 @@ sub check_cookie_auth { $session->param('cardnumber'), $session->param('firstname'), $session->param('surname'), $session->param('branch'), $session->param('branchname'), $session->param('flags'), - $session->param('emailaddress') + $session->param('emailaddress'), $session->param('shibboleth'), + $session->param('desk_id'), $session->param('desk_name'), + $session->param('register_id'), $session->param('register_name') ); my $ip = $session->param('ip'); @@ -1750,28 +1850,28 @@ sub _get_session_params { my $storage_method = C4::Context->preference('SessionStorage'); if ( $storage_method eq 'mysql' ) { my $dbh = C4::Context->dbh; - return { dsn => "driver:MySQL;serializer:yaml;id:md5", dsn_args => { Handle => $dbh } }; + return { dsn => "driver:MySQL;id:md5", dsn_args => { Handle => $dbh } }; } elsif ( $storage_method eq 'Pg' ) { my $dbh = C4::Context->dbh; - return { dsn => "driver:PostgreSQL;serializer:yaml;id:md5", dsn_args => { Handle => $dbh } }; + return { dsn => "driver:PostgreSQL;id:md5", dsn_args => { Handle => $dbh } }; } elsif ( $storage_method eq 'memcached' && Koha::Caches->get_instance->memcached_cache ) { my $memcached = Koha::Caches->get_instance()->memcached_cache; - return { dsn => "driver:memcached;serializer:yaml;id:md5", dsn_args => { Memcached => $memcached } }; + return { dsn => "driver:memcached;id:md5", dsn_args => { Memcached => $memcached } }; } else { # catch all defaults to tmp should work on all systems my $dir = C4::Context::temporary_directory; my $instance = C4::Context->config( 'database' ); #actually for packages not exactly the instance name, but generally safer to leave it as it is - return { dsn => "driver:File;serializer:yaml;id:md5", dsn_args => { Directory => "$dir/cgisess_$instance" } }; + return { dsn => "driver:File;id:md5", dsn_args => { Directory => "$dir/cgisess_$instance" } }; } } sub get_session { my $sessionID = shift; my $params = _get_session_params(); - return new CGI::Session( $params->{dsn}, $sessionID, $params->{dsn_args} ); + return CGI::Session->new( $params->{dsn}, $sessionID, $params->{dsn_args} ); } @@ -1862,6 +1962,14 @@ sub checkpw { $patron->update({ login_attempts => $patron->login_attempts + 1 }); } } + + # Optionally log success or failure + if( $patron && $passwd_ok && C4::Context->preference('AuthSuccessLog') ) { + logaction( 'AUTH', 'SUCCESS', $patron->id, "Valid password for $userid", $type ); + } elsif( !$passwd_ok && C4::Context->preference('AuthFailureLog') ) { + logaction( 'AUTH', 'FAILURE', $patron ? $patron->id : 0, "Wrong password for $userid", $type ); + } + return @return; }