]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-10407 Fix upgrade of too long permision_templates keys
authorEric Hartmann <hartmann.eric@gmail.com>
Fri, 9 Feb 2018 15:17:21 +0000 (16:17 +0100)
committerEric Hartmann <hartmann.eric@gmail.Com>
Tue, 13 Feb 2018 07:31:32 +0000 (08:31 +0100)
server/sonar-db-migration/src/main/java/org/sonar/server/platform/db/migration/version/v63/PopulateDefaultPermTemplateColumnsOfOrganizations.java
server/sonar-db-migration/src/test/java/org/sonar/server/platform/db/migration/version/v63/PopulateDefaultPermTemplateColumnsOfOrganizationsTest.java
server/sonar-db-migration/src/test/resources/org/sonar/server/platform/db/migration/version/v63/PopulateDefaultPermTemplateColumnsOfOrganizationsTest/properties_and_organizations.sql

index f39e51601ff38cc98db00179a113a6b030716fae..6987e11e768817f8b4ad13df8ad0d87880036505 100644 (file)
@@ -22,8 +22,11 @@ package org.sonar.server.platform.db.migration.version.v63;
 import java.sql.SQLException;
 import java.util.HashMap;
 import java.util.Map;
+import javax.annotation.Nullable;
 import org.sonar.api.utils.log.Loggers;
+import org.sonar.core.util.UuidFactory;
 import org.sonar.db.Database;
+import org.sonar.server.platform.db.migration.def.VarcharColumnDef;
 import org.sonar.server.platform.db.migration.step.DataChange;
 
 import static com.google.common.base.MoreObjects.firstNonNull;
@@ -49,10 +52,12 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizations extends DataChang
   private static final String DEFAULT_DEV_TEMPLATE_PROPERTY = "sonar.permission.template.DEV.default";
 
   private final DefaultOrganizationUuidProvider defaultOrganizationUuid;
+  private final UuidFactory uuidFactory;
 
-  public PopulateDefaultPermTemplateColumnsOfOrganizations(Database db, DefaultOrganizationUuidProvider defaultOrganizationUuid) {
+  public PopulateDefaultPermTemplateColumnsOfOrganizations(Database db, DefaultOrganizationUuidProvider defaultOrganizationUuid, UuidFactory uuidFactory) {
     super(db);
     this.defaultOrganizationUuid = defaultOrganizationUuid;
+    this.uuidFactory = uuidFactory;
   }
 
   @Override
@@ -67,8 +72,10 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizations extends DataChang
       // DB has just been created, default template of default organization will be populated by a startup task
       return;
     }
-    String projectDefaultTemplate = firstNonNull(defaultTemplateProperties.get(DEFAULT_PROJECT_TEMPLATE_PROPERTY), globalDefaultTemplate);
-    String viewDefaultTemplate = defaultTemplateProperties.get(DEFAULT_VIEW_TEMPLATE_PROPERTY);
+    String projectDefaultTemplate = updateKeeIfRequired(context,
+      firstNonNull(defaultTemplateProperties.get(DEFAULT_PROJECT_TEMPLATE_PROPERTY), globalDefaultTemplate));
+    String viewDefaultTemplate = updateKeeIfRequired(context,
+      defaultTemplateProperties.get(DEFAULT_VIEW_TEMPLATE_PROPERTY));
 
     Loggers.get(PopulateDefaultPermTemplateColumnsOfOrganizations.class)
       .debug("Setting default templates on default organization '{}': project='{}', view='{}'",
@@ -95,6 +102,23 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizations extends DataChang
       .commit();
   }
 
+  /**
+   * SONAR-10407 Ensure that the kee length is not greater than 40
+   * In this case, we must update the kee to a UUID
+   */
+  private String updateKeeIfRequired(Context context, @Nullable String kee) throws SQLException {
+    if (kee == null || kee.length() <= VarcharColumnDef.UUID_SIZE) {
+      return kee;
+    }
+
+    String newKee = uuidFactory.create();
+    context.prepareUpsert("update permission_templates set kee=? where kee=?")
+      .setString(1, newKee)
+      .setString(2, kee)
+      .execute();
+    return newKee;
+  }
+
   private static void ensureOnlyDefaultOrganizationExists(Context context, String defaultOrganizationUuid) throws SQLException {
     Integer otherOrganizationCount = context.prepareSelect("select count(*) from organizations where uuid <> ?")
       .setString(1, defaultOrganizationUuid)
index 9b37b2ebf36500f6bbf70df902c8c17f2473c22b..fc60ca1d117944e1ab544a3d4d323df671d809c1 100644 (file)
  */
 package org.sonar.server.platform.db.migration.version.v63;
 
+import com.google.common.collect.ImmutableList;
 import java.sql.SQLException;
+import java.sql.Timestamp;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Map;
 import javax.annotation.Nullable;
+import org.junit.After;
 import org.junit.Rule;
 import org.junit.Test;
 import org.junit.rules.ExpectedException;
+import org.sonar.core.util.UuidFactory;
+import org.sonar.core.util.UuidFactoryFast;
 import org.sonar.db.CoreDbTester;
 
+import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.assertj.core.api.Assertions.assertThat;
 
 public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
@@ -41,8 +49,14 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
   @Rule
   public ExpectedException expectedException = ExpectedException.none();
 
+  private RecordingUuidFactory recordingUuidFactory = new RecordingUuidFactory();
   private PopulateDefaultPermTemplateColumnsOfOrganizations underTest = new PopulateDefaultPermTemplateColumnsOfOrganizations(dbTester.database(),
-    new DefaultOrganizationUuidProviderImpl());
+    new DefaultOrganizationUuidProviderImpl(), recordingUuidFactory);
+
+  @After
+  public void clearRecordingUuidFactory() {
+    recordingUuidFactory.clear();
+  }
 
   @Test
   public void fails_with_ISE_when_no_default_organization_is_set() throws SQLException {
@@ -120,6 +134,44 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
     verifyPropertiesDoNotExist();
   }
 
