aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSimon Brandhof <simon.brandhof@sonarsource.com>2017-02-21 14:29:40 +0100
committerSimon Brandhof <simon.brandhof@sonarsource.com>2017-02-21 20:46:05 +0100
commit730daa2870ac4b1a40b6dd8e067d21f72c720f2d (patch)
tree6069e59a1cda6e7c38b0e143faceee0bc6bda268
parentabd5b2343c27d317357ed25e10b22343d490bc03 (diff)
downloadsonarqube-730daa2870ac4b1a40b6dd8e067d21f72c720f2d.tar.gz
sonarqube-730daa2870ac4b1a40b6dd8e067d21f72c720f2d.zip
SONAR-8704 allow roots to see all projects and measures
even if they don't have the expected permissions
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java6
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/project/ws/IndexAction.java8
-rw-r--r--server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java6
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java18
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchActionTest.java53
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/project/ws/IndexActionTest.java23
-rw-r--r--server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java16
8 files changed, 112 insertions, 24 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
index 79d794ca6b5..d9a9dd48a01 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/component/ws/SearchAction.java
@@ -160,6 +160,12 @@ public class SearchAction implements ComponentsWsAction {
}
private List<ComponentDto> filterAuthorizedComponents(DbSession dbSession, List<ComponentDto> componentDtos) {
+ if (userSession.isRoot()) {
+ // the method AuthorizationDao#keepAuthorizedProjectIds() should be replaced by
+ // a call to UserSession, which would transparently support roots.
+ // Meanwhile root is explicitly handled.
+ return componentDtos;
+ }
Set<String> projectUuids = componentDtos.stream().map(ComponentDto::projectUuid).collect(Collectors.toSet());
List<ComponentDto> projects = dbClient.componentDao().selectByUuids(dbSession, projectUuids);
Map<String, Long> projectIdsByUuids = projects.stream().collect(uniqueIndex(ComponentDto::uuid, ComponentDto::getId));
diff --git a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java
index 5b52b1cff15..d6be0710a10 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/measure/ws/SearchAction.java
@@ -137,6 +137,12 @@ public class SearchAction implements MeasuresWsAction {
}
private List<ComponentDto> getAuthorizedProjects(List<ComponentDto> projectDtos) {
+ if (userSession.isRoot()) {
+ // the method AuthorizationDao#keepAuthorizedProjectIds() should be replaced by
+ // a call to UserSession, which would transparently support roots.
+ // Meanwhile root is explicitly handled.
+ return projectDtos;
+ }
Map<String, Long> projectIdsByUuids = projectDtos.stream().collect(uniqueIndex(ComponentDto::uuid, ComponentDto::getId));
Set<Long> authorizedProjectIds = dbClient.authorizationDao().keepAuthorizedProjectIds(dbSession,
projectDtos.stream().map(ComponentDto::getId).collect(toList()),
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/IndexAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/IndexAction.java
index 91bd14e0899..3cc5576cfff 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/IndexAction.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/IndexAction.java
@@ -22,7 +22,6 @@ package org.sonar.server.project.ws;
import com.google.common.io.Resources;
import java.util.ArrayList;
import java.util.Collection;
-import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.Optional;
@@ -125,8 +124,11 @@ public class IndexAction implements ProjectsWsAction {
}
private List<ComponentDto> getAuthorizedComponents(DbSession dbSession, List<ComponentDto> components) {
- if (components.isEmpty()) {
- return Collections.emptyList();
+ if (userSession.isRoot() || components.isEmpty()) {
+ // the method AuthorizationDao#keepAuthorizedProjectIds() should be replaced by
+ // a call to UserSession, which would transparently support roots.
+ // Meanwhile root is explicitly handled.
+ return components;
}
Set<String> projectUuids = components.stream().map(ComponentDto::projectUuid).collect(Collectors.toSet());
List<ComponentDto> projects = dbClient.componentDao().selectByUuids(dbSession, projectUuids);
diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java
index b84860fe2c9..646c9890534 100644
--- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java
+++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/QgateProjectFinder.java
@@ -81,6 +81,12 @@ public class QgateProjectFinder {
}
private List<ProjectQgateAssociationDto> keepAuthorizedProjects(DbSession dbSession, List<ProjectQgateAssociationDto> projects) {
+ if (userSession.isRoot()) {
+ // the method AuthorizationDao#keepAuthorizedProjectIds() should be replaced by
+ // a call to UserSession, which would transparently support roots.
+ // Meanwhile root is explicitly handled.
+ return projects;
+ }
List<Long> projectIds = projects.stream().map(ProjectQgateAssociationDto::getId).collect(Collectors.toList());
Collection<Long> authorizedProjectIds = dbClient.authorizationDao().keepAuthorizedProjectIds(dbSession, projectIds, userSession.getUserId(), UserRole.USER);
return projects.stream().filter(project -> authorizedProjectIds.contains(project.getId())).collect(Collectors.toList());
diff --git a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
index f12883ad9d5..5f8bae83caf 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/component/ws/SearchActionTest.java
@@ -187,6 +187,24 @@ public class SearchActionTest {
}
@Test
+ public void do_not_verify_permissions_if_user_is_root() throws IOException {
+ OrganizationDto org = db.organizations().insert();
+ ComponentDto project1 = newProjectDto(org);
+ ComponentDto file1 = newFileDto(project1);
+ ComponentDto project2 = newProjectDto(org);
+ ComponentDto file2 = newFileDto(project2);
+ db.components().insertComponents(project1, file1, project2, file2);
+
+ SearchWsRequest request = new SearchWsRequest().setQualifiers(singletonList(FILE)).setOrganization(org.getKey());
+
+ userSession.logIn().setNonRoot();
+ assertThat(call(request).getComponentsCount()).isZero();
+
+ userSession.logIn().setRoot();
+ assertThat(call(request).getComponentsList()).extracting(Component::getKey).containsOnly(file1.getKey(), file2.getKey());
+ }
+
+ @Test
public void fail_if_unknown_qualifier_provided() {
expectedException.expect(IllegalArgumentException.class);
expectedException.expectMessage("Value of parameter 'qualifiers' (Unknown-Qualifier) must be one of: [BRC, DIR, FIL, TRK]");
diff --git a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchActionTest.java
index 76f81f68c7d..120da09a887 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/measure/ws/SearchActionTest.java
@@ -38,7 +38,6 @@ import org.sonar.api.web.UserRole;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
-import org.sonar.db.component.ComponentDbTester;
import org.sonar.db.component.ComponentDto;
import org.sonar.db.component.SnapshotDto;
import org.sonar.db.metric.MetricDto;
@@ -79,13 +78,10 @@ public class SearchActionTest {
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
- ComponentDbTester componentDb = new ComponentDbTester(db);
- DbClient dbClient = db.getDbClient();
- DbSession dbSession = db.getSession();
-
- UserDto user;
-
- WsActionTester ws = new WsActionTester(new SearchAction(userSession, dbClient));
+ private DbClient dbClient = db.getDbClient();
+ private DbSession dbSession = db.getSession();
+ private UserDto user;
+ private WsActionTester ws = new WsActionTester(new SearchAction(userSession, dbClient));
@Before
public void setUp() throws Exception {
@@ -109,7 +105,7 @@ public class SearchActionTest {
@Test
public void return_measures() throws Exception {
ComponentDto project = newProjectDto(db.getDefaultOrganization());
- SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(project);
+ SnapshotDto projectSnapshot = db.components().insertProjectAndSnapshot(project);
setBrowsePermissionOnUser(project);
MetricDto coverage = insertCoverageMetric();
dbClient.measureDao().insert(dbSession, newMeasureDto(coverage, project, projectSnapshot).setValue(15.5d));
@@ -127,7 +123,7 @@ public class SearchActionTest {
@Test
public void return_measures_on_leak_period() throws Exception {
ComponentDto project = newProjectDto(db.organizations().insert());
- SnapshotDto projectSnapshot = componentDb.insertProjectAndSnapshot(project);
+ SnapshotDto projectSnapshot = db.components().insertProjectAndSnapshot(project);
setBrowsePermissionOnUser(project);
MetricDto coverage = insertCoverageMetric();
dbClient.measureDao().insert(dbSession,
@@ -154,11 +150,11 @@ public class SearchActionTest {
MetricDto complexity = insertComplexityMetric();
OrganizationDto organizationDto = db.organizations().insert();
ComponentDto project1 = newProjectDto(organizationDto).setName("C");
- SnapshotDto projectSnapshot1 = componentDb.insertProjectAndSnapshot(project1);
+ SnapshotDto projectSnapshot1 = db.components().insertProjectAndSnapshot(project1);
ComponentDto project2 = newProjectDto(organizationDto).setName("A");
- SnapshotDto projectSnapshot2 = componentDb.insertProjectAndSnapshot(project2);
+ SnapshotDto projectSnapshot2 = db.components().insertProjectAndSnapshot(project2);
ComponentDto project3 = newProjectDto(organizationDto).setName("B");
- SnapshotDto projectSnapshot3 = componentDb.insertProjectAndSnapshot(project3);
+ SnapshotDto projectSnapshot3 = db.components().insertProjectAndSnapshot(project3);
setBrowsePermissionOnUser(project1, project2, project3);
dbClient.measureDao().insert(dbSession, newMeasureDto(coverage, project1, projectSnapshot1).setValue(5.5d));
dbClient.measureDao().insert(dbSession, newMeasureDto(coverage, project2, projectSnapshot2).setValue(6.5d));
@@ -180,9 +176,9 @@ public class SearchActionTest {
public void only_returns_authorized_projects() {
MetricDto metricDto = insertComplexityMetric();
ComponentDto project1 = newProjectDto(db.getDefaultOrganization());
- SnapshotDto projectSnapshot1 = componentDb.insertProjectAndSnapshot(project1);
+ SnapshotDto projectSnapshot1 = db.components().insertProjectAndSnapshot(project1);
ComponentDto project2 = newProjectDto(db.getDefaultOrganization());
- SnapshotDto projectSnapshot2 = componentDb.insertProjectAndSnapshot(project2);
+ SnapshotDto projectSnapshot2 = db.components().insertProjectAndSnapshot(project2);
dbClient.measureDao().insert(dbSession,
newMeasureDto(metricDto, project1, projectSnapshot1).setValue(15.5d),
newMeasureDto(metricDto, project2, projectSnapshot2).setValue(42.0d));
@@ -195,8 +191,25 @@ public class SearchActionTest {
}
@Test
+ public void do_not_verify_permissions_if_user_is_root() {
+ MetricDto metricDto = insertComplexityMetric();
+ ComponentDto project1 = newProjectDto(db.getDefaultOrganization());
+ SnapshotDto projectSnapshot1 = db.components().insertProjectAndSnapshot(project1);
+ dbClient.measureDao().insert(dbSession, newMeasureDto(metricDto, project1, projectSnapshot1).setValue(15.5d));
+ db.commit();
+
+ userSession.setNonRoot();
+ SearchWsResponse result = call(asList(project1.key()), singletonList("complexity"));
+ assertThat(result.getMeasuresCount()).isEqualTo(0);
+
+ userSession.setRoot();
+ result = call(asList(project1.key()), singletonList("complexity"));
+ assertThat(result.getMeasuresCount()).isEqualTo(1);
+ }
+
+ @Test
public void fail_if_no_metric() {
- ComponentDto project = componentDb.insertProject();
+ ComponentDto project = db.components().insertProject();
setBrowsePermissionOnUser(project);
expectedException.expect(IllegalArgumentException.class);
@@ -207,7 +220,7 @@ public class SearchActionTest {
@Test
public void fail_if_empty_metric() {
- ComponentDto project = componentDb.insertProject();
+ ComponentDto project = db.components().insertProject();
setBrowsePermissionOnUser(project);
expectedException.expect(IllegalArgumentException.class);
@@ -218,7 +231,7 @@ public class SearchActionTest {
@Test
public void fail_if_unknown_metric() {
- ComponentDto project = componentDb.insertProject();
+ ComponentDto project = db.components().insertProject();
setBrowsePermissionOnUser(project);
insertComplexityMetric();
@@ -251,7 +264,7 @@ public class SearchActionTest {
@Test
public void fail_if_more_than_100_project_keys() {
List<String> keys = IntStream.rangeClosed(1, 101)
- .mapToObj(i -> componentDb.insertProject())
+ .mapToObj(i -> db.components().insertProject())
.map(ComponentDto::key)
.collect(Collectors.toList());
insertComplexityMetric();
@@ -369,7 +382,7 @@ public class SearchActionTest {
ComponentDto project2 = newProjectDto(organizationDto).setKey("MY_PROJECT_2").setName("Project 2");
ComponentDto project3 = newProjectDto(organizationDto).setKey("MY_PROJECT_3").setName("Project 3");
projectKeys.addAll(asList(project1.key(), project2.key(), project3.key()));
- componentDb.insertComponents(project1, project2, project3);
+ db.components().insertComponents(project1, project2, project3);
SnapshotDto projectSnapshot1 = dbClient.snapshotDao().insert(dbSession, newAnalysis(project1)
.setPeriodDate(parseDateTime("2016-01-11T10:49:50+0100").getTime())
.setPeriodMode("previous_version")
diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/IndexActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/IndexActionTest.java
index 12a268a3a6b..cb19ed6b295 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/IndexActionTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/IndexActionTest.java
@@ -169,6 +169,28 @@ public class IndexActionTest {
}
@Test
+ public void do_not_verify_permissions_if_user_is_root() throws Exception {
+ ComponentDto project = db.components().insertProject(p -> p.setKey("P1").setName("POne"));
+
+ String result = call(null, null, null);
+
+ userSession.setNonRoot();
+ assertThat(result).isEqualTo("[]");
+
+ userSession.setRoot();
+ result = call(null, null, null);
+ assertJson(result).isSimilarTo("[" +
+ " {" +
+ " \"id\":" + project.getId() + "," +
+ " \"k\":\"P1\"," +
+ " \"nm\":\"POne\"," +
+ " \"sc\":\"PRJ\"," +
+ " \"qu\":\"TRK\"" +
+ " }" +
+ "]");
+ }
+
+ @Test
public void test_example() {
insertProjectsAuthorizedForUser(
newProjectDto(db.getDefaultOrganization()).setKey("org.jenkins-ci.plugins:sonar").setName("Jenkins Sonar Plugin"),
@@ -199,7 +221,6 @@ public class IndexActionTest {
private void insertProjectsAuthorizedForUser(ComponentDto... projects) {
db.components().insertComponents(projects);
setBrowsePermissionOnUser(projects);
- db.commit();
}
private void setBrowsePermissionOnUser(ComponentDto... projects) {
diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
index c781c2662d4..da5aaefe2f7 100644
--- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
+++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/QgateProjectFinderTest.java
@@ -37,6 +37,7 @@ import org.sonar.db.component.ComponentDto;
import org.sonar.db.organization.OrganizationDto;
import org.sonar.db.property.PropertyDto;
import org.sonar.db.qualitygate.ProjectQgateAssociation;
+import org.sonar.db.qualitygate.ProjectQgateAssociationQuery;
import org.sonar.db.qualitygate.QualityGateDto;
import org.sonar.db.user.UserDto;
import org.sonar.server.exceptions.NotFoundException;
@@ -160,6 +161,21 @@ public class QgateProjectFinderTest {
}
@Test
+ public void do_not_verify_permissions_if_user_is_root() throws Exception {
+ OrganizationDto org = dbTester.organizations().insert();
+ ComponentDto project = componentDbTester.insertProject(org);
+ ProjectQgateAssociationQuery query = builder()
+ .gateId(Long.toString(qGate.getId()))
+ .build();
+
+ userSession.logIn().setNonRoot();
+ verifyProjects(underTest.find(query));
+
+ userSession.logIn().setRoot();
+ verifyProjects(underTest.find(query), project.getId());
+ }
+
+ @Test
public void test_paging() throws Exception {
OrganizationDto org = dbTester.organizations().insert();
ComponentDto project1 = insertProjectAuthorizedToAnyone(newProjectDto(org).setName("Project 1"));