Pass the AuthenticationMethod to the controller

Resolves issue #6788
The AuthenticationMethed is passed in via hidden field as per usual, but due to changes, the fallback authenticator was always the MemberAuthenticator and the actual passed in authenticator was defaulting to an empty string.
This causes an issue when there are multiple authenticators and the default authenticator is _not_ in the allowed authenticators, but is still the default. It caused the getAuthenticator method to return the default MemberAuthenticator to be returned, despite it being disabled.
A second issue around multiple authenticators, was the template using a no-longer used method `getAuthenticatorName`. This method returned a null on the default MemberLoginForm (as nothing was set), causing a Warning.
Because the getAuthenticator and getAuthenticatorName are no longer in
use, I've opted to replace these with a translatable string
`getAuthenticatorName`, to
display the title of the form on the tabs, as per the tabset on
Security_MultiAuthenticatorLogin template.
This commit is contained in:
Simon Erkelens 2017-04-14 15:30:55 +12:00 committed by Sam Minnée
parent e2b0c56175
commit f862ce71d5
6 changed files with 38 additions and 52 deletions

View File

@ -79,15 +79,6 @@ abstract class Authenticator extends Object
}
/**
* Get the name of the authentication method
*
* @return string Returns the name of the authentication method.
*/
public static function get_name()
{
}
public static function register($authenticator)
{
self::register_authenticator($authenticator);

View File

@ -79,4 +79,12 @@ class CMSMemberLoginForm extends LoginForm
{
return CMSMemberLoginHandler::create($this);
}
/**
* @return string
*/
public function getAuthenticatorName()
{
return _t('CMSMemberLoginForm.AUTHENTICATORNAME', 'CMS Member Login Form');
}
}

View File

@ -23,31 +23,13 @@ abstract class LoginForm extends Form
* form.
* @var string
*/
protected $authenticator_class;
/**
* Get the authenticator instance
*
* @return Authenticator Returns the authenticator instance for this login form.
* Return the title of the form for use in the frontend
* For tabs with multiple login methods, for example.
* This replaces the old `get_name` method
* @return string
*/
public function getAuthenticator()
{
if (!class_exists($this->authenticator_class) || !is_subclass_of($this->authenticator_class, 'SilverStripe\\Security\\Authenticator')) {
user_error("The form uses an invalid authenticator class! '{$this->authenticator_class}'"
. " is not a subclass of 'Authenticator'", E_USER_ERROR);
return null;
}
return Injector::inst()->get($this->authenticator_class);
}
/**
* Get the authenticator name.
* @return string The friendly name for use in templates, etc.
*/
public function getAuthenticatorName()
{
$authClass = $this->authenticator_class;
return $authClass::get_name();
}
abstract public function getAuthenticatorName();
}

View File

@ -202,7 +202,7 @@ class MemberAuthenticator extends Authenticator
public static function get_login_form(Controller $controller)
{
/** @skipUpgrade */
return MemberLoginForm::create($controller, "LoginForm");
return MemberLoginForm::create($controller, self::class, "LoginForm");
}
public static function get_cms_login_form(Controller $controller)
@ -216,15 +216,4 @@ class MemberAuthenticator extends Authenticator
// Don't automatically support subclasses of MemberAuthenticator
return get_called_class() === __CLASS__;
}
/**
* Get the name of the authentication method
*
* @return string Returns the name of the authentication method.
*/
public static function get_name()
{
return _t('MemberAuthenticator.TITLE', "E-mail & Password");
}
}

View File

@ -47,6 +47,7 @@ class MemberLoginForm extends LoginForm
* @skipUpgrade
* @param Controller $controller The parent controller, necessary to
* create the appropriate form action tag.
* @param string $authenticatorClass Authenticator for this LoginForm
* @param string $name The method on the controller that will return this
* form object.
* @param FieldList $fields All of the fields in the form - a
@ -61,14 +62,14 @@ class MemberLoginForm extends LoginForm
*/
public function __construct(
$controller,
$authenticatorClass,
$name,
$fields = null,
$actions = null,
$checkCurrentUser = true
) {
// This is now set on the class directly to make it easier to create subclasses
// $this->authenticator_class = $authenticatorClassName;
$this->authenticator_class = $authenticatorClass;
$customCSS = project() . '/css/member_login.css';
if (Director::fileExists($customCSS)) {
@ -200,4 +201,15 @@ class MemberLoginForm extends LoginForm
{
return MemberLoginHandler::create($this);
}
/**
* The name of this login form, to display in the frontend
* Replaces Authenticator::get_name()
*
* @return string
*/
public function getAuthenticatorName()
{
return _t('MemberLoginForm.AUTHENTICATORNAME', "E-mail & Password");
}
}

View File

@ -3,6 +3,7 @@
namespace SilverStripe\Security;
use Page;
use LogicException;
use SilverStripe\CMS\Controllers\ContentController;
use SilverStripe\Control\Controller;
use SilverStripe\Control\Director;
@ -10,6 +11,7 @@ use SilverStripe\Control\HTTPRequest;
use SilverStripe\Control\HTTPResponse;
use SilverStripe\Control\Session;
use SilverStripe\Core\ClassInfo;
use SilverStripe\Core\Config\Config;
use SilverStripe\Core\Convert;
use SilverStripe\Dev\Deprecation;
use SilverStripe\Dev\TestOnly;
@ -360,17 +362,18 @@ class Security extends Controller implements TemplateGlobalProvider
* Get the selected authenticator for this request
*
* @return string Class name of Authenticator
* @throws LogicException
*/
protected function getAuthenticator()
{
$authenticator = $this->getRequest()->requestVar('AuthenticationMethod');
if ($authenticator) {
$authenticators = Authenticator::get_authenticators();
if (in_array($authenticator, $authenticators)) {
return $authenticator;
}
if ($authenticator && Authenticator::is_registered($authenticator)) {
return $authenticator;
} elseif ($authenticator !== "" && Authenticator::is_registered(Authenticator::get_default_authenticator())) {
return Authenticator::get_default_authenticator();
}
return Authenticator::get_default_authenticator();
throw new LogicException('No valid authenticator found');
}
/**
@ -694,6 +697,7 @@ class Security extends Controller implements TemplateGlobalProvider
{
return MemberLoginForm::create(
$this,
Config::inst()->get('Authenticator', 'default_authenticator'),
'LostPasswordForm',
new FieldList(
new EmailField('Email', _t('Member.EMAIL', 'Email'))