From 16ca956c05b1fa37e49b8d63f6bdfd6e14ec87b7 Mon Sep 17 00:00:00 2001 From: Daniel Schwarz Date: Thu, 28 Sep 2017 15:53:09 +0200 Subject: [PATCH] SONAR-9127 make api/qualitygates/get_by_project public, change parameters --- .../qualitygate/ws/GetByProjectAction.java | 55 +++++++------- .../ws/GetByProjectActionTest.java | 76 ++++++------------- .../src/main/js/api/quality-gates.ts | 4 +- 3 files changed, 55 insertions(+), 80 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java index 66bef0377e2..abcfee22a4d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/qualitygate/ws/GetByProjectAction.java @@ -20,6 +20,7 @@ package org.sonar.server.qualitygate.ws; import java.util.Optional; +import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; @@ -29,21 +30,19 @@ import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; import org.sonar.db.qualitygate.QualityGateDto; import org.sonar.server.component.ComponentFinder; -import org.sonar.server.component.ComponentFinder.ParamNames; import org.sonar.server.qualitygate.QualityGateFinder; import org.sonar.server.qualitygate.QualityGateFinder.QualityGateData; import org.sonar.server.user.UserSession; import org.sonarqube.ws.WsQualityGates.GetByProjectWsResponse; -import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonar.server.user.AbstractUserSession.insufficientPrivilegesException; import static org.sonar.server.ws.KeyExamples.KEY_PROJECT_EXAMPLE_001; import static org.sonar.server.ws.WsUtils.writeProtobuf; import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.ACTION_GET_BY_PROJECT; -import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID; -import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY; public class GetByProjectAction implements QualityGatesWsAction { + private static final String PARAM_PROJECT = "project"; + private final UserSession userSession; private final DbClient dbClient; private final ComponentFinder componentFinder; @@ -59,41 +58,43 @@ public class GetByProjectAction implements QualityGatesWsAction { @Override public void define(WebService.NewController context) { WebService.NewAction action = context.createAction(ACTION_GET_BY_PROJECT) - .setInternal(true) + .setInternal(false) .setSince("6.1") - .setDescription("Get the quality gate of a project.
" + - "Either project id or project key must be provided, not both.") + .setDescription("Get the quality gate of a project.
" + + "Requires one of the following permissions:" + + "") .setResponseExample(getClass().getResource("get_by_project-example.json")) - .setHandler(this); - - action.createParam(PARAM_PROJECT_ID) - .setDescription("Project id") - .setExampleValue(UUID_EXAMPLE_01); - - action.createParam(PARAM_PROJECT_KEY) + .setHandler(this) + .setChangelog( + new Change("6.6", "The parameter 'projectId' has been removed"), + new Change("6.6", "The parameter 'projectKey' has been renamed to 'project'"), + new Change("6.6", "This webservice is now part of the public API") + ); + + action.createParam(PARAM_PROJECT) .setDescription("Project key") - .setExampleValue(KEY_PROJECT_EXAMPLE_001); + .setExampleValue(KEY_PROJECT_EXAMPLE_001) + .setRequired(true); } @Override public void handle(Request request, Response response) throws Exception { try (DbSession dbSession = dbClient.openSession(false)) { - ComponentDto project = getProject(dbSession, request.param(PARAM_PROJECT_ID), request.param(PARAM_PROJECT_KEY)); - Optional data = qualityGateFinder.getQualityGate(dbSession, project.getId()); + ComponentDto project = componentFinder.getByKey(dbSession, request.mandatoryParam(PARAM_PROJECT)); - writeProtobuf(buildResponse(data), request, response); - } - } + if (!userSession.hasComponentPermission(UserRole.USER, project) && + !userSession.hasComponentPermission(UserRole.ADMIN, project)) { + throw insufficientPrivilegesException(); + } - private ComponentDto getProject(DbSession dbSession, String projectUuid, String projectKey) { - ComponentDto project = componentFinder.getByUuidOrKey(dbSession, projectUuid, projectKey, ParamNames.PROJECT_ID_AND_KEY); + Optional data = qualityGateFinder.getQualityGate(dbSession, project.getId()); - if (!userSession.hasComponentPermission(UserRole.USER, project) && - !userSession.hasComponentPermission(UserRole.ADMIN, project)) { - throw insufficientPrivilegesException(); + writeProtobuf(buildResponse(data), request, response); } - - return project; } private static GetByProjectWsResponse buildResponse(Optional data) { diff --git a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java index 4945ff91435..0529e7bfc26 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/qualitygate/ws/GetByProjectActionTest.java @@ -23,6 +23,7 @@ import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.WebService; import org.sonar.api.utils.System2; import org.sonar.api.web.UserRole; @@ -47,9 +48,8 @@ import org.sonarqube.ws.WsQualityGates.GetByProjectWsResponse; import static java.lang.String.format; import static org.assertj.core.api.Assertions.assertThat; +import static org.assertj.core.api.Assertions.tuple; import static org.sonar.test.JsonAssert.assertJson; -import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_ID; -import static org.sonarqube.ws.client.qualitygate.QualityGatesWsParameters.PARAM_PROJECT_KEY; public class GetByProjectActionTest { @Rule @@ -70,14 +70,18 @@ public class GetByProjectActionTest { public void definition() { WebService.Action def = ws.getDef(); assertThat(def.description()).isNotEmpty(); - assertThat(def.isInternal()).isTrue(); + assertThat(def.isInternal()).isFalse(); assertThat(def.since()).isEqualTo("6.1"); - assertThat(def.changelog()).isEmpty(); - assertThat(def.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("projectId", "projectKey"); - - WebService.Param projectKey = def.param("projectKey"); + assertThat(def.changelog()).extracting(Change::getVersion, Change::getDescription).containsExactlyInAnyOrder( + tuple("6.6", "The parameter 'projectId' has been removed"), + tuple("6.6", "The parameter 'projectKey' has been renamed to 'project'"), + tuple("6.6", "This webservice is now part of the public API") + ); + assertThat(def.params()).extracting(WebService.Param::key).containsExactlyInAnyOrder("project"); + + WebService.Param projectKey = def.param("project"); assertThat(projectKey.description()).isNotEmpty(); - assertThat(projectKey.isRequired()).isFalse(); + assertThat(projectKey.isRequired()).isTrue(); assertThat(projectKey.exampleValue()).isNotEmpty(); } @@ -89,7 +93,7 @@ public class GetByProjectActionTest { associateProjectToQualityGate(project.getId(), qualityGate.getId()); logInAsProjectUser(project); - String result = ws.newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).execute().getInput(); + String result = ws.newRequest().setParam("project", project.getKey()).execute().getInput(); assertJson(result) .ignoreFields("id") @@ -102,7 +106,7 @@ public class GetByProjectActionTest { insertQualityGate("Another QG"); logInAsProjectUser(project); - String result = ws.newRequest().setParam(PARAM_PROJECT_ID, project.uuid()).execute().getInput(); + String result = ws.newRequest().setParam("project", project.getKey()).execute().getInput(); assertThat(result).isEqualToIgnoringWhitespace("{}"); } @@ -114,7 +118,7 @@ public class GetByProjectActionTest { setDefaultQualityGate(dbQualityGate.getId()); logInAsProjectUser(project); - GetByProjectWsResponse result = callByUuid(project.uuid()); + GetByProjectWsResponse result = callByKey(project.getKey()); WsQualityGates.QualityGate qualityGate = result.getQualityGate(); assertThat(Long.valueOf(qualityGate.getId())).isEqualTo(dbQualityGate.getId()); @@ -131,7 +135,7 @@ public class GetByProjectActionTest { associateProjectToQualityGate(project.getId(), dbQualityGate.getId()); logInAsProjectUser(project); - GetByProjectWsResponse result = callByUuid(project.uuid()); + GetByProjectWsResponse result = callByKey(project.getKey()); WsQualityGates.QualityGate qualityGate = result.getQualityGate(); assertThat(qualityGate.getName()).isEqualTo(dbQualityGate.getName()); @@ -157,7 +161,7 @@ public class GetByProjectActionTest { QualityGateDto dbQualityGate = insertQualityGate("Sonar way"); setDefaultQualityGate(dbQualityGate.getId()); - GetByProjectWsResponse result = callByUuid(project.uuid()); + GetByProjectWsResponse result = callByKey(project.getKey()); assertThat(result.getQualityGate().getName()).isEqualTo(dbQualityGate.getName()); } @@ -169,7 +173,7 @@ public class GetByProjectActionTest { QualityGateDto dbQualityGate = insertQualityGate("Sonar way"); setDefaultQualityGate(dbQualityGate.getId()); - GetByProjectWsResponse result = callByUuid(project.uuid()); + GetByProjectWsResponse result = callByKey(project.getKey()); assertThat(result.getQualityGate().getName()).isEqualTo(dbQualityGate.getName()); } @@ -183,28 +187,21 @@ public class GetByProjectActionTest { expectedException.expect(ForbiddenException.class); - callByUuid(project.uuid()); + callByKey(project.getKey()); } @Test public void fail_when_project_does_not_exist() { expectedException.expect(NotFoundException.class); - callByUuid("Unknown"); + callByKey("Unknown"); } @Test public void fail_when_no_parameter() { expectedException.expect(IllegalArgumentException.class); - call(null, null); - } - - @Test - public void fail_when_project_uuid_and_key_provided() { - expectedException.expect(IllegalArgumentException.class); - - call("uuid", "key"); + call(null); } @Test @@ -217,41 +214,18 @@ public class GetByProjectActionTest { expectedException.expect(NotFoundException.class); expectedException.expectMessage(format("Component key '%s' not found", branch.getDbKey())); - call(null, branch.getDbKey()); - } - - @Test - public void fail_when_using_branch_uuid() throws Exception { - OrganizationDto organization = db.organizations().insert(); - ComponentDto project = db.components().insertMainBranch(organization); - userSession.logIn().addProjectPermission(UserRole.ADMIN, project); - ComponentDto branch = db.components().insertProjectBranch(project); - - expectedException.expect(NotFoundException.class); - expectedException.expectMessage(format("Component id '%s' not found", branch.uuid())); - - call(branch.uuid(), null); - } - - private GetByProjectWsResponse callByUuid(String projectUuid) { - return call(projectUuid, null); + call(branch.getDbKey()); } private GetByProjectWsResponse callByKey(String projectKey) { - return call(null, projectKey); + return call(projectKey); } - private GetByProjectWsResponse call(@Nullable String projectUuid, @Nullable String projectKey) { + private GetByProjectWsResponse call(@Nullable String projectKey) { TestRequest request = ws.newRequest(); - - if (projectUuid != null) { - request.setParam(PARAM_PROJECT_ID, projectUuid); - } - if (projectKey != null) { - request.setParam(PARAM_PROJECT_KEY, projectKey); + request.setParam("project", projectKey); } - return request.executeProtobuf(GetByProjectWsResponse.class); } diff --git a/server/sonar-web/src/main/js/api/quality-gates.ts b/server/sonar-web/src/main/js/api/quality-gates.ts index 2839607c23c..c4142d3958d 100644 --- a/server/sonar-web/src/main/js/api/quality-gates.ts +++ b/server/sonar-web/src/main/js/api/quality-gates.ts @@ -84,8 +84,8 @@ export function deleteCondition(id: string): Promise { return post('/api/qualitygates/delete_condition', { id }); } -export function getGateForProject(projectKey: string): Promise { - return getJSON('/api/qualitygates/get_by_project', { projectKey }).then( +export function getGateForProject(project: string): Promise { + return getJSON('/api/qualitygates/get_by_project', { project }).then( r => r.qualityGate && { id: r.qualityGate.id, -- 2.39.5