]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-20392 Add default mappings in github_perms_mapping
authorAurelien Poscia <aurelien.poscia@sonarsource.com>
Fri, 8 Sep 2023 10:05:00 +0000 (12:05 +0200)
committersonartech <sonartech@sonarsource.com>
Fri, 15 Sep 2023 20:03:05 +0000 (20:03 +0000)
server/sonar-db-dao/src/schema/schema-sq.ddl
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTable.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTable.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/DbVersion103.java
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMapping.java [new file with mode: 0644]
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/CreateGithubPermissionsMappingTableTest.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTableTest.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingTest.java [new file with mode: 0644]
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v103/CreateUniqueIndexForGithubPermissionsMappingTableTest/schema.sql
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingTest/schema.sql [new file with mode: 0644]

index 94c89f05103c106436b0ac4be0709923462b7f84..79d702ed08723d8b0ff41998f3325a4424ac587e 100644 (file)
@@ -360,10 +360,10 @@ ALTER TABLE "GITHUB_ORGS_GROUPS" ADD CONSTRAINT "PK_GITHUB_ORGS_GROUPS" PRIMARY
 CREATE TABLE "GITHUB_PERMS_MAPPING"(
     "UUID" CHARACTER VARYING(40) NOT NULL,
     "GITHUB_ROLE" CHARACTER VARYING(100) NOT NULL,
-    "SONARQUBE_ROLE" CHARACTER VARYING(64) NOT NULL
+    "SONARQUBE_PERMISSION" CHARACTER VARYING(64) NOT NULL
 );
 ALTER TABLE "GITHUB_PERMS_MAPPING" ADD CONSTRAINT "PK_GITHUB_PERMS_MAPPING" PRIMARY KEY("UUID");
-CREATE UNIQUE NULLS DISTINCT INDEX "UNIQ_GITHUB_PERM_MAPPINGS" ON "GITHUB_PERMS_MAPPING"("GITHUB_ROLE" NULLS FIRST, "SONARQUBE_ROLE" NULLS FIRST);
+CREATE UNIQUE NULLS DISTINCT INDEX "UNIQ_GITHUB_PERM_MAPPINGS" ON "GITHUB_PERMS_MAPPING"("GITHUB_ROLE" NULLS FIRST, "SONARQUBE_PERMISSION" NULLS FIRST);
 
 CREATE TABLE "GROUP_ROLES"(
     "UUID" CHARACTER VARYING(40) NOT NULL,
index eca8bc73781edfd88aa5dc644b4aef476474fb88..57dc63eb641ceedc49e56d7f4c2d7e179ee15733 100644 (file)
@@ -31,7 +31,7 @@ import static org.sonar.server.platform.db.migration.def.VarcharColumnDef.newVar
 public class CreateGithubPermissionsMappingTable extends CreateTableChange {
   static final String GITHUB_PERMISSIONS_MAPPING_TABLE_NAME = "github_perms_mapping";
   static final String GITHUB_ROLE_COLUMN = "github_role";
-  static final String SONARQUBE_ROLE_COLUMN = "sonarqube_role";
+  static final String SONARQUBE_PERMISSION_COLUMN = "sonarqube_permission";
 
   public CreateGithubPermissionsMappingTable(Database db) {
     super(db, GITHUB_PERMISSIONS_MAPPING_TABLE_NAME);
@@ -42,7 +42,7 @@ public class CreateGithubPermissionsMappingTable extends CreateTableChange {
     context.execute(new CreateTableBuilder(getDialect(), tableName)
       .addPkColumn(newVarcharColumnDefBuilder().setColumnName("uuid").setIsNullable(false).setLimit(UUID_SIZE).build())
       .addColumn(newVarcharColumnDefBuilder().setColumnName(GITHUB_ROLE_COLUMN).setIsNullable(false).setLimit(100).build())
-      .addColumn(newVarcharColumnDefBuilder().setColumnName(SONARQUBE_ROLE_COLUMN).setIsNullable(false).setLimit(64).build())
+      .addColumn(newVarcharColumnDefBuilder().setColumnName(SONARQUBE_PERMISSION_COLUMN).setIsNullable(false).setLimit(64).build())
       .build());
   }
 }
index d285b81b796948b4267c0adb01a579f3be6f7b8d..7be92b7c9b1f2c505b6ced711568d6ae27236b6d 100644 (file)
@@ -29,7 +29,7 @@ import org.sonar.server.platform.db.migration.step.DdlChange;
 
 import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME;
 import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_ROLE_COLUMN;
-import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.SONARQUBE_ROLE_COLUMN;
+import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.SONARQUBE_PERMISSION_COLUMN;
 
 public class CreateUniqueIndexForGithubPermissionsMappingTable extends DdlChange {
 
@@ -53,7 +53,7 @@ public class CreateUniqueIndexForGithubPermissionsMappingTable extends DdlChange
         .setTable(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME)
         .setName(INDEX_NAME)
         .addColumn(GITHUB_ROLE_COLUMN)
-        .addColumn(SONARQUBE_ROLE_COLUMN)
+        .addColumn(SONARQUBE_PERMISSION_COLUMN)
         .setUnique(true)
         .build());
     }
index ef11b1480d428a14a195ada2923433ac01ac6d50..e7f216fae9bf81457cf770c6317f0469c8b90b59 100644 (file)
@@ -44,6 +44,7 @@ public class DbVersion103 implements DbVersion {
       .add(10_3_000, "Set 'sonar.qualityProfiles.allowDisableInheritedRules' to false for upgraded instances", SetAllowQualityProfileDisableInheritedRules.class)
       .add(10_3_001, "Add table 'github_perms_mapping'", CreateGithubPermissionsMappingTable.class)
       .add(10_3_002, "Create unique index on 'github_perms_mapping'", CreateUniqueIndexForGithubPermissionsMappingTable.class)
+      .add(10_3_003, "Add default mappings to 'github_perms_mapping'", PopulateGithubPermissionsMapping.class)
     ;
   }
 }
