You are here

BasicOverview.php in Two-factor Authentication (TFA) 8

Namespace

Drupal\tfa\Form

File

src/Form/BasicOverview.php
View source
<?php

namespace Drupal\tfa\Form;

use Drupal\Core\Datetime\DateFormatterInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\tfa\TfaDataTrait;
use Drupal\tfa\TfaLoginPluginManager;
use Drupal\tfa\TfaSendPluginManager;
use Drupal\tfa\TfaSetupPluginManager;
use Drupal\tfa\TfaValidationPluginManager;
use Drupal\user\UserDataInterface;
use Drupal\user\UserInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * TFA Basic account setup overview page.
 */
class BasicOverview extends FormBase {
  use TfaDataTrait;

  /**
   * The setup plugin manager to fetch setup information.
   *
   * @var \Drupal\tfa\TfaLoginPluginManager
   */
  protected $tfaSetup;

  /**
   * Validation plugin manager.
   *
   * @var \Drupal\tfa\TfaValidationPluginManager
   */
  protected $tfaValidation;

  /**
   * Login plugin manager.
   *
   * @var \Drupal\tfa\TfaLoginPluginManager
   */
  protected $tfaLogin;

  /**
   * Send plugin manager.
   *
   * @var \Drupal\tfa\TfaSendPluginManager
   */
  protected $tfaSend;

  /**
   * Provides the user data service object.
   *
   * @var \Drupal\user\UserDataInterface
   */
  protected $userData;

  /**
   * The date formatter service.
   *
   * @var \Drupal\Core\Datetime\DateFormatterInterface
   */
  protected $dateFormatter;

