From 7e6178a4675405b097ab0a716086ef1b717b10bf Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Fri, 8 Jan 2016 16:56:38 +0100 Subject: [PATCH] SONAR-7174 Check scan perm per project in qgate project status WS --- .../qualitygate/ws/ProjectStatusAction.java | 19 +++--- .../ws/ProjectStatusActionTest.java | 59 +++++++++++++++++-- 2 files changed, 66 insertions(+), 12 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java index f550d642279..afb00b58101 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/ProjectStatusAction.java @@ -31,16 +31,18 @@ import org.sonar.api.measures.CoreMetrics; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; -import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.component.ComponentDto; import org.sonar.db.component.SnapshotDto; import org.sonar.db.measure.MeasureDto; import org.sonar.server.user.UserSession; import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse; import org.sonarqube.ws.client.qualitygate.ProjectStatusWsRequest; -import static com.google.common.collect.Sets.newHashSet; +import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; +import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.WsUtils.checkFound; import static org.sonar.server.ws.WsUtils.writeProtobuf; @@ -49,7 +51,7 @@ public class ProjectStatusAction implements QGateWsAction { .join(Lists.transform(Arrays.asList(ProjectStatusWsResponse.Status.values()), new Function() { @Nonnull @Override - public String apply(ProjectStatusWsResponse.Status input) { + public String apply(@Nonnull ProjectStatusWsResponse.Status input) { return input.toString(); } })); @@ -86,12 +88,12 @@ public class ProjectStatusAction implements QGateWsAction { } private ProjectStatusWsResponse doHandle(ProjectStatusWsRequest request) { - checkScanOrAdminPermission(); - DbSession dbSession = dbClient.openSession(false); try { String snapshotId = request.getAnalysisId(); SnapshotDto snapshotDto = getSnapshot(dbSession, snapshotId); + ComponentDto projectDto = dbClient.componentDao().selectOrFailById(dbSession, snapshotDto.getComponentId()); + checkPermission(projectDto.uuid()); String measureData = getQualityGateDetailsMeasureData(dbSession, snapshotDto); return ProjectStatusWsResponse.newBuilder() @@ -133,7 +135,10 @@ public class ProjectStatusAction implements QGateWsAction { .setAnalysisId(request.mandatoryParam("analysisId")); } - private void checkScanOrAdminPermission() { - userSession.checkAnyPermissions(newHashSet(GlobalPermissions.SCAN_EXECUTION, GlobalPermissions.SYSTEM_ADMIN)); + private void checkPermission(String projectUuid) { + if (!userSession.hasPermission(SYSTEM_ADMIN) + && !userSession.hasComponentUuidPermission(SCAN_EXECUTION, projectUuid)) { + throw insufficientPrivilegesException(); + } } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java index 07f9247b3bc..b515ad0edc4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/ProjectStatusActionTest.java @@ -29,7 +29,6 @@ import org.junit.experimental.categories.Category; import org.junit.rules.ExpectedException; import org.sonar.api.measures.CoreMetrics; import org.sonar.api.utils.System2; -import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; @@ -47,6 +46,9 @@ import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse; import org.sonarqube.ws.WsQualityGates.ProjectStatusWsResponse.Status; import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.core.permission.GlobalPermissions.PREVIEW_EXECUTION; +import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; import static org.sonar.db.component.ComponentTesting.newProjectDto; import static org.sonar.db.component.SnapshotTesting.newSnapshotForProject; import static org.sonar.db.measure.MeasureTesting.newMeasureDto; @@ -73,11 +75,12 @@ public class ProjectStatusActionTest { dbSession = db.getSession(); ws = new WsActionTester(new ProjectStatusAction(dbClient, userSession)); - userSession.setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); } @Test public void json_example() throws IOException { + userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN); + ComponentDto project = newProjectDto("project-uuid"); dbClient.componentDao().insert(dbSession, project); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project) @@ -106,6 +109,8 @@ public class ProjectStatusActionTest { @Test public void fail_if_no_snapshot_id_found() { + userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN); + expectedException.expect(NotFoundException.class); expectedException.expectMessage("Analysis with id 'task-uuid' is not found"); @@ -114,6 +119,8 @@ public class ProjectStatusActionTest { @Test public void return_undefined_status_if_measure_is_not_found() { + userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN); + ComponentDto project = newProjectDto("project-uuid"); dbClient.componentDao().insert(dbSession, project); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project)); @@ -127,7 +134,8 @@ public class ProjectStatusActionTest { @Test public void return_undefined_status_if_measure_data_is_not_well_formatted() { - userSession.setGlobalPermissions(GlobalPermissions.SCAN_EXECUTION); + userSession.login("john").setGlobalPermissions(SCAN_EXECUTION); + ComponentDto project = newProjectDto("project-uuid"); dbClient.componentDao().insert(dbSession, project); SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project)); @@ -146,10 +154,51 @@ public class ProjectStatusActionTest { @Test public void fail_if_insufficient_privileges() { - userSession.setGlobalPermissions(GlobalPermissions.PREVIEW_EXECUTION); + userSession.login("john").setGlobalPermissions(PREVIEW_EXECUTION); + + ComponentDto project = newProjectDto("project-uuid"); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project)); + dbSession.commit(); + expectedException.expect(ForbiddenException.class); + newRequest(snapshot.getId().toString()); + } - newRequest(ANALYSIS_ID); + @Test + public void not_fail_with_system_admin_permission() { + userSession.login("john").setGlobalPermissions(SYSTEM_ADMIN); + + ComponentDto project = newProjectDto("project-uuid"); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project)); + dbSession.commit(); + + newRequest(snapshot.getId().toString()); + } + + @Test + public void not_fail_with_global_scan_permission() { + userSession.login("john").setGlobalPermissions(SCAN_EXECUTION); + + ComponentDto project = newProjectDto("project-uuid"); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project)); + dbSession.commit(); + + newRequest(snapshot.getId().toString()); + } + + @Test + public void not_fail_with_project_scan_permission() { + ComponentDto project = newProjectDto("project-uuid"); + dbClient.componentDao().insert(dbSession, project); + SnapshotDto snapshot = dbClient.snapshotDao().insert(dbSession, newSnapshotForProject(project)); + dbSession.commit(); + + userSession.login("john").addProjectUuidPermissions(SCAN_EXECUTION, project.uuid()); + + newRequest(snapshot.getId().toString()); } private ProjectStatusWsResponse newRequest(String taskId) { -- 2.39.5