diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-02-21 14:29:40 +0100 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2017-02-21 20:46:05 +0100 |
commit | 730daa2870ac4b1a40b6dd8e067d21f72c720f2d (patch) | |
tree | 6069e59a1cda6e7c38b0e143faceee0bc6bda268 | |
parent | abd5b2343c27d317357ed25e10b22343d490bc03 (diff) | |
download | sonarqube-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
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")); |