diff --git a/security/Member.php b/security/Member.php index c12025e5e..bb72390af 100755 --- a/security/Member.php +++ b/security/Member.php @@ -126,15 +126,14 @@ class Member extends DataObject { } /** - * Check if the passed password matches the stored one + * Check if the passed password matches the stored one (if the member is not locked out). * - * @param string $password The clear text password to check - * @return bool Returns TRUE if the passed password is valid, otherwise FALSE. + * @param string $password + * @return ValidationResult */ public function checkPassword($password) { - // Only confirm that the password matches if the user isn't locked out - if($this->isLockedOut()) return false; - + $result = $this->canLogIn(); + $spec = Security::encrypt_password( $password, $this->Salt, @@ -142,10 +141,40 @@ class Member extends DataObject { $this ); $e = $spec['encryptor']; - - return $e->compare($this->Password, $spec['password']); + + if(!$e->compare($this->Password, $spec['password'])) { + $result->error(_t ( + 'Member.ERRORWRONGCRED', + 'That doesn\'t seem to be the right e-mail address or password. Please try again.' + )); + } + + return $result; } - + + /** + * Returns a valid {@link ValidationResult} if this member can currently log in, or an invalid + * one with error messages to display if the member is locked out. + * + * You can hook into this with a "canLogIn" method on an attached extension. + * + * @return ValidationResult + */ + public function canLogIn() { + $result = new ValidationResult(); + + if($this->isLockedOut()) { + $result->error(_t ( + 'Member.ERRORLOCKEDOUT', + 'Your account has been temporarily disabled because of too many failed attempts at ' . + 'logging in. Please try again in 20 minutes.' + )); + } + + $this->extend('canLogIn', $result); + return $result; + } + /** * Returns true if this user is locked out */ diff --git a/security/MemberAuthenticator.php b/security/MemberAuthenticator.php old mode 100644 new mode 100755 index 3c794f954..d63363bf8 --- a/security/MemberAuthenticator.php +++ b/security/MemberAuthenticator.php @@ -32,6 +32,7 @@ class MemberAuthenticator extends Authenticator { public static function authenticate($RAW_data, Form $form = null) { $SQL_user = Convert::raw2sql($RAW_data['Email']); $isLockedOut = false; + $result = null; // Default login (see Security::setDefaultAdmin()) if(Security::check_default_admin($RAW_data['Email'], $RAW_data['Password'])) { @@ -41,9 +42,9 @@ class MemberAuthenticator extends Authenticator { "Member", "\"" . Member::get_unique_identifier_field() . "\" = '$SQL_user' AND \"Password\" IS NOT NULL" ); - - if($member && ($member->checkPassword($RAW_data['Password']) == false)) { - if($member->isLockedOut()) $isLockedOut = true; + $result = $member->checkPassword($RAW_data['Password']); + + if($member && !$result->valid()) { $member->registerFailedLogin(); $member = false; } @@ -102,22 +103,14 @@ class MemberAuthenticator extends Authenticator { $member->write(); } - if($member) { - Session::clear("BackURL"); - } else if($isLockedOut) { - if($form) $form->sessionMessage( - _t('Member.ERRORLOCKEDOUT', "Your account has been temporarily disabled because of too many failed attempts at logging in. Please try again in 20 minutes."), - "bad" - ); - } else { - if($form) $form->sessionMessage( - _t('Member.ERRORWRONGCRED', "That doesn't seem to be the right e-mail address or password. Please try again."), - "bad" - ); - } + if($member) { + Session::clear('BackURL'); + } else { + if($form && $result) $form->sessionMessage($result->message(), 'bad'); + } - return $member; - } + return $member; + } /**