Merge branch 'bug_9587' into 3.12-master
This commit is contained in:
commit
5f40f3f0e4
292
C4/Auth.pm
292
C4/Auth.pm
|
|
@ -38,8 +38,8 @@ 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
|
||||
|
||||
|
|
@ -53,8 +53,8 @@ BEGIN {
|
|||
$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 ($cas) {
|
||||
import C4::Auth_with_cas qw(check_api_auth_cas checkpw_cas login_cas logout_cas login_cas_url);
|
||||
|
|
@ -234,34 +234,34 @@ sub get_template_and_user {
|
|||
}
|
||||
}
|
||||
}
|
||||
# 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;
|
||||
my $query = "SELECT COUNT(*) FROM search_history WHERE userid=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($borrowernumber);
|
||||
|
||||
# If at least one search has already been performed
|
||||
if ($sth->fetchrow_array > 0) {
|
||||
# We show the link in opac
|
||||
$template->param(ShowOpacRecentSearchLink => 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;
|
||||
my $query = "SELECT COUNT(*) FROM search_history WHERE userid=?";
|
||||
my $sth = $dbh->prepare($query);
|
||||
$sth->execute($borrowernumber);
|
||||
|
||||
# And if there's a cookie with searches performed when the user was not logged in,
|
||||
# we add them to the logged-in search history
|
||||
my $searchcookie = $in->{'query'}->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie){
|
||||
$searchcookie = uri_unescape($searchcookie);
|
||||
my @recentSearches = @{thaw($searchcookie) || []};
|
||||
if (@recentSearches) {
|
||||
my $sth = $dbh->prepare($SEARCH_HISTORY_INSERT_SQL);
|
||||
$sth->execute( $borrowernumber,
|
||||
$in->{'query'}->cookie("CGISESSID"),
|
||||
$_->{'query_desc'},
|
||||
$_->{'query_cgi'},
|
||||
$_->{'total'},
|
||||
$_->{'time'},
|
||||
# If at least one search has already been performed
|
||||
if ($sth->fetchrow_array > 0) {
|
||||
# We show the link in opac
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
|
||||
# And if there's a cookie with searches performed when the user was not logged in,
|
||||
# we add them to the logged-in search history
|
||||
my $searchcookie = $in->{'query'}->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie){
|
||||
$searchcookie = uri_unescape($searchcookie);
|
||||
my @recentSearches = @{thaw($searchcookie) || []};
|
||||
if (@recentSearches) {
|
||||
my $sth = $dbh->prepare($SEARCH_HISTORY_INSERT_SQL);
|
||||
$sth->execute( $borrowernumber,
|
||||
$in->{'query'}->cookie("CGISESSID"),
|
||||
$_->{'query_desc'},
|
||||
$_->{'query_cgi'},
|
||||
$_->{'total'},
|
||||
$_->{'time'},
|
||||
) foreach @recentSearches;
|
||||
|
||||
# And then, delete the cookie's content
|
||||
|
|
@ -271,34 +271,34 @@ sub get_template_and_user {
|
|||
-HttpOnly => 1,
|
||||
-expires => ''
|
||||
);
|
||||
$cookie = [$cookie, $newsearchcookie];
|
||||
}
|
||||
}
|
||||
}
|
||||
$cookie = [$cookie, $newsearchcookie];
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else { # if this is an anonymous session, setup to display public lists...
|
||||
else { # if this is an anonymous session, setup to display public lists...
|
||||
|
||||
$template->param( sessionID => $sessionID );
|
||||
|
||||
my ($total, $pubshelves) = C4::VirtualShelves::GetSomeShelfNames(undef, 'MASTHEAD');
|
||||
$template->param(
|
||||
pubshelves => $total->{pubtotal},
|
||||
pubshelvesloop => $pubshelves,
|
||||
);
|
||||
$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 $searchcookie = $in->{'query'}->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie){
|
||||
$searchcookie = uri_unescape($searchcookie);
|
||||
my @recentSearches = @{thaw($searchcookie) || []};
|
||||
# We show the link in opac
|
||||
if (@recentSearches) {
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
# 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 $searchcookie = $in->{'query'}->cookie('KohaOpacRecentSearches');
|
||||
if ($searchcookie){
|
||||
$searchcookie = uri_unescape($searchcookie);
|
||||
my @recentSearches = @{thaw($searchcookie) || []};
|
||||
# We show the link in opac
|
||||
if (@recentSearches) {
|
||||
$template->param(ShowOpacRecentSearchLink => 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(C4::Context->preference('dateformat')){
|
||||
$template->param( dateformat => C4::Context->preference('dateformat') );
|
||||
|
|
@ -323,6 +323,8 @@ sub get_template_and_user {
|
|||
LoginBranchcode => (C4::Context->userenv?C4::Context->userenv->{"branch"}:"insecure"),
|
||||
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'),
|
||||
|
|
@ -333,8 +335,8 @@ sub get_template_and_user {
|
|||
using_https => $in->{'query'}->https() ? 1 : 0,
|
||||
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"),
|
||||
|
|
@ -557,8 +559,8 @@ sub _version_check {
|
|||
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') {
|
||||
# also, if OpacMaintenance is ON, OPAC should redirect to maintenance
|
||||
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;
|
||||
|
|
@ -613,11 +615,12 @@ sub _timeout_syspref {
|
|||
|
||||
sub checkauth {
|
||||
my $query = shift;
|
||||
$debug and warn "Checking Auth";
|
||||
$debug and warn "Checking Auth";
|
||||
# $authnotrequired will be set for scripts which will run without authentication
|
||||
my $authnotrequired = shift;
|
||||
my $flagsrequired = shift;
|
||||
my $type = shift;
|
||||
my $persona = shift;
|
||||
$type = 'opac' unless $type;
|
||||
|
||||
my $dbh = C4::Context->dbh;
|
||||
|
|
@ -634,7 +637,7 @@ sub checkauth {
|
|||
# when using authentication against multiple CAS servers, as configured in Auth_cas_servers.yaml
|
||||
my $casparam = $query->param('cas');
|
||||
|
||||
if ( $userid = $ENV{'REMOTE_USER'} ) {
|
||||
if ( $userid = $ENV{'REMOTE_USER'} ) {
|
||||
# Using Basic Authentication, no cookies required
|
||||
$cookie = $query->cookie(
|
||||
-name => 'CGISESSID',
|
||||
|
|
@ -644,6 +647,9 @@ sub checkauth {
|
|||
);
|
||||
$loggedin = 1;
|
||||
}
|
||||
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);
|
||||
|
|
@ -655,7 +661,8 @@ 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('branchprinter')
|
||||
$session->param('emailaddress'), $session->param('branchprinter'),
|
||||
$session->param('persona')
|
||||
);
|
||||
C4::Context::set_shelves_userenv('bar',$session->param('barshelves'));
|
||||
C4::Context::set_shelves_userenv('pub',$session->param('pubshelves'));
|
||||
|
|
@ -674,9 +681,9 @@ sub checkauth {
|
|||
$session->flush;
|
||||
$session->delete();
|
||||
C4::Context->_unset_userenv($sessionID);
|
||||
$sessionID = undef;
|
||||
$userid = undef;
|
||||
}
|
||||
$sessionID = undef;
|
||||
$userid = undef;
|
||||
}
|
||||
elsif ($logout) {
|
||||
# voluntary logout the user
|
||||
$session->flush;
|
||||
|
|
@ -686,9 +693,9 @@ sub checkauth {
|
|||
$sessionID = undef;
|
||||
$userid = undef;
|
||||
|
||||
if ($cas and $caslogout) {
|
||||
logout_cas($query);
|
||||
}
|
||||
if ($cas and $caslogout) {
|
||||
logout_cas($query);
|
||||
}
|
||||
}
|
||||
elsif ( $lasttime < time() - $timeout ) {
|
||||
# timed logout
|
||||
|
|
@ -728,6 +735,7 @@ sub checkauth {
|
|||
}
|
||||
}
|
||||
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()";
|
||||
my $sessionID = $session->id;
|
||||
|
|
@ -741,9 +749,10 @@ sub checkauth {
|
|||
if ( ( $cas && $query->param('ticket') )
|
||||
|| $userid
|
||||
|| ( my $pki_field = C4::Context->preference('AllowPKIAuth') ) ne
|
||||
'None' )
|
||||
'None' || $persona )
|
||||
{
|
||||
my $password = $query->param('password');
|
||||
|
||||
my ( $return, $cardnumber );
|
||||
if ( $cas && $query->param('ticket') ) {
|
||||
my $retuserid;
|
||||
|
|
@ -752,7 +761,29 @@ sub checkauth {
|
|||
$userid = $retuserid;
|
||||
$info{'invalidCasLogin'} = 1 unless ($return);
|
||||
}
|
||||
elsif (
|
||||
|
||||
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'} )
|
||||
|
|
@ -780,25 +811,26 @@ sub checkauth {
|
|||
}
|
||||
}
|
||||
|
||||
# 0 for no user, 1 for normal, 2 for demo user.
|
||||
|
||||
$return = $value ? 1 : 0;
|
||||
$userid = $value;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
my $retuserid;
|
||||
( $return, $cardnumber, $retuserid ) =
|
||||
checkpw( $dbh, $userid, $password, $query );
|
||||
$userid = $retuserid if ( $retuserid ne '' );
|
||||
}
|
||||
if ($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 {
|
||||
$info{'nopermission'} = 1;
|
||||
C4::Context->_unset_userenv($sessionID);
|
||||
}
|
||||
if ( $flags = haspermission( $userid, $flagsrequired ) ) {
|
||||
$loggedin = 1;
|
||||
}
|
||||
else {
|
||||
$info{'nopermission'} = 1;
|
||||
C4::Context->_unset_userenv($sessionID);
|
||||
}
|
||||
my ($borrowernumber, $firstname, $surname, $userflags,
|
||||
$branchcode, $branchname, $branchprinter, $emailaddress);
|
||||
|
||||
|
|
@ -894,33 +926,37 @@ sub checkauth {
|
|||
$session->param('ip',$session->remote_addr());
|
||||
$session->param('lasttime',time());
|
||||
}
|
||||
if ($persona){
|
||||
$session->param('persona',1);
|
||||
}
|
||||
C4::Context::set_userenv(
|
||||
$session->param('number'), $session->param('id'),
|
||||
$session->param('cardnumber'), $session->param('firstname'),
|
||||
$session->param('surname'), $session->param('branch'),
|
||||
$session->param('branchname'), $session->param('flags'),
|
||||
$session->param('emailaddress'), $session->param('branchprinter')
|
||||
$session->param('emailaddress'), $session->param('branchprinter'),
|
||||
$session->param('persona')
|
||||
);
|
||||
|
||||
}
|
||||
else {
|
||||
if ($userid) {
|
||||
$info{'invalid_username_or_password'} = 1;
|
||||
C4::Context->_unset_userenv($sessionID);
|
||||
}
|
||||
}
|
||||
} # END if ( $userid = $query->param('userid') )
|
||||
elsif ($type eq "opac") {
|
||||
else {
|
||||
if ($userid) {
|
||||
$info{'invalid_username_or_password'} = 1;
|
||||
C4::Context->_unset_userenv($sessionID);
|
||||
}
|
||||
}
|
||||
} # END if ( $userid = $query->param('userid') )
|
||||
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...";
|
||||
$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');
|
||||
}
|
||||
} # END unless ($userid)
|
||||
# setting a couple of other session vars...
|
||||
$session->param('ip',$session->remote_addr());
|
||||
$session->param('lasttime',time());
|
||||
$session->param('sessiontype','anon');
|
||||
}
|
||||
} # END unless ($userid)
|
||||
my $insecure = C4::Context->boolean_preference('insecure');
|
||||
|
||||
# finished authentification, now respond
|
||||
|
|
@ -992,6 +1028,7 @@ sub checkauth {
|
|||
wrongip => $info{'wrongip'},
|
||||
PatronSelfRegistration => C4::Context->preference("PatronSelfRegistration"),
|
||||
PatronSelfRegistrationDefaultCategory => C4::Context->preference("PatronSelfRegistrationDefaultCategory"),
|
||||
persona => C4::Context->preference("Persona"),
|
||||
);
|
||||
|
||||
$template->param( OpacPublic => C4::Context->preference("OpacPublic"));
|
||||
|
|
@ -999,24 +1036,23 @@ sub checkauth {
|
|||
|
||||
if ($cas) {
|
||||
|
||||
# Is authentication against multiple CAS servers enabled?
|
||||
# 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" };
|
||||
}
|
||||
#warn Data::Dumper::Dumper(\@tmplservers);
|
||||
$template->param(
|
||||
casServersLoop => \@tmplservers
|
||||
);
|
||||
} else {
|
||||
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(
|
||||
$template->param(
|
||||
invalidCasLogin => $info{'invalidCasLogin'}
|
||||
);
|
||||
}
|
||||
|
|
@ -1161,23 +1197,23 @@ sub check_api_auth {
|
|||
# new login
|
||||
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);
|
||||
}
|
||||
( $return, $cardnumber ) = checkpw( $dbh, $userid, $password, $query );
|
||||
}
|
||||
# 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 );
|
||||
}
|
||||
|
||||
if ($return and haspermission( $userid, $flagsrequired)) {
|
||||
my $session = get_session("");
|
||||
|
|
@ -1420,7 +1456,7 @@ sub get_session {
|
|||
$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 } );
|
||||
$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
|
||||
|
|
@ -1440,11 +1476,11 @@ sub checkpw {
|
|||
|
||||
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
|
||||
my $ticket = $query->param('ticket');
|
||||
# In case of a CAS authentication, we use the ticket instead of the password
|
||||
my $ticket = $query->param('ticket');
|
||||
my ($retval,$retcard,$retuserid) = checkpw_cas($dbh, $ticket, $query); # EXTERNAL AUTH
|
||||
($retval) and return ($retval,$retcard,$retuserid);
|
||||
return 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
# INTERNAL AUTH
|
||||
|
|
|
|||
|
|
@ -1057,7 +1057,8 @@ sub userenv {
|
|||
=head2 set_userenv
|
||||
|
||||
C4::Context->set_userenv($usernum, $userid, $usercnum, $userfirstname,
|
||||
$usersurname, $userbranch, $userflags, $emailaddress);
|
||||
$usersurname, $userbranch, $userflags, $emailaddress, $branchprinter,
|
||||
$persona);
|
||||
|
||||
Establish a hash of user environment variables.
|
||||
|
||||
|
|
@ -1067,7 +1068,7 @@ set_userenv is called in Auth.pm
|
|||
|
||||
#'
|
||||
sub set_userenv {
|
||||
my ($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, $emailaddress, $branchprinter)= @_;
|
||||
my ($usernum, $userid, $usercnum, $userfirstname, $usersurname, $userbranch, $branchname, $userflags, $emailaddress, $branchprinter, $persona)= @_;
|
||||
my $var=$context->{"activeuser"} || '';
|
||||
my $cell = {
|
||||
"number" => $usernum,
|
||||
|
|
@ -1080,7 +1081,8 @@ sub set_userenv {
|
|||
"branchname" => $branchname,
|
||||
"flags" => $userflags,
|
||||
"emailaddress" => $emailaddress,
|
||||
"branchprinter" => $branchprinter
|
||||
"branchprinter" => $branchprinter,
|
||||
"persona" => $persona,
|
||||
};
|
||||
$context->{userenv}->{$var} = $cell;
|
||||
return $cell;
|
||||
|
|
|
|||
|
|
@ -415,3 +415,4 @@ INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) V
|
|||
INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('OPACNumbersPreferPhrase','0', NULL, 'Control the use of phr operator in callnumber and standard number OPAC searches', 'YesNo');
|
||||
INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ('IntranetNumbersPreferPhrase','0', NULL, 'Control the use of phr operator in callnumber and standard number staff client searches', 'YesNo');
|
||||
INSERT INTO systempreferences (variable,value,explanation,options,type) VALUES('UNIMARCField100Language', 'fre','UNIMARC field 100 default language',NULL,'short');
|
||||
INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('Persona',0,'Use Mozilla Persona for login','','YesNo');
|
||||
|
|
|
|||
|
|
@ -6428,6 +6428,15 @@ if ( CheckVersion($DBversion) ) {
|
|||
SetVersion($DBversion);
|
||||
}
|
||||
|
||||
$DBversion = "3.11.00.022";
|
||||
if ( CheckVersion($DBversion) ) {
|
||||
$dbh->do(
|
||||
"INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('Persona',0,'Use Mozilla Persona for login','','YesNo')"
|
||||
);
|
||||
print "Upgrade to $DBversion done (Bug 9587 - Allow login via Persona)\n";
|
||||
SetVersion($DBversion);
|
||||
}
|
||||
|
||||
|
||||
=head1 FUNCTIONS
|
||||
|
||||
|
|
|
|||
|
|
@ -104,6 +104,14 @@ Administration:
|
|||
Common Name: the Common Name
|
||||
emailAddress: the emailAddress
|
||||
- field for SSL client certificate authentication
|
||||
Mozilla Persona:
|
||||
-
|
||||
- pref: Persona
|
||||
default: 0
|
||||
choices:
|
||||
yes: Allow
|
||||
no: "Don't Allow"
|
||||
- Mozilla persona for login
|
||||
Search Engine:
|
||||
-
|
||||
- pref: SearchEngine
|
||||
|
|
|
|||
|
|
@ -0,0 +1,228 @@
|
|||
/* Link body */
|
||||
.persona-button{
|
||||
color: #fff;
|
||||
display: inline-block;
|
||||
font-size: 14px;
|
||||
font-family: Helvetica, Arial, sans-serif;
|
||||
font-weight: bold;
|
||||
line-height: 1.1;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 1px rgba(0,0,0,0.5), 0 0 2px rgba(0,0,0,0.2);
|
||||
|
||||
background: #297dc3;
|
||||
background: -moz-linear-gradient(top, #43a6e2, #287cc2);
|
||||
background: -ms-linear-gradient(top, #43a6e2, #287cc2);
|
||||
background: -o-linear-gradient(top, #43a6e2, #287cc2);
|
||||
background: -webkit-linear-gradient(top, #43a6e2, #287cc2);
|
||||
background: linear-gradient(top, #43a6e2, #287cc2);
|
||||
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
|
||||
-moz-box-shadow: 0 1px 0 rgba(0,0,0,0.2);
|
||||
-ms-box-shadow: 0 1px 0 rgba(0,0,0,0.2);
|
||||
-o-box-shadow: 0 1px 0 rgba(0,0,0,0.2);
|
||||
-webkit-box-shadow: 0 1px 0 rgba(0,0,0,0.2);
|
||||
box-shadow: 0 1px 0 rgba(0,0,0,0.2);
|
||||
}
|
||||
|
||||
.persona-button:hover{
|
||||
background: #21669f;
|
||||
background: -moz-linear-gradient(top, #3788b9, #21669f);
|
||||
background: -ms-linear-gradient(top, #3788b9, #21669f);
|
||||
background: -o-linear-gradient(top, #3788b9, #21669f);
|
||||
background: -webkit-linear-gradient(top, #3788b9, #21669f);
|
||||
background: linear-gradient(top, #3788b9, #21669f);
|
||||
}
|
||||
|
||||
.persona-button:active, .persona-button:focus{
|
||||
top: 1px;
|
||||
-moz-box-shadow: none;
|
||||
-ms-box-shadow: none;
|
||||
-o-box-shadow: none;
|
||||
-webkit-box-shadow: none;
|
||||
box-shadow: none;
|
||||
}
|
||||
|
||||
.persona-button span{
|
||||
display: inline-block;
|
||||
padding: 5px 10px 5px 40px;
|
||||
}
|
||||
|
||||
/* Icon */
|
||||
.persona-button span:after{
|
||||
background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA0AAAAPCAYAAAA/I0V3AAAA4klEQVR42o2RWaqEMBRE3YaCiDjPwQGcd9CrysLv4wTyoLFD90dxqbp1EgdPRB7Kskznea6Zn/aPoKoqUUrJOI5m4l2QBfSyLHKep1zXZSae3An1fS/7vst931bGkzuhaZrsLVbGkzuheZ7lOI6HyJ2QUkqv6yrbtv0LT+6E7G0UrfBfP3lZlpoXH4ZBmHgn5Pv+KwxDfqp0XQdgJp6c/RsUBIGOokiSJDE/s21bACbe5Ozp0TdAHMdSFIXUdS1N01C2wpObPT36HifwCJzI0iX29Oh7XP0E3CB9L01TzM+i/wePv4ZE5RtAngAAAABJRU5ErkJggg==) 10px center no-repeat;
|
||||
content: '';
|
||||
display: block;
|
||||
width: 31px;
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: -3px;
|
||||
top: 0;
|
||||
z-index: 10;
|
||||
}
|
||||
|
||||
/* Icon background */
|
||||
.persona-button span:before{
|
||||
content: '';
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 20px;
|
||||
|
||||
position: absolute;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
top: 0;
|
||||
z-index: 1;
|
||||
|
||||
background: #42a9dd;
|
||||
background: -moz-linear-gradient(top, #50b8e8, #3095ce);
|
||||
background: -ms-linear-gradient(top, #50b8e8, #3095ce);
|
||||
background: -o-linear-gradient(top, #50b8e8, #3095ce);
|
||||
background: -webkit-linear-gradient(top, #50b8e8, #3095ce);
|
||||
background: linear-gradient(top, #50b8e8, #3095ce);
|
||||
|
||||
-moz-border-radius: 3px 0 0 3px;
|
||||
-ms-border-radius: 3px 0 0 3px;
|
||||
-o-border-radius: 3px 0 0 3px;
|
||||
-webkit-border-radius: 3px 0 0 3px;
|
||||
border-radius: 3px 0 0 3px;
|
||||
}
|
||||
|
||||
/* Triangle */
|
||||
.persona-button:before{
|
||||
background: #42a9dd;
|
||||
content: '';
|
||||
display: block;
|
||||
height: 26px;
|
||||
width: 26px;
|
||||
|
||||
position: absolute;
|
||||
left: 2px;
|
||||
top: 50%;
|
||||
margin-top: -13px;
|
||||
z-index: 0;
|
||||
|
||||
background: -moz-linear-gradient(-45deg, #50b8e8, #3095ce);
|
||||
background: -ms-linear-gradient(-45deg, #50b8e8, #3095ce);
|
||||
background: -o-linear-gradient(-45deg, #50b8e8, #3095ce);
|
||||
background: -webkit-linear-gradient(-45deg, #50b8e8, #3095ce);
|
||||
background: linear-gradient(-45deg, #3095ce, #50b8e8); /* flipped for updated spec */
|
||||
|
||||
-moz-box-shadow: 1px -1px 1px rgba(0,0,0,0.1);
|
||||
-ms-box-shadow: 1px -1px 1px rgba(0,0,0,0.1);
|
||||
-o-box-shadow: 1px -1px 1px rgba(0,0,0,0.1);
|
||||
-webkit-box-shadow: 1px -1px 1px rgba(0,0,0,0.1);
|
||||
box-shadow: 1px -1px 1px rgba(0,0,0,0.1);
|
||||
|
||||
-moz-transform: rotate(45deg);
|
||||
-ms-transform: rotate(45deg);
|
||||
-o-transform: rotate(45deg);
|
||||
-webkit-transform: rotate(45deg);
|
||||
transform: rotate(45deg);
|
||||
}
|
||||
|
||||
/* Inset shadow (required here because the icon background clips it when on the `a` element) */
|
||||
.persona-button:after{
|
||||
content: '';
|
||||
display: block;
|
||||
height: 100%;
|
||||
width: 100%;
|
||||
|
||||
position: absolute;
|
||||
left: 0;
|
||||
top: 0;
|
||||
bottom: 0;
|
||||
right: 0;
|
||||
z-index: 10;
|
||||
|
||||
-moz-border-radius: 3px;
|
||||
-ms-border-radius: 3px;
|
||||
-o-border-radius: 3px;
|
||||
-webkit-border-radius: 3px;
|
||||
border-radius: 3px;
|
||||
|
||||
-moz-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.3);
|
||||
-ms-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.3);
|
||||
-o-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.3);
|
||||
-webkit-box-shadow: inset 0 -1px 0 rgba(0,0,0,0.3);
|
||||
box-shadow: inset 0 -1px 0 rgba(0,0,0,0.3);
|
||||
}
|
||||
|
||||
/* ========================================================
|
||||
* Dark button
|
||||
* ===================================================== */
|
||||
.persona-button.dark{
|
||||
background: #3c3c3c;
|
||||
background: -moz-linear-gradient(top, #606060, #3c3c3c);
|
||||
background: -ms-linear-gradient(top, #606060, #3c3c3c);
|
||||
background: -o-linear-gradient(top, #606060, #3c3c3c);
|
||||
background: -webkit-linear-gradient(top, #606060, #3c3c3c);
|
||||
background: linear-gradient(top, #606060, #3c3c3c);
|
||||
}
|
||||
.persona-button.dark:hover{
|
||||
background: #2d2d2d;
|
||||
background: -moz-linear-gradient(top, #484848, #2d2d2d);
|
||||
background: -ms-linear-gradient(top, #484848, #2d2d2d);
|
||||
background: -o-linear-gradient(top, #484848, #2d2d2d);
|
||||
background: -webkit-linear-gradient(top, #484848, #2d2d2d);
|
||||
background: linear-gradient(top, #484848, #2d2d2d);
|
||||
}
|
||||
.persona-button.dark span:before{ /* Icon BG */
|
||||
background: #d34f2d;
|
||||
background: -moz-linear-gradient(top, #ebac45, #d34f2d);
|
||||
background: -ms-linear-gradient(top, #ebac45, #d34f2d);
|
||||
background: -o-linear-gradient(top, #ebac45, #d34f2d);
|
||||
background: -webkit-linear-gradient(top, #ebac45, #d34f2d);
|
||||
background: linear-gradient(top, #ebac45, #d34f2d);
|
||||
}
|
||||
.persona-button.dark:before{ /* Triangle */
|
||||
background: #d34f2d;
|
||||
background: -moz-linear-gradient(-45deg, #ebac45, #d34f2d);
|
||||
background: -ms-linear-gradient(-45deg, #ebac45, #d34f2d);
|
||||
background: -o-linear-gradient(-45deg, #ebac45, #d34f2d);
|
||||
background: -webkit-linear-gradient(-45deg, #ebac45, #d34f2d);
|
||||
background: linear-gradient(-45deg, #d34f2d, #ebac45); /* flipped for updated spec */
|
||||
}
|
||||
|
||||
/* ========================================================
|
||||
* Orange button
|
||||
* ===================================================== */
|
||||
.persona-button.orange{
|
||||
background: #ee731a;
|
||||
background: -moz-linear-gradient(top, #ee731a, #d03116);
|
||||
background: -ms-linear-gradient(top, #ee731a, #d03116);
|
||||
background: -o-linear-gradient(top, #ee731a, #d03116);
|
||||
background: -webkit-linear-gradient(top, #ee731a, #d03116);
|
||||
background: linear-gradient(top, #ee731a, #d03116);
|
||||
}
|
||||
.persona-button.orange:hover{
|
||||
background: #cb6216;
|
||||
background: -moz-linear-gradient(top, #cb6216, #b12a13);
|
||||
background: -ms-linear-gradient(top, #cb6216, #b12a13);
|
||||
background: -o-linear-gradient(top, #cb6216, #b12a13);
|
||||
background: -webkit-linear-gradient(top, #cb6216, #b12a13);
|
||||
background: linear-gradient(top, #cb6216, #b12a13);
|
||||
}
|
||||
.persona-button.orange span:before{ /* Icon BG */
|
||||
background: #e84a21;
|
||||
background: -moz-linear-gradient(top, #f7ad27, #e84a21);
|
||||
background: -ms-linear-gradient(top, #f7ad27, #e84a21);
|
||||
background: -o-linear-gradient(top, #f7ad27, #e84a21);
|
||||
background: -webkit-linear-gradient(top, #f7ad27, #e84a21);
|
||||
background: linear-gradient(top, #f7ad27, #e84a21);
|
||||
}
|
||||
.persona-button.orange:before{ /* Triangle */
|
||||
background: #e84a21;
|
||||
background: -moz-linear-gradient(-45deg, #f7ad27, #e84a21);
|
||||
background: -ms-linear-gradient(-45deg, #f7ad27, #e84a21);
|
||||
background: -o-linear-gradient(-45deg, #f7ad27, #e84a21);
|
||||
background: -webkit-linear-gradient(-45deg, #f7ad27, #e84a21);
|
||||
background: linear-gradient(-45deg, #e84a21, #f7ad27); /* flipped for updated spec */
|
||||
}
|
||||
|
|
@ -20,6 +20,9 @@
|
|||
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/[% opac_css_override %]" />
|
||||
[% END %]
|
||||
<link rel="stylesheet" type="text/css" media="print" href="[% themelang %]/css/print.css" />
|
||||
[% IF persona %]
|
||||
<link rel="stylesheet" type="text/css" href="[% themelang %]/css/persona-buttons.css" />
|
||||
[% END %]
|
||||
[% IF ( OPACMobileUserCSS ) %]<style type="text/css" media="screen and (max-width:700px)">[% OPACMobileUserCSS %]</style>[% END %]
|
||||
[% IF ( OPACUserCSS ) %]<style type="text/css">[% OPACUserCSS %]</style>[% END %]
|
||||
<!-- yui js -->
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@
|
|||
[% IF ( ShowOpacRecentSearchLink ) %]
|
||||
<li><a href="/cgi-bin/koha/opac-search-history.pl" title="View your search history">Search history</a> [<a class="logout" href="/cgi-bin/koha/opac-search-history.pl?action=delete" title="Delete your search history" onclick="return confirm(MSG_DELETE_SEARCH_HISTORY);">x</a>]</li>
|
||||
[% END %]
|
||||
[% IF ( loggedinusername ) %]<li><a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">Log Out</a></li>[% END %]
|
||||
[% IF ( loggedinusername ) %]<li>[% IF persona %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1" onclick='navigator.id.logout();'>[% ELSE %]<a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1">[% END %]Log Out</a></li>[% END %]
|
||||
</ul>
|
||||
[% END %]
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -60,5 +60,44 @@
|
|||
|
||||
[% END %]
|
||||
|
||||
[% IF persona %]
|
||||
<script src="https://login.persona.org/include.js"></script>
|
||||
<script type="text/javascript" language="javascript">
|
||||
|
||||
navigator.id.watch({
|
||||
loggedInUser: [% IF emailaddress && loggedinpersona %]'[% emailaddress %]'[% ELSE %]null[% END %],
|
||||
onlogin: function (assertion) {
|
||||
$.post('/cgi-bin/koha/svc/login',
|
||||
{ assertion: assertion },
|
||||
function (data) {
|
||||
window.location = '/cgi-bin/koha/opac-user.pl';
|
||||
}
|
||||
)
|
||||
.fail(function() { var errstr = _("Could not login, perhaps your Persona email does not match your Koha one");
|
||||
alert(errstr);
|
||||
});
|
||||
},
|
||||
onlogout: function () {
|
||||
window.location = '/cgi-bin/koha/opac-main.pl?logout.x=1';
|
||||
}
|
||||
});
|
||||
|
||||
var signinLink = document.getElementById('browserid');
|
||||
|
||||
if (signinLink) {
|
||||
signinLink.onclick = function(evt) {
|
||||
// Requests a signed identity assertion from the user.
|
||||
navigator.id.request({
|
||||
siteName: "[% LibraryName | html %]",
|
||||
returnTo: '/cgi-bin/koha/opac-user.pl',
|
||||
oncancel: function() { alert('user refuses to share identity.'); }
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
</script>
|
||||
[% END %]
|
||||
|
||||
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -99,7 +99,13 @@ please choose against which one you would like to authenticate: </p>
|
|||
<a href="mailto:[% admin %]">email the Koha Administrator</a>.</li>
|
||||
<li>Use top menu bar to navigate to another part of Koha.</li>
|
||||
</ul>
|
||||
[% END %]</div>
|
||||
[% END %]
|
||||
|
||||
[% IF persona %]
|
||||
<a href="#" class="persona-button" id="browserid" ><span>Sign in with your Email</span></a>
|
||||
[% END %]
|
||||
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -63,6 +63,9 @@
|
|||
</form>
|
||||
</div>
|
||||
[% END %]
|
||||
[% IF persona %]
|
||||
<a href="#" class="persona-button" id="browserid" ><span>Sign in with your Email</span></a>
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% END %]
|
||||
[% IF ( OpacNavRight ) %]<div id="opacrightsidebar" class="container">[% OpacNavRight %]</div>[% END %]
|
||||
|
|
|
|||
Binary file not shown.
|
After Width: | Height: | Size: 1.8 KiB |
|
|
@ -16,7 +16,7 @@ the kohaversion is divided in 4 parts :
|
|||
use strict;
|
||||
|
||||
sub kohaversion {
|
||||
our $VERSION = '3.11.00.021';
|
||||
our $VERSION = '3.11.00.022';
|
||||
# version needs to be set this way
|
||||
# so that it can be picked up by Makefile.PL
|
||||
# during install
|
||||
|
|
|
|||
|
|
@ -0,0 +1,58 @@
|
|||
#!/usr/bin/perl
|
||||
|
||||
# Copyright chris@bigballofwax.co.nz 2013
|
||||
#
|
||||
# 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 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.
|
||||
#
|
||||
# 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.
|
||||
|
||||
use CGI;
|
||||
use strict;
|
||||
use warnings;
|
||||
use C4::Auth;
|
||||
use C4::Context;
|
||||
|
||||
use LWP::UserAgent;
|
||||
use HTTP::Request::Common qw{ POST };
|
||||
use JSON qw( decode_json );
|
||||
|
||||
my $url = 'https://verifier.login.persona.org/verify';
|
||||
|
||||
my $query = CGI->new();
|
||||
|
||||
my $host = C4::Context->preference('OPACBaseURL');
|
||||
|
||||
my $assertion = $query->param('assertion');
|
||||
|
||||
my $ua = LWP::UserAgent->new();
|
||||
my $response =
|
||||
$ua->post( $url, [ 'assertion' => $assertion, 'audience' => $host ] );
|
||||
|
||||
if ( $response->is_success ) {
|
||||
my $content = $response->decoded_content();
|
||||
my $decoded_json = decode_json($content);
|
||||
my ( $userid, $cookie, $sessionID ) =
|
||||
checkauth( $query, 1, { borrow => 1 }, 'opac', $decoded_json->{'email'} );
|
||||
if ($userid) { # a valid user has logged in
|
||||
print $query->header( -cookie => $cookie );
|
||||
print $decoded_json;
|
||||
}
|
||||
else {
|
||||
# logged in with an email that isn't associated with a borrower
|
||||
die "Email not associated with a borrower";
|
||||
}
|
||||
}
|
||||
else {
|
||||
warn $response->status_line, "\n";
|
||||
}
|
||||
Loading…
Reference in New Issue