diff --git a/.editorconfig b/.editorconfig index b986ce55f..91575c032 100644 --- a/.editorconfig +++ b/.editorconfig @@ -13,7 +13,7 @@ trim_trailing_whitespace = true [*.md] trim_trailing_whitespace = false -[*.{yml,js,json,css,scss,eslintrc}] +[*.{yml,js,json,css,scss,eslintrc,feature}] indent_size = 2 indent_style = space diff --git a/lang/en.yml b/lang/en.yml index 15cf4f57a..ce663fad6 100644 --- a/lang/en.yml +++ b/lang/en.yml @@ -207,19 +207,19 @@ en: ENTERINFO: 'Please enter a username and password.' ERRORNOTADMIN: 'That user is not an administrator.' ERRORNOTREC: 'That username / password isn''t recognised' - SilverStripe\Security\CMSMemberLoginForm: + SilverStripe\Security\MemberAuthenticator\CMSMemberLoginForm: AUTHENTICATORNAME: 'CMS Member Login Form' - BUTTONFORGOTPASSWORD: 'Forgot password?' - BUTTONLOGIN: 'Log back in' + BUTTONFORGOTPASSWORD: 'Forgot password' + BUTTONLOGIN: 'Let me back in' BUTTONLOGOUT: 'Log out' PASSWORDEXPIRED: '
Your password has expired. Please choose a new one.
' SilverStripe\Security\CMSSecurity: INVALIDUSER: 'Invalid user. Please re-authenticate here to continue.
' - LoginMessage: 'If you have any unsaved work you can return to where you left off by logging back in below.
' + LOGIN_MESSAGE: 'Your session has timed out due to inactivity.
' SUCCESS: Success SUCCESSCONTENT: 'Login success. If you are not automatically redirected click here
' - TimedOutTitleAnonymous: 'Your session has timed out.' - TimedOutTitleMember: 'Hey {name}!If you have any unsaved work you can return to where you left off by logging back in below.
' - ); + $message = parent::getLoginMessage($messageType); + if ($message) { + return $message; + } + + // Format + return _t( + __CLASS__.'.LOGIN_MESSAGE', + 'Your session has timed out due to inactivity
' + ); } - public function getTitle() + /** + * Check if there is a logged in member + * + * @return bool + */ + public function getIsloggedIn() { - // Check if logged in already - if (Security::getCurrentUser()) { - return _t('SilverStripe\\Security\\CMSSecurity.SUCCESS', 'Success'); - } - - // Display logged-out message - $member = $this->getTargetMember(); - if ($member) { - return _t( - 'SilverStripe\\Security\\CMSSecurity.TimedOutTitleMember', - 'Hey {name}!Invalid user. Please re-authenticate here to continue.
', 'Message displayed to user if their session cannot be restored', array('link' => $loginURLATT) @@ -188,7 +184,7 @@ PHP } // Get redirect url - $controller = $this->getResponseController(_t('SilverStripe\\Security\\CMSSecurity.SUCCESS', 'Success')); + $controller = $this->getResponseController(_t(__CLASS__.'.SUCCESS', 'Success')); $backURLs = array( $this->getRequest()->requestVar('BackURL'), Session::get('BackURL'), @@ -203,13 +199,13 @@ PHP // Show login $controller = $controller->customise(array( - 'Content' => _t( - 'SilverStripe\\Security\\CMSSecurity.SUCCESSCONTENT', - 'Login success. If you are not automatically redirected ' . + 'Content' => DBField::create_field(DBHTMLText::class, _t( + __CLASS__.'.SUCCESSCONTENT', + '
Login success. If you are not automatically redirected '. 'click here
', 'Login message displayed in the cms popup once a user has re-authenticated themselves', array('link' => Convert::raw2att($backURL)) - ) + )) )); return $controller->renderWith($this->getTemplatesFor('success')); diff --git a/src/Security/MemberAuthenticator/CMSLoginHandler.php b/src/Security/MemberAuthenticator/CMSLoginHandler.php index f30cdb7db..e976d1e5d 100644 --- a/src/Security/MemberAuthenticator/CMSLoginHandler.php +++ b/src/Security/MemberAuthenticator/CMSLoginHandler.php @@ -2,6 +2,7 @@ namespace SilverStripe\Security\MemberAuthenticator; +use SilverStripe\Control\Director; use SilverStripe\Control\HTTPResponse; use SilverStripe\Core\Convert; use SilverStripe\Security\CMSSecurity; @@ -28,10 +29,20 @@ class CMSLoginHandler extends LoginHandler public function redirectBackToForm() { // Redirect back to form - $url = $this->addBackURLParam(CMSSecurity::singleton()->Link('login')); + $url = $this->addBackURLParam($this->getReturnReferer()); return $this->redirect($url); } + public function getReturnReferer() + { + // Try to retain referer (includes tempid param) + $referer = $this->getReferer(); + if ($referer && Director::is_site_url($referer)) { + return $referer; + } + return CMSSecurity::singleton()->Link('login'); + } + /** * Redirect the user to the change password form. * diff --git a/src/Security/CMSMemberLoginForm.php b/src/Security/MemberAuthenticator/CMSMemberLoginForm.php similarity index 66% rename from src/Security/CMSMemberLoginForm.php rename to src/Security/MemberAuthenticator/CMSMemberLoginForm.php index 197240037..8e5c8d944 100644 --- a/src/Security/CMSMemberLoginForm.php +++ b/src/Security/MemberAuthenticator/CMSMemberLoginForm.php @@ -4,12 +4,14 @@ namespace SilverStripe\Security\MemberAuthenticator; use SilverStripe\Control\Controller; use SilverStripe\Control\RequestHandler; +use SilverStripe\Core\Convert; use SilverStripe\Forms\CheckboxField; use SilverStripe\Forms\FieldList; use SilverStripe\Forms\FormAction; use SilverStripe\Forms\HiddenField; use SilverStripe\Forms\LiteralField; use SilverStripe\Forms\PasswordField; +use SilverStripe\Security\RememberLoginHash; use SilverStripe\Security\Security; /** @@ -35,6 +37,8 @@ class CMSMemberLoginForm extends MemberLoginForm $actions = $this->getFormActions(); parent::__construct($controller, $authenticatorClass, $name, $fields, $actions); + + $this->addExtraClass('form--no-dividers'); } /** @@ -46,22 +50,24 @@ class CMSMemberLoginForm extends MemberLoginForm $fields = FieldList::create([ HiddenField::create("AuthenticationMethod", null, $this->authenticator_class, $this), HiddenField::create('tempid', null, $this->controller->getRequest()->requestVar('tempid')), - PasswordField::create("Password", _t('SilverStripe\\Security\\Member.PASSWORD', 'Password')), - LiteralField::create( - 'forgotPassword', - sprintf( - '', - $this->getExternalLink('lostpassword'), - _t('SilverStripe\\Security\\CMSMemberLoginForm.BUTTONFORGOTPASSWORD', "Forgot password?") - ) - ) + PasswordField::create("Password", _t('SilverStripe\\Security\\Member.PASSWORD', 'Password')) ]); if (Security::config()->get('autologin_enabled')) { - $fields->push(CheckboxField::create( - "Remember", - _t('SilverStripe\\Security\\Member.REMEMBERME', "Remember me next time?") - )); + $fields->insertAfter( + 'Password', + CheckboxField::create( + "Remember", + _t('SilverStripe\\Security\\Member.KEEPMESIGNEDIN', "Keep me signed in") + )->setAttribute( + 'title', + _t( + 'SilverStripe\\Security\\Member.REMEMBERME', + "Remember me next time? (for {count} days on this device)", + [ 'count' => RememberLoginHash::config()->uninherited('token_expiry_days') ] + ) + ) + ); } return $fields; @@ -72,7 +78,6 @@ class CMSMemberLoginForm extends MemberLoginForm */ public function getFormActions() { - // Determine returnurl to redirect to parent page $logoutLink = $this->getExternalLink('logout'); if ($returnURL = $this->controller->getRequest()->requestVar('BackURL')) { @@ -81,13 +86,22 @@ class CMSMemberLoginForm extends MemberLoginForm // Make actions $actions = FieldList::create([ - FormAction::create('doLogin', _t('SilverStripe\\Security\\CMSMemberLoginForm.BUTTONLOGIN', "Log back in")), + FormAction::create('doLogin', _t(__CLASS__.'.BUTTONLOGIN', "Let me back in")) + ->addExtraClass('btn-primary'), LiteralField::create( 'doLogout', sprintf( - '', - $logoutLink, - _t('SilverStripe\\Security\\CMSMemberLoginForm.BUTTONLOGOUT', "Log out") + '%s', + Convert::raw2att($logoutLink), + _t(__CLASS__.'.BUTTONLOGOUT', "Log out") + ) + ), + LiteralField::create( + 'forgotPassword', + sprintf( + '', + $this->getExternalLink('lostpassword'), + _t(__CLASS__.'.BUTTONFORGOTPASSWORD', "Forgot password") ) ) ]); @@ -111,6 +125,6 @@ class CMSMemberLoginForm extends MemberLoginForm */ public function getAuthenticatorName() { - return _t('SilverStripe\\Security\\CMSMemberLoginForm.AUTHENTICATORNAME', 'CMS Member Login Form'); + return _t(__CLASS__.'.AUTHENTICATORNAME', 'CMS Member Login Form'); } } diff --git a/src/Security/MemberAuthenticator/MemberLoginForm.php b/src/Security/MemberAuthenticator/MemberLoginForm.php index b6b7e8809..b56fe8f25 100644 --- a/src/Security/MemberAuthenticator/MemberLoginForm.php +++ b/src/Security/MemberAuthenticator/MemberLoginForm.php @@ -156,9 +156,10 @@ class MemberLoginForm extends BaseLoginForm _t('SilverStripe\\Security\\Member.KEEPMESIGNEDIN', "Keep me signed in") )->setAttribute( 'title', - sprintf( - _t('SilverStripe\\Security\\Member.REMEMBERME', "Remember me next time? (for %d days on this device)"), - RememberLoginHash::config()->uninherited('token_expiry_days') + _t( + 'SilverStripe\\Security\\Member.REMEMBERME', + "Remember me next time? (for {count} days on this device)", + [ 'count' => RememberLoginHash::config()->uninherited('token_expiry_days') ] ) ) ); diff --git a/src/Security/Security.php b/src/Security/Security.php index 2c39d18c0..3d1bff936 100644 --- a/src/Security/Security.php +++ b/src/Security/Security.php @@ -25,7 +25,6 @@ use SilverStripe\ORM\DB; use SilverStripe\ORM\FieldType\DBField; use SilverStripe\ORM\FieldType\DBHTMLText; use SilverStripe\ORM\ValidationResult; -use SilverStripe\Security\DefaultAdminService; use SilverStripe\View\ArrayData; use SilverStripe\View\SSViewer; use SilverStripe\View\TemplateGlobalProvider; @@ -241,7 +240,7 @@ class Security extends Controller implements TemplateGlobalProvider public function index() { - return $this->httpError(404); // no-op + $this->httpError(404); // no-op } /** @@ -358,7 +357,7 @@ class Security extends Controller implements TemplateGlobalProvider $messageSet = $configMessageSet; } else { $messageSet = array( - 'default' => _t( + 'default' => _t( 'SilverStripe\\Security\\Security.NOTEPAGESECURED', "That page is secured. Enter your credentials below and we will send " . "you right along." @@ -608,6 +607,10 @@ class Security extends Controller implements TemplateGlobalProvider */ protected function generateLoginFormSet($forms) { + if (count($forms) === 1) { + return $forms; + } + $viewData = new ArrayData(array( 'Forms' => new ArrayList($forms), )); @@ -773,6 +776,7 @@ class Security extends Controller implements TemplateGlobalProvider return $this->renderWrappedController( $title, [ + 'Forms' => ArrayList::create($forms), 'Form' => $this->generateLoginFormSet($forms), ], $templates @@ -1086,12 +1090,12 @@ class Security extends Controller implements TemplateGlobalProvider // New salts will only need to be generated if the password is hashed for the first time $salt = ($salt) ? $salt : $encryptor->salt($password); - return array( + return [ 'password' => $encryptor->encrypt($password, $salt, $member), - 'salt' => $salt, + 'salt' => $salt, 'algorithm' => $algorithm, 'encryptor' => $encryptor - ); + ]; } /** @@ -1238,12 +1242,12 @@ class Security extends Controller implements TemplateGlobalProvider */ public static function get_template_global_variables() { - return array( - "LoginURL" => "login_url", - "LogoutURL" => "logout_url", + return [ + "LoginURL" => "login_url", + "LogoutURL" => "logout_url", "LostPasswordURL" => "lost_password_url", - "CurrentMember" => "getCurrentUser", - "currentUser" => "getCurrentUser" - ); + "CurrentMember" => "getCurrentUser", + "currentUser" => "getCurrentUser" + ]; } } diff --git a/templates/SilverStripe/Security/CMSSecurity_login.ss b/templates/SilverStripe/Security/CMSSecurity_login.ss new file mode 100644 index 000000000..a4834f0b6 --- /dev/null +++ b/templates/SilverStripe/Security/CMSSecurity_login.ss @@ -0,0 +1,34 @@ + + + + <% base_tag %> +