Bugzilla – Attachment 15257 Details for
Bug 9587
Allow login via mozilla persona - https://www.mozilla.org/en-US/persona/
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
[SIGNED-OFF] Bug 9587 : Mozilla Persona login
Bug-9587--Mozilla-Persona-login.patch (text/plain), 40.30 KB, created by
Bernardo Gonzalez Kriegel
on 2013-02-11 19:30:41 UTC
(
hide
)
Description:
[SIGNED-OFF] Bug 9587 : Mozilla Persona login
Filename:
MIME Type:
Creator:
Bernardo Gonzalez Kriegel
Created:
2013-02-11 19:30:41 UTC
Size:
40.30 KB
patch
obsolete
>From 8fd084bd4d57ac2d473f7e372f5023ab58b5e832 Mon Sep 17 00:00:00 2001 >From: Chris Cormack <chris@bigballofwax.co.nz> >Date: Mon, 11 Feb 2013 22:34:20 +1300 >Subject: [PATCH] Bug 9587 : Mozilla Persona login > > Working on Mozilla Persona support (browser id) > > This will let a user log into Koha using browser id, if their email > address used matches the email address inside Koha. > > Once an assertion is received, we simply need to find the user that > matches that email address, and create a session for them. > > opac/svc/login handles this part. > > The nice thing about it is, the user doesn't have to do anything, like > linking their account. As long as the email address they are using to > identify themselves in browserid is the same as the one in Koha it > will just work. > > This is covered by a systempreference, to allow people to do it, and > is of course totally opt in, it works alongside normal Koha (or any > other method) of login. So only those choosing to use it, need use it > >Test Plan > >1/ Make sure OPACBaseURL is set correctly >2/ Switch on the Persona syspref >3/ Make a borrower (or edit one) to have the email you plan to use as >the primary email >4/ Click sign in with email, make or use a persona account >5/ Logout >6/ Check you can still login and logout the normal way > >Signed-off-by: Bernardo Gonzalez Kriegel <bgkriegel@gmail.com> > >Comment: Works great. >It's not browser dependent, but tested with chrome, firefox, opera and safari. >Old an new login system works. >Minor errors, addresed in follow-up. >--- > C4/Auth.pm | 49 ++++- > installer/data/mysql/sysprefs.sql | 1 + > installer/data/mysql/updatedatabase.pl | 9 + > .../prog/en/modules/admin/preferences/admin.pref | 8 + > .../opac-tmpl/prog/en/css/persona-buttons.css | 228 ++++++++++++++++++++ > .../opac-tmpl/prog/en/includes/doc-head-close.inc | 3 + > koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc | 2 +- > .../opac-tmpl/prog/en/includes/opac-bottom.inc | 36 ++++ > .../opac-tmpl/prog/en/js/browserid_include.js | 1 + > koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt | 8 +- > koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt | 3 + > koha-tmpl/opac-tmpl/prog/images/sign_in_green.png | Bin 0 -> 1803 bytes > opac/svc/login | 52 +++++ > 13 files changed, 390 insertions(+), 10 deletions(-) > create mode 100644 koha-tmpl/opac-tmpl/prog/en/css/persona-buttons.css > create mode 100644 koha-tmpl/opac-tmpl/prog/en/js/browserid_include.js > create mode 100644 koha-tmpl/opac-tmpl/prog/images/sign_in_green.png > create mode 100755 opac/svc/login > >diff --git a/C4/Auth.pm b/C4/Auth.pm >index 0c57a3f..d19a4e2 100644 >--- a/C4/Auth.pm >+++ b/C4/Auth.pm >@@ -323,6 +323,7 @@ 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, > TagsEnabled => C4::Context->preference("TagsEnabled"), > hide_marc => C4::Context->preference("hide_marc"), > item_level_itypes => C4::Context->preference('item-level_itypes'), >@@ -333,6 +334,7 @@ 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" ) { >@@ -618,6 +620,7 @@ sub checkauth { > 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); >@@ -728,6 +734,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; >@@ -737,13 +744,14 @@ sub checkauth { > -value => $session->id, > -HttpOnly => 1 > ); >- $userid = $query->param('userid'); >+ $userid = $query->param('userid'); > 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 +760,30 @@ 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,17 +811,18 @@ 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; >@@ -992,6 +1024,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")); >diff --git a/installer/data/mysql/sysprefs.sql b/installer/data/mysql/sysprefs.sql >index 9032bfa..e63bbf5 100644 >--- a/installer/data/mysql/sysprefs.sql >+++ b/installer/data/mysql/sysprefs.sql >@@ -411,3 +411,4 @@ INSERT INTO systempreferences (variable,value,options,explanation,type) VALUES ( > INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('IDreamBooksReviews','0','Display book review snippets from IDreamBooks.com','','YesNo'); > INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('IDreamBooksReadometer','0','Display Readometer from IDreamBooks.com','','YesNo'); > INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('IDreamBooksResults','0','Display IDreamBooks.com rating in search results','','YesNo'); >+INSERT IGNORE INTO systempreferences (variable,value,explanation,options,type) VALUES('Persona',0,'Use Mozilla Persona for login','','YesNo'); >diff --git a/installer/data/mysql/updatedatabase.pl b/installer/data/mysql/updatedatabase.pl >index ed922b8..bcc31ef 100755 >--- a/installer/data/mysql/updatedatabase.pl >+++ b/installer/data/mysql/updatedatabase.pl >@@ -6399,6 +6399,15 @@ if ( CheckVersion($DBversion) ) { > SetVersion($DBversion); > } > >+$DBversion = "XXX"; >+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 > >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >index 4e907e1..afffb3a 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/admin.pref >@@ -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 >diff --git a/koha-tmpl/opac-tmpl/prog/en/css/persona-buttons.css b/koha-tmpl/opac-tmpl/prog/en/css/persona-buttons.css >new file mode 100644 >index 0000000..d1acbb0 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/en/css/persona-buttons.css >@@ -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 */ >+} >diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc b/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc >index 35884af..1a991df 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc >+++ b/koha-tmpl/opac-tmpl/prog/en/includes/doc-head-close.inc >@@ -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 --> >diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc >index 87e35a6..88136d4 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc >+++ b/koha-tmpl/opac-tmpl/prog/en/includes/masthead.inc >@@ -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><a class="logout" id="logout" href="/cgi-bin/koha/opac-main.pl?logout.x=1" [% IF persona %] onclick='navigator.id.logout();'[% END %]>Log Out</a></li>[% END %] > </ul> > [% END %] > </div> >diff --git a/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc b/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc >index 3df0221..25d74e2 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc >+++ b/koha-tmpl/opac-tmpl/prog/en/includes/opac-bottom.inc >@@ -60,5 +60,41 @@ > > [% END %] > >+[% IF persona %] >+<script src="https://login.persona.org/include.js"></script> >+<script type="text/javascript" language="javascript"> >+ >+navigator.id.watch({ >+ loggedInUser: [% IF emailaddress %]'[% 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'; >+ } >+ ); >+ }, >+ 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> >diff --git a/koha-tmpl/opac-tmpl/prog/en/js/browserid_include.js b/koha-tmpl/opac-tmpl/prog/en/js/browserid_include.js >new file mode 100644 >index 0000000..5d65a03 >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/prog/en/js/browserid_include.js >@@ -0,0 +1 @@ >+(function(){var a=function(){function e(a){return Array.isArray?Array.isArray(a):a.constructor.toString().indexOf("Array")!=-1}function d(a,c,d){var e=b[c][d];for(var f=0;f<e.length;f++)e[f].win===a&&e.splice(f,1);b[c][d].length===0&&delete b[c][d]}function c(a,c,d,e){function f(b){for(var c=0;c<b.length;c++)if(b[c].win===a)return!0;return!1}var g=!1;if(c==="*")for(var h in b){if(!b.hasOwnProperty(h))continue;if(h==="*")continue;if(typeof b[h][d]=="object"){g=f(b[h][d]);if(g)break}}else b["*"]&&b["*"][d]&&(g=f(b["*"][d])),!g&&b[c]&&b[c][d]&&(g=f(b[c][d]));if(g)throw"A channel is already bound to the same window which overlaps with origin '"+c+"' and has scope '"+d+"'";typeof b[c]!="object"&&(b[c]={}),typeof b[c][d]!="object"&&(b[c][d]=[]),b[c][d].push({win:a,handler:e})}"use strict";var a=Math.floor(Math.random()*1000001),b={},f={},g=function(a){try{var c=JSON.parse(a.data);if(typeof c!="object"||c===null)throw"malformed"}catch(a){return}var d=a.source,e=a.origin,g,h,i;if(typeof c.method=="string"){var j=c.method.split("::");j.length==2?(g=j[0],i=j[1]):i=c.method}typeof c.id!="undefined"&&(h=c.id);if(typeof i=="string"){var k=!1;if(b[e]&&b[e][g])for(var h=0;h<b[e][g].length;h++)if(b[e][g][h].win===d){b[e][g][h].handler(e,i,c),k=!0;break}if(!k&&b["*"]&&b["*"][g])for(var h=0;h<b["*"][g].length;h++)if(b["*"][g][h].win===d){b["*"][g][h].handler(e,i,c);break}}else typeof h!="undefined"&&f[h]&&f[h](e,i,c)};window.addEventListener?window.addEventListener("message",g,!1):window.attachEvent&&window.attachEvent("onmessage",g);return{build:function(b){var g=function(a){if(b.debugOutput&&window.console&&window.console.log){try{typeof a!="string"&&(a=JSON.stringify(a))}catch(c){}console.log("["+j+"] "+a)}};if(!window.postMessage)throw"jschannel cannot run this browser, no postMessage";if(!window.JSON||!window.JSON.stringify||!window.JSON.parse)throw"jschannel cannot run this browser, no JSON parsing/serialization";if(typeof b!="object")throw"Channel build invoked without a proper object argument";if(!b.window||!b.window.postMessage)throw"Channel.build() called without a valid window argument";if(window===b.window)throw"target window is same as present window -- not allowed";var h=!1;if(typeof b.origin=="string"){var i;b.origin==="*"?h=!0:null!==(i=b.origin.match(/^https?:\/\/(?:[-a-zA-Z0-9_\.])+(?::\d+)?/))&&(b.origin=i[0].toLowerCase(),h=!0)}if(!h)throw"Channel.build() called with an invalid origin";if(typeof b.scope!="undefined"){if(typeof b.scope!="string")throw"scope, when specified, must be a string";if(b.scope.split("::").length>1)throw"scope may not contain double colons: '::'"}var j=function(){var a="",b="abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";for(var c=0;c<5;c++)a+=b.charAt(Math.floor(Math.random()*b.length));return a}(),k={},l={},m={},n=!1,o=[],p=function(a,b,c){var d=!1,e=!1;return{origin:b,invoke:function(b,d){if(!m[a])throw"attempting to invoke a callback of a nonexistent transaction: "+a;var e=!1;for(var f=0;f<c.length;f++)if(b===c[f]){e=!0;break}if(!e)throw"request supports no such callback '"+b+"'";t({id:a,callback:b,params:d})},error:function(b,c){e=!0;if(!m[a])throw"error called for nonexistent message: "+a;delete m[a],t({id:a,error:b,message:c})},complete:function(b){e=!0;if(!m[a])throw"complete called for nonexistent message: "+a;delete m[a],t({id:a,result:b})},delayReturn:function(a){typeof a=="boolean"&&(d=a===!0);return d},completed:function(){return e}}},q=function(a,b,c){return window.setTimeout(function(){if(l[a]){var d="timeout ("+b+"ms) exceeded on method '"+c+"'";(1,l[a].error)("timeout_error",d),delete l[a],delete f[a]}},b)},r=function(a,c,d){if(typeof b.gotMessageObserver=="function")try{b.gotMessageObserver(a,d)}catch(h){g("gotMessageObserver() raised an exception: "+h.toString())}if(d.id&&c){if(k[c]){var i=p(d.id,a,d.callbacks?d.callbacks:[]);m[d.id]={};try{if(d.callbacks&&e(d.callbacks)&&d.callbacks.length>0)for(var j=0;j<d.callbacks.length;j++){var n=d.callbacks[j],o=d.params,q=n.split("/");for(var r=0;r<q.length-1;r++){var s=q[r];typeof o[s]!="object"&&(o[s]={}),o=o[s]}o[q[q.length-1]]=function(){var a=n;return function(b){return i.invoke(a,b)}}()}var t=k[c](i,d.params);!i.delayReturn()&&!i.completed()&&i.complete(t)}catch(h){var u="runtime_error",v=null;typeof h=="string"?v=h:typeof h=="object"&&(h&&e(h)&&h.length==2?(u=h[0],v=h[1]):typeof h.error=="string"&&(u=h.error,h.message?typeof h.message=="string"?v=h.message:h=h.message:v=""));if(v===null)try{v=JSON.stringify(h),typeof v=="undefined"&&(v=h.toString())}catch(w){v=h.toString()}i.error(u,v)}}}else d.id&&d.callback?!l[d.id]||!l[d.id].callbacks||!l[d.id].callbacks[d.callback]?g("ignoring invalid callback, id:"+d.id+" ("+d.callback+")"):l[d.id].callbacks[d.callback](d.params):d.id?l[d.id]?(d.error?(1,l[d.id].error)(d.error,d.message):d.result!==undefined?(1,l[d.id].success)(d.result):(1,l[d.id].success)(),delete l[d.id],delete f[d.id]):g("ignoring invalid response: "+d.id):c&&k[c]&&k[c](null,d.params)};c(b.window,b.origin,typeof b.scope=="string"?b.scope:"",r);var s=function(a){typeof b.scope=="string"&&b.scope.length&&(a=[b.scope,a].join("::"));return a},t=function(a,c){if(!a)throw"postMessage called with null message";var d=n?"post ":"queue ";g(d+" message: "+JSON.stringify(a));if(!c&&!n)o.push(a);else{if(typeof b.postMessageObserver=="function")try{b.postMessageObserver(b.origin,a)}catch(e){g("postMessageObserver() raised an exception: "+e.toString())}b.window.postMessage(JSON.stringify(a),b.origin)}},u=function(a,c){g("ready msg received");if(n)throw"received ready message while in ready state. help!";c==="ping"?j+="-R":j+="-L",v.unbind("__ready"),n=!0,g("ready msg accepted."),c==="ping"&&v.notify({method:"__ready",params:"pong"});while(o.length)t(o.pop());typeof b.onReady=="function"&&b.onReady(v)},v={unbind:function(a){if(k[a]){if(delete k[a])return!0;throw"can't delete method: "+a}return!1},bind:function(a,b){if(!a||typeof a!="string")throw"'method' argument to bind must be string";if(!b||typeof b!="function")throw"callback missing from bind params";if(k[a])throw"method '"+a+"' is already bound!";k[a]=b;return this},call:function(b){if(!b)throw"missing arguments to call function";if(!b.method||typeof b.method!="string")throw"'method' argument to call must be string";if(!b.success||typeof b.success!="function")throw"'success' callback missing from call";var c={},d=[],e=function(a,b){if(typeof b=="object")for(var f in b){if(!b.hasOwnProperty(f))continue;var g=a+(a.length?"/":"")+f;typeof b[f]=="function"?(c[g]=b[f],d.push(g),delete b[f]):typeof b[f]=="object"&&e(g,b[f])}};e("",b.params);var g={id:a,method:s(b.method),params:b.params};d.length&&(g.callbacks=d),b.timeout&&q(a,b.timeout,s(b.method)),l[a]={callbacks:c,error:b.error,success:b.success},f[a]=r,a++,t(g)},notify:function(a){if(!a)throw"missing arguments to notify function";if(!a.method||typeof a.method!="string")throw"'method' argument to notify must be string";t({method:s(a.method),params:a.params})},destroy:function(){d(b.window,b.origin,typeof b.scope=="string"?b.scope:""),window.removeEventListener?window.removeEventListener("message",r,!1):window.detachEvent&&window.detachEvent("onmessage",r),n=!1,k={},m={},l={},b.origin=null,o=[],g("channel destroyed"),j=""}};v.bind("__ready",u),setTimeout(function(){},0);return v}}}();WinChan=function(){function j(){var b=window.location,c=window.opener.frames,d=b.protocol+"//"+b.host;for(i=c.length-1;i>=0;i++)try{if(c[i].location.href.indexOf(d)===0&&c[i].name===a)return c[i]}catch(e){}return}function h(a){/^https?:\/\//.test(a)||(a=window.location.href);var b=/^(https?:\/\/[-_a-zA-Z\.0-9:]+)/.exec(a);return b?b[1]:a}function g(){return window.JSON&&window.JSON.stringify&&window.JSON.parse&&window.postMessage}function f(){try{return d.indexOf("Fennec/")!=-1||d.indexOf("Firefox/")!=-1&&d.indexOf("Android")!=-1}catch(a){}return!1}function e(){var a=-1;if(navigator.appName=="Microsoft Internet Explorer"){var b=navigator.userAgent,c=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");c.exec(b)!=null&&(a=parseFloat(RegExp.$1))}return a>=8}function c(a,b,c){a.detachEvent?a.detachEvent("on"+b,c):a.removeEventListener&&a.removeEventListener(b,c,!1)}function b(a,b,c){a.attachEvent?a.attachEvent("on"+b,c):a.addEventListener&&a.addEventListener(b,c,!1)}var a="__winchan_relay_frame",k=e();return g()?{open:function(d,e){function p(a){try{var b=JSON.parse(a.data);b.a==="ready"?l.postMessage(n,j):b.a==="error"?e&&(e(b.d),e=null):b.a==="response"&&(c(window,"message",p),c(window,"unload",o),o(),e&&(e(null,b.d),e=null))}catch(a){}}function o(){i&&document.body.removeChild(i),i=undefined,m&&m.close(),m=undefined}if(!e)throw"missing required callback argument";var g;d.url||(g="missing required 'url' parameter"),d.relay_url||(g="missing required 'relay_url' parameter"),g&&setTimeout(function(){e(g)},0);if(!d.window_features||f())d.window_features=undefined;var i,j=h(d.url);if(j!==h(d.relay_url))return setTimeout(function(){e("invalid arguments: origin of url and relay_url must match")},0);var l;k&&(i=document.createElement("iframe"),i.setAttribute("src",d.relay_url),i.style.display="none",i.setAttribute("name",a),document.body.appendChild(i),l=i.contentWindow);var m=window.open(d.url,null,d.window_features);l||(l=m);var n=JSON.stringify({a:"request",d:d.params});b(window,"unload",o),b(window,"message",p);return{close:o,focus:function(){if(m)try{m.focus()}catch(a){}}}}}:{open:function(a,b,c,d){setTimeout(function(){d("unsupported browser")},0)}}}();var b=function(){function l(){return c}function k(){c=g()||h()||i()||j();return!c}function j(){if(!(window.JSON&&window.JSON.stringify&&window.JSON.parse))return"JSON_NOT_SUPPORTED"}function i(){if(!a.postMessage)return"POSTMESSAGE_NOT_SUPPORTED"}function h(){try{var b="localStorage"in a&&a.localStorage!==null;if(b)a.localStorage.setItem("test","true"),a.localStorage.removeItem("test");else return"LOCALSTORAGE_NOT_SUPPORTED"}catch(c){return"LOCALSTORAGE_DISABLED"}}function g(){return f()}function f(){var a=e(),b=a>-1&&a<8;if(b)return"BAD_IE_VERSION"}function e(){var a=-1;if(b.appName=="Microsoft Internet Explorer"){var c=b.userAgent,d=new RegExp("MSIE ([0-9]{1,}[.0-9]{0,})");d.exec(c)!=null&&(a=parseFloat(RegExp.$1))}return a}function d(c,d){b=c,a=d}var a=window,b=navigator,c;return{setTestEnv:d,isSupported:k,getNoSupportReason:l}}();navigator.id||(navigator.id={});if(!navigator.id.request||navigator.id._shimmed){var c="https://browserid.org",d=navigator.userAgent,e=d.indexOf("Fennec/")!=-1||d.indexOf("Firefox/")!=-1&&d.indexOf("Android")!=-1,f=e?undefined:"menubar=0,location=1,resizable=1,scrollbars=1,status=0,dialog=1,width=700,height=375",g,h={login:null,logout:null,ready:null},j=undefined;function k(a){a!==!0;if(j===undefined)j=a;else if(j!=a)throw"you cannot combine the navigator.id.watch() API with navigator.id.getVerifiedEmail() or navigator.id.get()this site should instead use navigator.id.request() and navigator.id.watch()"}var l,m=b.isSupported();function n(){if(!!m)try{if(!l){var b=window.document,d=b.createElement("iframe");d.style.display="none",b.body.appendChild(d),d.src=c+"/communication_iframe",l=a.build({window:d.contentWindow,origin:c,scope:"mozid_ni",onReady:function(){l.call({method:"loaded",success:function(){h.ready&&h.ready()},error:function(){}})}}),l.bind("logout",function(a,b){h.logout&&h.logout()}),l.bind("login",function(a,b){h.login&&h.login(b)})}}catch(e){l=undefined}}function o(a){if(typeof a=="object"){if(a.onlogin&&typeof a.onlogin!="function"||a.onlogout&&typeof a.onlogout!="function"||a.onready&&typeof a.onready!="function")throw"non-function where function expected in parameters to navigator.id.watch()";if(!a.onlogin)throw"'onlogin' is a required argument to navigator.id.watch()";if(!a.onlogout)throw"'onlogout' is a required argument to navigator.id.watch()";h.login=a.onlogin||null,h.logout=a.onlogout||null,h.ready=a.onready||null,n(),typeof a.loggedInEmail!="undefined"&&l&&l.notify({method:"loggedInUser",params:a.loggedInEmail})}}function p(a){if(g)try{g.focus()}catch(d){}else{if(!b.isSupported()){var e=b.getNoSupportReason(),i="unsupported_dialog";e==="LOCALSTORAGE_DISABLED"&&(i="cookies_disabled"),g=window.open(c+"/"+i,null,f);return}l&&l.notify({method:"dialog_running"}),g=WinChan.open({url:c+"/sign_in",relay_url:c+"/relay",window_features:f,params:{method:"get",params:a}},function(b,c){l&&(!b&&c&&c.email&&l.notify({method:"loggedInUser",params:c.email}),l.notify({method:"dialog_complete"})),g=undefined;if(!b&&c&&c.assertion)try{h.login&&h.login(c.assertion)}catch(d){}if(b==="client closed window"||!c)a&&a.oncancel&&a.oncancel(),delete a.oncancel})}}navigator.id={request:function(a){a=a||{},k(!1);return p(a)},watch:function(a){k(!1),o(a)},logout:function(a){n(),l&&l.notify({method:"logout"}),typeof a=="function"&&setTimeout(a,0)},get:function(a,b){b=b||{},k(!0),o({onlogin:function(b){a&&(a(b),a=null)},onlogout:function(){}}),b.oncancel=function(){a&&(a(null),a=null),h.login=h.logout=h.ready=null},b&&b.silent?a&&setTimeout(function(){a(null)},0):p(b)},getVerifiedEmail:function(a){k(!0),navigator.id.get(a)},_shimmed:!0}}})() >\ No newline at end of file >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt >index b5fca46..9d20db3 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-auth.tt >@@ -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> >diff --git a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt b/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt >index 61235e6..045313d 100644 >--- a/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt >+++ b/koha-tmpl/opac-tmpl/prog/en/modules/opac-main.tt >@@ -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 %] >diff --git a/koha-tmpl/opac-tmpl/prog/images/sign_in_green.png b/koha-tmpl/opac-tmpl/prog/images/sign_in_green.png >new file mode 100644 >index 0000000000000000000000000000000000000000..7e84129b4aa2d798213addb68e2fd01c23815e3b >GIT binary patch >literal 1803 >zcmV+m2lV)fP)<h;3K|Lk000e1NJLTq002(_000&U1^@s6fwjT8000KkNkl<ZSi|j^ >zYfO_@7{`w;Gg;zdVkFD5>>@5%vJZUOrzKm6F}iHoC%34>Yq5Akbk5C99A3C7BDH{5 >zkSU6kauWoV+LrsRRmMf3ltNqRjb1dvOr87k>^$f7eJL#k-i>`>JIOESJnwU!bNc@K >zob#T(CFK7yJEga`ccItojeO+stffe3TRIgfHAH$^H#f-C6G^6yM9JF8s?28cjws>W >zZud%$$5Za}cziyu7iLOw4FS1s?m&fnLFuBToope?W|VO#+@nX2V5WFI9)WL52pm$+ >z9TMxPh;0nDtd&GgDW1#ailmw66C<9_=L3)1EwD#P;9$)^=UnTGSsBNlByAXEG)9Pu >zIjSX)(MsS{3(?D3$f}UyjgF44b&tB~GV}#uu~?v`xkUhN-skmr0pob$6a;>}JvGNP >zVQ|-&4nw{+2Da1dBbcx9K|El=YtxM*hR09s@chp)(Q$`01k#%c(B<24qLF+ysdx^D >zLo(`e0bRO5G&MB^;qRvz3mD6@`#OOG)u9>kwljh1A6|jm9dd9yHo%alo%u4=pM%MM >z59F#ZrW`{obv^k|*PZ{jViQzUyhZ|Pja0zeNd$B{ol>X6$%F``v9T$Lz&@ii>oA^Y >zS3ZI7D}u?cU%`Z{?YatkuD%9)ue}PfIg25w_!H*;j_#coYPLW^<y%5bnmPjVTGudm >z8^QMB+hGiBqn~dFl2ZOL$ZmZp*fWjeIYhJYINb+RYe~m(ZNL(C+MH5{-A*%SG>C@! >zh9D;E=W@CL$Kcs<g^F=wA~_9FOuU|94J1^D3D@_PaCL6W8s^VwTEpxco!l~h{JS0e >zOGAGy99KoKw%%L}&*+lGf;C<boOj6G4uceIi;45+AkD&*S^~*hqD$0}PX+O8R-4p5 >zVy9W-3c_x8KwVwE0NRuFLmYM|;5a<n@(6np^TZX*1DnSvh%o4GgYu4e!GA%^iHkMb >zSlW6kVEdURkX;eOY-MdS#OBegE#mxkp8>Kfw?bOcSIoZCeQLs-$bdu7z_ysUKn_&W >zCo$az6V;@Oo^jt~;#sX$>4<fN3FD8A3eer%19i1^0%+s)z`g=DJK$J6(u-8IqH*@+ >zeh4>Pvccva7g0B)WWIB1PCTsRUf!g(>oRK}E&GVs)g2kaSXgehWzlV79>iYd?CSfn >z3G*QXc0EIE++^%8Cvb#5jT3H@-JE!4tJG?-GEsPj>5XeOwIM;je}A5lVH@CBNLgta >zM4u-RTQJTp`eC<UTmVw}Vu-)A9DHL=_Ti6JM!-4MOYvxpeHEHyc=pE=FuB^`*^4nI >z`2H*J31eZY(#t~HJVu+IAvSI@_7xNOneKt{x5!B*p4nuUTFe%9<2;?6U7*ouLxO() >z{s;<+;~=FarLZNNz|Q>8?D&NqPnxsXhd--Y2WReZ;$e+`W#eIZO2xa`B8QY~t07vp >z7<OD9k7pUAlZCW-c=5!>1+teO#p0_t;^a%Y%rluxQuCl0tkz)x^<B-h`1iNaOv5pd >zlHwBBbed*Z-b9X+L_pR3bXN1WZ_Ez9-<%M0em-PZbK+r*expstY^(<y?a*da3b6>c >z{A3|*9^;6fAvVsRIGS}oRdB>+EUluy?YTYAWHd<!O@l(#AS%_}Y2o{thb(~cNU^dQ >z*2@UQ<OGwa-o?c7FUH|}kd(ig`7>{F;$e+;T=oYbQ^Y`S^**R*ma{ChdHaO%uvE6n >zLfSmMcw*ytVrka>P|mUARJe{F?Z%(BMx#+m1%#nNi$G0{YFe=0pvepvizt;!h)O50 >z^}^&x<gdWSlqGQB>~fG5#;|(RiA4~7W*+CynhzTj-(YoSHFs>0S46S6EwTlmYR_la >z`0=nWUJqsS;2en9IAkZ?Cia(dY(E*^LC>`l&w2g*{gMI002N|L6sCbez&NBxQ3UHw >zPyx<P&z39#n@`VYb*MhO&%X^%pFd%lTG^fscRO>Ka7~>RGn!*I*mj8?QIs4pX-v4_ >zUl@H4`quXM8JQR}Wq@WH#vmx%niMKX<}4zo-*(n=D67kY{$U;bYSciPHXAmiE}Y$Y >zLV!oCJqiwKY6#)5^z;}a4G#@Iqrn6N{nLZ}488pfMPU(qok&w(Hv4QiMPPmE0*E@c >z2%-{SXYGGuo<Q(;g}>2}=+tn1&{Fj;#b=8b((EhmduRYLD6T6Ynx;1%H0L7G$>C~z >zT{rCu(ZXwmD+>w=%dZz)_Z1c>U?zNX@LiB3FPm$;kR-j|wK+LFjb_|3QU76}()3l+ >tT8f0e=ac?dczM53xJ2nuWJdpC`~_3{>|Z<f$NT^Q002ovPDHLkV1jREe1rf1 > >literal 0 >HcmV?d00001 > >diff --git a/opac/svc/login b/opac/svc/login >new file mode 100755 >index 0000000..607b566 >--- /dev/null >+++ b/opac/svc/login >@@ -0,0 +1,52 @@ >+#!/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'} ); >+ print $query->header( -cookie => $cookie ); >+ print $decoded_json; >+} >+else { >+ warn $response->status_line, "\n"; >+} >-- >1.7.9.5
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
|
Splinter Review
Attachments on
bug 9587
:
15226
|
15254
|
15257
|
15258
|
15265
|
15266
|
15449
|
15459
|
15474
|
15475
|
15476
|
15477
|
15478
|
15578
|
15580
|
15585