]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-15579 Improve error verbosity on permission template matching key collision...
authorKlaudio Sinani <klaudio.sinani@sonarsource.com>
Mon, 8 Nov 2021 16:56:58 +0000 (17:56 +0100)
committersonartech <sonartech@sonarsource.com>
Tue, 9 Nov 2021 20:03:15 +0000 (20:03 +0000)
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateDbTester.java
server/sonar-db-dao/src/testFixtures/java/org/sonar/db/permission/template/PermissionTemplateTesting.java
server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/TemplateMatchingKeyException.java [new file with mode: 0644]
server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/TemplateMatchingKeyExceptionTest.java [new file with mode: 0644]
server/sonar-webserver-webapi/src/main/java/org/sonar/server/permission/PermissionTemplateService.java
server/sonar-webserver-webapi/src/test/java/org/sonar/server/permission/PermissionTemplateServiceTest.java
server/sonar-webserver-ws/src/main/java/org/sonar/server/ws/WebServiceEngine.java

index 96500a78418c0b9f5fbe62c5c9dd18c0869b3d7f..6f1c4cc41a70f97b562c5cf34426f20ef69bea09 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.db.permission.template;
 
+import java.util.function.Consumer;
 import javax.annotation.Nullable;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -59,8 +60,9 @@ public class PermissionTemplateDbTester {
       ofNullable(portfoliosDefaultTemplate).map(PermissionTemplateDto::getUuid).orElse(null));
   }
 
