aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-migration
diff options
context:
space:
mode:
authorMatteo Mara <matteo.mara@sonarsource.com>2025-01-07 16:05:21 +0100
committersonartech <sonartech@sonarsource.com>2025-01-09 20:03:23 +0000
commit7adbfc4ef63efbdd8ed284c66d3bc4ba461d724d (patch)
treec195ec7abd54cdc98375bca4846c5bd4036bbf2f /server/sonar-db-migration
parentd6dda575139a485af627fd3d0d0a5a50359ade5c (diff)
downloadsonarqube-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')
-rw-r--r--server/sonar-db-migration/src/it/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsedIT.java83
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/DbVersion202501.java1
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v202501/LogMessageIfInvalidHashMechanismUsed.java66
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;
+ }
+}