diff --git a/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMapping.java b/server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMapping.java
new file mode 100644 (file)
index 0000000..f9f4b62
--- /dev/null
@@ -0,0 +1,95 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v103;
+
+import java.sql.SQLException;
+import java.util.Map;
+import java.util.Optional;
+import java.util.Set;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.step.DataChange;
+import org.sonar.server.platform.db.migration.step.Select;
+import org.sonar.server.platform.db.migration.step.Upsert;
+
+import static org.sonar.api.web.UserRole.ADMIN;
+import static org.sonar.api.web.UserRole.CODEVIEWER;
+import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
+import static org.sonar.api.web.UserRole.SCAN;
+import static org.sonar.api.web.UserRole.SECURITYHOTSPOT_ADMIN;
+import static org.sonar.api.web.UserRole.USER;
+
+public class PopulateGithubPermissionsMapping extends DataChange {
+
+  private static final Map<String, Set<String>> GITHUB_ROLE_TO_SQ_PERMISSIONS = Map.of(
+    "read", Set.of(USER, CODEVIEWER),
+    "triage", Set.of(USER, CODEVIEWER),
+    "write", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN),
+    "maintain", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN),
+    "admin", Set.of(USER, CODEVIEWER, ISSUE_ADMIN, SECURITYHOTSPOT_ADMIN, SCAN, ADMIN)
+  );
+
+  private static final String INSERT_QUERY = """
+    insert into github_perms_mapping (uuid, github_role, sonarqube_permission)
+    values (?, ?, ?)
+    """;
+
+  private final UuidFactory uuidFactory;
+
+  public PopulateGithubPermissionsMapping(Database db, UuidFactory uuidFactory) {
+    super(db);
+    this.uuidFactory = uuidFactory;
+  }
+
+  @Override
+  protected void execute(Context context) throws SQLException {
+    if (isDefaultMappingAlreadyDefined(context)) {
+      return;
+    }
+    try (Upsert upsert = context.prepareUpsert(INSERT_QUERY)) {
+      GITHUB_ROLE_TO_SQ_PERMISSIONS.forEach((key, value) -> insertGithubRoleToSonarqubePermissionMapping(upsert, key, value));
+      upsert.commit();
+    }
+  }
+
+  private void insertGithubRoleToSonarqubePermissionMapping(Upsert upsert, String githubRole, Set<String> sonarqubePermissions) {
+    sonarqubePermissions.forEach(permission -> insertGithubRoleToSonarqubePermissionMapping(upsert, githubRole, permission));
+  }
+
+  private void insertGithubRoleToSonarqubePermissionMapping(Upsert upsert, String githubRole, String sonarqubePermission) {
+    try {
+      upsert
+        .setString(1, uuidFactory.create())
+        .setString(2, githubRole)
+        .setString(3, sonarqubePermission)
+        .execute();
+    } catch (SQLException e) {
+      throw new IllegalStateException(e);
+    }
+  }
+
+  private static boolean isDefaultMappingAlreadyDefined(Context context) throws SQLException {
+    try (Select select = context.prepareSelect("select count(*) from github_perms_mapping")) {
+      return Optional.ofNullable(select.get(t -> t.getInt(1) > 0))
+        .orElseThrow();
+    }
+  }
+
+}
index 52155bcc787fbcf0c74405fd290b02ef3842e9d2..3e0cd7038dab221b684804f1f53a33341dca993b 100644 (file)
@@ -44,7 +44,7 @@ public class CreateGithubPermissionsMappingTableTest {
     db.assertTableExists(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME);
     db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "uuid", Types.VARCHAR, UUID_SIZE, false);
     db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "github_role", Types.VARCHAR, 100, false);
