FEATURE: Moved the log-in validation process from individual authenticators into Member->checkPassword() and canLogIn(), to allow more extensibility and control (trunk, 2.4).

MINOR: Use a ValidationResult to log in a member so that custom errors can be generated.

From: Andrew Short <andrewjshort@gmail.com>

git-svn-id: svn://svn.silverstripe.com/silverstripe/open/modules/sapphire/trunk@98267 467b73ca-7a2a-4603-9d3b-597d59a354a9
This commit is contained in:
Andrew Short 2010-02-05 00:36:25 +00:00 committed by Sam Minnee
parent fda7836aca
commit 5e9b78b798
2 changed files with 49 additions and 27 deletions

View File

@ -129,15 +129,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,
@ -145,10 +144,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
*/

29
security/MemberAuthenticator.php Normal file → Executable file
View File

@ -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",
"\"Email\" = '$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;
}
/**