]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7278 fail /api/batch/project if component is not a project
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 18 May 2016 08:16:34 +0000 (10:16 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Wed, 18 May 2016 15:42:20 +0000 (17:42 +0200)
neither a module

server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java
server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java [new file with mode: 0644]

index 7228cdb4aa1ba4343026120ea7a88da83ce50676..32e1f90a7e72990d722494ce13cc26598eed1906 100644 (file)
@@ -26,6 +26,8 @@ import java.util.Collections;
 import java.util.Date;
 import java.util.List;
 import java.util.Map;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
 import org.sonar.api.server.ServerSide;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
@@ -35,11 +37,13 @@ import org.sonar.db.component.FilePathWithHashDto;
 import org.sonar.db.property.PropertyDto;
 import org.sonar.scanner.protocol.input.FileData;
 import org.sonar.scanner.protocol.input.ProjectRepositories;
+import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.user.UserSession;
 
 import static com.google.common.collect.Lists.newArrayList;
 import static com.google.common.collect.Maps.newHashMap;
+import static java.lang.String.format;
 import static org.sonar.api.web.UserRole.USER;
 import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
 import static org.sonar.server.ws.WsUtils.checkFoundWithOptional;
@@ -61,6 +65,9 @@ public class ProjectDataLoader {
       ProjectRepositories data = new ProjectRepositories();
       ComponentDto module = checkFoundWithOptional(dbClient.componentDao().selectByKey(session, query.getModuleKey()),
         "Project or module with key '%s' is not found", query.getModuleKey());
+      if (!isProjectOrModule(module)) {
+        throw new BadRequestException(format("Key '%s' belongs to a component which is not a Project", query.getModuleKey()));
+      }
 
       boolean hasScanPerm = userSession.hasComponentUuidPermission(SCAN_EXECUTION, module.projectUuid());
       boolean hasBrowsePerm = userSession.hasComponentUuidPermission(USER, module.projectUuid());
@@ -92,6 +99,13 @@ public class ProjectDataLoader {
     }
   }
 
+  private static boolean isProjectOrModule(ComponentDto module) {
+    if (!Scopes.PROJECT.equals(module.scope())) {
+      return false;
+    }
+    return Qualifiers.PROJECT.equals(module.qualifier()) || Qualifiers.MODULE.equals(module.qualifier());
+  }
+
   private List<FilePathWithHashDto> searchFilesWithHashAndRevision(DbSession session, ComponentDto module) {
     return module.isRootProject() ? dbClient.componentDao().selectEnabledFilesFromProject(session, module.uuid())
       : dbClient.componentDao().selectEnabledDescendantFiles(session, module.uuid());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java
new file mode 100644 (file)
index 0000000..cc3683e
--- /dev/null
@@ -0,0 +1,110 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact 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.batch;
+
+import org.assertj.core.api.Assertions;
+import org.junit.After;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.rules.ExpectedException;
+import org.sonar.api.resources.Qualifiers;
+import org.sonar.api.resources.Scopes;
+import org.sonar.api.utils.System2;
+import org.sonar.db.DbClient;
+import org.sonar.db.DbSession;
+import org.sonar.db.DbTester;
+import org.sonar.db.component.ComponentDto;
+import org.sonar.server.exceptions.BadRequestException;
+import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.server.user.UserSession;
+
+import static java.lang.String.format;
+import static org.junit.Assert.fail;
+import static org.mockito.Mockito.mock;
+
+public class ProjectDataLoaderTest {
+  @Rule
+  public final DbTester dbTester = DbTester.create(System2.INSTANCE);
+  @Rule
+  public ExpectedException expectedException = ExpectedException.none();
+
+  private DbClient dbClient = dbTester.getDbClient();
+  private DbSession dbSession = dbTester.getSession();
+
+  private ProjectDataLoader underTest = new ProjectDataLoader(dbClient, mock(UserSession.class));
+
+  @After
+  public void tearDown() throws Exception {
+    dbSession.close();
+  }
+
+  @Test
+  public void load_fails_with_NPE_if_query_is_null() {
+    expectedException.expect(NullPointerException.class);
+
+    underTest.load(null);
+  }
+
+  @Test
+  public void load_fails_with_NFE_if_query_is_empty() {
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage("Project or module with key 'null' is not found");
+
+    underTest.load(ProjectDataQuery.create());
+  }
+
+  @Test
+  public void load_fails_with_NFE_if_component_does_not_exist() {
+    String key = "theKey";
+
+    expectedException.expect(NotFoundException.class);
+    expectedException.expectMessage("Project or module with key '" + key + "' is not found");
+
+    underTest.load(ProjectDataQuery.create().setModuleKey(key));
+  }
+
+  @Test
+  public void load_fails_with_BRE_if_component_is_neither_a_project_or_a_module() {
+    String[][] allScopesAndQualifierButProjectAndModule = {
+      {Scopes.PROJECT, Qualifiers.VIEW},
+      {Scopes.PROJECT, Qualifiers.SUBVIEW},
+      {Scopes.FILE, Qualifiers.PROJECT},
+      {Scopes.DIRECTORY, Qualifiers.DIRECTORY},
+      {Scopes.FILE, Qualifiers.UNIT_TEST_FILE},
+      {Scopes.PROJECT, "DEV"},
+      {Scopes.PROJECT, "DEV_PRJ"}
+    };
+
+    for (String[] scopeAndQualifier : allScopesAndQualifierButProjectAndModule) {
+      String scope = scopeAndQualifier[0];
+      String qualifier = scopeAndQualifier[1];
+      String key = "theKey_" + scope + "_" + qualifier;
+      dbClient.componentDao().insert(dbSession, new ComponentDto().setScope(scope).setQualifier(qualifier).setKey(key));
+      dbSession.commit();
+
+      try {
+        underTest.load(ProjectDataQuery.create().setModuleKey(key));
+        fail(format("A NotFoundException should have been raised because scope (%s) or qualifier (%s) is not project", scope, qualifier));
+      } catch (BadRequestException e) {
+        Assertions.assertThat(e).hasMessage("Key '" + key + "' belongs to a component which is not a Project");
+      }
+    }
+  }
+}