Bugzilla – Attachment 44323 Details for
Bug 8753
Add forgot password link to OPAC
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
[patch]
Bug 8753 - Add forgot password link to OPAC
Bug-8753---Add-forgot-password-link-to-OPAC.patch (text/plain), 31.72 KB, created by
Marc Véron
on 2015-11-03 11:04:43 UTC
(
hide
)
Description:
Bug 8753 - Add forgot password link to OPAC
Filename:
MIME Type:
Creator:
Marc Véron
Created:
2015-11-03 11:04:43 UTC
Size:
31.72 KB
patch
obsolete
>From 11a96d4df4fde998953961d1f47ddd2e508d014b Mon Sep 17 00:00:00 2001 >From: Maxime Beaulieu <maxime.beaulieu@inlibro.com> >Date: Wed, 11 Mar 2015 13:52:59 -0400 >Subject: [PATCH] Bug 8753 - Add forgot password link to OPAC >MIME-Version: 1.0 >Content-Type: text/plain; charset=UTF-8 >Content-Transfer-Encoding: 8bit > > I've addressed a lot of Liz Rea's points. > >1. I have moved the code from updatedatabase.pl and kohastructure.sql to a file in the atomicupdates directory. >1a. The feature is now off by default when the atomicupdate is run. > >2. The password reset link is now visible on the home page, in the modal box and on opac-user.pl . > >3. The password recovery pages now use bootstrap markup. > >4. I am unsure here. I see "New Password:" and "Confirm new password:". > >5. This should still work :). > >6. I could not reproduce. > >7. I have added the userid field. > You can now reset the password by submitting either your useid or email address. > Both fields can be filled, but the email address must be one of the borrower's (email, emailpro or b_email). > When entering only the email address and two borrowers use that same address, the system tells the user to try with another address or to specify his userid. > >8. The text is in the atomicupdate file. Have at it, anyone. > >Concerning the email. It is inconvenient for the use to have to wait X minutes for the message queue the be processed. >Maybe we could add a sub in Letters.pm that: > Takes the same argments as EnqueueLetter > Sends the letter. > Saves the letter in the message queue with a 'sent' status. > > TEST PLAN: > >Setup) > 1) apply the patch > 2) go to system preferences OPAC>>Privacy and set 'OpacResetPassword' to ON. > 2b) make sure that OpacPasswordChange is also ON. >A) > 1) refresh front page, click on 'Forgot your password' and enter a VALID address > 1b) Also try an INVALID address (valid yet not in your koha db). An error message will show up. > 2) An email should be received at that address with a link. > 3) Follow the link in the mail to fill the new password. > Until a satisfactory new password is entered, the old password is not reset. > 4) Go to main page try the new password. >B) > 1) Repeat the password reset, this time use the userid (username) field. > 2) Try to reset the password using a userid and an email not linked to the account. An error appears. > 3) Make sure the borrower has many available email addresses. > 4) For each email, reset the password using both the userid and the email. The link should be sent to the specified address >C) > 1) Make sure two borrowers use the same email. > 2) Repeat the reset procedure in test case A). An error message appears > >http://bugs.koha-community.org/show_bug.cgi?id=13068 > > Author: Maxime Beaulieu <maxime.beaulieu@inlibro.com> > >Followed test plan. Works as described. >Signed-off-by: Marc Véron <veron@veron.ch> > >New sign-off after testing all patches together >Signed-off-by: Marc Véron <veron@veron.ch> >--- > C4/Passwordrecovery.pm | 173 +++++++++++++++++++ > Koha/Schema/Result/BorrowerPasswordRecovery.pm | 66 ++++++++ > .../bug_8753-Add_forgot_password_link_to_OPAC.sql | 12 ++ > .../data/mysql/en/mandatory/sample_notices.sql | 4 + > .../prog/en/modules/admin/preferences/opac.pref | 8 + > .../opac-tmpl/bootstrap/en/includes/masthead.inc | 6 + > .../opac-tmpl/bootstrap/en/modules/opac-auth.tt | 6 + > .../opac-tmpl/bootstrap/en/modules/opac-main.tt | 6 + > .../bootstrap/en/modules/opac-password-recovery.tt | 134 +++++++++++++++ > opac/opac-password-recovery.pl | 179 ++++++++++++++++++++ > 10 files changed, 594 insertions(+) > create mode 100644 C4/Passwordrecovery.pm > create mode 100644 Koha/Schema/Result/BorrowerPasswordRecovery.pm > create mode 100644 installer/data/mysql/atomicupdate/bug_8753-Add_forgot_password_link_to_OPAC.sql > create mode 100644 koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt > create mode 100755 opac/opac-password-recovery.pl > >diff --git a/C4/Passwordrecovery.pm b/C4/Passwordrecovery.pm >new file mode 100644 >index 0000000..67b5695 >--- /dev/null >+++ b/C4/Passwordrecovery.pm >@@ -0,0 +1,173 @@ >+package C4::Passwordrecovery; >+ >+# Copyright 2014 Solutions InLibro inc. >+# >+# 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, see <http://www.gnu.org/licenses>. >+ >+use Modern::Perl; >+use C4::Context; >+ >+use vars qw($VERSION @ISA @EXPORT); >+ >+BEGIN { >+ # set the version for version checking >+ $VERSION = 3.07.00.049; >+ require Exporter; >+ @ISA = qw(Exporter); >+ push @EXPORT, qw( >+ &ValidateBorrowernumber >+ &SendPasswordRecoveryEmail >+ &GetValidLinkInfo >+ &CompletePasswordRecovery >+ ); >+} >+ >+=head1 NAME >+ >+C4::Passwordrecovery - Koha password recovery module >+ >+=head1 SYNOPSIS >+ >+use C4::Passwordrecovery; >+ >+=head1 FUNCTIONS >+ >+=head2 ValidateBorrowernumber >+ >+$alread = ValidateBorrowernumber( $borrower_number ); >+ >+Check if the system already start recovery >+ >+Returns true false >+ >+=cut >+ >+sub ValidateBorrowernumber { >+ my ($borrower_number) = @_; >+ my $schema = Koha::Database->new->schema; >+ >+ my $rs = $schema->resultset('BorrowerPasswordRecovery')->search( >+ { >+ borrowernumber => $borrower_number, >+ valid_until => \'> NOW()' >+ }, { >+ columns => 'borrowernumber' >+ }); >+ >+ if ($rs->next){ >+ return 1; >+ } >+ >+ return 0; >+} >+ >+=head2 GetValidLinkInfo >+ >+ Check if the link is still valid and return some info. >+ >+=cut >+ >+sub GetValidLinkInfo { >+ my ($uniqueKey) = @_; >+ my $dbh = C4::Context->dbh; >+ my $query = ' >+ SELECT borrower_password_recovery.borrowernumber, userid >+ FROM borrower_password_recovery, borrowers >+ WHERE borrowers.borrowernumber = borrower_password_recovery.borrowernumber >+ AND NOW() < valid_until >+ AND uuid = ? >+ '; >+ my $sth = $dbh->prepare($query); >+ $sth->execute($uniqueKey); >+ return $sth->fetchrow; >+} >+ >+=head2 SendPasswordRecoveryEmail >+ >+ It creates an email using the templates and send it to the user, using the specified email >+ >+=cut >+ >+sub SendPasswordRecoveryEmail { >+ my $borrower = shift; # from GetMember >+ my $userEmail = shift; #to_address (the one specified in the request) >+ my $protocol = shift; #only required to determine if 'http' or 'https' >+ my $update = shift; >+ >+ my $schema = Koha::Database->new->schema; >+ >+ # generate UUID >+ my @chars = ("A".."Z", "a".."z", "0".."9"); >+ my $uuid_str; >+ $uuid_str .= $chars[rand @chars] for 1..32; >+ >+ # insert into database >+ my $expirydate = DateTime->now(time_zone => C4::Context->tz())->add( days => 2 ); >+ if($update){ >+ my $rs = $schema->resultset('BorrowerPasswordRecovery')->search( >+ { >+ borrowernumber => $borrower->{'borrowernumber'}, >+ }); >+ $rs->update({uuid => $uuid_str, valid_until => $expirydate->datetime()}); >+ } else { >+ my $rs = $schema->resultset('BorrowerPasswordRecovery')->create({ >+ borrowernumber=>$borrower->{'borrowernumber'}, >+ uuid => $uuid_str, >+ valid_until=> $expirydate->datetime() >+ }); >+ } >+ >+ # create link >+ my $uuidLink = $protocol . C4::Context->preference( 'OPACBaseURL' ) . "/cgi-bin/koha/opac-password-recovery.pl?uniqueKey=$uuid_str"; >+ >+ # prepare the email >+ my $letter = C4::Letters::GetPreparedLetter ( >+ module => 'members', >+ letter_code => 'PASSWORD_RESET', >+ branchcode => $borrower->{branchcode}, >+ substitute => {passwordreseturl => $uuidLink, user => $borrower->{userid} }, >+ ); >+ >+ # define to/from emails >+ my $kohaEmail = C4::Context->preference( 'KohaAdminEmailAddress' ); # from >+ >+ C4::Letters::EnqueueLetter( { >+ letter => $letter, >+ borrowernumber => $borrower->{borrowernumber}, >+ to_address => $userEmail, >+ from_address => $kohaEmail, >+ message_transport_type => 'email', >+ } ); >+ >+ return 1; >+} >+=head2 CompletePasswordRecovery >+ >+ $bool = CompletePasswordRevovery($uuid); >+ >+ Deletes a password recovery entry. >+ >+=cut >+sub CompletePasswordRecovery{ >+ my $uniqueKey = shift; >+ my $model = Koha::Database->new->schema->resultset('BorrowerPasswordRecovery'); >+ my $entry = $model->search({-or => [uuid => $uniqueKey, valid_until => \'< NOW()']}); >+ return $entry->delete(); >+} >+ >+END { } # module clean-up code here (global destructor) >+ >+1; >\ No newline at end of file >diff --git a/Koha/Schema/Result/BorrowerPasswordRecovery.pm b/Koha/Schema/Result/BorrowerPasswordRecovery.pm >new file mode 100644 >index 0000000..5b41fbf >--- /dev/null >+++ b/Koha/Schema/Result/BorrowerPasswordRecovery.pm >@@ -0,0 +1,66 @@ >+use utf8; >+package Koha::Schema::Result::BorrowerPasswordRecovery; >+ >+# Created by DBIx::Class::Schema::Loader >+# DO NOT MODIFY THE FIRST PART OF THIS FILE >+ >+=head1 NAME >+ >+Koha::Schema::Result::BorrowerPasswordRecovery >+ >+=cut >+ >+use strict; >+use warnings; >+ >+use base 'DBIx::Class::Core'; >+ >+=head1 TABLE: C<borrower_password_recovery> >+ >+=cut >+ >+__PACKAGE__->table("borrower_password_recovery"); >+ >+=head1 ACCESSORS >+ >+=head2 borrowernumber >+ >+ data_type: 'integer' >+ is_nullable: 0 >+ >+=head2 uuid >+ >+ data_type: 'varchar' >+ is_nullable: 0 >+ size: 128 >+ >+=head2 valid_until >+ >+ data_type: 'timestamp' >+ datetime_undef_if_invalid: 1 >+ default_value: current_timestamp >+ is_nullable: 0 >+ >+=cut >+ >+__PACKAGE__->add_columns( >+ "borrowernumber", >+ { data_type => "integer", is_nullable => 0 }, >+ "uuid", >+ { data_type => "varchar", is_nullable => 0, size => 128 }, >+ "valid_until", >+ { >+ data_type => "timestamp", >+ datetime_undef_if_invalid => 1, >+ default_value => \"current_timestamp", >+ is_nullable => 0, >+ }, >+); >+ >+ >+# Created by DBIx::Class::Schema::Loader v0.07039 @ 2014-11-03 12:08:20 >+# DO NOT MODIFY THIS OR ANYTHING ABOVE! md5sum:ORAWxUHIkefSfPSqrcfeXA >+ >+ >+# You can replace this text with custom code or comments, and it will be preserved on regeneration >+1; >diff --git a/installer/data/mysql/atomicupdate/bug_8753-Add_forgot_password_link_to_OPAC.sql b/installer/data/mysql/atomicupdate/bug_8753-Add_forgot_password_link_to_OPAC.sql >new file mode 100644 >index 0000000..9719bee >--- /dev/null >+++ b/installer/data/mysql/atomicupdate/bug_8753-Add_forgot_password_link_to_OPAC.sql >@@ -0,0 +1,12 @@ >+INSERT IGNORE INTO systempreferences (variable,value,options,explanation,type) >+VALUES ('OpacResetPassword', '0','','Shows the ''Forgot your password?'' link in the OPAC','YesNo'); >+ >+CREATE TABLE IF NOT EXISTS borrower_password_recovery ( >+ borrowernumber int(11) NOT NULL, >+ uuid varchar(128) NOT NULL, >+ valid_until timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP, >+ KEY borrowernumber (borrowernumber) >+) ENGINE=InnoDB DEFAULT CHARSET=utf8; >+ >+INSERT IGNORE INTO `letter` (module, code, branchcode, name, is_html, title, content, message_transport_type) >+VALUES ('members','PASSWORD_RESET','','Online password reset',1,'Koha password recovery','<html>\r\n<p>This email has been sent in response to your password recovery request for the account <strong><<user>></strong>.\r\n</p>\r\n<p>\r\nYou can now create your new password using the following link:\r\n<br/><a href=\"<<passwordreseturl>>\"><<passwordreseturl>></a>\r\n</p>\r\n<p>This link will be valid for 2 days from this email\'s reception, then you must reapply if you do not change your password.</p>\r\n<p>Thank you.</p>\r\n</html>\r\n','email'); >diff --git a/installer/data/mysql/en/mandatory/sample_notices.sql b/installer/data/mysql/en/mandatory/sample_notices.sql >index f20d9d3..82d1b32 100644 >--- a/installer/data/mysql/en/mandatory/sample_notices.sql >+++ b/installer/data/mysql/en/mandatory/sample_notices.sql >@@ -156,3 +156,7 @@ Your library.' > INSERT INTO letter(module, code, branchcode, name, title, content, message_transport_type) > VALUES ('acquisition', 'ACQ_NOTIF_ON_RECEIV', '', 'Notification on receiving', 'Order received', 'Dear <<borrowers.firstname>> <<borrowers.surname>>,\n\n The order <<aqorders.ordernumber>> (<<biblio.title>>) has been received.\n\nYour library.', 'email'), > ('members','MEMBERSHIP_EXPIRY','','Account expiration','Account expiration','Dear <<borrowers.title>> <<borrowers.firstname>> <<borrowers.surname>>,.\r\n\r\nYour library card will expire soon, on:\r\n\r\n<<borrowers.dateexpiry>>\r\n\r\nThank you,\r\n\r\nLibrarian\r\n\r\n<<branches.branchname>>','email'); >+ >+INSERT INTO `letter` (module, code, branchcode, name, is_html, title, content, message_transport_type) >+VALUES ('members','PASSWORD_RESET','','Online password reset',1,'Koha password recovery','<html>\r\n<p>This email has been sent in response to your password recovery request for the account <strong><<user>></strong>.\r\n</p>\r\n<p>\r\nYou can now create your new password using the following link:\r\n<br/><a href=\"<<passwordreseturl>>\"><<passwordreseturl>></a>\r\n</p>\r\n<p>This link will be valid for 2 days from this email\'s reception, then you must reapply if you do not change your password.</p>\r\n<p>Thank you.</p>\r\n</html>\r\n','email' >+); >diff --git a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >index 17d0b1a..5dcf5f4 100644 >--- a/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >+++ b/koha-tmpl/intranet-tmpl/prog/en/modules/admin/preferences/opac.pref >@@ -346,6 +346,14 @@ OPAC: > no: "Don't allow" > - patrons to change their own password on the OPAC. Note that this must be off to use LDAP authentication. > - >+ - "The user " >+ - pref: OpacResetPassword >+ default: 1 >+ choices: >+ yes: "can reset" >+ no: "can not reset" >+ - " their password on OPAC." >+ - > - pref: OPACPatronDetails > choices: > yes: Allow >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >index e034009..55008c7 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/includes/masthead.inc >@@ -306,6 +306,12 @@ > <fieldset class="brief"> > <label for="muserid">Login:</label><input type="text" id="muserid" name="userid" /> > <label for="mpassword">Password:</label><input type="password" id="mpassword" name="password" /> >+ [% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %] >+ <div id="forgotpassword-modal"> >+ <h5>Forgot your password?</h5> >+ <p>If you do not remember your password, click <a href="/cgi-bin/koha/opac-password-recovery.pl">here</a> to create a new one.</p> >+ </div> >+ [% END %] > [% IF Koha.Preference( 'NoLoginInstructions' ) %] > <div id="nologininstructions-modal"> > [% Koha.Preference( 'NoLoginInstructions' ) %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >index 3dc1c56..1174f59 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt >@@ -150,6 +150,12 @@ > </fieldset> > > <input type="submit" value="Log in" class="btn" /> >+ [% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %] >+ <div id="forgotpassword"> >+ <h5>Forgot your password?</h5> >+ <p>If you do not remember your password, click <a href="/cgi-bin/koha/opac-password-recovery.pl">here</a> to create a new one.</p> >+ </div> >+ [% END %] > <div id="nologininstructions"> > [% IF Koha.Preference('NoLoginInstructions') %] > [% Koha.Preference('NoLoginInstructions') %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-main.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-main.tt >index 7e51a94..87051fb 100644 >--- a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-main.tt >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-main.tt >@@ -85,6 +85,12 @@ > </fieldset> > [% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<div id="patronregistration"><p>Don't have an account? <a href="/cgi-bin/koha/opac-memberentry.pl">Register here.</a></p></div>[% END %] > </fieldset> >+ [% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %] >+ <div id="forgotpassword"> >+ <h5>Forgot your password?</h5> >+ <p>If you do not remember your password, click <a href="/cgi-bin/koha/opac-password-recovery.pl">here</a> to create a new one.</p> >+ </div> >+ [% END %] > [% IF Koha.Preference( 'NoLoginInstructions' ) %] > <div id="nologininstructions-main"> > [% Koha.Preference( 'NoLoginInstructions' ) %] >diff --git a/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt >new file mode 100644 >index 0000000..8eedb7d >--- /dev/null >+++ b/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-password-recovery.tt >@@ -0,0 +1,134 @@ >+[% USE Koha %] >+[% INCLUDE 'doc-head-open.inc' %] >+[% IF (LibraryNameTitle) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog › >+[% INCLUDE 'doc-head-close.inc' %] >+[% BLOCK cssinclude %][% END %] >+[% BLOCK jsinclude %] >+<script type="text/javascript" language="javascript"> >+ $(function() { >+ $("#CheckAll").click(function(){ >+ $("[name=deleteRequest]").attr('checked', true); >+ return false; >+ }); >+ >+ $("#CheckNone").click(function(){ >+ $("[name=deleteRequest]").attr('checked', false); >+ return false; >+ }); >+ >+ $("select#type").change(function() { >+ $("fieldset#serial, fieldset#book, fieldset#chapter").hide() >+ $("fieldset#" + $(this).val() ).show(); >+ }); >+ }); >+</script> >+[% END %] >+</head> >+[% INCLUDE 'bodytag.inc' bodyid='opac-password-recovery' %] >+[% INCLUDE 'masthead.inc' %] >+ >+<div class="main"> >+ <ul class="breadcrumb"> >+ <li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">›</span></li> >+ <li><a href="#">Change your password</a></li> >+ </ul> >+ >+ <div class="container-fluid"> >+ <div class="row-fluid"> >+ <div class="span2"> >+ <div id="navigation"> >+ [% INCLUDE 'navigation.inc' IsPatronPage=0 %] >+ </div> >+ </div> >+ <div class="span10"> >+ <h3>Password recovery</h3> >+ [% IF (hasError) %] >+ <div class="alert alert-warning"> >+ <h3>An error occured</h3> >+ <p> >+ [% IF (sendmailError) %] >+ An error has occured while sending you the password recovery link. >+ <br/>Please try again later. >+ [% ELSIF (errNoBorrowerFound) %] >+ No account was found with the provided information. >+ <br/>Check if you typed it correctly. >+ [% ELSIF (errBadEmail) %] >+ The provided email address is not tied to this account. >+ [% ELSIF (errTooManyEmailFound) %] >+ More than one account has been found for the email address: "<strong>[% email %]</strong>" >+ <br/>Try to use your username or an alternative email if you have one. >+ [% ELSIF (errNoBorrowerEmail) %] >+ This account has no email address we can send the email to. >+ [% ELSIF (errAlreadyStartRecovery) %] >+ The process of password recovery has already started for this account ("<strong>[% username %]</strong>") >+ <br/>Check your emails; you should receive the link to reset your password. >+ <br/>If you did not receive it, click <a href="/cgi-bin/koha/opac-password-recovery.pl?resendEmail=true&email=[% email %]&username=[% username %]">here</a> to get a new password recovery link. >+ [% ELSIF (errPassNotMatch) %] >+ The passwords entered does not match. >+ <br/>Please try again. >+ [% ELSIF (errPassTooShort) %] >+ The password is too short. >+ <br/>The password must contain at least [% minPassLength %] characters. >+ [% ELSIF (errLinkNotValid) %] >+ We could not authenticate you as the account owner. >+ <br/>Be sure to use the link you received in your email. >+ [% END %] >+ </p> >+ <p>Please contact the staff if you need further assistance.</p> >+ </div> >+ [% END %] >+ <div id="password-recovery"> >+[% IF (!Koha.Preference('OpacResetPassword')) %] >+ <div class="alert alert-info">You can't reset your password.</div> >+[% ELSIF (password_recovery) %] >+ <form action="/cgi-bin/koha/opac-password-recovery.pl" method="post"> >+ <input type="hidden" name="koha_login_context" value="opac" /> >+ <fieldset> >+ <p>To reset your password, enter your username or email address. >+ <br/>A link to reset your password will be sent at this address.</p> >+ <label for="username">Login:</label> >+ <input type="text" id="username" size="40" name="username" value="[% username %]" /> >+ <label for="email">Email:</label> >+ <input type="text" id="email" size="40" name="email" value="[% email %]" /> >+ <fieldset class="action"> >+ <input type="submit" value="Submit" class="btn" name="sendEmail" /> >+ </fieldset> >+ </fieldset> >+ </form> >+[% ELSIF (new_password) %] >+ <form action="/cgi-bin/koha/opac-password-recovery.pl" method="post"> >+ <input type="hidden" name="koha_login_context" value="opac" /> >+ <fieldset> >+ <div class="alert alert-info">The password must contain at least [% minPassLength %] characters.</div> >+ <label for="password">New password:</label> >+ <input type="password" id="password" size="40" name="password" /> >+ <label for="repeatPassword">Confirm new password:</label> >+ <input type="password" id="repeatPassword" size="40" name="repeatPassword" /> >+ <fieldset class="action"> >+ <input type="hidden" name="username" value="[% username %]" /> >+ <input type="hidden" name="uniqueKey" value="[% uniqueKey %]" /> >+ <input type="submit" value="Submit" class="btn" name="passwordReset" /> >+ </fieldset> >+ </fieldset> >+ </form> >+[% ELSIF (mail_sent) %] >+ <div class="alert alert-info"> >+ <p> >+ An email has been sent to "[% email %]". >+ <br/>It contains a link to create a new password. >+ <br/>This link will be valid for 2 days starting now. >+ </p> >+ Click <a href="/cgi-bin/koha/opac-main.pl"">here</a> to return to the main page. >+ </div> >+[% ELSIF (password_reset_done) %] >+ <div class="alert alert-success"> >+ <p>The password has been changed for user "[% username %]".</p> >+ Click <a href="/cgi-bin/koha/opac-user.pl">here</a> to login. >+ </div> >+[% END %] >+ </div><!-- / #password-recovery --> >+ </div><!-- / .span10 --> >+ </div><!-- / .row-fluid --> >+ </div><!-- / .container-fluid --> >+</div><!-- / .main --> >+[% INCLUDE 'opac-bottom.inc' %] >\ No newline at end of file >diff --git a/opac/opac-password-recovery.pl b/opac/opac-password-recovery.pl >new file mode 100755 >index 0000000..0013870 >--- /dev/null >+++ b/opac/opac-password-recovery.pl >@@ -0,0 +1,179 @@ >+#!/usr/bin/perl >+ >+use strict; >+use Modern::Perl; >+use CGI; >+ >+use C4::Auth; >+use C4::Koha; >+use C4::Members qw(changepassword Search); >+use C4::Output; >+use C4::Context; >+use C4::Passwordrecovery qw(SendPasswordRecoveryEmail ValidateBorrowernumber GetValidLinkInfo CompletePasswordRecovery); >+use Koha::AuthUtils qw(hash_password); >+my $query = new CGI; >+use HTML::Entities; >+ >+my ( $template, $dummy, $cookie ) = get_template_and_user( >+ { >+ template_name => "opac-password-recovery.tt", >+ query => $query, >+ type => "opac", >+ authnotrequired => 1, >+ debug => 1, >+ } >+); >+ >+my $email = $query->param('email') // q{}; >+my $password = $query->param('password'); >+my $repeatPassword = $query->param('repeatPassword'); >+my $minPassLength = C4::Context->preference('minPasswordLength'); >+my $id = $query->param('id'); >+my $uniqueKey = $query->param('uniqueKey'); >+my $username = $query->param('username'); >+my $borrower_number; >+ >+#errors >+my $hasError; >+ >+#email form error >+my $errNoBorrowerFound; >+my $errNoBorrowerEmail; >+my $errAlreadyStartRecovery; >+my $errTooManyEmailFound; >+my $errBadEmail; >+ >+#new password form error >+my $errLinkNotValid; >+my $errPassNotMatch; >+my $errPassTooShort; >+ >+if ( $query->param('sendEmail') || $query->param('resendEmail') ) { >+ my $protocol = $query->https() ? "https://" : "http://"; >+ #try with the main email >+ $email ||= ''; # avoid undef >+ my $borrower; >+ my $search_results; >+ >+ # Find the borrower by his userid or email >+ if( $username ){ >+ $search_results = Search({ userid => $username }); >+ } >+ elsif ( $email ){ >+ $search_results = Search({ '' => $email }, undef, undef, undef, ['emailpro', 'email', 'B_email']); >+ } >+ >+ if(scalar @$search_results > 1){ # Many matching borrowers >+ $hasError = 1; >+ $errTooManyEmailFound = 1; >+ } >+ elsif( $borrower = shift @$search_results ){ # One matching borrower >+ $username ||= $borrower->{'userid'}; >+ my @emails = ( $borrower->{'email'}, $borrower->{'emailpro'}, $borrower->{'B_email'} ); >+ # Is the given email one of the borrower's ? >+ if( $email && !($email ~~ @emails) ){ >+ $hasError = 1; >+ $errBadEmail = 1; >+ } >+ # If we dont have an email yet. Get one of the borrower's email or raise an error. >+ # FIXME: That ugly shift-grep contraption. >+ # $email = shift [ grep { length() } @emails ] >+ # It's supposed to get a non-empty string from the @emails array. There's surely a simpler way >+ elsif( !$email && !($email = shift [ grep { length() } @emails ]) ){ >+ $hasError = 1; >+ $errNoBorrowerEmail = 1; >+ } >+ # Check if a password reset already issued for this borrower AND we are not asking for a new email >+ elsif( ValidateBorrowernumber( $borrower->{'borrowernumber'} ) && !$query->param('resendEmail') ){ >+ $hasError = 1; >+ $errAlreadyStartRecovery = 1; >+ } >+ } >+ else{ # 0 matching borrower >+ $hasError = 1; >+ $errNoBorrowerFound = 1; >+ } >+ if ($hasError) { >+ $template->param( >+ hasError => 1, >+ errNoBorrowerFound => $errNoBorrowerFound, >+ errTooManyEmailFound => $errTooManyEmailFound, >+ errAlreadyStartRecovery => $errAlreadyStartRecovery, >+ errBadEmail => $errBadEmail, >+ errNoBorrowerEmail => $errNoBorrowerEmail, >+ password_recovery => 1, >+ email => HTML::Entities::encode($email), >+ username => $username >+ ); >+ } >+ elsif ( SendPasswordRecoveryEmail( $borrower, $email, $protocol, $query->param('resendEmail') ) ) {#generate uuid and send recovery email >+ $template->param( >+ mail_sent => 1, >+ email => $email >+ ); >+ } >+ else {# if it doesnt work.... >+ $template->param( >+ password_recovery => 1, >+ sendmailError => 1 >+ ); >+ } >+} >+elsif ( $query->param('passwordReset') ) { >+ ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey); >+ #validate password length & match >+ if ( ($borrower_number) >+ && ( $password eq $repeatPassword ) >+ && ( length($password) >= $minPassLength ) ) >+ { #apply changes >+ changepassword( $username, $borrower_number, hash_password($password) ); >+ CompletePasswordRecovery($uniqueKey); >+ $template->param( >+ password_reset_done => 1, >+ username => $username >+ ); >+ } >+ else { #errors >+ if ( !$borrower_number ) { #parameters not valid >+ $errLinkNotValid = 1; >+ } >+ elsif ( $password ne $repeatPassword ) { #passwords does not match >+ $errPassNotMatch = 1; >+ } >+ elsif ( length($password) < $minPassLength ) { #password too short >+ $errPassTooShort = 1; >+ } >+ $template->param( >+ new_password => 1, >+ minPassLength => $minPassLength, >+ email => $email, >+ uniqueKey => $uniqueKey, >+ errLinkNotValid => $errLinkNotValid, >+ errPassNotMatch => $errPassNotMatch, >+ errPassTooShort => $errPassTooShort, >+ hasError => 1 >+ ); >+ } >+} >+elsif ($uniqueKey) { #reset password form >+ #check if the link is valid >+ ( $borrower_number, $username ) = GetValidLinkInfo($uniqueKey); >+ >+ if ( !$borrower_number ) { >+ $errLinkNotValid = 1; >+ } >+ >+ $template->param( >+ new_password => 1, >+ minPassLength => $minPassLength, >+ email => $email, >+ uniqueKey => $uniqueKey, >+ username => $username, >+ errLinkNotValid => $errLinkNotValid >+ ); >+} >+else { #password recovery form (to send email) >+ $template->param( password_recovery => 1 ); >+} >+ >+output_html_with_http_headers $query, $cookie, $template->output; >-- >1.7.10.4
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 8753
:
21502
|
21512
|
21521
|
21849
|
22175
|
22430
|
24586
|
24780
|
24781
|
24846
|
24853
|
24854
|
24855
|
24862
|
24906
|
24907
|
24908
|
25038
|
25039
|
25051
|
29111
|
33175
|
33176
|
34472
|
36819
|
37492
|
39049
|
39144
|
39165
|
39166
|
39167
|
39168
|
39827
|
41181
|
41192
|
41193
|
41455
|
41686
|
41687
|
41688
|
41706
|
43017
|
43183
|
43576
|
44305
|
44306
|
44307
|
44308
|
44309
|
44310
|
44311
|
44323
|
44324
|
44325
|
44326
|
44327
|
44329
|
44330
|
45209
|
45210
|
45211
|
45212
|
45213
|
45214
|
45215
|
45223
|
45224
|
45225
|
45226
|
45227
|
45228
|
45229
|
45230
|
46379
|
47164
|
47165
|
47166
|
47167
|
47168
|
47169
|
47170
|
47171
|
47357
|
47366