diff options
author | Matteo Mara <matteo.mara@sonarsource.com> | 2025-01-07 16:05:21 +0100 |
---|---|---|
committer | sonartech <sonartech@sonarsource.com> | 2025-01-09 20:03:23 +0000 |
commit | 7adbfc4ef63efbdd8ed284c66d3bc4ba461d724d (patch) | |
tree | c195ec7abd54cdc98375bca4846c5bd4036bbf2f /server/sonar-db-migration | |
parent | d6dda575139a485af627fd3d0d0a5a50359ade5c (diff) | |
download | sonarqube-7adbfc4ef63efbdd8ed284c66d3bc4ba461d724d.tar.gz sonarqube-7adbfc4ef63efbdd8ed284c66d3bc4ba461d724d.zip |
SONAR-19225 Add migration to warn about the dropped BCRYPT hashing method
Diffstat (limited to 'server/sonar-db-migration')
3 files changed, 150 insertions, 0 deletions
diff --git a/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsedIT.java b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsedIT.java new file mode 100644 index 00000000000..f9066d5ef26 --- /dev/null +++ b/server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsedIT.java @@ -0,0 +1,83 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v202501; + +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.sonar.api.testfixtures.log.LogTesterJUnit5; +import org.sonar.db.MigrationDbTester; +import org.sonar.server.platform.db.migration.step.DataChange; + +import static org.assertj.core.api.Assertions.assertThat; + + +class LogMessageIfInvalidHashMechanismUsedIT { + + @RegisterExtension + public final MigrationDbTester db = MigrationDbTester.createForMigrationStep(LogMessageIfInvalidHashMechanismUsed.class); + + @RegisterExtension + public final LogTesterJUnit5 logTester = new LogTesterJUnit5(); + + private final DataChange underTest = new LogMessageIfInvalidHashMechanismUsed(db.database()); + + @Test + void execute_whenNoActiveUsersOnBcrypt_doesNothing() throws Exception { + addUser("user1", "PBKDF2", true); + addUser("user2", "BCRYPT", false); + underTest.execute(); + assertThat(logTester.logs()).isEmpty(); + } + + @Test + void execute_whenActiveUsersAreStillOnBcrypt_warns() throws Exception { + addUser("user1", "BCRYPT", true); + addUser("user2", "BCRYPT", false); + addUser("user3", "BCRYPT", true); + addUser("user4", "PBKDF2", true); + + underTest.execute(); + assertThat(logTester.logs()).containsExactly("The following active users are still relying on passwords using the unsupported hash mechanism (BCRYPT). Their passwords should" + + " be manually updated by an administrator: user1, user3"); + } + + private void addUser(String login, String hashAlgorithm, boolean active) { + Map<String, Object> map = new HashMap<>(); + map.put("uuid", login); + map.put("login", login); + map.put("name", "name"); + map.put("email", "email"); + map.put("external_id", login); + map.put("external_login", login); + map.put("external_identity_provider", "sonarqube"); + map.put("user_local", true); + map.put("crypted_password", "password"); + map.put("salt", ""); + map.put("active", active); + map.put("hash_method", hashAlgorithm); + map.put("reset_password", false); + map.put("created_at", 1_000_000_000_000L); + map.put("updated_at", 1_000_000_000_000L); + + db.executeInsert("users", map); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java index 1d15ff6db24..10dbd196377 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java @@ -48,6 +48,7 @@ public class DbVersion202501 implements DbVersion { .add(2025_01_008, "Log message if SAML configuration is not valid", LogMessageIfInvalidSamlSetup.class) .add(2025_01_009, "Add 'inline_annotations_enabled' column to 'project_alm_settings' table", AddInlineAnnotationsEnabledColumnToProjectAlmSettingsTable.class) .add(2025_01_010, "Populate 'inline_annotations_enabled' column for Azure", PopulateInlineAnnotationsEnabledColumnForAzure.class) + .add(2025_01_011, "Log message if users are still relying on BCRYPT hashed passwords", LogMessageIfInvalidHashMechanismUsed.class) ; } } diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsed.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsed.java new file mode 100644 index 00000000000..edffb5e20db --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsed.java @@ -0,0 +1,66 @@ +/* + * SonarQube + * Copyright (C) 2009-2025 SonarSource SA + * mailto:info AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program; if not, write to the Free Software Foundation, + * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + */ +package org.sonar.server.platform.db.migration.version.v202501; + +import com.google.common.annotations.VisibleForTesting; +import java.sql.SQLException; +import java.util.ArrayList; +import java.util.List; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; + +public class LogMessageIfInvalidHashMechanismUsed extends DataChange { + private static final Logger LOG = LoggerFactory.getLogger(LogMessageIfInvalidHashMechanismUsed.class); + + @VisibleForTesting + static final String BCRYPT_HASH = "BCRYPT"; + + public LogMessageIfInvalidHashMechanismUsed(Database db) { + super(db); + } + + @Override + protected void execute(Context context) throws SQLException { + + List<String> usersOnBcryptHash = getUsersOnBcryptHash(context); + + if (usersOnBcryptHash.isEmpty()) { + return; + } + + LOG.atWarn().log("The following active users are still relying on passwords using the unsupported hash mechanism ({}). " + + "Their passwords should be manually updated by an administrator: {}", + BCRYPT_HASH, String.join(", ", usersOnBcryptHash)); + + } + + private static List<String> getUsersOnBcryptHash(Context context) throws SQLException { + List<String> usersOnBcryptHash = new ArrayList<>(); + + context.prepareSelect("select login from users where active = ? and hash_method = ?") + .setBoolean(1, true) + .setString(2, BCRYPT_HASH) + .scroll(row -> usersOnBcryptHash.add(row.getString(1))); + + return usersOnBcryptHash; + } +} |