aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-05-18 10:16:34 +0200
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>2016-05-18 17:42:20 +0200
commita0bbadad133d1ab014cbce1b775c54ac367d7862 (patch)
tree383fee75c8b6937c01cb5bc325e36b681b6a7cc7
parent2b68ee77eeda3926a78d79fab7a9f208a5df9de1 (diff)
downloadsonarqube-a0bbadad133d1ab014cbce1b775c54ac367d7862.tar.gz
sonarqube-a0bbadad133d1ab014cbce1b775c54ac367d7862.zip
SONAR-7278 fail /api/batch/project if component is not a project
neither a module
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java14
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java110
2 files changed, 124 insertions, 0 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java
index 7228cdb4aa1..32e1f90a7e7 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/batch/ProjectDataLoader.java
@@ -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
index 00000000000..cc3683e6098
--- /dev/null
+++ b/server/sonar-server/src/test/java/org/sonar/server/batch/ProjectDataLoaderTest.java
@@ -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");
+ }
+ }
+ }
+}