diff --git a/core/modules/user/config/schema/user.schema.yml b/core/modules/user/config/schema/user.schema.yml index ed7e3875eda929b68150afb01ce08fc3fba7a23a..e768e25558a9c0871f10a8e81d96b72ebd32df4c 100644 --- a/core/modules/user/config/schema/user.schema.yml +++ b/core/modules/user/config/schema/user.schema.yml @@ -3,6 +3,8 @@ user.settings: type: config_object label: 'User settings' + constraints: + FullyValidatable: ~ mapping: anonymous: type: required_label @@ -41,12 +43,27 @@ user.settings: register: type: string label: 'Who can register accounts?' + # Choices are derived from the constants. + # @see \Drupal\user\UserInterface::REGISTER_* + # @todo Convert to use Enum in https://www.drupal.org/project/drupal/issues/3450782 + constraints: + Choice: + choices: + - 'visitors' + - 'admin_only' + - 'visitors_admin_approval' cancel_method: type: string label: 'When cancelling a user account' + constraints: + UserCancelMethod: [] password_reset_timeout: type: integer label: 'Password reset timeout' + # @todo Increase min in https://www.drupal.org/i/3441772 + constraints: + Range: + min: 1 password_strength: type: boolean label: 'Enable password strength indicator' diff --git a/core/modules/user/migrations/d6_user_settings.yml b/core/modules/user/migrations/d6_user_settings.yml index 911682a27803bc8bc9413fe6fe95e84b63bb3e66..8503756bcf1923cb5debd96fb48a299928208f47 100644 --- a/core/modules/user/migrations/d6_user_settings.yml +++ b/core/modules/user/migrations/d6_user_settings.yml @@ -16,6 +16,35 @@ process: 'notify/status_blocked': user_mail_status_blocked_notify 'notify/status_activated': user_mail_status_activated_notify verify_mail: user_email_verification + # @see core/modules/user/config/install/user.settings.yml + # Default values + cancel_method: + plugin: default_value + default_value: user_cancel_block + password_reset_timeout: + plugin: default_value + default_value: 86400 + password_strength: + plugin: default_value + default_value: true + 'notify/cancel_confirm': + plugin: default_value + default_value: true + 'notify/password_reset': + plugin: default_value + default_value: true + 'notify/status_canceled': + plugin: default_value + default_value: false + 'notify/register_admin_created': + plugin: default_value + default_value: true + 'notify/register_no_approval_required': + plugin: default_value + default_value: true + 'notify/register_pending_approval': + plugin: default_value + default_value: true register: plugin: static_map source: user_register diff --git a/core/modules/user/migrations/d7_user_settings.yml b/core/modules/user/migrations/d7_user_settings.yml index 8139cdf706c39fa1b827b5a3bd0429e5d29f0779..70c3c2bb1dce2c1bd91d09bf8db8c92901f08402 100644 --- a/core/modules/user/migrations/d7_user_settings.yml +++ b/core/modules/user/migrations/d7_user_settings.yml @@ -16,6 +16,35 @@ process: 'notify/status_blocked': user_mail_status_blocked_notify 'notify/status_activated': user_mail_status_activated_notify verify_mail: user_email_verification + # @see core/modules/user/config/install/user.settings.yml + # Default values + cancel_method: + plugin: default_value + default_value: user_cancel_block + password_reset_timeout: + plugin: default_value + default_value: 86400 + password_strength: + plugin: default_value + default_value: true + 'notify/cancel_confirm': + plugin: default_value + default_value: true + 'notify/password_reset': + plugin: default_value + default_value: true + 'notify/status_canceled': + plugin: default_value + default_value: false + 'notify/register_admin_created': + plugin: default_value + default_value: true + 'notify/register_no_approval_required': + plugin: default_value + default_value: true + 'notify/register_pending_approval': + plugin: default_value + default_value: true register: plugin: static_map source: user_register diff --git a/core/modules/user/src/Plugin/Validation/Constraint/UserCancelMethodsConstraint.php b/core/modules/user/src/Plugin/Validation/Constraint/UserCancelMethodsConstraint.php new file mode 100644 index 0000000000000000000000000000000000000000..483c6a8dce1a5a3f934daa89a5d6a04ef0b4d2de --- /dev/null +++ b/core/modules/user/src/Plugin/Validation/Constraint/UserCancelMethodsConstraint.php @@ -0,0 +1,27 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\user\Plugin\Validation\Constraint; + +use Drupal\Core\Plugin\ContainerFactoryPluginInterface; +use Drupal\Core\StringTranslation\TranslatableMarkup; +use Drupal\Core\Validation\Attribute\Constraint; +use Symfony\Component\DependencyInjection\ContainerInterface; +use Symfony\Component\Validator\Constraints\Choice; + +#[Constraint( + id: 'UserCancelMethod', + label: new TranslatableMarkup('UserCancelMethod', [], ['context' => 'Validation']), +)] +class UserCancelMethodsConstraint implements ContainerFactoryPluginInterface { + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition): Choice { + $configuration['choices'] = array_keys(user_cancel_methods()['#options']); + return new Choice($configuration); + } + +} diff --git a/core/modules/user/tests/src/Kernel/UserConfigValidationTest.php b/core/modules/user/tests/src/Kernel/UserConfigValidationTest.php new file mode 100644 index 0000000000000000000000000000000000000000..991f13241302d0682d23ceb981a68c11b10850ad --- /dev/null +++ b/core/modules/user/tests/src/Kernel/UserConfigValidationTest.php @@ -0,0 +1,70 @@ +<?php + +declare(strict_types=1); + +namespace Drupal\Tests\user\Kernel; + +use Drupal\KernelTests\KernelTestBase; + +/** + * Tests validating user modules' configuration. + * + * @group user + */ +class UserConfigValidationTest extends KernelTestBase { + + /** + * {@inheritdoc} + */ + protected static $modules = ['system', 'user']; + + /** + * {@inheritdoc} + */ + protected function setUp(): void { + parent::setUp(); + $this->installConfig('user'); + } + + /** + * Data provider for testUserSettings(). + * + * @return array + */ + public static function providerTestUserSettings(): array { + return [ + "Invalid register" => [ + 'register', + 'somebody', + 'The value you selected is not a valid choice.', + ], + "Invalid cancel_method" => [ + 'cancel_method', + 'somebody', + 'The value you selected is not a valid choice.', + ], + "Invalid password_reset_timeout" => [ + 'password_reset_timeout', + '0', + 'This value should be <em class="placeholder">1</em> or more.', + ], + ]; + } + + /** + * Tests invalid values in 'user.settings' config properties. + * + * @dataProvider providerTestUserSettings + */ + public function testUserSettings($property, $property_value, $expected_message): void { + $config_name = 'user.settings'; + $config = $this->config($config_name); + $violations = $this->container->get('config.typed') + ->createFromNameAndData($config_name, $config->set($property, $property_value)->get()) + ->validate(); + $this->assertCount(1, $violations); + $this->assertSame($property, $violations[0]->getPropertyPath()); + $this->assertSame($expected_message, (string) $violations[0]->getMessage()); + } + +} diff --git a/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php b/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php index 6205404532014059c31cbca53aa142c1ab18ed8b..3e13061be0a3002f1c796cf9b72f1b116fdf28bc 100644 --- a/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php +++ b/core/modules/user/tests/src/Kernel/UserMailNotifyTest.php @@ -103,6 +103,7 @@ public function testUserMailsSent($op, array $mail_keys): void { * @dataProvider userMailsProvider */ public function testUserMailsNotSent($op): void { + $this->installConfig('user'); $this->config('user.settings')->set('notify.' . $op, FALSE)->save(); $return = _user_mail_notify($op, $this->createUser()); $this->assertNull($return);