-    db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "sonarqube_role", Types.VARCHAR, 64, false);
+    db.assertColumnDefinition(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "sonarqube_permission", Types.VARCHAR, 64, false);
     db.assertPrimaryKey(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, "pk_github_perms_mapping", "uuid");
   }
 
index 7e7420572d8a3774bf4f7e438c0e0e4a5abc5d3b..0e0f26059caaf838677e151716665049173f715d 100644 (file)
@@ -26,7 +26,7 @@ import org.sonar.db.CoreDbTester;
 
 import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME;
 import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_ROLE_COLUMN;
-import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.SONARQUBE_ROLE_COLUMN;
+import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.SONARQUBE_PERMISSION_COLUMN;
 import static org.sonar.server.platform.db.migration.version.v103.CreateUniqueIndexForGithubPermissionsMappingTable.INDEX_NAME;
 
 public class CreateUniqueIndexForGithubPermissionsMappingTableTest {
@@ -41,7 +41,7 @@ public class CreateUniqueIndexForGithubPermissionsMappingTableTest {
 
     createIndex.execute();
 
-    db.assertUniqueIndex(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, GITHUB_ROLE_COLUMN, SONARQUBE_ROLE_COLUMN);
+    db.assertUniqueIndex(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, GITHUB_ROLE_COLUMN, SONARQUBE_PERMISSION_COLUMN);
   }
 
   @Test
@@ -49,6 +49,6 @@ public class CreateUniqueIndexForGithubPermissionsMappingTableTest {
     createIndex.execute();
     createIndex.execute();
 
-    db.assertUniqueIndex(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, GITHUB_ROLE_COLUMN, SONARQUBE_ROLE_COLUMN);
+    db.assertUniqueIndex(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME, INDEX_NAME, GITHUB_ROLE_COLUMN, SONARQUBE_PERMISSION_COLUMN);
   }
 }
