You are here

class LegalLogin in Legal 2.0.x

Same name and namespace in other branches
  1. 8 src/Form/LegalLogin.php \Drupal\legal\Form\LegalLogin

After login display new T&Cs to user and require that they are agreed to.

User has been logged out before arriving at this page, and is logged back in if they accept T&Cs.

Hierarchy

Expanded class hierarchy of LegalLogin

1 string reference to 'LegalLogin'
legal.routing.yml in ./legal.routing.yml
legal.routing.yml

File

src/Form/LegalLogin.php, line 20

Namespace

Drupal\legal\Form
View source
class LegalLogin extends FormBase {

  /**
   * Database connection.
   *
   * @var \Drupal\Core\Database\Connection
   */
  protected $database;

  /**
   * Module handler.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * Language handling.
   *
   * @var \Drupal\Core\Language\LanguageManagerInterface
   */
  protected $languageManager;

  /**
   * The account the shortcut set is for.
   *
   * @var \Drupal\user\UserInterface
   */
  protected $user;

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

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    $config = $this
      ->config('legal.settings');
    $language = \Drupal::languageManager()
      ->getCurrentLanguage();
    $id_hash = $_COOKIE['Drupal_visitor_legal_hash'];
    $uid = $_COOKIE['Drupal_visitor_legal_id'];
    $token = $_GET['token'];

    // Get last accepted version for this account.
    $legal_account = legal_get_accept($uid);

    // If no version accepted, get version with current language revision.
    if (empty($legal_account['version'])) {
      $conditions = legal_get_conditions($language
        ->getId());

      // No conditions set yet.
      if (empty($conditions['conditions'])) {
        return;
      }
    }
    else {

      // Get version / revision of last accepted language.
      $conditions = legal_get_conditions($legal_account['language']);

      // No conditions set yet.
      if (empty($conditions['conditions'])) {
        return;
      }

      // Check latest version of T&C has been accepted.
      $accepted = legal_version_check($uid, $conditions['version'], $conditions['revision'], $legal_account);
      if ($accepted) {
        if ($config
          ->get('accept_every_login') == 0) {
          return;
        }
        else {
          $request = \Drupal::request();
          $session = $request
            ->getSession();
          $newly_accepted = $session
            ->get('legal_login', FALSE);
          if ($newly_accepted) {
            return;
          }
        }
      }
    }
    legal_display_fields($form, $conditions, 'login');
    $form['uid'] = [
      '#type' => 'value',
      '#value' => $uid,
    ];
    $form['token'] = [
      '#type' => 'value',
      '#value' => $token,
    ];
    $form['hash'] = [
      '#type' => 'value',
      '#value' => $id_hash,
    ];
    $form['tc_id'] = [
      '#type' => 'value',
      '#value' => $conditions['tc_id'],
    ];
    $form['version'] = [
      '#type' => 'value',
      '#value' => $conditions['version'],
    ];
    $form['revision'] = [
      '#type' => 'value',
      '#value' => $conditions['revision'],
    ];
    $form['language'] = [
      '#type' => 'value',
      '#value' => $conditions['language'],
    ];
    $form = legal_display_changes($form, $uid);
    $form['save'] = [
      '#type' => 'submit',
      '#value' => t('Confirm'),
      '#weight' => 100,
    ];

