class TfaLoginForm in Two-factor Authentication (TFA) 8
TFA user login form.
@noinspection PhpInternalEntityUsedInspection
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\user\Form\UserLoginForm
- class \Drupal\tfa\Form\TfaLoginForm uses TfaDataTrait, TfaLoginTrait
- class \Drupal\user\Form\UserLoginForm
Expanded class hierarchy of TfaLoginForm
1 string reference to 'TfaLoginForm'
File
- src/
Form/ TfaLoginForm.php, line 27
Namespace
Drupal\tfa\FormView source
class TfaLoginForm extends UserLoginForm {
use TfaDataTrait;
use TfaLoginTrait;
/**
* The validation plugin manager to fetch plugin information.
*
* @var \Drupal\tfa\TfaValidationPluginManager
*/
protected $tfaValidationManager;
/**
* The login plugin manager to fetch plugin information.
*
* @var \Drupal\tfa\TfaLoginPluginManager
*/
protected $tfaLoginManager;
/**
* The current validation plugin.
*
* @var \Drupal\tfa\Plugin\TfaValidationInterface
*/
protected $tfaValidationPlugin;
/**
* The user data service.
*
* @var \Drupal\user\UserDataInterface
*/
protected $userData;
/**
* Redirect destination service.
*
* @var \Drupal\Core\Routing\RedirectDestinationInterface
*/
protected $destination;
/**
* Tfa login context object.
*
* This will be initialized in the submitForm() method.
*
* @var \Drupal\tfa\TfaContext
*/
protected $tfaContext;
/**
* Constructs a new user login form.
*
* @param \Drupal\Core\Flood\FloodInterface $flood
* The flood service.
* @param \Drupal\user\UserStorageInterface $user_storage
* The user storage.
* @param \Drupal\user\UserAuthInterface $user_auth
* The user authentication object.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
* @param \Drupal\tfa\TfaValidationPluginManager $tfa_validation_manager
* Tfa validation plugin manager.
* @param \Drupal\tfa\TfaLoginPluginManager $tfa_plugin_manager
* Tfa setup plugin manager.
* @param \Drupal\user\UserDataInterface $user_data
* User data service.
* @param \Drupal\Core\Routing\RedirectDestinationInterface $destination
* Redirect destination.
*/
public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, UserAuthInterface $user_auth, RendererInterface $renderer, TfaValidationPluginManager $tfa_validation_manager, TfaLoginPluginManager $tfa_plugin_manager, UserDataInterface $user_data, RedirectDestinationInterface $destination) {
parent::__construct($flood, $user_storage, $user_auth, $renderer);
$this->tfaValidationManager = $tfa_validation_manager;
$this->tfaLoginManager = $tfa_plugin_manager;
$this->userData = $user_data;
$this->destination = $destination;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('flood'), $container
->get('entity_type.manager')
->getStorage('user'), $container
->get('user.auth'), $container
->get('renderer'), $container
->get('plugin.manager.tfa.validation'), $container
->get('plugin.manager.tfa.login'), $container
->get('user.data'), $container
->get('redirect.destination'));
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form = parent::buildForm($form, $form_state);
$form['#submit'][] = '::tfaLoginFormRedirect';
$form['#cache'] = [
'max-age' => 0,
];
return $form;
}
/**
* Login submit handler.
*
* Determine if TFA process applies. If not, call the parent form submit.
*
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
// The user ID must not be NULL.
if (empty($uid = $form_state
->get('uid'))) {
return;
}
// Similar to tfa_user_login() but not required to force user logout.
/** @var \Drupal\user\Entity\User $user */
$user = $this->userStorage
->load($uid);
$this->tfaContext = new TfaContext($this->tfaValidationManager, $this->tfaLoginManager, $this
->configFactory(), $user, $this->userData, $this
->getRequest());
/* Uncomment when things go wrong and you get logged out.
user_login_finalize($user);
$form_state->setRedirect('<front>');
return;
*/
// Stop processing if Tfa is not enabled.
if (!$this->tfaContext
->isModuleSetup() || !$this->tfaContext
->isTfaRequired()) {
parent::submitForm($form, $form_state);
}
else {
// Setup TFA.
if ($this->tfaContext
->isReady()) {
$this
->loginWithTfa($form_state);
}
else {
$this
->loginWithoutTfa($form_state);
}
}
}
/**
* Handle login when TFA is set up for the user.
*
* TFA is set up for this user, and $this->tfaContext is initialized.
*
* If any of the TFA plugins allows login, then finalize the login. Otherwise,
* set a redirect to enter a second factor.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The state of the login form.
*/
public function loginWithTfa(FormStateInterface $form_state) {
$user = $this->tfaContext
->getUser();
if ($this->tfaContext
->pluginAllowsLogin()) {
$this->tfaContext
->doUserLogin();
$this
->messenger()
->addStatus($this
->t('You have logged in on a trusted browser.'));
$form_state
->setRedirect('<front>');
}
else {
// Begin TFA and set process context.
// @todo This is used in send plugins which has not been implemented yet.
// $this->begin($tfaValidationPlugin);
$parameters = $this->destination
->getAsArray();
$parameters['user'] = $user
->id();
$parameters['hash'] = $this
->getLoginHash($user);
$this
->getRequest()->query
->remove('destination');
$form_state
->setRedirect('tfa.entry', $parameters);
}
}
/**
* Handle the case where TFA is not yet set up.
*
* TFA is not set up for this user, and $this->tfaContext is initialized.
*
* If the user has any remaining logins, then finalize the login with a
* message to set up TFA. Otherwise, leave the user logged out.
*
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The state of the login form.
*/
public function loginWithoutTfa(FormStateInterface $form_state) {
// User may be able to skip TFA, depending on module settings and number of
// prior attempts.
$remaining = $this->tfaContext
->remainingSkips();
if ($remaining) {
$user = $this->tfaContext
->getUser();
$tfa_setup_link = Url::fromRoute('tfa.overview', [
'user' => $user
->id(),
])
->toString();
$message = $this
->formatPlural($remaining - 1, 'You are required to setup two-factor authentication <a href="@link">here.</a> You have @remaining attempt left. After this you will be unable to login.', 'You are required to setup two-factor authentication <a href="@link">here.</a> You have @remaining attempts left. After this you will be unable to login.', [
'@remaining' => $remaining - 1,
'@link' => $tfa_setup_link,
]);
$this
->messenger()
->addError($message);
$this->tfaContext
->hasSkipped();
$this->tfaContext
->doUserLogin();
$form_state
->setRedirect('<front>');
}
else {
$message = $this
->config('tfa.settings')
->get('help_text');
$this
->messenger()
->addError($message);
$this
->logger('tfa')
->notice('@name has no more remaining attempts for bypassing the second authentication factor.', [
'@name' => $this->tfaContext
->getUser()
->getAccountName(),
]);
}
}
/**
* Login submit handler for TFA form redirection.
*
* Should be last invoked form submit handler for forms user_login and
* user_login_block so that when the TFA process is applied the user will be
* sent to the TFA form.
*
* @param array $form
* The current form api array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current form state.
*/
public function tfaLoginFormRedirect(array $form, FormStateInterface $form_state) {
$route = $form_state
->getValue('tfa_redirect');
if (isset($route)) {
$form_state
->setRedirect($route);
}
}
/**
* Begin the TFA process.
*
* @param \Drupal\tfa\Plugin\TfaSendInterface $tfaSendPlugin
* The send plugin instance.
*/
protected function begin(TfaSendInterface $tfaSendPlugin) {
// Invoke begin method on send validation plugins.
if (method_exists($tfaSendPlugin, 'begin')) {
$tfaSendPlugin
->begin();
}
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
FormBase:: |
protected | property | The config factory. | 1 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 1 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
FormBase:: |
public | function |
Form validation handler. Overrides FormInterface:: |
62 |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. | |
TfaDataTrait:: |
protected | function | Deletes data stored for the current validated user account. | |
TfaDataTrait:: |
protected | function | Returns data stored for the current validated user account. | |
TfaDataTrait:: |
protected | function | Store user specific information. | |
TfaDataTrait:: |
protected | function | Get TFA data for an account. | |
TfaDataTrait:: |
public | function | Save TFA data for an account. | |
TfaLoginForm:: |
protected | property | Redirect destination service. | |
TfaLoginForm:: |
protected | property | Tfa login context object. | |
TfaLoginForm:: |
protected | property | The login plugin manager to fetch plugin information. | |
TfaLoginForm:: |
protected | property | The validation plugin manager to fetch plugin information. | |
TfaLoginForm:: |
protected | property | The current validation plugin. | |
TfaLoginForm:: |
protected | property | The user data service. | |
TfaLoginForm:: |
protected | function | Begin the TFA process. | |
TfaLoginForm:: |
public | function |
Form constructor. Overrides UserLoginForm:: |
|
TfaLoginForm:: |
public static | function |
Instantiates a new instance of this class. Overrides UserLoginForm:: |
|
TfaLoginForm:: |
public | function | Handle the case where TFA is not yet set up. | |
TfaLoginForm:: |
public | function | Handle login when TFA is set up for the user. | |
TfaLoginForm:: |
public | function |
Login submit handler. Overrides UserLoginForm:: |
|
TfaLoginForm:: |
public | function | Login submit handler for TFA form redirection. | |
TfaLoginForm:: |
public | function |
Constructs a new user login form. Overrides UserLoginForm:: |
|
TfaLoginTrait:: |
protected | function | Generate a hash that can uniquely identify an account's state. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. | |
UserLoginForm:: |
protected | property | The flood service. | |
UserLoginForm:: |
protected | property | The renderer. | |
UserLoginForm:: |
protected | property | The user authentication object. | |
UserLoginForm:: |
protected | property | The user storage. | |
UserLoginForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
|
UserLoginForm:: |
public | function | Checks supplied username/password against local users table. | |
UserLoginForm:: |
public | function | Checks if user was not authenticated, or if too many logins were attempted. | |
UserLoginForm:: |
public | function | Sets an error if supplied username has been blocked. |