View source
<?php
namespace Drupal\tfa\Form;
use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Flood\FloodInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Core\Url;
use Drupal\tfa\TfaLoginPluginManager;
use Drupal\tfa\TfaValidationPluginManager;
use Drupal\user\UserDataInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
class EntryForm extends FormBase {
protected $tfaValidationManager;
protected $tfaLoginManager;
protected $tfaValidationPlugin;
protected $tfaLoginPlugins;
protected $tfaSettings;
protected $flood;
protected $floodIdentifier;
protected $dateFormatter;
protected $userData;
public function __construct(TfaValidationPluginManager $tfa_validation_manager, TfaLoginPluginManager $tfa_login_manager, FloodInterface $flood, DateFormatterInterface $date_formatter, UserDataInterface $user_data) {
$this->tfaValidationManager = $tfa_validation_manager;
$this->tfaLoginManager = $tfa_login_manager;
$this->tfaSettings = $this
->config('tfa.settings');
$this->flood = $flood;
$this->dateFormatter = $date_formatter;
$this->userData = $user_data;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('plugin.manager.tfa.validation'), $container
->get('plugin.manager.tfa.login'), $container
->get('flood'), $container
->get('date.formatter'), $container
->get('user.data'));
}
public function getFormId() {
return 'tfa_entry_form';
}
public function buildForm(array $form, FormStateInterface $form_state, AccountInterface $user = NULL) {
$alternate_plugin = $this
->getRequest()
->get('plugin');
$validation_plugin_definitions = $this->tfaValidationManager
->getDefinitions();
$user_settings = $this->userData
->get('tfa', $user
->id(), 'tfa_user_settings');
$user_enabled_validation_plugins = isset($user_settings['data']['plugins']) ? $user_settings['data']['plugins'] : [];
$validation_plugin = $this->tfaSettings
->get('default_validation_plugin');
if ($alternate_plugin && !empty($validation_plugin_definitions[$alternate_plugin]) && !empty($user_enabled_validation_plugins[$alternate_plugin])) {
$validation_plugin = $alternate_plugin;
$form['#cache'] = [
'max-age' => 0,
];
}
$this->tfaValidationPlugin = $this->tfaValidationManager
->createInstance($validation_plugin, [
'uid' => $user
->id(),
]);
$form = $this->tfaValidationPlugin
->getForm($form, $form_state);
$this->tfaLoginPlugins = $this->tfaLoginManager
->getPlugins([
'uid' => $user
->id(),
]);
if ($this->tfaLoginPlugins) {
foreach ($this->tfaLoginPlugins as $login_plugin) {
if (method_exists($login_plugin, 'getForm')) {
$form = $login_plugin
->getForm($form, $form_state);
}
}
}
$form['account'] = [
'#type' => 'value',
'#value' => $user,
];
$other_validation_plugin_links = [];
foreach ($user_enabled_validation_plugins as $user_enabled_validation_plugin) {
if ($validation_plugin == $user_enabled_validation_plugin) {
continue;
}
if (empty($validation_plugin_definitions[$user_enabled_validation_plugin]['label'])) {
continue;
}
$other_validation_plugin_links[$user_enabled_validation_plugin] = [
'title' => $validation_plugin_definitions[$user_enabled_validation_plugin]['label'],
'url' => Url::fromRoute('tfa.entry', [
'user' => $user
->id(),
'hash' => $this
->getRequest()
->get('hash'),
'plugin' => $user_enabled_validation_plugin,
]),
];
}
$form['validation_plugin'] = [
'#type' => 'value',
'#value' => $validation_plugin,
];
if (!empty($other_validation_plugin_links)) {
$form['change_validation_plugin'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Having Trouble?'),
'#collapsible' => TRUE,
'#collapsed' => TRUE,
'content' => [
'help' => [
'#markup' => $this
->t('Try one of your other enabled validation methods.'),
],
'other_validation_plugins' => [
'#theme' => 'links',
'#links' => $other_validation_plugin_links,
],
],
];
}
return $form;
}
public function validateForm(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
$window = $this->tfaSettings
->get('tfa_flood_window') ?: 300;
$threshold = $this->tfaSettings
->get('tfa_flood_threshold') ?: 6;
if ($this->tfaSettings
->get('tfa_flood_uid_only')) {
$this->floodIdentifier = $values['account']
->id();
}
else {
$this->floodIdentifier = $values['account']
->id() . '-' . $this
->getRequest()
->getClientIP();
}
if (!$this->flood
->isAllowed('tfa.failed_validation', $threshold, $window, $this->floodIdentifier)) {
$form_state
->setErrorByName('', $this
->t('Failed validation limit reached. %limit wrong codes in @interval. Try again later.', [
'%limit' => $threshold,
'@interval' => $this->dateFormatter
->formatInterval($window),
]));
return;
}
$validated = $this->tfaValidationPlugin
->validateForm($form, $form_state);
if (!$validated) {
if (method_exists($this->tfaValidationPlugin, 'getErrorMessages')) {
$form_state
->clearErrors();
$errors = $this->tfaValidationPlugin
->getErrorMessages();
$form_state
->setErrorByName(key($errors), current($errors));
}
$this->flood
->register('tfa.failed_validation', $this->tfaSettings
->get('tfa_flood_window'), $this->floodIdentifier);
}
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$user = $form_state
->getValue('account');
if (!empty($this->tfaLoginPlugins)) {
foreach ($this->tfaLoginPlugins as $plugin) {
if (method_exists($plugin, 'submitForm')) {
$plugin
->submitForm($form, $form_state);
}
}
}
user_login_finalize($user);
$this
->finalize();
$this->flood
->clear('tfa.failed_validation', $this->floodIdentifier);
$form_state
->setRedirect('<front>');
}
public function finalize() {
if (method_exists($this->tfaValidationPlugin, 'finalize')) {
$this->tfaValidationPlugin
->finalize();
}
if (!empty($this->tfaLoginPlugins)) {
foreach ($this->tfaLoginPlugins as $plugin) {
if (method_exists($plugin, 'finalize')) {
$plugin
->finalize();
}
}
}
}
}