This is an automated email from the ASF dual-hosted git repository. quantranhong1999 pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/james-project.git
commit d445433ebe7a338fe56eeb223f3a3d74bd3bef8a Author: Quan Tran <[email protected]> AuthorDate: Wed Jul 29 14:43:17 2026 +0700 [ENHANCEMENT] WebAdmin: create a Guice bean for default password generation value Default to `true` still. Allow extension app to override the default value easily. --- .../james/modules/server/WebAdminServerModule.java | 28 +++++++++++++++++----- .../modules/server/WebAdminServerModuleTest.java | 28 +++++++++++++++------- 2 files changed, 41 insertions(+), 15 deletions(-) diff --git a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java index 228fced7bc..838b412417 100644 --- a/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java +++ b/server/container/guice/protocols/webadmin/src/main/java/org/apache/james/modules/server/WebAdminServerModule.java @@ -72,6 +72,7 @@ import com.github.fge.lambdas.Throwing; import com.google.common.annotations.VisibleForTesting; import com.google.common.collect.ImmutableList; import com.google.inject.AbstractModule; +import com.google.inject.Module; import com.google.inject.Provider; import com.google.inject.Provides; import com.google.inject.Scopes; @@ -80,6 +81,9 @@ import com.google.inject.multibindings.Multibinder; import com.google.inject.multibindings.ProvidesIntoSet; public class WebAdminServerModule extends AbstractModule { + public record PasswordGenerationDefault(boolean enabled) { + } + private static final Logger LOGGER = LoggerFactory.getLogger(WebAdminServerModule.class); private static final boolean DEFAULT_JWT_DISABLED = false; @@ -93,11 +97,17 @@ public class WebAdminServerModule extends AbstractModule { private static final String DEFAULT_NO_TRUST_KEYSTORE = null; private static final String DEFAULT_NO_TRUST_PASSWORD = null; + public static Module defaultPasswordGenerationModule(boolean enabled) { + return binder -> binder.bind(PasswordGenerationDefault.class) + .toInstance(new PasswordGenerationDefault(enabled)); + } + @Override protected void configure() { install(new TaskRoutesModule()); install(new HealthCheckRoutesModule()); install(new ServerRouteModule()); + install(defaultPasswordGenerationModule(DEFAULT_PASSWORD_GENERATION_ENABLED)); bind(JsonTransformer.class).in(Scopes.SINGLETON); bind(WebAdminServer.class).in(Scopes.SINGLETON); @@ -139,7 +149,9 @@ public class WebAdminServerModule extends AbstractModule { @Provides @Singleton - public WebAdminConfiguration provideWebAdminConfiguration(FileSystem fileSystem, PropertiesProvider propertiesProvider) throws Exception { + public WebAdminConfiguration provideWebAdminConfiguration(FileSystem fileSystem, + PropertiesProvider propertiesProvider, + PasswordGenerationDefault passwordGenerationDefault) throws Exception { try { Configuration configurationFile = propertiesProvider.getConfiguration("webadmin"); @@ -158,7 +170,7 @@ public class WebAdminServerModule extends AbstractModule { Optional.ofNullable(configurationFile.getString("jwt.publickeypem.url", null)))) .maxThreadCount(Optional.ofNullable(configurationFile.getInteger("maxThreadCount", null))) .minThreadCount(Optional.ofNullable(configurationFile.getInteger("minThreadCount", null))) - .password(password(configurationFile, webAdminEnabled)) + .password(password(configurationFile, webAdminEnabled, passwordGenerationDefault)) .readOnlyPassword(Optional.ofNullable(configurationFile.getString("password.readonly", null))) .noDeletePassword(Optional.ofNullable(configurationFile.getString("password.nodelete", null))) .build(); @@ -178,20 +190,24 @@ public class WebAdminServerModule extends AbstractModule { } @VisibleForTesting - Optional<String> password(Configuration configurationFile, boolean webAdminEnabled) { + Optional<String> password(Configuration configurationFile, + boolean webAdminEnabled, + PasswordGenerationDefault passwordGenerationDefault) { Optional<String> configuredPassword = Optional.ofNullable(configurationFile.getString("password", null)); if (configuredPassword.isPresent()) { return configuredPassword; } - if (shouldGeneratePassword(configurationFile, webAdminEnabled)) { + if (shouldGeneratePassword(configurationFile, webAdminEnabled, passwordGenerationDefault)) { return Optional.of(generateAndLogPassword()); } return Optional.empty(); } - private boolean shouldGeneratePassword(Configuration configurationFile, boolean webAdminEnabled) { - return configurationFile.getBoolean("password.generate", DEFAULT_PASSWORD_GENERATION_ENABLED) + private boolean shouldGeneratePassword(Configuration configurationFile, + boolean webAdminEnabled, + PasswordGenerationDefault passwordGenerationDefault) { + return configurationFile.getBoolean("password.generate", passwordGenerationDefault.enabled()) && webAdminEnabled && !configurationFile.getBoolean("jwt.enabled", DEFAULT_JWT_DISABLED); } diff --git a/server/container/guice/protocols/webadmin/src/test/java/org/apache/james/modules/server/WebAdminServerModuleTest.java b/server/container/guice/protocols/webadmin/src/test/java/org/apache/james/modules/server/WebAdminServerModuleTest.java index bbe213d2ed..a596a1b697 100644 --- a/server/container/guice/protocols/webadmin/src/test/java/org/apache/james/modules/server/WebAdminServerModuleTest.java +++ b/server/container/guice/protocols/webadmin/src/test/java/org/apache/james/modules/server/WebAdminServerModuleTest.java @@ -32,6 +32,10 @@ import org.junit.jupiter.api.Test; class WebAdminServerModuleTest { private static final boolean WEBADMIN_ENABLED = true; private static final boolean WEBADMIN_DISABLED = false; + private static final WebAdminServerModule.PasswordGenerationDefault GENERATION_ENABLED_BY_DEFAULT = + new WebAdminServerModule.PasswordGenerationDefault(true); + private static final WebAdminServerModule.PasswordGenerationDefault GENERATION_DISABLED_BY_DEFAULT = + new WebAdminServerModule.PasswordGenerationDefault(false); @Test void shouldReturnEmptyWhenNoField() throws Exception { @@ -73,32 +77,38 @@ class WebAdminServerModuleTest { class PasswordGeneration { @Test void passwordShouldBeGeneratedByDefault() { - assertThat(new WebAdminServerModule().password(new PropertiesConfiguration(), WEBADMIN_ENABLED)) + assertThat(new WebAdminServerModule().password(new PropertiesConfiguration(), WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT)) .isNotEmpty(); } + @Test + void passwordShouldBeEmptyWhenGenerationIsDisabledByDefault() { + assertThat(new WebAdminServerModule().password(new PropertiesConfiguration(), WEBADMIN_ENABLED, GENERATION_DISABLED_BY_DEFAULT)) + .isEmpty(); + } + @Test void passwordShouldBeEmptyWhenGenerationIsDisabled() { - assertThat(new WebAdminServerModule().password(configuration("password.generate", false), WEBADMIN_ENABLED)) + assertThat(new WebAdminServerModule().password(configuration("password.generate", false), WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT)) .isEmpty(); } @Test void passwordShouldBeGeneratedWhenGenerationIsEnabled() { - assertThat(new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED)) + assertThat(new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED, GENERATION_DISABLED_BY_DEFAULT)) .isNotEmpty(); } @Test void generatedPasswordShouldNotContainThePasswordSeparator() { - assertThat(new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED)) + assertThat(new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT)) .hasValueSatisfying(password -> assertThat(password).doesNotContain(",")); } @Test void generatedPasswordsShouldBeRandom() { - Optional<String> firstPassword = new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED); - Optional<String> secondPassword = new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED); + Optional<String> firstPassword = new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT); + Optional<String> secondPassword = new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT); assertThat(firstPassword).isNotEqualTo(secondPassword); } @@ -108,13 +118,13 @@ class WebAdminServerModuleTest { PropertiesConfiguration configuration = configuration("password.generate", true); configuration.addProperty("password", "secret"); - assertThat(new WebAdminServerModule().password(configuration, WEBADMIN_ENABLED)) + assertThat(new WebAdminServerModule().password(configuration, WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT)) .contains("secret"); } @Test void passwordShouldNotBeGeneratedWhenWebAdminIsDisabled() { - assertThat(new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_DISABLED)) + assertThat(new WebAdminServerModule().password(configuration("password.generate", true), WEBADMIN_DISABLED, GENERATION_ENABLED_BY_DEFAULT)) .isEmpty(); } @@ -123,7 +133,7 @@ class WebAdminServerModuleTest { PropertiesConfiguration configuration = configuration("password.generate", true); configuration.addProperty("jwt.enabled", true); - assertThat(new WebAdminServerModule().password(configuration, WEBADMIN_ENABLED)) + assertThat(new WebAdminServerModule().password(configuration, WEBADMIN_ENABLED, GENERATION_ENABLED_BY_DEFAULT)) .isEmpty(); } --------------------------------------------------------------------- To unsubscribe, e-mail: [email protected] For additional commands, e-mail: [email protected]
