Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

update #10

Open
wants to merge 4 commits into
base: 1
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 11 additions & 71 deletions code/forms/UsernameOrEmailLoginForm.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,80 +7,20 @@ class UsernameOrEmailLoginForm extends MemberLoginForm

public function __construct($controller, $name, $fields = null, $actions = null, $checkCurrentUser = true)
{
$form_action_url = Controller::join_links(
BASE_URL,
"Security",
$name
);

$lost_password_url = Controller::join_links(
BASE_URL,
"Security",
"lostpassword"
);

if (isset($_REQUEST['BackURL'])) {
$backURL = $_REQUEST['BackURL'];
} else {
$backURL = Session::get('BackURL');
}

$fields = new FieldList(
HiddenField::create(
"AuthenticationMethod",
null,
$this->authenticator_class,
$this
),
$identity_field = TextField::create(
'Identity',
_t('AuthUsernameOrEmail.UsernameOrEmail', 'Username or Email')
),
PasswordField::create(
"Password",
_t('Member.PASSWORD', 'Password')
)
);

if(!Security::config()->remember_username) {
// Some browsers won't respect this attribute unless it's added to the form
$this->setAttribute('autocomplete', 'off');
$identity_field->setAttribute('autocomplete', 'off');
}

if(Security::config()->autologin_enabled) {
$fields->push(new CheckboxField(
"Remember",
_t('Member.REMEMBERME', "Remember me?")
));
}


if (isset($backURL)) {
$fields->push(new HiddenField('BackURL', 'BackURL', $backURL));
}

$actions = new FieldList(
FormAction::create('dologin', _t('Member.BUTTONLOGIN', "Log in")),
LiteralField::create(
'forgotPassword',
'<p id="ForgotPassword"><a href="' . $lost_password_url . '">'
. _t('Member.BUTTONLOSTPASSWORD', "I've lost my password") . '</a></p>'
)
);

// Reduce attack surface by enforcing POST requests
$this->setFormMethod('POST', true);

// LoginForm does its magic
parent::__construct($controller, $name, $fields, $actions);

$this
->setAttribute("action",$form_action_url);

$this
->setValidator(RequiredFields::create('Identity', 'Password'));
if ($emailField = $this->Fields()->fieldByName("Email")) {
$emailField->setTitle(_t('AuthUsernameOrEmail.UsernameOrEmail', 'Username or Email'));
}

// Focus on the Email input when the page is loaded
$js = <<<JS
(function() {
var el = document.getElementById("UsernameOrEmailLoginForm_LoginForm_Email");
if(el && el.focus && (typeof jQuery == 'undefined' || jQuery(el).is(':visible'))) el.focus();
})();
JS;
Requirements::customScript($js, 'UsernameOrEmailLoginFormFieldFocus');
}

/**
Expand Down
63 changes: 3 additions & 60 deletions code/security/UsernameOrEmailAuthenticator.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,17 +7,6 @@
*/
class UsernameOrEmailAuthenticator extends MemberAuthenticator
{

/**
* @var Array Contains encryption algorithm identifiers.
* If set, will migrate to new precision-safe password hashing
* upon login. See http://open.silverstripe.org/ticket/3004.
*/
public static $migrate_legacy_hashes = array(
'md5' => 'md5_v2.4',
'sha1' => 'sha1_v2.4'
);

/**
* Overwrite standard authentication in order to also look for user ID
* (as well as email)
Expand Down Expand Up @@ -47,8 +36,8 @@ protected static function authenticate_member($data, $form, &$success)
}

// Otherwise, get identifier from posted value instead
if(!$member && !empty($data['Identity'])) {
$identity = $data['Identity'];
if(!$member && !empty($data['Email'])) {
$identity = $data['Email'];
}

// Check default login (see Security::setDefaultAdmin())
Expand All @@ -72,7 +61,7 @@ protected static function authenticate_member($data, $form, &$success)

// Attempt to identify user
if(!$member && $filter) {
// Find user by email
// Find user by filter (Username or Email)
$member = Member::get()
->filter($filter)
->first();
Expand All @@ -97,52 +86,6 @@ protected static function authenticate_member($data, $form, &$success)
return $member;
}

/**
* Log login attempt
* TODO We could handle this with an extension
*
* @param array $data
* @param Member $member
* @param bool $success
*/
protected static function record_login_attempt($data, $member, $success) {
if(!Security::config()->login_recording) return;

// Check email is valid
$identity = isset($data['Identity']) ? $data['Identity'] : null;

if(is_array($identity)) {
throw new InvalidArgumentException("Bad email passed to MemberAuthenticator::authenticate(): $identity");
}

$attempt = new LoginAttempt();
if($success) {
// successful login (member is existing with matching password)
$attempt->MemberID = $member->ID;
$attempt->Status = 'Success';

// Audit logging hook
$member->extend('authenticated');

} else {
// Failed login - we're trying to see if a user exists with this email (disregarding wrong passwords)
$attempt->Status = 'Failure';
if($member) {
// Audit logging hook
$attempt->MemberID = $member->ID;
$member->extend('authenticationFailed');
} else {
// Audit logging hook
singleton('Member')->extend('authenticationFailedUnknownUser', $data);
}
}

$attempt->Email = $identity;
$attempt->IP = Controller::curr()->getRequest()->getIP();
$attempt->write();
}


/**
* Tell this Authenticator to use your custom login form
* The 3rd parameter MUST be 'LoginForm' to fit within the authentication
Expand Down
6 changes: 6 additions & 0 deletions lang/sk.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
sk:
AuthUsernameOrEmail:
Title: "Používateľské meno"
Description: "Slúži na prihlasovanie."
UsernameOrEmail: "Používateľské meno alebo e-mail"
LoginError: "Poskytnuté detaily vyzerajú byť nesprávne. Prosím skúste opäť."
8 changes: 4 additions & 4 deletions tests/UsernameAuthenticatorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,7 @@ public function testDefaultAdmin()

// Test correct login
$result = UsernameOrEmailAuthenticator::authenticate(array(
'Identity' => 'admin',
'Email' => 'admin',
'Password' => 'password'
), $form);
$this->assertNotEmpty($result);
Expand All @@ -103,7 +103,7 @@ public function testDefaultAdmin()
// Test incorrect login
$form->clearMessage();
$result = UsernameOrEmailAuthenticator::authenticate(array(
'Identity' => 'admin',
'Email' => 'admin',
'Password' => 'notmypassword'
), $form);
$this->assertEmpty($result);
Expand All @@ -121,11 +121,11 @@ public function testDefaultAdminLockOut()

// Test correct login
UsernameOrEmailAuthenticator::authenticate(array(
'Identity' => 'admin',
'Email' => 'admin',
'Password' => 'wrongpassword'
), $form);

$this->assertTrue(Member::default_admin()->isLockedOut());
$this->assertEquals(Member::default_admin()->LockedOutUntil, '2016-04-18 00:10:00');
}
}
}