diff options
author | Simon Brandhof <simon.brandhof@sonarsource.com> | 2018-04-05 21:06:07 +0200 |
---|---|---|
committer | Simon Brandhof <simon.brandhof@sonarsource.com> | 2018-04-06 13:32:52 +0200 |
commit | a4a42f925ce3de8977588e69c362700b11332acd (patch) | |
tree | 1b0fda9ba106e0a60810441fccd3a01d04fc40e3 /server/sonar-server/src | |
parent | 124aaa43b6f65bee01c167d2bceb8c71f58fc06a (diff) | |
download | sonarqube-a4a42f925ce3de8977588e69c362700b11332acd.tar.gz sonarqube-a4a42f925ce3de8977588e69c362700b11332acd.zip |
SONAR-10536 no longer possible to analyse a module that was removed from another project
Diffstat (limited to 'server/sonar-server/src')
-rw-r--r-- | server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java | 56 | ||||
-rw-r--r-- | server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java | 122 |
2 files changed, 114 insertions, 64 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java index 4f14b4793e8..bda6d52b955 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/project/ws/UpdateKeyAction.java @@ -17,9 +17,9 @@ * 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.project.ws; +import com.google.common.base.Optional; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Response; @@ -27,11 +27,10 @@ import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.component.ComponentDto; -import org.sonar.server.component.ComponentFinder; -import org.sonar.server.component.ComponentFinder.ParamNames; import org.sonar.server.component.ComponentService; -import org.sonarqube.ws.client.project.UpdateKeyWsRequest; +import org.sonar.server.exceptions.NotFoundException; +import static com.google.common.base.Preconditions.checkArgument; import static org.sonar.core.util.Uuids.UUID_EXAMPLE_01; import static org.sonarqube.ws.client.project.ProjectsWsParameters.ACTION_UPDATE_KEY; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM; @@ -40,12 +39,10 @@ import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO; public class UpdateKeyAction implements ProjectsWsAction { private final DbClient dbClient; - private final ComponentFinder componentFinder; private final ComponentService componentService; - public UpdateKeyAction(DbClient dbClient, ComponentFinder componentFinder, ComponentService componentService) { + public UpdateKeyAction(DbClient dbClient, ComponentService componentService) { this.dbClient = dbClient; - this.componentFinder = componentFinder; this.componentService = componentService; } @@ -57,19 +54,20 @@ public class UpdateKeyAction implements ProjectsWsAction { public WebService.NewAction doDefine(WebService.NewController context) { WebService.NewAction action = context.createAction(ACTION_UPDATE_KEY) .setDescription("Update a project or module key and all its sub-components keys.<br>" + - "Either '%s' or '%s' must be provided.<br> " + - "Requires one of the following permissions: " + - "<ul>" + - "<li>'Administer System'</li>" + - "<li>'Administer' rights on the specified project</li>" + - "</ul>", + "Either '%s' or '%s' must be provided.<br> " + + "Requires one of the following permissions: " + + "<ul>" + + "<li>'Administer System'</li>" + + "<li>'Administer' rights on the specified project</li>" + + "</ul>", PARAM_FROM, PARAM_PROJECT_ID) .setSince("6.1") .setPost(true) .setHandler(this); action.setChangelog( - new Change("6.4", "Move from api/components/update_key to api/projects/update_key")); + new Change("6.4", "Move from api/components/update_key to api/projects/update_key"), + new Change("7.1", "Ability to update key of a disabled module")); action.createParam(PARAM_PROJECT_ID) .setDescription("Project or module id") @@ -93,22 +91,24 @@ public class UpdateKeyAction implements ProjectsWsAction { @Override public void handle(Request request, Response response) throws Exception { - doHandle(toWsRequest(request)); - response.noContent(); - } + String uuid = request.param(PARAM_PROJECT_ID); + String key = request.param(PARAM_FROM); + String newKey = request.mandatoryParam(PARAM_TO); + checkArgument(uuid != null ^ key != null, "Either '%s' or '%s' must be provided", PARAM_PROJECT_ID, PARAM_FROM); - private void doHandle(UpdateKeyWsRequest request) { try (DbSession dbSession = dbClient.openSession(false)) { - ComponentDto projectOrModule = componentFinder.getByUuidOrKey(dbSession, request.getId(), request.getKey(), ParamNames.PROJECT_ID_AND_FROM); - componentService.updateKey(dbSession, projectOrModule, request.getNewKey()); - } - } + Optional<ComponentDto> component; + if (uuid != null) { + component = dbClient.componentDao().selectByUuid(dbSession, uuid); + } else { + component = dbClient.componentDao().selectByKey(dbSession, key); + } + if (!component.isPresent() || component.get().getMainBranchProjectUuid() != null) { + throw new NotFoundException("Component not found"); + } - private static UpdateKeyWsRequest toWsRequest(Request request) { - return UpdateKeyWsRequest.builder() - .setId(request.param(PARAM_PROJECT_ID)) - .setKey(request.param(PARAM_FROM)) - .setNewKey(request.mandatoryParam(PARAM_TO)) - .build(); + componentService.updateKey(dbSession, component.get(), newKey); + } + response.noContent(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java index 975a4a61aba..0b5f8e6d5e0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/project/ws/UpdateKeyActionTest.java @@ -17,9 +17,9 @@ * 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.project.ws; +import com.google.common.base.Optional; import javax.annotation.Nullable; import org.junit.Rule; import org.junit.Test; @@ -27,23 +27,21 @@ import org.junit.rules.ExpectedException; import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.utils.System2; +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.ComponentTesting; import org.sonar.server.component.ComponentService; -import org.sonar.server.component.TestComponentFinder; +import org.sonar.server.es.ProjectIndexers; +import org.sonar.server.es.ProjectIndexersImpl; +import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.tester.UserSessionRule; import org.sonar.server.ws.TestRequest; import org.sonar.server.ws.WsActionTester; import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.Matchers.any; -import static org.mockito.Matchers.eq; -import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.verify; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_FROM; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_PROJECT_ID; import static org.sonarqube.ws.client.project.ProjectsWsParameters.PARAM_TO; @@ -55,55 +53,104 @@ public class UpdateKeyActionTest { public ExpectedException expectedException = ExpectedException.none(); @Rule public DbTester db = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + private DbClient dbClient = db.getDbClient(); + private ProjectIndexers projectIndexers = new ProjectIndexersImpl(); + private ComponentService componentService = new ComponentService(dbClient, userSessionRule, projectIndexers); + private WsActionTester ws = new WsActionTester(new UpdateKeyAction(dbClient, componentService)); - ComponentDbTester componentDb = new ComponentDbTester(db); - DbClient dbClient = db.getDbClient(); + @Test + public void update_key_of_project_referenced_by_its_key() { + ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); - ComponentService componentService = mock(ComponentService.class); + callByKey(project.getKey(), ANOTHER_KEY); - WsActionTester ws = new WsActionTester(new org.sonar.server.project.ws.UpdateKeyAction(dbClient, TestComponentFinder.from(db), componentService)); + assertThat(selectByKey(project.getKey()).isPresent()).isFalse(); + assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(project.uuid()); + } @Test - public void call_by_key() { + public void update_key_of_project_referenced_by_its_uuid() { ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); - callByKey(project.getDbKey(), ANOTHER_KEY); + callByUuid(project.uuid(), ANOTHER_KEY); - assertCallComponentService(ANOTHER_KEY); + assertThat(selectByKey(project.getKey()).isPresent()).isFalse(); + assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(project.uuid()); } @Test - public void call_by_uuid() { + public void update_key_of_module_referenced_by_its_uuid() { ComponentDto project = insertProject(); + ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project)); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); - callByUuid(project.uuid(), ANOTHER_KEY); + callByUuid(module.uuid(), ANOTHER_KEY); - assertCallComponentService(ANOTHER_KEY); + assertThat(selectByKey(project.getKey()).isPresent()).isTrue(); + assertThat(selectByKey(module.getKey()).isPresent()).isFalse(); + assertThat(selectByKey(ANOTHER_KEY).get().uuid()).isEqualTo(module.uuid()); } @Test - public void fail_if_new_key_is_not_provided() { - expectedException.expect(IllegalArgumentException.class); + public void update_key_of_disabled_module() { + ComponentDto project = insertProject(); + ComponentDto module = db.components().insertComponent(ComponentTesting.newModuleDto(project).setEnabled(false)); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); + + callByKey(module.getKey(), ANOTHER_KEY); + + assertThat(selectByKey(project.getKey()).isPresent()).isTrue(); + assertThat(selectByKey(module.getKey()).isPresent()).isFalse(); + ComponentDto loadedModule = selectByKey(ANOTHER_KEY).get(); + assertThat(loadedModule.uuid()).isEqualTo(module.uuid()); + assertThat(loadedModule.isEnabled()).isFalse(); + } + + @Test + public void fail_if_not_authorized() { ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.USER, project); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); - callByKey(project.getDbKey(), null); + callByKey(project.getKey(), ANOTHER_KEY); + } + + @Test + public void fail_if_new_key_is_not_provided() { + ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("The 'to' parameter is missing"); + + callByKey(project.getKey(), null); } @Test public void fail_if_uuid_nor_key_provided() { expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Either 'projectId' or 'from' must be provided"); call(null, null, ANOTHER_KEY); } @Test - public void fail_if_uuid_and_key_provided() { + public void fail_if_both_uuid_and_key_provided() { + ComponentDto project = insertProject(); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Either 'projectId' or 'from' must be provided"); - ComponentDto project = insertProject(); - call(project.uuid(), project.getDbKey(), ANOTHER_KEY); + call(project.uuid(), project.getKey(), ANOTHER_KEY); } @Test @@ -117,20 +164,22 @@ public class UpdateKeyActionTest { public void fail_when_using_branch_db_key() throws Exception { ComponentDto project = db.components().insertMainBranch(); ComponentDto branch = db.components().insertProjectBranch(project); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); expectedException.expect(NotFoundException.class); - expectedException.expectMessage(String.format("Component key '%s' not found", branch.getDbKey())); + expectedException.expectMessage("Component not found"); callByKey(branch.getDbKey(), ANOTHER_KEY); } @Test - public void fail_when_using_branch_uuid() throws Exception { + public void fail_when_using_branch_uuid() { ComponentDto project = db.components().insertMainBranch(); ComponentDto branch = db.components().insertProjectBranch(project); + userSessionRule.addProjectPermission(UserRole.ADMIN, project); expectedException.expect(NotFoundException.class); - expectedException.expectMessage(String.format("Component id '%s' not found", branch.uuid())); + expectedException.expectMessage("Component not found"); callByUuid(branch.uuid(), ANOTHER_KEY); } @@ -142,26 +191,23 @@ public class UpdateKeyActionTest { assertThat(definition.since()).isEqualTo("6.1"); assertThat(definition.isPost()).isTrue(); assertThat(definition.key()).isEqualTo("update_key"); + assertThat(definition.changelog()).hasSize(2); assertThat(definition.params()) .hasSize(3) .extracting(Param::key) .containsOnlyOnce("projectId", "from", "to"); } - private void assertCallComponentService(@Nullable String newKey) { - verify(componentService).updateKey(any(DbSession.class), any(ComponentDto.class), eq(newKey)); - } - private ComponentDto insertProject() { - return componentDb.insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert())); + return db.components().insertComponent(ComponentTesting.newPrivateProjectDto(db.organizations().insert())); } - private String callByUuid(@Nullable String uuid, @Nullable String newKey) { - return call(uuid, null, newKey); + private void callByUuid(@Nullable String uuid, @Nullable String newKey) { + call(uuid, null, newKey); } - private String callByKey(@Nullable String key, @Nullable String newKey) { - return call(null, key, newKey); + private void callByKey(@Nullable String key, @Nullable String newKey) { + call(null, key, newKey); } private String call(@Nullable String uuid, @Nullable String key, @Nullable String newKey) { @@ -179,4 +225,8 @@ public class UpdateKeyActionTest { return request.execute().getInput(); } + + private Optional<ComponentDto> selectByKey(String key) { + return db.getDbClient().componentDao().selectByKey(db.getSession(), key); + } } |