diff --git a/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingTest.java b/server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingTest.java
new file mode 100644 (file)
index 0000000..2c15509
--- /dev/null
@@ -0,0 +1,100 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2023 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.v103;
+
+import java.sql.SQLException;
+import org.junit.Rule;
+import org.junit.Test;
+import org.sonar.api.testfixtures.log.LogTester;
+import org.sonar.core.util.UuidFactoryFast;
+import org.sonar.db.CoreDbTester;
+
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.tuple;
+import static org.sonar.server.platform.db.migration.version.v103.CreateGithubPermissionsMappingTable.GITHUB_PERMISSIONS_MAPPING_TABLE_NAME;
+
+public class PopulateGithubPermissionsMappingTest {
+
+  @Rule
+  public final CoreDbTester db = CoreDbTester.createForSchema(PopulateGithubPermissionsMappingTest.class, "schema.sql");
+
+  @Rule
+  public LogTester logTester = new LogTester();
+
+  private final PopulateGithubPermissionsMapping migration = new PopulateGithubPermissionsMapping(db.database(), UuidFactoryFast.getInstance());
+
+  @Test
+  public void execute_whenTableAlreadyPopulated_doesNothing() throws SQLException {
+    db.executeInsert(GITHUB_PERMISSIONS_MAPPING_TABLE_NAME,
+      "UUID", UuidFactoryFast.getInstance().create(),
+      "github_role", "gh_role",
+      "sonarqube_permission", "sq_perm");
+
+    migration.execute();
+
+    assertThat(db.select("select github_role, sonarqube_permission from github_perms_mapping"))
+      .extracting(stringObjectMap -> stringObjectMap.get("GITHUB_ROLE"), stringObjectMap -> stringObjectMap.get("SONARQUBE_PERMISSION"))
+      .containsExactly(tuple("gh_role", "sq_perm"));
+  }
+
+  @Test
+  public void execute_whenTableIsEmpty_shouldPopulate() throws SQLException {
+    migration.execute();
+
+    verifyMapping();
+  }
+
+  @Test
+  public void execute_isReentrant() throws SQLException {
+    migration.execute();
+    migration.execute();
+    migration.execute();
+
+    verifyMapping();
+  }
+
+  private void verifyMapping() {
+    assertThat(db.select("select github_role, sonarqube_permission from github_perms_mapping"))
+      .extracting(stringObjectMap -> stringObjectMap.get("GITHUB_ROLE"), stringObjectMap -> stringObjectMap.get("SONARQUBE_PERMISSION"))
+      .containsExactlyInAnyOrder(
+        tuple("read", "codeviewer"),
+        tuple("read", "user"),
+        tuple("triage", "codeviewer"),
+        tuple("triage", "user"),
+        tuple("write", "codeviewer"),
+        tuple("write", "user"),
+        tuple("write", "issueadmin"),
+        tuple("write", "securityhotspotadmin"),
+        tuple("write", "scan"),
+        tuple("maintain", "codeviewer"),
+        tuple("maintain", "user"),
+        tuple("maintain", "issueadmin"),
+        tuple("maintain", "securityhotspotadmin"),
+        tuple("maintain", "scan"),
+        tuple("admin", "codeviewer"),
+        tuple("admin", "user"),
+        tuple("admin", "issueadmin"),
+        tuple("admin", "securityhotspotadmin"),
+        tuple("admin", "scan"),
+        tuple("admin", "admin")
+      );
+  }
+
+}
index 5b5efb5c97f1cfd4ef75ac2f6a233d2cf8b28b76..be58344838d621e411a2d57fbaa3dadcd4c3171c 100644 (file)
@@ -1,6 +1,6 @@
 CREATE TABLE "GITHUB_PERMS_MAPPING"(
     "UUID" CHARACTER VARYING(40) NOT NULL,
     "GITHUB_ROLE" CHARACTER VARYING(100) NOT NULL,
-    "SONARQUBE_ROLE" CHARACTER VARYING(64) NOT NULL
+    "SONARQUBE_PERMISSION" CHARACTER VARYING(64) NOT NULL
 );
 ALTER TABLE "GITHUB_PERMS_MAPPING" ADD CONSTRAINT "PK_GITHUB_PERMS_MAPPING" PRIMARY KEY("UUID");
diff --git a/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingTest/schema.sql b/server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v103/PopulateGithubPermissionsMappingTest/schema.sql
new file mode 100644 (file)
index 0000000..42fc4f9
--- /dev/null
@@ -0,0 +1,7 @@
+CREATE TABLE "GITHUB_PERMS_MAPPING"(
+    "UUID" CHARACTER VARYING(40) NOT NULL,
+    "GITHUB_ROLE" CHARACTER VARYING(100) NOT NULL,
+    "SONARQUBE_PERMISSION" CHARACTER VARYING(64) NOT NULL
+);
+ALTER TABLE "GITHUB_PERMS_MAPPING" ADD CONSTRAINT "PK_GITHUB_PERMS_MAPPING" PRIMARY KEY("UUID");
+CREATE UNIQUE INDEX "UNIQ_GITHUB_PERM_MAPPINGS" ON "GITHUB_PERMS_MAPPING"("GITHUB_ROLE" NULLS FIRST, "SONARQUBE_PERMISSION" NULLS FIRST);