From: dbs Date: Wed, 7 Apr 2010 05:17:13 +0000 (+0000) Subject: Implement complex password checking on self-serve password resets. X-Git-Url: https://old-git.evergreen-ils.org/?a=commitdiff_plain;h=6d97f4f484c6541464653404c22331e4dcb318d8;p=working%2FEvergreen.git Implement complex password checking on self-serve password resets. Add a new text code for weak passwords and a corresponding reset failure message. git-svn-id: svn://svn.open-ils.org/ILS/branches/rel_1_6@16149 dcc99617-32d9-48b4-a31d-7c20da2025e4 --- diff --git a/Open-ILS/examples/apache/eg_vhost.conf b/Open-ILS/examples/apache/eg_vhost.conf index 9070338647..5f2013cc54 100644 --- a/Open-ILS/examples/apache/eg_vhost.conf +++ b/Open-ILS/examples/apache/eg_vhost.conf @@ -176,7 +176,6 @@ RewriteRule - - [E=locale:en-US] [L] # Force clients to use HTTPS RewriteEngine On RewriteCond %{HTTPS} !=on [NC] - RewriteCond %{REQUEST_URI} ^/opac/password(/.*)? RewriteRule ^ https://%{SERVER_NAME}%{REQUEST_URI} [R,L] diff --git a/Open-ILS/src/extras/ils_events.xml b/Open-ILS/src/extras/ils_events.xml index a5d9622152..0ce709b209 100644 --- a/Open-ILS/src/extras/ils_events.xml +++ b/Open-ILS/src/extras/ils_events.xml @@ -833,6 +833,9 @@ The user attempted to update their password using a stale or inactive password reset request session. + + The user attempted to set their password to a weak value. + diff --git a/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm b/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm index 15aafaabc8..dbc17fc24f 100644 --- a/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm +++ b/Open-ILS/src/perlmods/OpenILS/Application/Actor.pm @@ -35,6 +35,7 @@ use OpenILS::Utils::CStoreEditor qw/:funcs/; use OpenILS::Utils::Penalty; use UUID::Tiny qw/:std/; +use JavaScript::SpiderMonkey; sub initialize { OpenILS::Application::Actor::Container->initialize(); @@ -3513,7 +3514,51 @@ sub commit_password_reset { return OpenILS::Event->new('PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST'); } - # TODO Check complexity of password against OU-defined regex + # Check complexity of password against OU-defined regex + my $pw_regex = $U->ou_ancestor_setting_value($user->home_ou, 'global.password_regex'); + + my $is_strong = 'false'; + if (!$pw_regex) { + # Use the default set of checks + if ((length($password) < 7) + or ($password !~ m/.*\d+.*/) + or ($password !~ m/.*[A-Za-z]+.*/)) { + # Still false! + } else { + $is_strong = 'true'; + } + } else { + # The password regex is for JavaScript, so we have to use SpiderMonkey to eval it + my $js = JavaScript::SpiderMonkey->new(); + $js->init(); + $js->property_by_path('pw.is_strong', 'false'); + $js->property_by_path('pw.password', $password); + $js->property_by_path('pw.regex', $pw_regex || 'blank'); + + my $pw_script = << 'PWCHECK'; + if (pw.regex != 'blank') { + if (pw.password.match(new RegExp(pwregex))) { + pw.is_strong = 'true'; + } + } else { + } while(0); + } +PWCHECK + + my $rc = $js->eval($pw_script); + if (!$rc) { + $logger->error("Error interpreting JavaScript while checking password strength: %s", $@); + } + + # Get the value of a property set in JS + $is_strong = $js->property_get('pw.is_strong'); + $js->destroy(); + } + + if ($is_strong eq 'false') { + $e->die_event; + return OpenILS::Event->new('PATRON_PASSWORD_WAS_NOT_STRONG'); + } # All is well; update the password $user->passwd($password); diff --git a/Open-ILS/src/perlmods/OpenILS/WWW/PasswordReset.pm b/Open-ILS/src/perlmods/OpenILS/WWW/PasswordReset.pm index c8b390fe82..410e7b216d 100644 --- a/Open-ILS/src/perlmods/OpenILS/WWW/PasswordReset.pm +++ b/Open-ILS/src/perlmods/OpenILS/WWW/PasswordReset.pm @@ -119,15 +119,23 @@ sub reset_password { if ($password_1 and $password_2 and ($password_1 eq $password_2)) { my $response = $actor->request('open-ils.actor.patron.password_reset.commit', $uuid, $password_1)->gather(); - if (ref($response) && - $response->{'textcode'} && - $response->{'textcode'} eq 'PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST') { + if (ref($response) && $response->{'textcode'}) { $apache->status(Apache2::Const::DECLINED); - $ctx->{'status'} = { - style => 'error', - msg => $ctx->{'i18n'}{'NOT_ACTIVE'} - }; + if ($response->{'textcode'} eq 'PATRON_NOT_AN_ACTIVE_PASSWORD_RESET_REQUEST') { + $ctx->{'status'} = { + style => 'error', + msg => $ctx->{'i18n'}{'NOT_ACTIVE'} + + }; + } + if ($response->{'textcode'} eq 'PATRON_PASSWORD_WAS_NOT_STRONG') { + $ctx->{'status'} = { + style => 'error', + msg => $ctx->{'i18n'}{'NOT_STRONG'} + + }; + } $tt->process('password-reset/reset-form.tt2', $ctx) || die $tt->error(); return Apache2::Const::OK; diff --git a/Open-ILS/src/templates/password-reset/strings.en-US b/Open-ILS/src/templates/password-reset/strings.en-US index 1db08118ab..5927ee5d4a 100644 --- a/Open-ILS/src/templates/password-reset/strings.en-US +++ b/Open-ILS/src/templates/password-reset/strings.en-US @@ -7,6 +7,7 @@ EMAIL_PROMPT=Email address associated with the account: NO_SESSION=Could not find the requested password reset session. NO_MATCH=Passwords did not match. Please try again NOT_ACTIVE=This was not an active password reset request. Your password has not been reset. +NOT_STRONG=The password you chose was not considered complex enough to protect your account. Your password has not been reset. SUCCESS=Password has been reset. TITLE=Library system password reset PASSWORD_PROMPT=New password: