diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-10-19 11:14:12 +0200 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2016-10-20 17:17:53 +0200 |
commit | a729e675c7fbe66212502068f4f38ea2b74f899d (patch) | |
tree | c12c986a321e6f9efdc30e1865e23e6c44cff65d | |
parent | e49f905d8931cf5ee8c5586c8db780bf5f68c531 (diff) | |
download | sonarqube-a729e675c7fbe66212502068f4f38ea2b74f899d.tar.gz sonarqube-a729e675c7fbe66212502068f4f38ea2b74f899d.zip |
SONAR-8100 check user's organization in api/organizations/delete
3 files changed, 185 insertions, 6 deletions
diff --git a/it/it-tests/src/test/java/it/organization/OrganizationIt.java b/it/it-tests/src/test/java/it/organization/OrganizationIt.java index e048b7724dc..5187d7a76ae 100644 --- a/it/it-tests/src/test/java/it/organization/OrganizationIt.java +++ b/it/it-tests/src/test/java/it/organization/OrganizationIt.java @@ -128,7 +128,7 @@ public class OrganizationIt { // verify anonymous can't create update nor delete an organization by default verifyAnonymousNotAuthorized(service -> service.create(new CreateWsRequest.Builder().setName("An org").build())); verifyUserNotAuthenticated(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build())); - verifyAnonymousNotAuthorized(service -> service.delete(KEY)); + verifyUserNotAuthenticated(service -> service.delete(KEY)); // verify logged in user without any permission can't create update nor delete an organization by default userRule.createUser("john", "doh"); @@ -140,9 +140,9 @@ public class OrganizationIt { // verify anonymous still can't create update nor delete an organization if property is true verifyUserNotAuthenticated(service -> service.create(new CreateWsRequest.Builder().setName("An org").build())); verifyUserNotAuthenticated(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build())); - verifyAnonymousNotAuthorized(service -> service.delete(KEY)); + verifyUserNotAuthenticated(service -> service.delete(KEY)); - // verify logged in user without any permission can create nor update nor delete an organization if property is true + // verify logged in user without any permission can't create nor update nor delete an organization if property is true verifyUserNotAuthorized("john", "doh", service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build())); verifyUserNotAuthorized("john", "doh", service -> service.delete(KEY)); // clean-up diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/DeleteAction.java b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/DeleteAction.java index cfe785bdad0..bd9e5603302 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/DeleteAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/DeleteAction.java @@ -22,15 +22,17 @@ package org.sonar.server.organization.ws; 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.organization.OrganizationDto; import org.sonar.server.organization.DefaultOrganization; import org.sonar.server.organization.DefaultOrganizationProvider; import org.sonar.server.user.UserSession; import static com.google.common.base.Preconditions.checkArgument; +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_KEY; +import static org.sonar.server.ws.WsUtils.checkFoundWithOptional; public class DeleteAction implements OrganizationsAction { private static final String ACTION = "delete"; @@ -50,7 +52,7 @@ public class DeleteAction implements OrganizationsAction { WebService.NewAction action = context.createAction(ACTION) .setPost(true) .setDescription("Delete an organization.<br/>" + - "Require 'Administer System' permission.") + "Require 'Administer System' permission on the specified organization.") .setInternal(true) .setSince("6.2") .setHandler(this); @@ -63,12 +65,19 @@ public class DeleteAction implements OrganizationsAction { @Override public void handle(Request request, Response response) throws Exception { - userSession.checkPermission(GlobalPermissions.SYSTEM_ADMIN); + userSession.checkLoggedIn(); String key = request.mandatoryParam(PARAM_KEY); preventDeletionOfDefaultOrganization(key, defaultOrganizationProvider.get()); try (DbSession dbSession = dbClient.openSession(false)) { + OrganizationDto organizationDto = checkFoundWithOptional( + dbClient.organizationDao().selectByKey(dbSession, key), + "Organization with key '%s' not found", + key); + + userSession.checkOrganizationPermission(organizationDto.getUuid(), SYSTEM_ADMIN); + dbClient.organizationDao().deleteByKey(dbSession, key); dbSession.commit(); diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/DeleteActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/DeleteActionTest.java new file mode 100644 index 00000000000..a93ef085952 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/DeleteActionTest.java @@ -0,0 +1,170 @@ +/* + * SonarQube + * Copyright (C) 2009-2016 SonarSource SA + * mailto:contact AT sonarsource DOT com + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3 of the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * 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.organization.ws; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.System2; +import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.permission.template.PermissionTemplateDto; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.NotFoundException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.organization.TestDefaultOrganizationProvider; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; +import static org.sonar.server.organization.ws.OrganizationsWsSupport.PARAM_KEY; + +public class DeleteActionTest { + + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public ExpectedException expectedException = ExpectedException.none(); + + private DeleteAction underTest = new DeleteAction(userSession, dbTester.getDbClient(), TestDefaultOrganizationProvider.from(dbTester)); + private WsActionTester wsTester = new WsActionTester(underTest); + + @Test + public void verify_define() { + WebService.Action action = wsTester.getDef(); + assertThat(action.key()).isEqualTo("delete"); + assertThat(action.isPost()).isTrue(); + assertThat(action.description()).isEqualTo("Delete an organization.<br/>" + + "Require 'Administer System' permission on the specified organization."); + assertThat(action.isInternal()).isTrue(); + assertThat(action.since()).isEqualTo("6.2"); + assertThat(action.handler()).isEqualTo(underTest); + assertThat(action.params()).hasSize(1); + assertThat(action.responseExample()).isNull(); + + assertThat(action.param("key")) + .matches(param -> param.isRequired()) + .matches(param -> "foo-company".equals(param.exampleValue())) + .matches(param -> "Organization key".equals(param.description())); + } + + @Test + public void request_fails_with_UnauthorizedException_if_user_is_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + expectedException.expectMessage("Authentication is required"); + + wsTester.newRequest() + .execute(); + } + + @Test + public void request_fails_with_IAE_if_key_param_is_missing() { + userSession.login(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("The 'key' parameter is missing"); + + wsTester.newRequest() + .execute(); + } + + @Test + public void request_fails_with_IAE_if_key_is_the_one_of_default_organization() { + userSession.login(); + + expectedException.expect(IllegalArgumentException.class); + expectedException.expectMessage("Default Organization can't be deleted"); + + sendRequest(dbTester.getDefaultOrganization()); + } + + @Test + public void request_fails_with_NotFoundException_if_organization_with_specified_key_does_not_exist() { + userSession.login(); + + expectedException.expect(NotFoundException.class); + expectedException.expectMessage("Organization with key 'foo' not found"); + + sendRequest("foo"); + } + + @Test + public void request_fails_with_ForbiddenException_when_user_has_no_System_Administer_permission() { + OrganizationDto organization = dbTester.organizations().insert(); + userSession.login(); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + sendRequest(organization); + } + + @Test + public void request_fails_with_ForbiddenException_when_user_does_not_have_System_Administer_permission_on_specified_organization() { + OrganizationDto organization = dbTester.organizations().insert(); + userSession.login().addOrganizationPermission(dbTester.getDefaultOrganization().getUuid(), SYSTEM_ADMIN); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("Insufficient privileges"); + + sendRequest(organization); + } + + @Test + public void request_deletes_specified_organization_if_exists_and_user_has_Admin_permission_on_it() { + OrganizationDto organization = dbTester.organizations().insert(); + userSession.login().addOrganizationPermission(organization.getUuid(), SYSTEM_ADMIN); + + sendRequest(organization); + + verifyOrganizationDoesNotExist(organization); + } + + @Test + public void request_deletes_specified_organization_if_exists_and_user_is_root() { + OrganizationDto organization = dbTester.organizations().insert(); + userSession.login().setRoot(); + + sendRequest(organization); + + verifyOrganizationDoesNotExist(organization); + } + + private void verifyOrganizationDoesNotExist(OrganizationDto organization) { + assertThat(dbTester.getDbClient().organizationDao().selectByKey(dbTester.getSession(), organization.getKey())) + .isEmpty(); + } + + private void sendRequest(OrganizationDto organization) { + sendRequest(organization.getKey()); + } + + private void sendRequest(String organizationKey) { + wsTester.newRequest() + .setParam(PARAM_KEY, organizationKey) + .execute(); + } +} |