aboutsummaryrefslogtreecommitdiffstats
path: root/server/sonar-db-migration/src
diff options
context:
space:
mode:
authorEric Hartmann <hartmann.eric@gmail.com>2018-09-20 13:39:34 +0200
committerSonarTech <sonartech@sonarsource.com>2018-10-10 20:20:57 +0200
commitd933f38f5f0d4b2b19bbbc7474973ed8721486ed (patch)
tree0001476971630e5a53e4655349063eec9960a96e /server/sonar-db-migration/src
parent4d159788f0d56b73d178e686be74a903d71ea2fd (diff)
downloadsonarqube-d933f38f5f0d4b2b19bbbc7474973ed8721486ed.tar.gz
sonarqube-d933f38f5f0d4b2b19bbbc7474973ed8721486ed.zip
SONAR-11271 Add migration to create new permissions
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/CreateApplicationsAndPortfoliosCreatorPermissions.java103
-rw-r--r--server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74.java1
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest.java213
-rw-r--r--server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74Test.java2
-rw-r--r--server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest/perm_templates_groups.sql49
5 files changed, 367 insertions, 1 deletions
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissions.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissions.java
new file mode 100644
index 00000000000..c72291a09ba
--- /dev/null
+++ b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissions.java
@@ -0,0 +1,103 @@
+/*
+ * 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 org.sonar.api.security.DefaultGroups;
+import org.sonar.api.utils.System2;
+import org.sonar.api.utils.log.Logger;
+import org.sonar.api.utils.log.Loggers;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.SupportsBlueGreen;
+import org.sonar.server.platform.db.migration.step.DataChange;
+
+import java.sql.SQLException;
+import java.util.Date;
+
+@SupportsBlueGreen
+public class CreateApplicationsAndPortfoliosCreatorPermissions extends DataChange {
+
+ private static final Logger LOG = Loggers.get(CreateApplicationsAndPortfoliosCreatorPermissions.class);
+ private static final String DEFAULT_ORGANIZATION_KEY = "default-organization";
+
+ private final System2 system2;
+
+ public CreateApplicationsAndPortfoliosCreatorPermissions(Database db, System2 system2) {
+ super(db);
+ this.system2 = system2;
+ }
+
+ @Override
+ protected void execute(Context context) throws SQLException {
+ Date now = new Date(system2.now());
+ Long adminGroupId = context.prepareSelect("SELECT id FROM groups WHERE name=?")
+ .setString(1, DefaultGroups.ADMINISTRATORS)
+ .get(row -> row.getLong(1));
+ String templateKey = context.prepareSelect("SELECT default_perm_template_view FROM organizations WHERE kee=?")
+ .setString(1, DEFAULT_ORGANIZATION_KEY)
+ .get(row -> row.getString(1));
+
+ if (adminGroupId == null) {
+ LOG.info("Unable to find {} group. Skipping adding applications and portfolios creator permissions.", DefaultGroups.ADMINISTRATORS);
+ return;
+ }
+
+ if (templateKey == null) {
+ LOG.info("There is no default template for views. Skipping adding applications and portfolios creator permissions.");
+ }
+
+ Long templateId = context.prepareSelect("SELECT id FROM permission_templates WHERE kee=?")
+ .setString(1, templateKey)
+ .get(row -> row.getLong(1));
+
+ if (templateId == null) {
+ LOG.info("Unable to find the default template [{}] for views. Skipping adding applications and portfolios creator permissions.", templateKey);
+ return;
+ }
+
+ if (isPermissionAbsent(context, adminGroupId, "applicationcreator")) {
+ insertPermission(context, adminGroupId, templateId, "applicationcreator", now);
+ }
+
+ if (isPermissionAbsent(context, adminGroupId, "portfoliocreator")) {
+ insertPermission(context, adminGroupId, templateId, "portfoliocreator", now);
+ }
+ }
+
+ private static boolean isPermissionAbsent(Context context, Long groupId, String permission) throws SQLException {
+ Long count = context.prepareSelect("SELECT count(*) FROM perm_templates_groups WHERE group_id=? AND permission_reference=?")
+ .setLong(1, groupId)
+ .setString(2, permission)
+ .get(row -> (row.getLong(1)));
+
+ return (count == null) || count == 0;
+ }
+
+ private static void insertPermission(Context context, Long groupId, Long templateId, String permission, Date now) throws SQLException {
+ context.prepareUpsert("INSERT INTO perm_templates_groups (group_id, template_id, permission_reference, created_at, updated_at) values (?,?,?,?,?)")
+ .setLong(1, groupId)
+ .setLong(2, templateId)
+ .setString(3, permission)
+ .setDate(4, now)
+ .setDate(5, now)
+ .execute()
+ .commit();
+ }
+}
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 45186436a14..da1f3af2268 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
@@ -44,6 +44,7 @@ public class DbVersion74 implements DbVersion {
.add(2321, "Increase organization key and name length", IncreaseOrganizationsKeeAndNameLength.class)
.add(2322, "Create table CE_TASK_MESSAGE", CreateCeTaskMessage.class)
.add(2323, "Clean orphans from deleted branches and PRs in CE_* tables", CleanOrphanRowsInCeTables.class)
+ .add(2324, "Create new creator permissions for applications and portfolios", CreateApplicationsAndPortfoliosCreatorPermissions.class)
;
}
}
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest.java
new file mode 100644
index 00000000000..b9fe947e5ad
--- /dev/null
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest.java
@@ -0,0 +1,213 @@
+/*
+ * 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 org.assertj.core.groups.Tuple;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.utils.System2;
+import org.sonar.api.web.UserRole;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.groups.Tuple.tuple;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+public class CreateApplicationsAndPortfoliosCreatorPermissionsTest {
+ @Rule
+ public ExpectedException expectedException = ExpectedException.none();
+
+ @Rule
+ public CoreDbTester db = CoreDbTester.createForSchema(CreateApplicationsAndPortfoliosCreatorPermissionsTest.class, "perm_templates_groups.sql");
+
+ private static final Date PAST = new Date(100_000_000_000L);
+ private static final Date NOW = new Date(500_000_000_000L);
+ private static final String DEFAULT_ORGANIZATION_UUID = UuidFactoryFast.getInstance().create();
+ private static final String DEFAULT_PERM_TEMPLATE_VIEW = "default_view_template";
+ private static final String ANOTHER_PERM_TEMPLATE_VIEW = "another_template";
+
+ private System2 system2 = mock(System2.class);
+ private CreateApplicationsAndPortfoliosCreatorPermissions underTest = new CreateApplicationsAndPortfoliosCreatorPermissions(db.database(), system2);
+
+ @Before
+ public void setupDatabase() {
+ insertDefaultOrganization();
+ insertDefaultGroups();
+ insertPermissionTemplate();
+ }
+
+
+ @Test
+ public void migration_is_reentrant() throws SQLException {
+ when(system2.now()).thenReturn(NOW.getTime());
+
+ underTest.execute();
+ underTest.execute();
+
+ Long idOfDefaultPermissionTemplate = getIdOfPermissionTemplate(DEFAULT_PERM_TEMPLATE_VIEW);
+ Long idOfAdministratorGroup = getIdOfGroup("sonar-administrators");
+
+ assertPermTemplateGroupRoles(
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "applicationcreator", NOW, NOW),
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "portfoliocreator", NOW, NOW));
+ }
+
+ @Test
+ public void insert_missing_permissions() throws SQLException {
+ when(system2.now()).thenReturn(NOW.getTime());
+
+ underTest.execute();
+
+ Long idOfDefaultPermissionTemplate = getIdOfPermissionTemplate(DEFAULT_PERM_TEMPLATE_VIEW);
+ Long idOfAdministratorGroup = getIdOfGroup("sonar-administrators");
+
+ assertPermTemplateGroupRoles(
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "applicationcreator", NOW, NOW),
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "portfoliocreator", NOW, NOW));
+ }
+
+ @Test
+ public void does_nothing_if_template_group_has_the_permissions_already() throws SQLException {
+ Long idOfDefaultPermissionTemplate = getIdOfPermissionTemplate(DEFAULT_PERM_TEMPLATE_VIEW);
+ Long idOfAdministratorGroup = getIdOfGroup("sonar-administrators");
+
+ insertPermTemplateGroupRole(1, 2, "noissueadmin");
+ insertPermTemplateGroupRole(3, 4, "issueadmin");
+ insertPermTemplateGroupRole(3, 4, "another");
+ insertPermTemplateGroupRole(5, 6, "securityhotspotadmin");
+ insertPermTemplateGroupRole(idOfDefaultPermissionTemplate.intValue(), idOfAdministratorGroup.intValue(), "applicationcreator");
+ insertPermTemplateGroupRole(idOfDefaultPermissionTemplate.intValue(), idOfAdministratorGroup.intValue(), "portfoliocreator");
+
+ when(system2.now()).thenReturn(NOW.getTime());
+ underTest.execute();
+
+ assertPermTemplateGroupRoles(
+ tuple(1L, 2L, "noissueadmin", PAST, PAST),
+ tuple(3L, 4L, "issueadmin", PAST, PAST),
+ tuple(3L, 4L, "another", PAST, PAST),
+ tuple(5L, 6L, "securityhotspotadmin", PAST, PAST),
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "applicationcreator", PAST, PAST),
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "portfoliocreator", PAST, PAST));
+ }
+
+ @Test
+ public void insert_missing_permission_keeping_other_template_group_permissions() throws SQLException {
+ when(system2.now()).thenReturn(NOW.getTime());
+ insertPermTemplateGroupRole(1, 2, "noissueadmin");
+ insertPermTemplateGroupRole(3, 4, "issueadmin");
+ insertPermTemplateGroupRole(3, 4, "another");
+ insertPermTemplateGroupRole(5, 6, "securityhotspotadmin");
+
+ underTest.execute();
+
+ Long idOfDefaultPermissionTemplate = getIdOfPermissionTemplate(DEFAULT_PERM_TEMPLATE_VIEW);
+ Long idOfAdministratorGroup = getIdOfGroup("sonar-administrators");
+
+ assertPermTemplateGroupRoles(
+ tuple(1L, 2L, "noissueadmin", PAST, PAST),
+ tuple(3L, 4L, "issueadmin", PAST, PAST),
+ tuple(3L, 4L, "another", PAST, PAST),
+ tuple(5L, 6L, "securityhotspotadmin", PAST, PAST),
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "applicationcreator", NOW, NOW),
+ tuple(idOfDefaultPermissionTemplate, idOfAdministratorGroup, "portfoliocreator", NOW, NOW));
+ }
+
+ private void insertPermTemplateGroupRole(int templateId, int groupId, String role) {
+ db.executeInsert(
+ "PERM_TEMPLATES_GROUPS",
+ "TEMPLATE_ID", templateId,
+ "GROUP_ID", groupId,
+ "PERMISSION_REFERENCE", role,
+ "CREATED_AT", PAST,
+ "UPDATED_AT", PAST);
+ }
+
+ private void insertDefaultGroups() {
+ db.executeInsert(
+ "GROUPS",
+ "NAME", "sonar-administrators",
+ "CREATED_AT", PAST,
+ "UPDATED_AT", PAST,
+ "ORGANIZATION_UUID", DEFAULT_ORGANIZATION_UUID);
+ db.executeInsert(
+ "GROUPS",
+ "NAME", "sonar-users",
+ "CREATED_AT", PAST,
+ "UPDATED_AT", PAST,
+ "ORGANIZATION_UUID", DEFAULT_ORGANIZATION_UUID);
+ }
+
+ private void insertDefaultOrganization() {
+ db.executeInsert(
+ "ORGANIZATIONS",
+ "UUID", DEFAULT_ORGANIZATION_UUID,
+ "KEE", "default-organization",
+ "NAME", "Default Organization",
+ "GUARDED", true,
+ "DEFAULT_PERM_TEMPLATE_VIEW", DEFAULT_PERM_TEMPLATE_VIEW,
+ "DEFAULT_QUALITY_GATE_UUID", UuidFactoryFast.getInstance().create(),
+ "NEW_PROJECT_PRIVATE", false,
+ "SUBSCRIPTION", "SONARQUBE",
+ "CREATED_AT", PAST.getTime(),
+ "UPDATED_AT", PAST.getTime());
+ }
+
+ private void insertPermissionTemplate() {
+ db.executeInsert(
+ "PERMISSION_TEMPLATES",
+ "ORGANIZATION_UUID", DEFAULT_ORGANIZATION_UUID,
+ "NAME", "Default template for views",
+ "KEE", DEFAULT_PERM_TEMPLATE_VIEW,
+ "CREATED_AT", PAST,
+ "UPDATED_AT", PAST);
+ db.executeInsert(
+ "PERMISSION_TEMPLATES",
+ "ORGANIZATION_UUID", DEFAULT_ORGANIZATION_UUID,
+ "NAME", ANOTHER_PERM_TEMPLATE_VIEW,
+ "KEE", ANOTHER_PERM_TEMPLATE_VIEW,
+ "CREATED_AT", PAST,
+ "UPDATED_AT", PAST);
+ }
+
+ private Long getIdOfPermissionTemplate(String key) {
+ return (Long) db.selectFirst("SELECT id FROM permission_templates WHERE kee='" + key + "'")
+ .get("ID");
+ }
+
+ private Long getIdOfGroup(String key) {
+ return (Long) db.selectFirst("SELECT id FROM groups WHERE name='" + key + "'")
+ .get("ID");
+ }
+
+ private void assertPermTemplateGroupRoles(Tuple... expectedTuples) {
+ assertThat(db.select("SELECT TEMPLATE_ID, GROUP_ID, PERMISSION_REFERENCE, CREATED_AT, UPDATED_AT FROM PERM_TEMPLATES_GROUPS")
+ .stream()
+ .map(map -> new Tuple(map.get("TEMPLATE_ID"), map.get("GROUP_ID"), map.get("PERMISSION_REFERENCE"), map.get("CREATED_AT"), 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/v74/DbVersion74Test.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74Test.java
index b67fedaffea..5064842d84d 100644
--- a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74Test.java
+++ b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v74/DbVersion74Test.java
@@ -35,6 +35,6 @@ public class DbVersion74Test {
@Test
public void verify_migration_count() {
- verifyMigrationCount(underTest, 17);
+ verifyMigrationCount(underTest, 18);
}
}
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest/perm_templates_groups.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest/perm_templates_groups.sql
new file mode 100644
index 00000000000..0a8c29211f0
--- /dev/null
+++ b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v74/CreateApplicationsAndPortfoliosCreatorPermissionsTest/perm_templates_groups.sql
@@ -0,0 +1,49 @@
+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 "PERMISSION_TEMPLATES" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "ORGANIZATION_UUID" VARCHAR(40) NOT NULL,
+ "NAME" VARCHAR(100) NOT NULL,
+ "KEE" VARCHAR(100) NOT NULL,
+ "DESCRIPTION" VARCHAR(4000),
+ "KEY_PATTERN" VARCHAR(500),
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "PERM_TEMPLATES_GROUPS" (
+ "ID" INTEGER NOT NULL GENERATED BY DEFAULT AS IDENTITY (START WITH 1, INCREMENT BY 1),
+ "GROUP_ID" INTEGER,
+ "TEMPLATE_ID" INTEGER NOT NULL,
+ "PERMISSION_REFERENCE" VARCHAR(64) NOT NULL,
+ "CREATED_AT" TIMESTAMP,
+ "UPDATED_AT" TIMESTAMP
+);
+
+CREATE TABLE "ORGANIZATIONS" (
+ "UUID" VARCHAR(40) NOT NULL,
+ "KEE" VARCHAR(32) NOT NULL,
+ "NAME" VARCHAR(64) NOT NULL,
+ "DESCRIPTION" VARCHAR(256),
+ "URL" VARCHAR(256),
+ "AVATAR_URL" VARCHAR(256),
+ "GUARDED" BOOLEAN NOT NULL,
+ "DEFAULT_PERM_TEMPLATE_PROJECT" VARCHAR(40),
+ "DEFAULT_PERM_TEMPLATE_VIEW" VARCHAR(40),
+ "DEFAULT_GROUP_ID" INTEGER,
+ "DEFAULT_QUALITY_GATE_UUID" VARCHAR(40) NOT NULL,
+ "NEW_PROJECT_PRIVATE" BOOLEAN NOT NULL,
+ "SUBSCRIPTION" VARCHAR(40) NOT NULL,
+ "CREATED_AT" BIGINT NOT NULL,
+ "UPDATED_AT" BIGINT NOT NULL,
+
+ CONSTRAINT "PK_ORGANIZATIONS" PRIMARY KEY ("UUID")
+);
+CREATE UNIQUE INDEX "ORGANIZATION_KEY" ON "ORGANIZATIONS" ("KEE");