diff options
author | Julien Lancelot <julien.lancelot@sonarsource.com> | 2017-07-03 11:45:28 +0200 |
---|---|---|
committer | Julien Lancelot <julien.lancelot@sonarsource.com> | 2017-09-05 12:07:45 +0200 |
commit | 4f2fb99e70dc6a477792b4741db3239fe3676f0b (patch) | |
tree | 183e037f286abe08fb68d59cd55497f83388bc3a | |
parent | 46063d6f8b23ac3f133e8a844811144b692dd2c2 (diff) | |
download | sonarqube-4f2fb99e70dc6a477792b4741db3239fe3676f0b.tar.gz sonarqube-4f2fb99e70dc6a477792b4741db3239fe3676f0b.zip |
SONAR-9426 Migrate users not having identity provider
5 files changed, 182 insertions, 1 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsers.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsers.java new file mode 100644 index 00000000000..f26cacbf311 --- /dev/null +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsers.java @@ -0,0 +1,55 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.v65; + +import java.sql.SQLException; +import org.sonar.api.utils.System2; +import org.sonar.db.Database; +import org.sonar.server.platform.db.migration.step.DataChange; +import org.sonar.server.platform.db.migration.step.MassUpdate; + +public class FixEmptyIdentityProviderInUsers extends DataChange { + + private static final String SQ_AUTHORITY = "sonarqube"; + + private final System2 system2; + + public FixEmptyIdentityProviderInUsers(Database db, System2 system2) { + super(db); + this.system2 = system2; + } + + @Override + protected void execute(Context context) throws SQLException { + long now = system2.now(); + MassUpdate massUpdate = context.prepareMassUpdate(); + massUpdate.select("select u.id, u.login from users u " + + "where u.external_identity is null or u.external_identity_provider is null"); + massUpdate.update("update users set external_identity = ?, external_identity_provider = ?, updated_at = ? where id = ?"); + massUpdate.rowPluralName("users without external identity information"); + massUpdate.execute((row, update) -> { + update.setString(1, row.getString(2)); + update.setString(2, SQ_AUTHORITY); + update.setLong(3, now); + update.setLong(4, row.getLong(1)); + return true; + }); + } +} diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66.java index 8a040e89ee4..0954693d9e5 100644 --- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66.java +++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66.java @@ -22,6 +22,7 @@ package org.sonar.server.platform.db.migration.version.v66; import org.sonar.server.platform.db.migration.step.MigrationStepRegistry; import org.sonar.server.platform.db.migration.version.DbVersion; +import org.sonar.server.platform.db.migration.version.v65.FixEmptyIdentityProviderInUsers; public class DbVersion66 implements DbVersion { @Override @@ -30,6 +31,7 @@ public class DbVersion66 implements DbVersion { .add(1800, "Add incremental column to snapthots table", AddIncrementalColumnToSnapshotsTable.class) .add(1801, "Create table CE task characteristics", CreateTableCeTaskCharacteristics.class) .add(1802, "Delete leak settings on views", DeleteLeakSettingsOnViews.class) + .add(1803, "Fix empty USERS.EXTERNAL_IDENTITY and USERS.EXTERNAL_IDENTITY_PROVIDER", FixEmptyIdentityProviderInUsers.class) ; } } diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsersTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsersTest.java new file mode 100644 index 00000000000..af53254be12 --- /dev/null +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsersTest.java @@ -0,0 +1,105 @@ +/* + * SonarQube + * Copyright (C) 2009-2017 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.v65; + +import com.google.common.collect.ImmutableMap; +import java.sql.SQLException; +import java.util.stream.Collectors; +import javax.annotation.Nullable; +import org.assertj.core.groups.Tuple; +import org.junit.Rule; +import org.junit.Test; +import org.sonar.api.utils.System2; +import org.sonar.api.utils.internal.TestSystem2; +import org.sonar.db.CoreDbTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; + +public class FixEmptyIdentityProviderInUsersTest { + + private final static long PAST = 100_000_000_000l; + private final static long NOW = 500_000_000_000l; + + private System2 system2 = new TestSystem2().setNow(NOW); + + @Rule + public CoreDbTester db = CoreDbTester.createForSchema(FixEmptyIdentityProviderInUsersTest.class, "users.sql"); + + private FixEmptyIdentityProviderInUsers underTest = new FixEmptyIdentityProviderInUsers(db.database(), system2); + + @Test + public void execute_has_no_effect_if_tables_are_empty() throws SQLException { + underTest.execute(); + } + + @Test + public void migrate_user_without_external_identity_info() throws SQLException { + insertUser("userWithoutExternalIdentityInfo", null, null); + + underTest.execute(); + + assertUsers(tuple("userWithoutExternalIdentityInfo", "userWithoutExternalIdentityInfo", "sonarqube", NOW)); + } + + @Test + public void migrate_user_with_partial_external_identity_info() throws SQLException { + insertUser("userWithoutExternalIdentity", "user", null); + insertUser("userWithoutExternalIdentityProvider", null, "github"); + + underTest.execute(); + + assertUsers(tuple("userWithoutExternalIdentity", "userWithoutExternalIdentity", "sonarqube", NOW), + tuple("userWithoutExternalIdentityProvider", "userWithoutExternalIdentityProvider", "sonarqube", NOW)); + } + + @Test + public void does_not_migrate_user_with_external_identity_info() throws SQLException { + insertUser("userWithIdentityInfo", "user", "sonarqube"); + + underTest.execute(); + + assertUsers(tuple("userWithIdentityInfo", "user", "sonarqube", PAST)); + } + + private void insertUser(String login, @Nullable String externalIdentity, @Nullable String externalIdentityProvider) { + ImmutableMap.Builder<String, Object> map = ImmutableMap.<String, Object>builder() + .put("LOGIN", login) + .put("IS_ROOT", true) + .put("ONBOARDED", true) + .put("CREATED_AT", PAST) + .put("UPDATED_AT", PAST); + if (externalIdentity != null) { + map.put("EXTERNAL_IDENTITY", externalIdentity); + } + if (externalIdentityProvider != null) { + map.put("EXTERNAL_IDENTITY_PROVIDER", externalIdentityProvider); + } + db.executeInsert("USERS", map.build()); + } + + private void assertUsers(Tuple... expectedTuples) { + assertThat(db.select("SELECT LOGIN, EXTERNAL_IDENTITY, EXTERNAL_IDENTITY_PROVIDER, UPDATED_AT FROM USERS") + .stream() + .map(map -> new Tuple(map.get("LOGIN"), map.get("EXTERNAL_IDENTITY"), map.get("EXTERNAL_IDENTITY_PROVIDER"), map.get("UPDATED_AT"))) + .collect(Collectors.toList())) + .containsExactlyInAnyOrder(expectedTuples); + } +} diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66Test.java index 407ed300852..4a97a611e52 100644 --- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66Test.java +++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v66/DbVersion66Test.java @@ -34,6 +34,6 @@ public class DbVersion66Test { @Test public void verify_migration_count() { - verifyMigrationCount(underTest, 3); + verifyMigrationCount(underTest, 4); } } diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsersTest/users.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsersTest/users.sql new file mode 100644 index 00000000000..8d6baaacafa --- /dev/null +++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v65/FixEmptyIdentityProviderInUsersTest/users.sql @@ -0,0 +1,19 @@ +CREATE TABLE "USERS" ( + "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1), + "LOGIN" VARCHAR(255), + "NAME" VARCHAR(200), + "EMAIL" VARCHAR(100), + "CRYPTED_PASSWORD" VARCHAR(40), + "SALT" VARCHAR(40), + "ACTIVE" BOOLEAN DEFAULT TRUE, + "SCM_ACCOUNTS" VARCHAR(4000), + "EXTERNAL_IDENTITY" VARCHAR(255), + "EXTERNAL_IDENTITY_PROVIDER" VARCHAR(100), + "IS_ROOT" BOOLEAN NOT NULL, + "USER_LOCAL" BOOLEAN, + "ONBOARDED" BOOLEAN NOT NULL, + "CREATED_AT" BIGINT, + "UPDATED_AT" BIGINT +); +CREATE UNIQUE INDEX "USERS_LOGIN" ON "USERS" ("LOGIN"); +CREATE INDEX "USERS_UPDATED_AT" ON "USERS" ("UPDATED_AT"); |