]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-11951 Prevent deleting all projects when using api/projects/bulk_delete without...
authorPierre Guillot <pierre.guillot@sonarsource.com>
Wed, 15 May 2019 09:20:13 +0000 (11:20 +0200)
committerSonarTech <sonartech@sonarsource.com>
Fri, 17 May 2019 18:21:08 +0000 (20:21 +0200)
server/sonar-server/src/main/java/org/sonar/server/project/ws/BulkDeleteAction.java
server/sonar-server/src/test/java/org/sonar/server/project/ws/BulkDeleteActionTest.java

index 8d006f612075caf66258bd2087911855ec9672aa..1d55087544c6699d6392b1e4c2e06d2dcf27a62a 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.project.ws;
 
+import com.google.common.base.Strings;
 import java.util.List;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -40,7 +41,9 @@ import org.sonar.server.project.ProjectLifeCycleListeners;
 import org.sonar.server.project.Visibility;
 import org.sonar.server.user.UserSession;
 
+import static com.google.common.base.Preconditions.checkArgument;
 import static java.lang.Math.min;
+import static java.lang.String.format;
 import static org.sonar.api.resources.Qualifiers.APP;
 import static org.sonar.api.resources.Qualifiers.PROJECT;
 import static org.sonar.api.resources.Qualifiers.VIEW;
@@ -85,7 +88,9 @@ public class BulkDeleteAction implements ProjectsWsAction {
         "Requires 'Administer System' permission.")
       .setSince("5.2")
       .setHandler(this)
-      .setChangelog(new Change("6.7.2", "Only the 1'000 first items in project filters are taken into account"));
+      .setChangelog(
+        new Change("7.8", format("parameters are optionals, but at least one is required among %s, %s and %s", PARAM_ANALYZED_BEFORE, PARAM_PROJECTS, Param.TEXT_QUERY)),
+        new Change("6.7.2", "Only the 1'000 first items in project filters are taken into account"));
 
     support.addOrganizationParam(action);
 
@@ -140,9 +145,12 @@ public class BulkDeleteAction implements ProjectsWsAction {
   public void handle(Request request, Response response) throws Exception {
     SearchRequest searchRequest = toSearchWsRequest(request);
     userSession.checkLoggedIn();
+
+
     try (DbSession dbSession = dbClient.openSession(false)) {
       OrganizationDto organization = support.getOrganization(dbSession, searchRequest.getOrganization());
       userSession.checkPermission(OrganizationPermission.ADMINISTER, organization);
+      checkAtLeastOneParameterIsPresent(searchRequest);
 
       ComponentQuery query = buildDbQuery(searchRequest);
       List<ComponentDto> componentDtos = dbClient.componentDao().selectByQuery(dbSession, organization.getUuid(), query, 0, Integer.MAX_VALUE);
@@ -155,6 +163,18 @@ public class BulkDeleteAction implements ProjectsWsAction {
     response.noContent();
   }
 
+  private void checkAtLeastOneParameterIsPresent(SearchRequest searchRequest) {
+    boolean analyzedBeforePresent = !Strings.isNullOrEmpty(searchRequest.getAnalyzedBefore());
+    List<String> projects = searchRequest.getProjects();
+    boolean projectsPresent = projects != null && !projects.isEmpty();
+    List<String> projectIds = searchRequest.getProjectIds();
+    boolean projectIdsPresent = projectIds != null && !projectIds.isEmpty();
+    boolean queryPresent = !Strings.isNullOrEmpty(searchRequest.getQuery());
+    boolean atLeastOneParameterIsPresent = analyzedBeforePresent || projectsPresent || queryPresent || projectIdsPresent;
+
+    checkArgument(atLeastOneParameterIsPresent, format("At lease one parameter among %s, %s, %s, and %s must be provided", PARAM_ANALYZED_BEFORE, PARAM_PROJECTS, PARAM_PROJECT_IDS, Param.TEXT_QUERY));
+  }
+
   private static SearchRequest toSearchWsRequest(Request request) {
     return SearchRequest.builder()
       .setOrganization(request.param(PARAM_ORGANIZATION))
index b018e0603520b1577a55703c1abf084acff7f93e..8c2bcf62e25a31bbcd0fb9d78119f06f738d7c09 100644 (file)
@@ -26,6 +26,7 @@ import java.util.List;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
+import java.util.stream.Stream;
 import org.apache.commons.lang.StringUtils;
 import org.junit.Before;
 import org.junit.Rule;
@@ -128,6 +129,22 @@ public class BulkDeleteActionTest {
     verifyListenersOnProjectsDeleted(toDeleteInOrg1, toDeleteInOrg2);
   }
 
+  @Test
+  public void throw_IllegalArgumentException_if_request_without_any_parameters(){
+    userSession.logIn().setRoot();
+    db.components().insertPrivateProject(org1);
+
+    expectedException.expect(IllegalArgumentException.class);
+    expectedException.expectMessage("At lease one parameter among analyzedBefore, projects, projectIds, and q must be provided");
+
+    try {
+      ws.newRequest().execute();
+    } finally {
+      verifyNoDeletions();
+      verifyZeroInteractions(projectLifeCycleListeners);
+    }
+  }
+
   @Test
   public void projects_that_dont_exist_are_ignored_and_dont_break_bulk_deletion() {
     userSession.logIn().setRoot();
@@ -169,7 +186,7 @@ public class BulkDeleteActionTest {
     ComponentDto analyzedProject = db.components().insertPrivateProject();
     db.components().insertSnapshot(newAnalysis(analyzedProject));
 
-    ws.newRequest().setParam(PARAM_ON_PROVISIONED_ONLY, "true").execute();
+    ws.newRequest().setParam(PARAM_PROJECTS, provisionedProject.getKey() + "," + analyzedProject.getKey()).setParam(PARAM_ON_PROVISIONED_ONLY, "true").execute();
 
     verifyDeleted(provisionedProject);
     verifyListenersOnProjectsDeleted(provisionedProject);
@@ -180,7 +197,8 @@ public class BulkDeleteActionTest {
     userSession.logIn().addPermission(ADMINISTER, db.getDefaultOrganization());
     ComponentDto[] projects = IntStream.range(0, 55).mapToObj(i -> db.components().insertPrivateProject()).toArray(ComponentDto[]::new);
 
-    ws.newRequest().execute();
+    List<String> projectKeys = Stream.of(projects).map(ComponentDto::getKey).collect(Collectors.toList());
+    ws.newRequest().setParam(PARAM_PROJECTS, String.join(",", projectKeys)).execute();
 
     verifyDeleted(projects);
     verifyListenersOnProjectsDeleted(projects);
@@ -192,7 +210,10 @@ public class BulkDeleteActionTest {
     ComponentDto project = db.components().insertPrivateProject();
     ComponentDto view = db.components().insertView();
 
-    ws.newRequest().setParam(PARAM_QUALIFIERS, String.join(",", Qualifiers.PROJECT, Qualifiers.VIEW)).execute();
+    ws.newRequest()
+      .setParam(PARAM_PROJECTS, project.getKey() + "," + view.getKey())
+      .setParam(PARAM_QUALIFIERS, String.join(",", Qualifiers.PROJECT, Qualifiers.VIEW))
+      .execute();
 
     verifyDeleted(project, view);
     verifyListenersOnProjectsDeleted(project, view);