aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-migration/src
diff options
context:
space:
mode:
authorEric Hartmann <hartmann.eric@gmail.com>2018-10-09 07:38:37 +0200
committerSonarTech <sonartech@sonarsource.com>2018-10-10 20:20:58 +0200
commit924ce6095da8a1116727639e2c3771a4d5dc391f (patch)
tree6a1943b41a0d8e5cef49f8a0aa29cacd559afbd4 /server/sonar-db-migration/src
parentd989b1803ffbbb038065e6c5843f88bce5d31096 (diff)
downloadsonarqube-924ce6095da8a1116727639e2c3771a4d5dc391f.tar.gz
sonarqube-924ce6095da8a1116727639e2c3771a4d5dc391f.zip
SONAR-11271 Add application and portfolio creator to sonar-administrators group
Diffstat (limited to 'server/sonar-db-migration/src')
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator.java82
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74.java4
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest.java149
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest/group_roles_and_internal_properties.sql36
4 files changed, 269 insertions, 2 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator.java
new file mode 100644
index 00000000000..32e8512cd50
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator.java
@@ -0,0 +1,82 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import java.sql.SQLException;
+import org.sonar.api.config.Configuration;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.version.v63.DefaultOrganizationUuidProvider;
+
+@SupportsBlueGreen
+public class AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator extends DataChange {
+
+ private final Configuration configuration;
+ private final DefaultOrganizationUuidProvider defaultOrganizationUuidProvider;
+
+ public AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator(Database db, Configuration configuration,
+ DefaultOrganizationUuidProvider defaultOrganizationUuidProvider) {
+ super(db);
+ this.configuration = configuration;
+ this.defaultOrganizationUuidProvider = defaultOrganizationUuidProvider;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ if (configuration.getBoolean("sonar.sonarcloud.enabled").orElse(false)) {
+ // Nothing to do on SonarCloud
+ return;
+ }
+
+ Integer sonarAdmGroupId = context.prepareSelect("select ID from GROUPS where name=?")
+ .setString(1, "sonar-administrators")
+ .get(r -> r.getInt(1));
+
+ if (sonarAdmGroupId == null) {
+ // We cannot find the default sonar-administrators groups
+ return;
+ }
+
+ insertPermissionIfMissing(context, sonarAdmGroupId, "applicationcreator");
+ insertPermissionIfMissing(context, sonarAdmGroupId, "portfoliocreator");
+ }
+
+ private void insertPermissionIfMissing(Context context, Integer sonarAdmGroupId, String role) throws SQLException {
+ if (isPermissionMissing(context, sonarAdmGroupId, role)) {
+ context.prepareUpsert("insert into GROUP_ROLES(ORGANIZATION_UUID, GROUP_ID, ROLE) values(?, ?, ?)")
+ .setString(1, defaultOrganizationUuidProvider.get(context))
+ .setInt(2, sonarAdmGroupId)
+ .setString(3, role)
+ .execute()
+ .commit();
+ }
+ }
+
+ private static boolean isPermissionMissing(Context context, Integer sonarAdmGroupId, String role) throws SQLException {
+ Integer count = context.prepareSelect("select count(ID) from GROUP_ROLES where GROUP_ID=? and ROLE=?")
+ .setInt(1, sonarAdmGroupId)
+ .setString(2, role)
+ .get(r -> r.getInt(1));
+
+ return count == null || count == 0;
+ }
+}
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74.java
index 285adb6a2f4..b092e76abdc 100644
--- a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74.java
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74.java
@@ -47,8 +47,8 @@ public class DbVersion74 implements DbVersion {
.add(2324, "Create new creator permissions for applications and portfolios", CreateApplicationsAndPortfoliosCreatorPermissions.class)
.add(2325, "Add default templates for applications and portfolios", AddDefaultPermTemplateColumnsToOrganizations.class)
.add(2326, "Create new creator permissions for applications and portfolios", CreateApplicationsAndPortfoliosCreatorPermissions.class)
- .add(2327, "Add default templates for applications and portfolios", AddDefaultPermTemplateColumnsToOrganizations.class)
- .add(2328, "Populate default template permissions on organizations", PopulateDefaultPermTemplateOnOrganizations.class)
+ .add(2327, "Populate default template permissions on organizations", PopulateDefaultPermTemplateOnOrganizations.class)
+ .add(2328, "Add portfolio and application creator permissions on sonar-administrators group", AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator.class)
;
}
}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest.java
new file mode 100644
index 00000000000..b9908b7889e
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest.java
@@ -0,0 +1,149 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2018 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.v74;
+
+import java.sql.SQLException;
+import java.util.Date;
+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.config.internal.MapSettings;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+import org.sonar.server.platform.db.migration.version.v63.DefaultOrganizationUuidProvider;
+import org.sonar.server.platform.db.migration.version.v63.DefaultOrganizationUuidProviderImpl;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+
+public class AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest {
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest.class,
+ "group_roles_and_internal_properties.sql");
+
+ private UuidFactoryFast uuidFactoryFast = UuidFactoryFast.getInstance();
+ private MapSettings settings = new MapSettings();
+ private DefaultOrganizationUuidProvider defaultOrganizationUuidProvider = new DefaultOrganizationUuidProviderImpl();
+ private AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator underTest = new AddApplicationCreatorAndPortfolioCreatorToSonarAdministrator(db.database(), settings.asConfig(),
+ defaultOrganizationUuidProvider);
+
+ @Test
+ public void is_reentrant() throws SQLException {
+ String orgUuid = uuidFactoryFast.create();
+ insertDefaultOrganizationUuid(orgUuid);
+ insertGroup(orgUuid, "sonar-administrators");
+ Long adminGroupId = getGroupId("sonar-administrators");
+
+ underTest.execute();
+ underTest.execute();
+
+ assertGroupRoles(
+ tuple(orgUuid, adminGroupId, null, "applicationcreator"),
+ tuple(orgUuid, adminGroupId, null, "portfoliocreator"));
+ }
+
+ @Test
+ public void create_missing_permissions() throws SQLException {
+ String orgUuid = uuidFactoryFast.create();
+ insertDefaultOrganizationUuid(orgUuid);
+ insertGroup(orgUuid, "sonar-administrators");
+ Long adminGroupId = getGroupId("sonar-administrators");
+
+ underTest.execute();
+
+ assertGroupRoles(
+ tuple(orgUuid, adminGroupId, null, "applicationcreator"),
+ tuple(orgUuid, adminGroupId, null, "portfoliocreator"));
+ }
+
+ @Test
+ public void has_no_effect_if_group_does_not_exist() throws SQLException {
+ String orgUuid = uuidFactoryFast.create();
+ insertDefaultOrganizationUuid(orgUuid);
+ insertGroup(orgUuid, "sonar");
+
+ underTest.execute();
+
+ assertGroupRoles();
+ }
+
+ @Test
+ public void has_no_effect_if_roles_are_already_present() throws SQLException {
+ String orgUuid = uuidFactoryFast.create();
+ insertDefaultOrganizationUuid(orgUuid);
+ insertGroup(orgUuid, "sonar-administrators");
+ Long adminGroupId = getGroupId("sonar-administrators");
+ insertGroupRole(orgUuid, adminGroupId, null, "applicationcreator");
+ insertGroupRole(orgUuid, adminGroupId, null, "portfoliocreator");
+
+ underTest.execute();
+
+ assertGroupRoles(
+ tuple(orgUuid, adminGroupId, null, "applicationcreator"),
+ tuple(orgUuid, adminGroupId, null, "portfoliocreator"));
+ }
+
+ @Test
+ public void has_no_effect_on_SonarCloud() throws SQLException {
+ settings.setProperty("sonar.sonarcloud.enabled", true);
+ underTest.execute();
+ assertGroupRoles();
+ }
+
+ private void insertDefaultOrganizationUuid(String uuid) {
+ db.executeInsert("INTERNAL_PROPERTIES",
+ "KEE", "organization.default",
+ "IS_EMPTY", false,
+ "TEXT_VALUE", uuid,
+ "CREATED_AT", System.currentTimeMillis());
+ }
+
+ private void insertGroup(String organizationUuid, String name) {
+ db.executeInsert("GROUPS",
+ "ORGANIZATION_UUID", organizationUuid,
+ "NAME", name,
+ "CREATED_AT", new Date(),
+ "UPDATED_AT", new Date());
+ }
+
+ private void insertGroupRole(String organizationUuid, @Nullable Long groupId, @Nullable Integer resourceId, String role) {
+ db.executeInsert("GROUP_ROLES",
+ "ORGANIZATION_UUID", organizationUuid,
+ "GROUP_ID", groupId,
+ "RESOURCE_ID", resourceId,
+ "ROLE", role);
+ }
+
+ private Long getGroupId(String groupName) {
+ return (Long) db.selectFirst("SELECT id FROM groups WHERE name = '" + groupName + "'").get("ID");
+ }
+
+ private void assertGroupRoles(Tuple... expectedTuples) {
+ assertThat(db.select("SELECT organization_uuid, group_id, resource_id, role FROM group_roles")
+ .stream()
+ .map(row -> new Tuple(row.get("ORGANIZATION_UUID"), row.get("GROUP_ID"), row.get("RESOURCE_ID"), row.get("ROLE")))
+ .collect(Collectors.toList()))
+ .containsExactlyInAnyOrder(expectedTuples);
+ }
+}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest/group_roles_and_internal_properties.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest/group_roles_and_internal_properties.sql
new file mode 100644
index 00000000000..8871f93bca8
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/AddApplicationCreatorAndPortfolioCreatorToSonarAdministratorTest/group_roles_and_internal_properties.sql
@@ -0,0 +1,36 @@
+CREATE TABLE "PROPERTIES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "PROP_KEY" VARCHAR(512),
+ "RESOURCE_ID" INTEGER,
+ "TEXT_VALUE" CLOB(2147483647),
+ "USER_ID" INTEGER
+);
+
+CREATE TABLE "INTERNAL_PROPERTIES" (
+ "KEE" VARCHAR(50) NOT NULL PRIMARY KEY,
+ "IS_EMPTY" BOOLEAN NOT NULL,
+ "TEXT_VALUE" VARCHAR(4000),
+ "CLOB_VALUE" CLOB,
+ "CREATED_AT" BIGINT
+);
+
+CREATE UNIQUE INDEX "UNIQ_INTERNAL_PROPERTIES" ON "INTERNAL_PROPERTIES" ("KEE");
+
+CREATE TABLE "GROUPS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+ "NAME" VARCHAR(500),
+ "DESCRIPTION" VARCHAR(200),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "GROUP_ROLES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+ "GROUP_ID" INTEGER,
+ "RESOURCE_ID" INTEGER,
+ "ROLE" VARCHAR(64) NOT NULL
+);
+CREATE INDEX "GROUP_ROLES_RESOURCE" ON "GROUP_ROLES" ("RESOURCE_ID");
+CREATE UNIQUE INDEX "UNIQ_GROUP_ROLES" ON "GROUP_ROLES" ("ORGANIZATION_UUID", "GROUP_ID", "RESOURCE_ID", "ROLE");