-  public PermissionTemplateDto insertTemplate() {
-    return insertTemplate(newPermissionTemplateDto());
+  @SafeVarargs
+  public final PermissionTemplateDto insertTemplate(Consumer<PermissionTemplateDto>... populators) {
+    return insertTemplate(newPermissionTemplateDto(populators));
   }
 
   public PermissionTemplateDto insertTemplate(PermissionTemplateDto template) {
index 7f66840d1a6eb5c2e627d6cbc16340cb60b00ae9..61279e233ec745d271d009c20253d0a18c71a527 100644 (file)
 package org.sonar.db.permission.template;
 
 import java.util.Date;
+import java.util.function.Consumer;
 import org.apache.commons.lang.math.RandomUtils;
 import org.sonar.core.util.Uuids;
 import org.sonar.db.permission.PermissionsTestHelper;
 
+import static java.util.Arrays.stream;
 import static org.apache.commons.lang.RandomStringUtils.randomAlphanumeric;
 import static org.apache.commons.lang.RandomStringUtils.randomAscii;
 
 public class PermissionTemplateTesting {
-  public static PermissionTemplateDto newPermissionTemplateDto() {
-    return new PermissionTemplateDto()
+  @SafeVarargs
+  public static PermissionTemplateDto newPermissionTemplateDto(Consumer<PermissionTemplateDto>... populators) {
+    PermissionTemplateDto dto = new PermissionTemplateDto()
       .setName(randomAlphanumeric(60))
       .setDescription(randomAscii(500))
       .setUuid(Uuids.create())
       .setCreatedAt(new Date())
       .setUpdatedAt(new Date());
+    stream(populators).forEach(p -> p.accept(dto));
+    return dto;
   }
 
   public static PermissionTemplateUserDto newPermissionTemplateUserDto() {
diff --git a/server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/TemplateMatchingKeyException.java b/server/sonar-webserver-api/src/main/java/org/sonar/server/exceptions/TemplateMatchingKeyException.java
new file mode 100644 (file)
index 0000000..b296dd6
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.exceptions;
+
+  import com.google.common.base.MoreObjects;
+  import java.util.List;
+
+  import static java.net.HttpURLConnection.HTTP_BAD_REQUEST;
+  import static java.util.Collections.singletonList;
+
+/**
+ * Provided request is not valid due to Permission template matching key collision.
+ */
+public class TemplateMatchingKeyException extends ServerException {
+  private final transient List<String> errors;
+
+  public TemplateMatchingKeyException(String errorMessage) {
+    super(HTTP_BAD_REQUEST, errorMessage);
+    this.errors = singletonList(errorMessage);
+  }
+
+  public List<String> errors() {
+    return this.errors;
+  }
+
+  @Override
+  public String toString() {
+    return MoreObjects.toStringHelper(this)
+      .add("errors", this.errors())
+      .toString();
+  }
+
+}
+
diff --git a/server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/TemplateMatchingKeyExceptionTest.java b/server/sonar-webserver-api/src/test/java/org/sonar/server/exceptions/TemplateMatchingKeyExceptionTest.java
new file mode 100644 (file)
index 0000000..e68355a
--- /dev/null
@@ -0,0 +1,35 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2021 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.exceptions;
+
+import org.junit.Test;
+
+import static org.assertj.core.api.Assertions.assertThat;
+
+public class TemplateMatchingKeyExceptionTest {
+
+  @Test
+  public void testMethods() {
+    TemplateMatchingKeyException ex = new TemplateMatchingKeyException("error");
+
+    assertThat(ex).hasToString("TemplateMatchingKeyException{errors=[error]}");
+  }
+
+}
index 487cf1cfa674f68a66e443c0487c6486ce02f590..e3f684c7b9d8a2a324311792d9fa0a388c13bd45 100644 (file)
@@ -46,6 +46,7 @@ import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserId;
 import org.sonar.server.es.ProjectIndexer;
 import org.sonar.server.es.ProjectIndexers;
+import org.sonar.server.exceptions.TemplateMatchingKeyException;
 import org.sonar.server.permission.DefaultTemplatesResolver.ResolvedDefaultTemplates;
 import org.sonar.server.user.UserSession;
 
@@ -230,7 +231,7 @@ public class PermissionTemplateService {
           templatesNames.append(", ");
         }
       }
-      throw new IllegalStateException(MessageFormat.format(
+      throw new TemplateMatchingKeyException(MessageFormat.format(
         "The \"{0}\" key matches multiple permission templates: {1}."
           + " A system administrator must update these templates so that only one of them matches the key.",
         componentKey,
index aa55361ae541b17f8631ebce9b87988862b93689..b8e68cfd14d1adf048a7bbd4d63a6b85a6866c08 100644 (file)
@@ -20,6 +20,8 @@
 package org.sonar.server.permission;
 
 import java.util.List;
+import java.util.stream.Collectors;
+import java.util.stream.Stream;
 import javax.annotation.Nullable;
 import org.junit.Rule;
 import org.junit.Test;
@@ -36,10 +38,12 @@ import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.es.ProjectIndexers;
 import org.sonar.server.es.TestProjectIndexers;
+import org.sonar.server.exceptions.TemplateMatchingKeyException;
 import org.sonar.server.tester.UserSessionRule;
 
 import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
+import static org.assertj.core.api.Assertions.assertThatThrownBy;
 import static org.sonar.api.resources.Qualifiers.APP;
 import static org.sonar.api.resources.Qualifiers.PROJECT;
 import static org.sonar.api.resources.Qualifiers.VIEW;
@@ -63,6 +67,7 @@ public class PermissionTemplateServiceTest {
   private final ProjectIndexers projectIndexers = new TestProjectIndexers();
   private final PermissionTemplateService underTest = new PermissionTemplateService(dbTester.getDbClient(), projectIndexers, userSession, defaultTemplatesResolver,
     new SequenceUuidFactory());
+  private ComponentDto privateProject;
 
   @Test
   public void apply_does_not_insert_permission_to_group_AnyOne_when_applying_template_on_private_project() {
@@ -452,6 +457,29 @@ public class PermissionTemplateServiceTest {
     checkWouldUserHaveScanPermission(null, false);
   }
 
+  @Test
+  public void apply_permission_template_with_key_pattern_collision() {
+    final String key = "hi-test";
+    final String keyPattern = ".*-test";
+
+    Stream<PermissionTemplateDto> templates = Stream.of(
+      templateDb.insertTemplate(t -> t.setKeyPattern(keyPattern)),
+      templateDb.insertTemplate(t -> t.setKeyPattern(keyPattern))
+    );
+
+    String templateNames = templates
+      .map(PermissionTemplateDto::getName)
+      .sorted(String.CASE_INSENSITIVE_ORDER)
+      .map(x -> String.format("\"%s\"", x))
+      .collect(Collectors.joining(", "));
+
+    ComponentDto project = dbTester.components().insertPrivateProject(p -> p.setDbKey(key));
+
+    assertThatThrownBy(() -> underTest.applyDefaultToNewComponent(session, project, null))
+      .isInstanceOf(TemplateMatchingKeyException.class)
+      .hasMessageContaining("The \"%s\" key matches multiple permission templates: %s.", key, templateNames);
+  }
+
   private void checkWouldUserHaveScanPermission(@Nullable String userUuid, boolean expectedResult) {
     assertThat(underTest.wouldUserHaveScanPermissionWithDefaultTemplate(session, userUuid, "PROJECT_KEY"))
       .isEqualTo(expectedResult);
index 52082613569347a0664bae603de24e1c23bcc56a..5ba171e5ccf2166264280c614fa34b32845d2ffc 100644 (file)
@@ -37,8 +37,8 @@ import org.sonar.api.server.ws.WebService;
 import org.sonar.api.utils.log.Logger;
 import org.sonar.api.utils.log.Loggers;
 import org.sonar.api.utils.text.JsonWriter;
-import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.BadConfigurationException;
+import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ServerException;
 import org.sonarqube.ws.MediaTypes;