class TfaLoginController in Two-factor Authentication (TFA) 8
Provides access control on the verification form.
@package Drupal\tfa\Controller
Hierarchy
- class \Drupal\tfa\Controller\TfaLoginController uses TfaLoginTrait
Expanded class hierarchy of TfaLoginController
File
- src/
Controller/ TfaLoginController.php, line 16
Namespace
Drupal\tfa\ControllerView source
class TfaLoginController {
use TfaLoginTrait;
/**
* Denies access unless user matches hash value.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route
* The route to be checked.
* @param \Drupal\Core\Session\AccountInterface $account
* The current logged in user, if any.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*/
public function access(RouteMatchInterface $route, AccountInterface $account) {
$user = $route
->getParameter('user');
// Start with a positive access check which is cacheable for the current
// route, which includes both route name and parameters.
$access = AccessResult::allowed();
$access
->addCacheContexts([
'route',
]);
if (!$user instanceof UserInterface) {
return $access
->andIf(AccessResult::forbidden('Invalid user.'));
}
// Since we're about to check the login hash, which is based on properties
// of the user, we now need to vary the cache based on the user object.
$access
->addCacheableDependency($user);
// If the login hash doesn't match, forbid access.
if ($this
->getLoginHash($user) !== $route
->getParameter('hash')) {
return $access
->andIf(AccessResult::forbidden('Invalid hash.'));
}
// If we've gotten here, we need to check that the current user is allowed
// to use TFA features for this account. To make this decision, we need to
// vary the cache based on the current user.
$access
->addCacheableDependency($account);
if ($account
->isAuthenticated()) {
return $access
->andIf($this
->accessSelfOrAdmin($route, $account));
}
return $access;
}
/**
* Checks that current user is selected user or is admin.
*
* @param \Drupal\Core\Routing\RouteMatchInterface $route
* The route to be checked.
* @param \Drupal\Core\Session\AccountInterface $account
* The current user.
*
* @return \Drupal\Core\Access\AccessResult
* The access result.
*/
public function accessSelfOrAdmin(RouteMatchInterface $route, AccountInterface $account) {
$target_user = $route
->getParameter('user');
// Start with a positive access result that can be cached based on the
// current route, which includes both route name and parameters.
$access = AccessResult::allowed();
$access
->addCacheContexts([
'route',
]);
if (!$target_user instanceof UserInterface) {
return $access
->andIf(AccessResult::forbidden('Invalid user.'));
}
// Before we perform any checks that are dependent on the current user, make
// the result dependent on the current user. If we were just checking perms
// here, we could rely on user.permissions, but in this case we are also
// dependent on the ID of the user, which requires the higher level user
// context.
$access
->addCacheableDependency($account);
if (!$account
->isAuthenticated()) {
return $access
->andIf(AccessResult::forbidden('User is not logged in.'));
}
$is_self = $account
->id() === $target_user
->id();
$is_admin = $account
->hasPermission('administer users');
$is_self_or_admin = AccessResult::allowedIf($is_self || $is_admin);
return $access
->andIf($is_self_or_admin);
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
TfaLoginController:: |
public | function | Denies access unless user matches hash value. | |
TfaLoginController:: |
public | function | Checks that current user is selected user or is admin. | |
TfaLoginTrait:: |
protected | function | Generate a hash that can uniquely identify an account's state. |