Koha/koha-tmpl/opac-tmpl/bootstrap/en/modules/opac-auth.tt
Jonathan Druart cfc484b173 Bug 18314: Account lockout
To prevent brute force attacks on Koha accounts, staff and opac, we need to
implement an account lockout process to Koha.

After a number of failed login attempts a users account would become locked.
The user would then need to use the reset password functionality to send a reset
token to their email account. After a successful password reset the lockout flag
would be removed.

The number of failed login attempts before lockout is configurable using a new
system preference 'FailedLoginAttempts'.

How does it work?
When a patron enter an invalid password, the borrowers.login_attempts value
for this patron is incremented. When this value reach the value of the
pref FailedLoginAttempts, the password comparison is not done and the
authentication is rejected.
This login_attempts field is reset when a patron correctly logs in. When
the account is locked the patron has to reset his/her password using
the OpacResetPassword feature or ask a staff member to generate a new
password.
If the pref is not set (0, or '') the feature is considered as disabled,
but the failed login attempts are stored anyway.

Test plan:
0/ Apply patch and execute the update DB entry
1/ Switch on the feature by setting FailedLoginAttempts to 3
2/ Use an invalid password to login at the staff or OPAC interface
3/ After the third consecutive failures, you will be asked to reset your
password if OpacResetPassword is set, or contact a staff member
4/ Switch on OpacResetPassword and reset your password
5/ Confirm that you are able to login
6/ Play with the different combinations

QA details: The trick happens in C4::Auth::checkpw, to make things clear
I had to create a return value (note the awesome name: @return) and
replace the 3 successives if statements with elsif. Indeed if one of
the condition is reached, it will return inside the given block.

Signed-off-by: Jonathan Field <jonathan.field@ptfs-europe.com>

Signed-off-by: Nick Clemens <nick@bywatersolutions.com>

Signed-off-by: Kyle M Hall <kyle@bywatersolutions.com>
2017-05-12 10:58:44 -04:00

220 lines
12 KiB
Text