+  @Test
+  public void execute_should_update_kee_when_old_kee_is_too_long() throws SQLException {
+    setupDefaultOrganization();
+    insertProperty(DEFAULT_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(100)));
+    insertProperty(DEFAULT_VIEW_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(100)));
+    insertProperty(DEFAULT_PROJECT_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(100)));
+    insertProperty(DEFAULT_DEV_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(100)));
+
+    underTest.execute();
+
+    verifyTemplateColumns(recordingUuidFactory.getRecordedUuids().get(0), recordingUuidFactory.getRecordedUuids().get(1));
+    verifyPropertiesDoNotExist();
+    verifyExistenceOfPermissionTemplate(recordingUuidFactory.getRecordedUuids().get(0));
+    verifyExistenceOfPermissionTemplate(recordingUuidFactory.getRecordedUuids().get(1));
+  }
+
+  @Test
+  public void execute_should_update_kee_only_when_old_kee_length_is_41_or_more() throws SQLException {
+    setupDefaultOrganization();
+    insertProperty(DEFAULT_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(40)));
+    insertProperty(DEFAULT_VIEW_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(40)));
+    insertProperty(DEFAULT_PROJECT_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(40)));
+    insertProperty(DEFAULT_DEV_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(40)));
+
+    underTest.execute();
+
+    assertThat(recordingUuidFactory.getRecordedUuids()).isEmpty();
+
+    insertProperty(DEFAULT_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(41)));
+    insertProperty(DEFAULT_VIEW_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(41)));
+    insertProperty(DEFAULT_PROJECT_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(41)));
+    insertProperty(DEFAULT_DEV_TEMPLATE_PROPERTY, insertPermissionTemplates(randomAlphanumeric(41)));
+
+    underTest.execute();
+
+    assertThat(recordingUuidFactory.getRecordedUuids()).hasSize(2);
+  }
+
   @Test
   public void execute_sets_project_from_project_property_and_view_from_view_property_when_all_properties_are_defined() throws SQLException {
     setupDefaultOrganization();
@@ -153,6 +205,16 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
     assertThat(row.get("viewDefaultPermTemplate")).isEqualTo(view);
   }
 
+  @Test
+  public void migration_is_reentrant() throws SQLException {
+    setupDefaultOrganization();
+    insertProperty(DEFAULT_TEMPLATE_PROPERTY, "foo");
+
+    underTest.execute();
+
+    underTest.execute();
+  }
+
   private void verifyPropertiesDoNotExist() {
     verifyPropertyDoesNotExist(DEFAULT_TEMPLATE_PROPERTY);
     verifyPropertyDoesNotExist(DEFAULT_PROJECT_TEMPLATE_PROPERTY);
@@ -165,14 +227,8 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
       .isEqualTo(0);
   }
 
-  @Test
-  public void migration_is_reentrant() throws SQLException {
-    setupDefaultOrganization();
-    insertProperty(DEFAULT_TEMPLATE_PROPERTY, "foo");
-
-    underTest.execute();
-
-    underTest.execute();
+  private void verifyExistenceOfPermissionTemplate(String kee) {
+    assertThat(dbTester.countSql("select count(kee) from permission_templates where kee='" + kee +"'")).isEqualTo(1);
   }
 
   private void setupDefaultOrganization() {
@@ -190,6 +246,20 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
       "UPDATED_AT", "1000");
   }
 
+  private String insertPermissionTemplates(String kee) {
+    dbTester.executeInsert(
+      "PERMISSION_TEMPLATES",
+      "ORGANIZATION_UUID", DEFAULT_ORGANIZATION_UUID,
+      "NAME", randomAlphanumeric(50),
+      "KEE", kee,
+      "DESCRIPTION", randomAlphanumeric(500),
+      "KEY_PATTERN", "",
+      "CREATED_AT", new Timestamp(1000L),
+      "UPDATED_AT", new Timestamp(1000L));
+
+    return kee;
+  }
+
   private void insertDefaultOrganizationUuid(String defaultOrganizationUuid) {
     dbTester.executeInsert(
       "INTERNAL_PROPERTIES",
@@ -205,4 +275,24 @@ public class PopulateDefaultPermTemplateColumnsOfOrganizationsTest {
       "IS_EMPTY", String.valueOf(value == null),
       "TEXT_VALUE", value);
   }
+
+  private static final class RecordingUuidFactory implements UuidFactory {
+    private final List<String> generatedUuids = new ArrayList<>();
+    private final UuidFactory uuidFactory = UuidFactoryFast.getInstance();
+
+    @Override
+    public String create() {
+      String uuid = uuidFactory.create();
+      generatedUuids.add(uuid);
+      return uuid;
+    }
+
+    public void clear() {
+      generatedUuids.clear();
+    }
+
+    public List<String> getRecordedUuids() {
+      return ImmutableList.copyOf(generatedUuids);
+    }
+  }
 }
index 056ce7cd9ef0a7aa263966e19e8fc50f29af8d1a..d6b052f42e219ff0ca93a79cb1e1bdff66f8a2f0 100644 (file)
@@ -34,3 +34,14 @@ CREATE TABLE "INTERNAL_PROPERTIES" (
   "CREATED_AT" BIGINT
 );
 CREATE UNIQUE INDEX "UNIQ_INTERNAL_PROPERTIES" ON "INTERNAL_PROPERTIES" ("KEE");
+
+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
+);