diff --git a/CLAUDE_FEATURES.md b/CLAUDE_FEATURES.md index 874dab1e457..2007c51de98 100644 --- a/CLAUDE_FEATURES.md +++ b/CLAUDE_FEATURES.md @@ -692,7 +692,7 @@ Notable env-vars (non-exhaustive — full list lives in the source): | ------- | ------- | ------- | | `DIRIGIBLE_SERVER_PORT` | `8080` | HTTP listen port. | | `DIRIGIBLE_HOME_URL` | `services/web/shell-ide/` | Landing URL after `/`. | -| `DIRIGIBLE_BASIC_USERNAME` / `_PASSWORD` | `admin` / `admin` | Default basic-auth credentials. | +| `DIRIGIBLE_BASIC_USERNAME` / `_PASSWORD` | `admin` / `admin` | Default basic-auth credentials. Values are Base64-encoded (e.g. `printf '%s' 'admin' \| base64`); a value that is not valid Base64 is refused at startup. | | `DIRIGIBLE_REPOSITORY_LOCAL_ROOT_FOLDER` | `./target/` | On-disk root for the registry. | | `DIRIGIBLE_DATASOURCE_DEFAULT_DRIVER` / `_URL` / `_USERNAME` / `_PASSWORD` | H2 file-backed | Default JDBC datasource. | | `DIRIGIBLE_DATABASE_DATASOURCE_NAME_DEFAULT` / `_SYSTEM` | `DefaultDB` / `SystemDB` | Logical names. | diff --git a/modules/commons/commons-config/src/main/java/org/eclipse/dirigible/commons/config/DirigibleConfig.java b/modules/commons/commons-config/src/main/java/org/eclipse/dirigible/commons/config/DirigibleConfig.java index 755fa7d1286..e972820a18c 100644 --- a/modules/commons/commons-config/src/main/java/org/eclipse/dirigible/commons/config/DirigibleConfig.java +++ b/modules/commons/commons-config/src/main/java/org/eclipse/dirigible/commons/config/DirigibleConfig.java @@ -977,13 +977,19 @@ public static List tenantOverridableKeys() { } /** - * Gets the from base 64 value. + * Gets the Base64-decoded value of this configuration. * - * @return the from base 64 value + * @return the decoded value + * @throws InvalidConfigException if the configured value is not valid Base64 */ public String getFromBase64Value() { String val = getStringValue(); - return fromBase64(val); + try { + return fromBase64(val); + } catch (IllegalArgumentException ex) { + throw new InvalidConfigException("The value of [" + key + "] must be Base64-encoded, but it could not be decoded (" + + ex.getMessage() + "). Encode the plain value, e.g. `printf '%s' '' | base64`.", key); + } } /** diff --git a/modules/commons/commons-config/src/test/java/org/eclipse/dirigible/commons/config/DirigibleConfigBase64Test.java b/modules/commons/commons-config/src/test/java/org/eclipse/dirigible/commons/config/DirigibleConfigBase64Test.java new file mode 100644 index 00000000000..93c600d5b6c --- /dev/null +++ b/modules/commons/commons-config/src/test/java/org/eclipse/dirigible/commons/config/DirigibleConfigBase64Test.java @@ -0,0 +1,58 @@ +/* + * Copyright (c) 2010-2026 Eclipse Dirigible contributors + * + * All rights reserved. This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v2.0 which accompanies this distribution, and is available at + * http://www.eclipse.org/legal/epl-v20.html + * + * SPDX-FileCopyrightText: Eclipse Dirigible contributors SPDX-License-Identifier: EPL-2.0 + */ +package org.eclipse.dirigible.commons.config; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + +import java.nio.charset.StandardCharsets; +import java.util.Base64; + +import org.junit.After; +import org.junit.Test; + +/** + * Verifies that a Base64-only configuration refuses a plain-text value with a message naming the + * variable, instead of aborting boot with a bare decoder error. + */ +public class DirigibleConfigBase64Test { + + private static final String KEY = DirigibleConfig.BASIC_ADMIN_PASS.getKey(); + + @After + public void restoreDefault() { + Configuration.remove(KEY); + } + + @Test + public void plainTextValueIsRefusedNamingTheVariable() { + // a plain value with a non-Base64 character ('-'), as in the issue + Configuration.set(KEY, "qahunt-pw"); + try { + DirigibleConfig.BASIC_ADMIN_PASS.getFromBase64Value(); + fail("A non-Base64 value should be refused"); + } catch (InvalidConfigException ex) { + assertEquals(KEY, ex.getConfigKey()); + assertTrue("message should name the variable: " + ex.getMessage(), ex.getMessage() + .contains(KEY)); + assertTrue("message should mention Base64: " + ex.getMessage(), ex.getMessage() + .contains("Base64")); + } + } + + @Test + public void validBase64IsDecoded() { + Configuration.set(KEY, Base64.getEncoder() + .encodeToString("s3cr3t".getBytes(StandardCharsets.UTF_8))); + + assertEquals("s3cr3t", DirigibleConfig.BASIC_ADMIN_PASS.getFromBase64Value()); + } +}