  /**
   * BasicOverview constructor.
   *
   * @param \Drupal\user\UserDataInterface $user_data
   *   The user data service.
   * @param \Drupal\Core\Datetime\DateFormatterInterface $date_formatter
   *   The date formatter service.
   * @param \Drupal\tfa\TfaSetupPluginManager $tfa_setup_manager
   *   The setup plugin manager.
   * @param \Drupal\tfa\TfaValidationPluginManager $tfa_validation_manager
   *   The validation plugin manager.
   * @param \Drupal\tfa\TfaLoginPluginManager $tfa_login_manager
   *   The login plugin manager.
   * @param \Drupal\tfa\TfaSendPluginManager $tfa_send_manager
   *   The send plugin manager.
   */
  public function __construct(UserDataInterface $user_data, DateFormatterInterface $date_formatter, TfaSetupPluginManager $tfa_setup_manager, TfaValidationPluginManager $tfa_validation_manager, TfaLoginPluginManager $tfa_login_manager, TfaSendPluginManager $tfa_send_manager) {
    $this->userData = $user_data;
    $this->dateFormatter = $date_formatter;
    $this->tfaSetup = $tfa_setup_manager;
    $this->tfaValidation = $tfa_validation_manager;
    $this->tfaLogin = $tfa_login_manager;
    $this->tfaSend = $tfa_send_manager;
  }

  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static($container
      ->get('user.data'), $container
      ->get('date.formatter'), $container
      ->get('plugin.manager.tfa.setup'), $container
      ->get('plugin.manager.tfa.validation'), $container
      ->get('plugin.manager.tfa.login'), $container
      ->get('plugin.manager.tfa.send'));
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() {
    return 'tfa_base_overview';
  }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state, UserInterface $user = NULL) {
    $output['info'] = [
      '#type' => 'markup',
      '#markup' => '<p>' . $this
        ->t('Two-factor authentication (TFA) provides
      additional security for your account. With TFA enabled, you log in to
      the site with a verification code in addition to your username and
      password.') . '</p>',
    ];

    // $form_state['storage']['account'] = $user;.
    $configuration = $this
      ->config('tfa.settings')
      ->getRawData();
    $user_tfa = $this
      ->tfaGetTfaData($user
      ->id(), $this->userData);
    $enabled = isset($user_tfa['status']) && $user_tfa['status'];
    if (!empty($user_tfa)) {
      if ($enabled && !empty($user_tfa['data']['plugins'])) {
        if ($this
          ->currentUser()
          ->hasPermission('disable own tfa')) {
          $status_text = $this
            ->t('Status: <strong>TFA enabled</strong>, set
          @time. <a href=":url">Disable TFA</a>', [
            '@time' => $this->dateFormatter
              ->format($user_tfa['saved']),
            ':url' => Url::fromRoute('tfa.disable', [
              'user' => $user
                ->id(),
            ])
              ->toString(),
          ]);
        }
        else {
          $status_text = $this
            ->t('Status: <strong>TFA enabled</strong>, set @time.', [
            '@time' => $this->dateFormatter
              ->format($user_tfa['saved']),
          ]);
        }
      }
      else {
        $status_text = $this
          ->t('Status: <strong>TFA disabled</strong>, set @time.', [
          '@time' => $this->dateFormatter
            ->format($user_tfa['saved']),
        ]);
      }
      $output['status'] = [
        '#type' => 'markup',
        '#markup' => '<p>' . $status_text . '</p>',
      ];
    }
    if ($configuration['enabled']) {
      $enabled = isset($user_tfa['status'], $user_tfa['data']) && !empty($user_tfa['data']['plugins']) && $user_tfa['status'];
      $enabled_plugins = isset($user_tfa['data']['plugins']) ? $user_tfa['data']['plugins'] : [];
      $validation_plugins = $this->tfaValidation
        ->getDefinitions();
      foreach ($validation_plugins as $plugin_id => $plugin) {
        if (!empty($configuration['allowed_validation_plugins'][$plugin_id])) {
          $output[$plugin_id] = $this
            ->tfaPluginSetupFormOverview($plugin, $user, !empty($enabled_plugins[$plugin_id]));
        }
      }
      if ($enabled) {
        $login_plugins = $this->tfaLogin
          ->getDefinitions();
        foreach ($login_plugins as $plugin_id => $plugin) {
          if (!empty($configuration['login_plugins'][$plugin_id])) {
            $output[$plugin_id] = $this
              ->tfaPluginSetupFormOverview($plugin, $user, TRUE);
          }
        }
        $send_plugins = $this->tfaSend
          ->getDefinitions();
        foreach ($send_plugins as $plugin_id => $plugin) {
          if (!empty($configuration['send_plugins'][$plugin_id])) {
            $output[$plugin_id] = $this
              ->tfaPluginSetupFormOverview($plugin, $user, TRUE);
          }
        }
      }
    }
    else {
      $output['disabled'] = [
        '#type' => 'markup',
        '#markup' => '<b>Currently there are no enabled plugins.</b>',
      ];
    }
    if ($configuration['enabled']) {
      $output['validation_skip_status'] = [
        '#type' => 'markup',
        '#markup' => $this
          ->t('Number of times validation skipped: @skipped of @limit', [
          '@skipped' => isset($user_tfa['validation_skipped']) ? $user_tfa['validation_skipped'] : 0,
          '@limit' => $configuration['validation_skip'],
        ]),
      ];
    }
    if ($this
      ->canPerformReset($user)) {
      $output['actions'] = [
        '#type' => 'actions',
      ];
      $output['actions']['reset_skip_attempts'] = [
        '#type' => 'submit',
        '#value' => $this
          ->t('Reset skip validation attempts'),
        '#submit' => [
          '::resetSkipValidationAttempts',
        ],
      ];
      $output['account'] = [
        '#type' => 'value',
        '#value' => $user,
      ];
    }
    return $output;
  }

  /**
   * Get TFA basic setup action links for use on overview page.
   *
   * @param array $plugin
   *   Plugin definition.
   * @param object $account
   *   Current user account.
   * @param bool $enabled
   *   Tfa data for current user.
   *
   * @return array
   *   Render array
   */
  protected function tfaPluginSetupFormOverview(array $plugin, $account, $enabled) {
    $params = [
      'enabled' => $enabled,
      'account' => $account,
      'plugin_id' => $plugin['id'],
    ];
    try {
      return $this->tfaSetup
        ->createInstance($plugin['setupPluginId'], [
        'uid' => $account
          ->id(),
      ])
        ->getOverview($params);
    } catch (\Exception $e) {
      return [];
    }
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
  }

  /**
   * Resets TFA attempts for the given user account.
   *
   * @param array $form
   *   The form definition.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The form state.
   */
  public function resetSkipValidationAttempts(array $form, FormStateInterface $form_state) {
    $account = $form_state
      ->getValue('account');
    $tfa_data = $this
      ->tfaGetTfaData($account
      ->id(), $this->userData);
    $tfa_data['validation_skipped'] = 0;
    $this
      ->tfaSaveTfaData($account
      ->id(), $this->userData, $tfa_data);
    $this
      ->messenger()
      ->addMessage($this
      ->t('Validation attempts have been reset for user @name.', [
      '@name' => $account
        ->getDisplayName(),
    ]));
    $this
      ->logger('tfa')
      ->notice('Validation attempts reset for @account by @current_user.', [
      '@account' => $account
        ->getAccountName(),
      '@current_user' => $this
        ->currentUser()
        ->getAccountName(),
    ]);
  }

  /**
   * Determine if the current user can perform a TFA attempt reset.
   *
   * @param \Drupal\user\UserInterface $account
   *   The account that TFA is for.
   *
   * @return bool
   *   Whether the user can perform a TFA reset.
   */
  protected function canPerformReset(UserInterface $account) {
    $current_user = $this
      ->currentUser();
    return $current_user
      ->hasPermission('administer users') && $current_user
      ->id() != $account
      ->id();
  }

}

Classes

Namesort descending Description
BasicOverview TFA Basic account setup overview page.