diff --git a/CHANGELOG.md b/CHANGELOG.md index a874b49..3aaf55f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,9 @@ Latest * [#186](https://github.com/cleverage/ui-process-bundle/issues/186) `ProcessExecuteController`, `ProcessExecuteHandler`, `LaunchType`, `ProcessConfigurationsManager` and `IsValidProcessCodeValidator` are typed on `ProcessManagerInterface` / `ProcessConfigurationRegistryInterface` (process-bundle 5.4) instead of the concrete classes, `@final since 5.4`: the process manager and the process configuration registry can be decorated or replaced for the UI. * [#209](https://github.com/cleverage/ui-process-bundle/issues/209) The files sent as input of a process (launch form, HTTP API) are deleted from the upload directory once the process has been executed, successfully or not (they were kept forever). Set the new `cleverage_ui_process.delete_uploaded_files` parameter to `false` to keep them. Update documentation, add tests. +## Fixes +* [#222](https://github.com/cleverage/ui-process-bundle/issues/222) The login throttling of the `main` firewall (#207) is added after the application configuration, with the rest of the firewall, instead of before: an application declaring another firewall (e.g. the `dev` firewall of the Symfony recipe) could no longer boot ("You are not allowed to define new elements for path "security.firewalls""). The application settings of `login_throttling` are kept. Update documentation and tests. + v3.3.1 ------ diff --git a/docs/reference/03-users_and_security.md b/docs/reference/03-users_and_security.md index 5510609..b243c95 100644 --- a/docs/reference/03-users_and_security.md +++ b/docs/reference/03-users_and_security.md @@ -27,13 +27,14 @@ security: clear_site_data: '*' ``` -The [login throttling](https://symfony.com/doc/current/security.html#limiting-login-attempts) is added **before** the -application configuration: its default settings (5 failed attempts per minute for a username and an IP address, 25 for -an IP address) can be changed in the `main` firewall of the application (e.g. `login_throttling: { max_attempts: 3 }`). -The rest of this configuration is added **after** the application one, so it overrides it: the `provider`, `form_login` and `logout` +This configuration is added **after** the application one, so it overrides it: the `provider`, `form_login` and `logout` of your `main` firewall are replaced by the bundle ones (e.g. the `provider: users_in_memory` of the default Symfony recipe), and the API token authenticator is added to it. So your application firewall must be named `main`, and it is -dedicated to the UI. To keep the control of your security configuration, disable it, see +dedicated to the UI. The default settings of the +[login throttling](https://symfony.com/doc/current/security.html#limiting-login-attempts) (5 failed attempts per minute +for a username and an IP address, 25 for an IP address) can still be changed in the `main` firewall of the application +(e.g. `login_throttling: { max_attempts: 3 }`): the empty `login_throttling` of the bundle keeps them. To keep the +control of your security configuration, disable it, see [configuring the security in your application](#configuring-the-security-in-your-application). With this configuration, the only required application configuration is a password diff --git a/src/DependencyInjection/CleverAgeUiProcessExtension.php b/src/DependencyInjection/CleverAgeUiProcessExtension.php index 201bfc4..f5d14f0 100644 --- a/src/DependencyInjection/CleverAgeUiProcessExtension.php +++ b/src/DependencyInjection/CleverAgeUiProcessExtension.php @@ -136,10 +136,9 @@ public function getConfiguration(array $config, ContainerBuilder $container): Co /** * Configure the other bundles: Monolog handlers, migrations path, Messenger transport and security. * - * The Messenger configuration and the login throttling of the "main" firewall are prepended (the application - * configuration wins). The other ones are appended, so they override the application configuration: in particular - * the security one replaces the provider, login form and logout of the application "main" firewall, unless the - * "security.configure_firewall" option is false. + * The Messenger configuration is prepended (the application configuration wins). The other ones are appended, so + * they override the application configuration: in particular the security one replaces the provider, login form and + * logout of the application "main" firewall, unless the "security.configure_firewall" option is false. */ public function prepend(ContainerBuilder $container): void { @@ -227,8 +226,6 @@ private function configureMonolog(ContainerBuilder $container): void private function configureSecurity(ContainerBuilder $container): void { - // Prepended: the application can change the throttling settings (max_attempts, interval...) - $container->prependExtensionConfig('security', ['firewalls' => ['main' => ['login_throttling' => []]]]); $container->loadFromExtension( 'security', [ @@ -248,6 +245,10 @@ private function configureSecurity(ContainerBuilder $container): void 'login_path' => 'cleverage_ui_process_login', 'check_path' => 'cleverage_ui_process_login', ], + // Not prepended: a prepended firewall would be the first definition of the "firewalls" node, + // the other firewalls of the application (e.g. "dev") could no longer be declared. Merged + // after the application configuration, it keeps its settings (max_attempts, interval...) + 'login_throttling' => [], 'logout' => [ 'path' => 'cleverage_ui_process_logout', 'target' => 'cleverage_ui_process_login', diff --git a/tests/App/config/packages.yaml b/tests/App/config/packages.yaml index ce4eb59..7493170 100644 --- a/tests/App/config/packages.yaml +++ b/tests/App/config/packages.yaml @@ -39,7 +39,11 @@ security: password_hashers: Symfony\Component\Security\Core\User\PasswordAuthenticatedUserInterface: algorithm: plaintext + # As in the Symfony recipe: another firewall than "main" must still be declarable (#222) firewalls: + dev: + pattern: ^/(_profiler|_wdt)/ + security: false main: lazy: true diff --git a/tests/DependencyInjection/CleverAgeUiProcessExtensionTest.php b/tests/DependencyInjection/CleverAgeUiProcessExtensionTest.php index 182c794..65acb58 100644 --- a/tests/DependencyInjection/CleverAgeUiProcessExtensionTest.php +++ b/tests/DependencyInjection/CleverAgeUiProcessExtensionTest.php @@ -403,12 +403,11 @@ public function testPrepend(): void ); $security = $container->getExtensionConfig('security'); - self::assertCount(2, $security); - // Prepended: the application can change the throttling settings - self::assertSame(['firewalls' => ['main' => ['login_throttling' => []]]], $security[0]); + // Only appended: a prepended firewall would prevent the application from declaring its other firewalls + self::assertCount(1, $security); self::assertSame( ['process_user_provider' => ['entity' => ['class' => User::class, 'property' => 'email']]], - $security[1]['providers'] + $security[0]['providers'] ); self::assertSame( [ @@ -416,10 +415,11 @@ public function testPrepend(): void 'provider' => 'process_user_provider', 'custom_authenticator' => ['cleverage_ui_process.security.http_process_execution_authenticator'], 'form_login' => ['login_path' => 'cleverage_ui_process_login', 'check_path' => 'cleverage_ui_process_login'], + 'login_throttling' => [], 'logout' => ['path' => 'cleverage_ui_process_logout', 'target' => 'cleverage_ui_process_login', 'clear_site_data' => '*'], ], ], - $security[1]['firewalls'] + $security[0]['firewalls'] ); }