[% USE Koha %]
[% INCLUDE 'doc-head-open.inc' %]
<title>[% IF ( LibraryNameTitle ) %][% LibraryNameTitle %][% ELSE %]Koha online[% END %] catalog &rsaquo;
[% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
Log in to your account
[% ELSE %]
Catalog login disabled
[% END %]</title>
[% INCLUDE 'doc-head-close.inc' %]
[% BLOCK cssinclude %][% END %]
</head>
[% INCLUDE 'bodytag.inc' bodyid='opac-login-page' bodyclass='scrollto' %]
[% INCLUDE 'masthead.inc' %]
<div class="main">
<ul class="breadcrumb">
<li><a href="/cgi-bin/koha/opac-main.pl">Home</a> <span class="divider">&rsaquo;</span></li>
<li><a href="#">Log in</a></li>
</ul>
<div class="container-fluid">
<div class="row-fluid">
<div class="span7 offset2">
<div id="opac-auth" class="maincontent">
<!--CONTENT-->
[% IF Koha.Preference( 'opacuserlogin' ) == 1 %]
[% IF ( nopermission ) %]
<!-- This is what is displayed if user doesnt have permission -->
<div class="alert">
<h3>Access denied</h3>
<p>Sorry, the system doesn't think you have permission to access this page. </p>
[% IF SCO_login %]
<p><a href="/cgi-bin/koha/sco/sco-main.pl?logout.x=1">Log out and try again with a different user.</a></p>
[% END %]
</div>
[% END %]
[% IF ( loginprompt ) %]
<!-- login prompt time-->
<h3>Log in to your account</h3>
[% IF ( timed_out ) %]
<!-- This is what is displayed if login has timed out -->
<div class="alert alert-info">
<p>Sorry, your session has timed out. Please log in again.</p>
</div>
[% END %]
[% IF ( different_ip ) %]
<!-- This is what is displayed if user doesnt have permission -->
<div class="alert alert-info">
<p>You are logging from a different IP address. Please log in again.</p>
</div>
[% END %]
[% IF too_many_login_attempts %]
<div class="alert alert-info">
This account has been locked!
[% IF Koha.Preference('OpacResetPassword') %]
<a href="/cgi-bin/koha/opac-password-recovery.pl">You must reset your password</a>.
[% ELSE %]
Please contact a library staff member.
[% END %]
</div>
[% ELSIF invalid_username_or_password %]
<!-- This is what is displayed if user doesnt have permission -->
<div class="alert alert-info">
<p>You entered an incorrect username or password. Please try again! And remember, passwords are case sensitive.</p>
</div>
[% END %]
[% IF ( shibbolethAuthentication ) %]
[% IF ( invalidShibLogin ) %]
<!-- This is what is displayed if shibboleth login has failed to match a koha user -->
<div class="alert alert-info">
<p>Sorry, your Shibboleth identity does not match a valid library identity.</p>
[% IF ( casAuthentication ) %]
[% IF ( invalidCasLogin ) %]
<!-- This is what is displayed if cas login has failed -->
<p>Sorry, the CAS login also failed. If you have a local login you may use that below.</p>
[% ELSE %]
<p>If you have a CAS account, you may use that below.</p>
[% END %]
[% ELSE %]
<p>If you have a local account, you may use that below.</p>
[% END %]
</div>
[% ELSE %]
<h4>Shibboleth Login</h4>
<p><a href="[% shibbolethLoginUrl %]">If you have a Shibboleth account, please click here to log in.</a></p>
[% END %]
[% IF ( casAuthentication ) %]
<h4>CAS login</h4>
<p>If you do not have a Shibboleth account, but you do have a CAS account, you can use CAS.</p>
[% ELSE %]
<h4>Local login</h4>
<p>If you do not have a Shibboleth account, but you do have a local login, then you may login below.</p>
[% END %]
[% END %]
[% IF ( casAuthentication ) %]
[% IF ( shibbolethAuthentication ) %]
[% IF ( casServerUrl ) %]
<p><a href="[% casServerUrl %]">Please click here to log in.</a><p>
[% END %]
[% IF ( casServersLoop ) %]
<p>Please choose against which one you would like to authenticate: </p>
<ul>
[% FOREACH casServer IN casServersLoop %]
<li><a href="[% casServer.value %]">[% casServer.name %]</a></li>
[% END %]
</ul>
[% END %]
[% ELSE %]
<h4>CAS login</h4>
[% IF ( invalidCasLogin ) %]
<!-- This is what is displayed if cas login has failed -->
<p>Sorry, the CAS login failed.</p>
[% END %]
[% IF ( casServerUrl ) %]
<p><a href="[% casServerUrl %]">If you have a CAS account, please click here to log in.</a><p>
[% END %]
[% IF ( casServersLoop ) %]
<p>If you have a CAS account, please choose against which one you would like to authenticate:</p>
<ul>
[% FOREACH casServer IN casServersLoop %]
<li><a href="[% casServer.value %]">[% casServer.name %]</a></li>
[% END %]
</ul>
[% END %]
[% END %]
[% IF ( shibbolethAuthentication ) %]
<p>Nothing</p>
[% ELSE %]
<h4>Local login</h4>
<p>If you do not have a CAS account, but do have a local account, you can still log in: </p>
[% END %]
[% END # / IF casAuthentication %]
[% IF ( Koha.Preference('GoogleOpenIDConnect') == 1 ) %]
[% IF ( invalidGoogleOpenIDConnectLogin ) %]
<h4>Google login</h4>
<p>Sorry, your Google login failed. <span class="error">[% invalidGoogleOpenIDConnectLogin %]</span></p>
<p>Please note that the Google login will only work if you are using the e-mail address registered with this library.</p>
<p>If you want to, you can try to <a href="/cgi-bin/koha/svc/auth/googleopenidconnect?reauthenticate=select_account">log in using a different account</a>
[% END %]
<a href="/cgi-bin/koha/svc/auth/googleopenidconnect" class="btn btn-primary" id="openid_connect">Log in with Google</a>
<p>If you do not have a Google account, but do have a local account, you can still log in: </p>
[% END %]
[% IF SCO_login %]
<form action="/cgi-bin/koha/sco/sco-main.pl" name="auth" id="auth" method="post">
[% ELSE %]
<form action="[% script_name %]" name="auth" id="auth" method="post">
[% END %]
<input type="hidden" name="koha_login_context" value="opac" />
<fieldset class="brief">
[% FOREACH INPUT IN INPUTS %]
<input type="hidden" name="[% INPUT.name |html %]" value="[% INPUT.value |html %]" />
[% END %]
<label for="userid">Login</label>
<input type="text" size="25" id="userid" name="userid" />
<label for="password">Password</label><input type="password" size="25" id="password" name="password" />
</fieldset>
<input type="submit" value="Log in" class="btn" />
[% IF Koha.Preference('OpacPasswordChange') && Koha.Preference('OpacResetPassword') %]
<div id="forgotpassword">
<a href="/cgi-bin/koha/opac-password-recovery.pl">Forgot your password?</a>
</div>
[% END %]
<div id="nologininstructions">
[% IF Koha.Preference('NoLoginInstructions') %]
[% Koha.Preference('NoLoginInstructions') %]
[% ELSE %]
<h5>Don't have a password yet?</h5>
<p>If you don't have a password yet, stop by the circulation desk the next time you're in the library. We'll happily set one up for you.</p>
<h5>Don't have a library card?</h5>
<p>If you don't have a library card, stop by your local library to sign up.</p>
[% END # / IF Koha.Preference('NoLoginInstructions') %]
[% IF PatronSelfRegistration && PatronSelfRegistrationDefaultCategory %]<span id="registrationinstructions"><a href="/cgi-bin/koha/opac-memberentry.pl">You may register here.</a></span>
[% END %]
</div>
</form>
[% END # / IF loginprompt %]
[% ELSE %]
<h4>Logging on to the catalog has not been enabled by the library.</h4>
<ul>
<li>To report this error, you can email the Koha Administrator.<a href="mailto:[% admin %]">Email</a></li>
<li>Use top menu bar to navigate to another part of Koha.</li>
</ul>
[% END # / IF opacuserlogin %]
</div> <!-- /.opac-auth -->
</div> <!-- /.span12 -->
</div> <!-- /.row-fluid -->
</div> <!-- /.container-fluid -->
</div> <!-- /.main -->
[% INCLUDE 'opac-bottom.inc' %]
[% BLOCK jsinclude %]
<script type="text/javascript">
//<![CDATA[
// Hide circular 'Log in to Your Account' link in opac-auth.pl
$(document).ready(function() {
if ( $("#auth" ) ) { $("#members ul li a").hide(); }
});
//]]>
</script>
[% END %]