-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
release/5.0.2
- Loading branch information
Showing
8 changed files
with
217 additions
and
108 deletions.
There are no files selected for viewing
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
name: 'Close stale issues and PRs' | ||
on: | ||
workflow_dispatch: | ||
schedule: | ||
- cron: '30 1 * * *' | ||
|
||
permissions: | ||
contents: write # only for delete-branch option | ||
issues: write | ||
pull-requests: write | ||
|
||
jobs: | ||
stale: | ||
runs-on: ubuntu-latest | ||
steps: | ||
- uses: actions/stale@v9 | ||
with: | ||
exempt-pr-labels: "DO NOT MERGE" | ||
stale-issue-message: 'This issue is stale because it has been open 28 days with no activity. Remove stale label or comment or this will be closed in 14 days.' | ||
days-before-stale: 28 | ||
days-before-close: 14 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
143 changes: 143 additions & 0 deletions
143
modules/tide_tfa/src/Controller/TideTfaUserController.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,143 @@ | ||
<?php | ||
|
||
namespace Drupal\tide_tfa\Controller; | ||
|
||
use Drupal\Component\Utility\Crypt; | ||
use Drupal\prlp\Controller\PrlpController; | ||
use Drupal\tfa\Controller\TfaUserControllerBase; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException; | ||
|
||
/** | ||
* Custom controller to override the TfaUserControllerBase. | ||
*/ | ||
class TideTfaUserController extends TfaUserControllerBase { | ||
|
||
/** | ||
* The request stack service. | ||
* | ||
* @var \Symfony\Component\HttpFoundation\RequestStack | ||
*/ | ||
protected $requestStack; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function create(ContainerInterface $container) { | ||
// Get the parent instance with inherited dependencies. | ||
$instance = parent::create($container); | ||
$instance->requestStack = $container->get('request_stack'); | ||
|
||
return $instance; | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function doResetPassLogin($uid, $timestamp, $hash, $request = NULL) { | ||
// Ensure a valid request object. | ||
if (!$request) { | ||
$request = $this->requestStack->getCurrentRequest(); | ||
} | ||
|
||
// Check if the PRLP module is enabled. | ||
if (!\Drupal::moduleHandler()->moduleExists('prlp')) { | ||
// If PRLP is not enabled, call the parent method. | ||
return parent::doResetPassLogin($uid, $timestamp, $hash, $request); | ||
} | ||
|
||
// Create an instance of PrlpController. | ||
$prlp_controller = new PrlpController( | ||
\Drupal::service('date.formatter'), | ||
\Drupal::entityTypeManager()->getStorage('user'), | ||
\Drupal::service('user.data'), | ||
\Drupal::service('logger.factory')->get('prlp'), | ||
\Drupal::service('flood'), | ||
\Drupal::service('event_dispatcher') | ||
); | ||
|
||
/** @var \Drupal\user\UserInterface $user */ | ||
$user = $this->userStorage->load($uid); | ||
$this->setUser($user); | ||
|
||
// Let Drupal core deal with the one-time login, | ||
// if TFA is not enabled or | ||
// current user can skip TFA while resetting password. | ||
if ($this->isTfaDisabled() || $this->canSkipPassReset()) { | ||
// Use PRLP's resetPassLogin instead of the core function. | ||
return $prlp_controller->prlpResetPassLogin($request, $uid, $timestamp, $hash); | ||
} | ||
|
||
// Whether the TFA Validation Plugin is set and ready for use. | ||
$tfa_ready = $this->isReady(); | ||
|
||
// Check for authentication plugin. | ||
if ($tfa_ready && $this->pluginAllowsLogin()) { | ||
$this->messenger()->addStatus($this->t('You have logged in on a trusted browser.')); | ||
return $prlp_controller->prlpResetPassLogin($request, $uid, $timestamp, $hash); | ||
} | ||
|
||
// Borrow the following codes from the core function: | ||
$current = \Drupal::time()->getRequestTime(); | ||
|
||
// Verify that the user exists and is active. | ||
if ($user === NULL || !$user->isActive()) { | ||
throw new AccessDeniedHttpException(); | ||
} | ||
|
||
// Time out, in seconds, until login URL expires. | ||
$timeout = $this->config('user.settings')->get('password_reset_timeout'); | ||
if ($user->getLastLoginTime() && $current - $timestamp > $timeout) { | ||
$this->messenger()->addError($this->t('You have tried to use a one-time login link that has expired. Please request a new one using the form below.')); | ||
return $this->redirect('user.pass'); | ||
} | ||
elseif ($user->isAuthenticated() && ($timestamp >= $user->getLastLoginTime()) && ($timestamp <= $current) && hash_equals($hash, user_pass_rehash($user, $timestamp))) { | ||
if ($tfa_ready) { | ||
$this->session->migrate(); | ||
$token = Crypt::randomBytesBase64(55); | ||
$request->getSession()->set('pass_reset_' . $uid, $token); | ||
|
||
$this->logger->notice('User %name used one-time login link at time %timestamp.', [ | ||
'%name' => $user->getDisplayName(), | ||
'%timestamp' => $timestamp, | ||
]); | ||
|
||
$this->tempStoreUid($user->id()); | ||
|
||
return $this->redirect('tfa.entry', [ | ||
'uid' => $uid, | ||
'hash' => $this->getLoginHash($user), | ||
], [ | ||
'query' => ['pass-reset-token' => $token], | ||
'absolute' => TRUE, | ||
]); | ||
} | ||
else { | ||
if ($this->canLoginWithoutTfa($this->getLogger('tfa'))) { | ||
return $this->redirectToUserForm($user, $request, $timestamp); | ||
} | ||
else { | ||
return $this->redirect('<front>'); | ||
} | ||
} | ||
} | ||
|
||
// Use PRLP's resetPassLogin instead of the core function. | ||
return $prlp_controller->prlpResetPassLogin($request, $uid, $timestamp, $hash); | ||
} | ||
|
||
/** | ||
* Determines if the user can skip tfa on password reset. | ||
* | ||
* This function checks the TFA settings to see if the option to skip TFA | ||
* during password reset is enabled. If enabled, users will not be required | ||
* to complete two-factor authentication when resetting their password. | ||
* | ||
* @return bool | ||
* TRUE if the user can skip TFA on password reset, FALSE otherwise. | ||
*/ | ||
public function canSkipPassReset() { | ||
return $this->tfaSettings->get('reset_pass_skip_enabled'); | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<?php | ||
|
||
namespace Drupal\tide_tfa\Routing; | ||
|
||
use Drupal\Core\Routing\RouteSubscriberBase; | ||
use Symfony\Component\Routing\RouteCollection; | ||
|
||
/** | ||
* Listens to the dynamic route events. | ||
* | ||
* Class TideTfaRouteSubscriber. | ||
* | ||
* @package Drupal\tide_tfa\Routing | ||
*/ | ||
class TideTfaRouteSubscriber extends RouteSubscriberBase { | ||
|
||
/** | ||
* Alters existing routes for TFA user password reset login. | ||
* | ||
* @param \Symfony\Component\Routing\RouteCollection $collection | ||
* Route collection to be altered. | ||
*/ | ||
protected function alterRoutes(RouteCollection $collection) { | ||
// Override the user reset pass login route to use TideTfaUserController. | ||
if ($route = $collection->get('user.reset.login')) { | ||
$route->setDefault('_controller', '\Drupal\tide_tfa\Controller\TideTfaUserController::doResetPassLogin'); | ||
} | ||
} | ||
|
||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
services: | ||
tide_tfa.route_subscriber: | ||
class: Drupal\tide_tfa\Routing\TideTfaRouteSubscriber | ||
tags: | ||
- { name: event_subscriber } |