    // Prevent this page from being cached.
    \Drupal::service('page_cache_kill_switch')
      ->trigger();
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state) {
    $token = $form_state
      ->getValue('token');
    $uid = $form_state
      ->getValue('uid');
    $account = User::load($uid);
    $this->user = $account;
    $last_login = $account
      ->get('login')->value;
    $password = $account
      ->get('pass')->value;
    $data = $last_login . $uid . $password;
    $hash = Crypt::hmacBase64($data, $token);
    if ($hash != $form_state
      ->getValue('hash')) {
      $form_state
        ->setErrorByName('legal_accept', $this
        ->t('User ID cannot be identified.'));
      legal_deny_with_redirect();
    }
  }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    user_cookie_delete('legal_hash');
    user_cookie_delete('legal_id');
    $values = $form_state
      ->getValues();
    $user = $this->user;
    $redirect = '/user/' . $values['uid'];
    $config = $this
      ->config('legal.settings');
    if (!empty($_GET['destination'])) {
      $redirect = $_GET['destination'];
    }
    $form_state
      ->setRedirectUrl(Url::fromUserInput($redirect));

    // Option to require user to accept T&Cs on every login.
    if ($config
      ->get('accept_every_login') == '1') {

      // Set flag that user has accepted T&Cs again.
      $request = \Drupal::request();
      $session = $request
        ->getSession();
      $session
        ->set('legal_login', TRUE);

      // Get last accepted version for this account.
      $legal_account = legal_get_accept($values['uid']);
      $already_accepted = legal_version_check($values['uid'], $values['version'], $values['revision'], $legal_account);

      // If already accepted just update the time.
      if ($already_accepted) {
        $accepted = Accepted::load($legal_account['legal_id']);
        $accepted
          ->set("accepted", time());
        $accepted
          ->save();
      }
      else {
        legal_save_accept($values['version'], $values['revision'], $values['language'], $values['uid']);
      }
    }
    else {
      legal_save_accept($values['version'], $values['revision'], $values['language'], $values['uid']);
    }
    $this
      ->logger('legal')
      ->notice('%name accepted T&C version %tc_id.', [
      '%name' => $user
        ->get('name')
        ->getString(),
      '%tc_id' => $values['tc_id'],
    ]);

    // User has new permissions, so we clear their menu cache.
    \Drupal::cache('menu')
      ->delete($values['uid']);

    // Log user in.
    user_login_finalize($user);
  }

  /**
   * Access control callback.
   *
   * Check that access cookie and hash have been set.
   *
   * @param \Drupal\Core\Session\AccountInterface $account
   *   Run access checks for this account.
   */
  public function access(AccountInterface $account) {

    // Check we have all the data and there are no shenanigans.
    if (!isset($_GET['token']) || !isset($_COOKIE['Drupal_visitor_legal_id']) || !is_numeric($_COOKIE['Drupal_visitor_legal_id']) || !isset($_COOKIE['Drupal_visitor_legal_hash'])) {
      return AccessResult::forbidden();
    }
    $visitor = User::load($_COOKIE['Drupal_visitor_legal_id']);
    $last_login = $visitor
      ->get('login')->value;
    if (empty($last_login)) {
      return AccessResult::forbidden();
    }

    // Limit how long $id_hash can be used to 1 hour.
    // Timestamp and $id_hash are used to generate the authentication token.
    if (\Drupal::time()
      ->getRequestTime() - $last_login > 3600) {
      return AccessResult::forbidden();
    }
    return AccessResult::allowed();
  }

}

Members

Namesort descending Modifiers Type Description Overrides
DependencySerializationTrait::$_entityStorages protected property
DependencySerializationTrait::$_serviceIds protected property
DependencySerializationTrait::__sleep public function 2
DependencySerializationTrait::__wakeup public function 2
FormBase::$configFactory protected property The config factory. 3
FormBase::$requestStack protected property The request stack. 1
FormBase::$routeMatch protected property The route match.
FormBase::config protected function Retrieves a configuration object.
FormBase::configFactory protected function Gets the config factory for this form. 3
FormBase::container private function Returns the service container.
FormBase::create public static function Instantiates a new instance of this class. Overrides ContainerInjectionInterface::create 105
FormBase::currentUser protected function Gets the current user.
FormBase::getRequest protected function Gets the request object.
FormBase::getRouteMatch protected function Gets the route match.
FormBase::logger protected function Gets the logger for a specific channel.
FormBase::redirect protected function Returns a redirect response object for the specified route.
FormBase::resetConfigFactory public function Resets the configuration factory.
FormBase::setConfigFactory public function Sets the config factory for this form.
FormBase::setRequestStack public function Sets the request stack object to use.
LegalLogin::$database protected property Database connection.
LegalLogin::$languageManager protected property Language handling.
LegalLogin::$moduleHandler protected property Module handler.
LegalLogin::$user protected property The account the shortcut set is for.
LegalLogin::access public function Access control callback.
LegalLogin::buildForm public function Form constructor. Overrides FormInterface::buildForm
LegalLogin::getFormId public function Returns a unique string identifying the form. Overrides FormInterface::getFormId
LegalLogin::submitForm public function Form submission handler. Overrides FormInterface::submitForm
LegalLogin::validateForm public function Form validation handler. Overrides FormBase::validateForm
LoggerChannelTrait::$loggerFactory protected property The logger channel factory service.
LoggerChannelTrait::getLogger protected function Gets the logger for a specific channel.
LoggerChannelTrait::setLoggerFactory public function Injects the logger channel factory.
MessengerTrait::$messenger protected property The messenger. 27
MessengerTrait::messenger public function Gets the messenger. 27
MessengerTrait::setMessenger public function Sets the messenger.
RedirectDestinationTrait::$redirectDestination protected property The redirect destination service. 1
RedirectDestinationTrait::getDestinationArray protected function Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url.
RedirectDestinationTrait::getRedirectDestination protected function Returns the redirect destination service.
RedirectDestinationTrait::setRedirectDestination public function Sets the redirect destination service.
StringTranslationTrait::$stringTranslation protected property The string translation service. 4
StringTranslationTrait::formatPlural protected function Formats a string containing a count of items.
StringTranslationTrait::getNumberOfPlurals protected function Returns the number of plurals supported by a given language.
StringTranslationTrait::getStringTranslation protected function Gets the string translation service.
StringTranslationTrait::setStringTranslation public function Sets the string translation service to use. 2
StringTranslationTrait::t protected function Translates a string to the current language or to a given language.