-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #37 from City-of-Helsinki/UHF-9515
UHF-9515: Disable external user password on login and deploy
- Loading branch information
Showing
6 changed files
with
137 additions
and
5 deletions.
There are no files selected for viewing
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 |
---|---|---|
@@ -1,9 +1,11 @@ | ||
services: | ||
helfi_tunnistamo.http_exception_subscriber: | ||
class: Drupal\helfi_tunnistamo\EventSubscriber\HttpExceptionSubscriber | ||
arguments: ['@entity_type.manager', '@openid_connect.session', '@current_user'] | ||
tags: | ||
- { name: event_subscriber } | ||
_defaults: | ||
autowire: true | ||
autoconfigure: true | ||
|
||
logger.channel.helfi_tunnistamo: | ||
parent: logger.channel_base | ||
arguments: [ 'helfi_tunnistamo' ] | ||
|
||
Drupal\helfi_tunnistamo\EventSubscriber\HttpExceptionSubscriber: ~ | ||
Drupal\helfi_tunnistamo\EventSubscriber\DisableExternalUsersPasswordSubscriber: ~ |
59 changes: 59 additions & 0 deletions
59
src/EventSubscriber/DisableExternalUsersPasswordSubscriber.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,59 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Drupal\helfi_tunnistamo\EventSubscriber; | ||
|
||
use Drupal\Core\Database\Connection; | ||
use Drupal\Core\Entity\EntityTypeManagerInterface; | ||
use Drupal\helfi_api_base\EventSubscriber\DeployHookEventSubscriberBase; | ||
use Symfony\Contracts\EventDispatcher\Event; | ||
|
||
/** | ||
* Sets tunnistamo users' password to NULL. | ||
* | ||
* This should prevent given users from logging in using password. | ||
*/ | ||
final class DisableExternalUsersPasswordSubscriber extends DeployHookEventSubscriberBase { | ||
|
||
/** | ||
* Constructs a new instance. | ||
* | ||
* @param \Drupal\Core\Database\Connection $database | ||
* Database connection. | ||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager | ||
* The entity type manager. | ||
*/ | ||
public function __construct( | ||
private readonly Connection $database, | ||
private readonly EntityTypeManagerInterface $entityTypeManager, | ||
) { | ||
} | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public function onPostDeploy(Event $event) : void { | ||
// Query tunnistamo users that have their passwords set. | ||
$query = $this->database->select('authmap', 'am'); | ||
$query->leftJoin('users_field_data', 'ufd', 'ufd.uid = am.uid'); | ||
$query | ||
->fields('am', ['uid']) | ||
->condition('ufd.pass', NULL, 'IS NOT NULL') | ||
// Make sure we have an upper bound. | ||
->range(0, 50); | ||
|
||
$storage = $this->entityTypeManager->getStorage('user'); | ||
foreach ($query->execute()->fetchCol() as $id) { | ||
/** @var \Drupal\user\UserInterface $account */ | ||
$account = $storage->load($id); | ||
|
||
// Set user password to null. This prevents the user | ||
// from logging in with the local user in the future. | ||
$account | ||
->setPassword(NULL) | ||
->save(); | ||
} | ||
} | ||
|
||
} |
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
52 changes: 52 additions & 0 deletions
52
tests/src/Kernel/DisableExternalUsersPasswordSubscriberTest.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,52 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Drupal\Tests\helfi_tunnistamo\Kernel; | ||
|
||
use Drupal\helfi_api_base\Event\PostDeployEvent; | ||
use Drupal\Tests\user\Traits\UserCreationTrait; | ||
use Drupal\user\Entity\User; | ||
|
||
/** | ||
* Tests disable local users subscriber. | ||
* | ||
* @group helfi_tunnistamo | ||
*/ | ||
class DisableExternalUsersPasswordSubscriberTest extends KernelTestBase { | ||
|
||
use UserCreationTrait; | ||
|
||
/** | ||
* Tests that deploy prevents external users from logging in with password. | ||
*/ | ||
public function testSubscriber() : void { | ||
/** @var \Drupal\externalauth\Authmap $authmap */ | ||
$authmap = $this->container->get('externalauth.authmap'); | ||
$external = $this->createUser(values: ['pass' => '123']); | ||
$local = $this->createUser(values: ['pass' => '123']); | ||
|
||
// Add external auth to user. | ||
$authmap->save($external, 'test_provider', 'test_authname'); | ||
|
||
// User login is enabled. | ||
$this->assertNotEmpty($external->getPassword()); | ||
$this->assertNotEmpty($local->getPassword()); | ||
|
||
$this->triggerEvent(); | ||
|
||
// User password is disabled. | ||
$this->assertEmpty(User::load($external->id())->getPassword()); | ||
$this->assertNotEmpty(User::load($local->id())->getPassword()); | ||
} | ||
|
||
/** | ||
* Triggers the post deploy event. | ||
*/ | ||
private function triggerEvent() : void { | ||
/** @var \Symfony\Contracts\EventDispatcher\EventDispatcherInterface $service */ | ||
$service = $this->container->get('event_dispatcher'); | ||
$service->dispatch(new PostDeployEvent()); | ||
} | ||
|
||
} |