diff --git a/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php b/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php index 5b5d9204daa..3ae9beb22d7 100644 --- a/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php +++ b/core/modules/user/src/Plugin/rest/resource/UserRegistrationResource.php @@ -3,6 +3,7 @@ namespace Drupal\user\Plugin\rest\resource; use Drupal\Core\Config\ImmutableConfig; +use Drupal\Core\Password\PasswordGeneratorInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Core\StringTranslation\TranslatableMarkup; use Drupal\rest\Attribute\RestResource; @@ -48,6 +49,13 @@ class UserRegistrationResource extends ResourceBase { */ protected $currentUser; + /** + * The password generator. + * + * @var \Drupal\Core\Password\PasswordGeneratorInterface + */ + protected $passwordGenerator; + /** * Constructs a new UserRegistrationResource instance. * @@ -65,11 +73,19 @@ class UserRegistrationResource extends ResourceBase { * A user settings config instance. * @param \Drupal\Core\Session\AccountInterface $current_user * The current user. + * @param \Drupal\Core\Password\PasswordGeneratorInterface|null $password_generator + * The password generator. */ - public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, ImmutableConfig $user_settings, AccountInterface $current_user) { + public function __construct(array $configuration, $plugin_id, $plugin_definition, array $serializer_formats, LoggerInterface $logger, ImmutableConfig $user_settings, AccountInterface $current_user, PasswordGeneratorInterface $password_generator = NULL) { + if (is_null($password_generator)) { + @trigger_error('Calling ' . __METHOD__ . '() without the $password_generator argument is deprecated in drupal:10.3.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3405799', E_USER_DEPRECATED); + $password_generator = \Drupal::service('password_generator'); + } + parent::__construct($configuration, $plugin_id, $plugin_definition, $serializer_formats, $logger); $this->userSettings = $user_settings; $this->currentUser = $current_user; + $this->passwordGenerator = $password_generator; } /** @@ -83,7 +99,8 @@ class UserRegistrationResource extends ResourceBase { $container->getParameter('serializer.formats'), $container->get('logger.factory')->get('rest'), $container->get('config.factory')->get('user.settings'), - $container->get('current_user') + $container->get('current_user'), + $container->get('password_generator') ); } @@ -102,15 +119,19 @@ class UserRegistrationResource extends ResourceBase { public function post(UserInterface $account = NULL) { $this->ensureAccountCanRegister($account); - // Only activate new users if visitors are allowed to register and no email - // verification required. - if ($this->userSettings->get('register') == UserInterface::REGISTER_VISITORS && !$this->userSettings->get('verify_mail')) { + // Only activate new users if visitors are allowed to register. + if ($this->userSettings->get('register') == UserInterface::REGISTER_VISITORS) { $account->activate(); } else { $account->block(); } + // Generate password if email verification required. + if ($this->userSettings->get('verify_mail')) { + $account->setPassword($this->passwordGenerator->generate()); + } + $this->checkEditFieldAccess($account); // Make sure that the user entity is valid (email and name are valid). diff --git a/core/modules/user/tests/src/Functional/UserRegistrationRestTest.php b/core/modules/user/tests/src/Functional/UserRegistrationRestTest.php index 94ce514a569..aadf5ada016 100644 --- a/core/modules/user/tests/src/Functional/UserRegistrationRestTest.php +++ b/core/modules/user/tests/src/Functional/UserRegistrationRestTest.php @@ -103,8 +103,8 @@ class UserRegistrationRestTest extends ResourceTestBase { $config->save(); $name = 'Jason.Taverner'; $user = $this->registerUser($name, FALSE); - $this->assertEmpty($user->getPassword()); - $this->assertTrue($user->isBlocked()); + $this->assertNotEmpty($user->getPassword()); + $this->assertFalse($user->isBlocked()); $this->resetAll(); $this->assertMailString('body', 'You may now log in by clicking this link', 1); @@ -128,7 +128,7 @@ class UserRegistrationRestTest extends ResourceTestBase { $name = 'PhilipK.Dick'; $user = $this->registerUser($name, FALSE); $this->resetAll(); - $this->assertEmpty($user->getPassword()); + $this->assertNotEmpty($user->getPassword()); $this->assertTrue($user->isBlocked()); $this->assertMailString('body', 'Your application for an account is', 2); diff --git a/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php b/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php index 5bb7511e973..5d8f9ac92f6 100644 --- a/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php +++ b/core/modules/user/tests/src/Unit/UserRegistrationResourceTest.php @@ -5,6 +5,8 @@ declare(strict_types=1); namespace Drupal\Tests\user\Unit; use Drupal\Core\Config\ImmutableConfig; +use Drupal\Core\DependencyInjection\ContainerBuilder; +use Drupal\Core\Password\PasswordGeneratorInterface; use Drupal\Core\Session\AccountInterface; use Drupal\Tests\UnitTestCase; use Drupal\user\Entity\User; @@ -59,6 +61,13 @@ class UserRegistrationResourceTest extends UnitTestCase { */ protected $currentUser; + /** + * The password generator. + * + * @var \Drupal\Core\Password\PasswordGeneratorInterface|\PHPUnit\Framework\MockObject\MockObject + */ + protected $passwordGenerator; + /** * {@inheritdoc} */ @@ -71,7 +80,9 @@ class UserRegistrationResourceTest extends UnitTestCase { $this->currentUser = $this->prophesize(AccountInterface::class); - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + $this->passwordGenerator = $this->prophesize(PasswordGeneratorInterface::class)->reveal(); + + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal(), $this->passwordGenerator); $this->reflection = new \ReflectionClass($this->testClass); } @@ -103,7 +114,7 @@ class UserRegistrationResourceTest extends UnitTestCase { $this->currentUser->isAnonymous()->willReturn(TRUE); - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal(), $this->passwordGenerator); $entity = $this->prophesize(User::class); $entity->isNew()->willReturn(TRUE); @@ -119,7 +130,7 @@ class UserRegistrationResourceTest extends UnitTestCase { public function testRegistrationAnonymousOnlyPost() { $this->currentUser->isAnonymous()->willReturn(FALSE); - $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal(), $this->passwordGenerator); $entity = $this->prophesize(User::class); $entity->isNew()->willReturn(TRUE); @@ -129,4 +140,24 @@ class UserRegistrationResourceTest extends UnitTestCase { $this->testClass->post($entity->reveal()); } + /** + * Tests the deprecation messages. + * + * @covers ::__construct + * + * @group legacy + */ + public function testDeprecations() { + $this->expectDeprecation('Calling Drupal\user\Plugin\rest\resource\UserRegistrationResource::__construct() without the $password_generator argument is deprecated in drupal:10.3.0 and will be required in drupal:11.0.0. See https://www.drupal.org/node/3405799'); + $this->expectException(BadRequestHttpException::class); + + $container = new ContainerBuilder(); + $password_generator = $this->prophesize(PasswordGeneratorInterface::class); + $container->set('password_generator', $password_generator->reveal()); + \Drupal::setContainer($container); + + $this->testClass = new UserRegistrationResource([], 'plugin_id', '', [], $this->logger, $this->userSettings->reveal(), $this->currentUser->reveal()); + $this->testClass->post(NULL); + } + }