From 3ac0e9be3fc589b4c8b7dd8e2468638b9b84ca32 Mon Sep 17 00:00:00 2001 From: =?utf8?q?S=C3=A9bastien=20Lesaint?= Date: Thu, 29 Sep 2016 14:54:07 +0200 Subject: [PATCH] SONAR-8151 test WS organizations authorizations in IT --- .../java/it/organization/OrganizationIt.java | 156 ++++++++++++++---- .../organization/OrganizationService.java | 2 +- 2 files changed, 126 insertions(+), 32 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 2d7b6bfc316..90c8be7a2c6 100644 --- a/it/it-tests/src/test/java/it/organization/OrganizationIt.java +++ b/it/it-tests/src/test/java/it/organization/OrganizationIt.java @@ -22,16 +22,24 @@ package it.organization; import com.sonar.orchestrator.Orchestrator; import it.Category3Suite; import java.util.List; +import java.util.function.Consumer; +import java.util.function.Function; +import org.junit.Before; import org.junit.ClassRule; +import org.junit.Rule; import org.junit.Test; +import org.junit.rules.ExpectedException; import org.sonarqube.ws.Organizations; +import org.sonarqube.ws.client.HttpException; import org.sonarqube.ws.client.organization.CreateWsRequest; import org.sonarqube.ws.client.organization.OrganizationService; import org.sonarqube.ws.client.organization.SearchWsRequest; import org.sonarqube.ws.client.organization.UpdateWsRequest; import util.ItUtils; +import util.user.UserRule; import static org.assertj.core.api.Assertions.assertThat; +import static org.junit.Assert.fail; public class OrganizationIt { private static final String DEFAULT_ORGANIZATION_KEY = "default-organization"; @@ -40,25 +48,37 @@ public class OrganizationIt { private static final String DESCRIPTION = "the description of Foo company"; private static final String URL = "https://www.foo.fr"; private static final String AVATAR_URL = "https://www.foo.fr/corporate_logo.png"; + private static final String SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS = "sonar.organizations.anyoneCanCreate"; @ClassRule public static Orchestrator orchestrator = Category3Suite.ORCHESTRATOR; + @ClassRule + public static UserRule userRule = UserRule.from(orchestrator); + @Rule + public ExpectedException expectedException = ExpectedException.none(); private OrganizationService anonymousOrganizationService = ItUtils.newWsClient(orchestrator).organizations(); private OrganizationService adminOrganizationService = ItUtils.newAdminWsClient(orchestrator).organizations(); + @Before + public void setUp() throws Exception { + orchestrator.resetData(); + userRule.resetUsers(); + ItUtils.resetSettings(orchestrator, null, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS); + } + @Test - public void create_update_delete_an_organization() { + public void create_update_delete_organizations_and_check_security() { verifyNoExtraOrganization(); Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder() - .setName(NAME) - .setKey(KEY) - .setDescription(DESCRIPTION) - .setUrl(URL) - .setAvatar(AVATAR_URL) - .build()) - .getOrganization(); + .setName(NAME) + .setKey(KEY) + .setDescription(DESCRIPTION) + .setUrl(URL) + .setAvatar(AVATAR_URL) + .build()) + .getOrganization(); assertThat(createdOrganization.getName()).isEqualTo(NAME); assertThat(createdOrganization.getKey()).isEqualTo(KEY); assertThat(createdOrganization.getDescription()).isEqualTo(DESCRIPTION); @@ -69,46 +89,120 @@ public class OrganizationIt { // update by id adminOrganizationService.update(new UpdateWsRequest.Builder() - .setKey(createdOrganization.getKey()) - .setName("new name") - .setDescription("new description") - .setUrl("new url") - .setAvatar("new avatar url") - .build()); + .setKey(createdOrganization.getKey()) + .setName("new name") + .setDescription("new description") + .setUrl("new url") + .setAvatar("new avatar url") + .build()); verifySingleSearchResult(createdOrganization, "new name", "new description", "new url", "new avatar url"); // update by key adminOrganizationService.update(new UpdateWsRequest.Builder() - .setKey(createdOrganization.getKey()) - .setName("new name 2") - .setDescription("new description 2") - .setUrl("new url 2") - .setAvatar("new avatar url 2") - .build()); + .setKey(createdOrganization.getKey()) + .setName("new name 2") + .setDescription("new description 2") + .setUrl("new url 2") + .setAvatar("new avatar url 2") + .build()); verifySingleSearchResult(createdOrganization, "new name 2", "new description 2", "new url 2", "new avatar url 2"); // remove optional fields adminOrganizationService.update(new UpdateWsRequest.Builder() - .setKey(createdOrganization.getKey()) - .setName("new name 3") - .build()); + .setKey(createdOrganization.getKey()) + .setName("new name 3") + .build()); verifySingleSearchResult(createdOrganization, "new name 3", null, null, null); // delete organization adminOrganizationService.delete(createdOrganization.getKey()); verifyNoExtraOrganization(); + + adminOrganizationService.create(new CreateWsRequest.Builder() + .setName(NAME) + .setKey(KEY) + .build()) + .getOrganization(); + verifySingleSearchResult(createdOrganization, NAME, null, null, null); + + // verify anonymous can't create update nor delete an organization by default + verifyAnonymousNotAuthorized(service -> service.create(new CreateWsRequest.Builder().setName("An org").build())); + verifyAnonymousNotAuthorized(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build())); + verifyAnonymousNotAuthorized(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"); + verifyUserNotAuthorized("john", "doh", service -> service.create(new CreateWsRequest.Builder().setName("An org").build())); + verifyUserNotAuthorized("john", "doh", service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build())); + verifyUserNotAuthorized("john", "doh", service -> service.delete(KEY)); + + ItUtils.setServerProperty(orchestrator, SETTING_ANYONE_CAN_CREATE_ORGANIZATIONS, "true"); + // 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())); + verifyAnonymousNotAuthorized(service -> service.update(new UpdateWsRequest.Builder().setKey(KEY).setName("new name").build())); + verifyAnonymousNotAuthorized(service -> service.delete(KEY)); + + // clean-up + adminOrganizationService.delete(KEY); + + // verify logged in user without any permission can create not not 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)); + verifySingleSearchResult( + verifyUserAuthorized("john", "doh", service -> service.create(new CreateWsRequest.Builder().setName("An org").build())).getOrganization(), + "An org", null, null, null); + + // clean-up + adminOrganizationService.delete("an-org"); + } + + private void verifyAnonymousNotAuthorized(Consumer consumer) { + try { + consumer.accept(anonymousOrganizationService); + fail("An HttpException should have been raised"); + } catch (HttpException e) { + assertThat(e.code()).isEqualTo(403); + } + } + + private void verifyUserNotAuthenticated(Consumer consumer) { + try { + consumer.accept(anonymousOrganizationService); + fail("An HttpException should have been raised"); + } catch (HttpException e) { + assertThat(e.code()).isEqualTo(401); + } + } + + private void verifyUserNotAuthorized(String login, String password, Consumer consumer) { + try { + OrganizationService organizationService = ItUtils.newUserWsClient(orchestrator, login, password).organizations(); + consumer.accept(organizationService); + fail("An HttpException should have been raised"); + } catch (HttpException e) { + assertThat(e.code()).isEqualTo(403); + } + } + + private T verifyUserAuthorized(String login, String password, Function consumer) { + OrganizationService organizationService = ItUtils.newUserWsClient(orchestrator, login, password).organizations(); + return consumer.apply(organizationService); } @Test public void create_generates_key_from_name() { // create organization without key String name = "Foo Company to keyize"; + String expectedKey = "foo-company-to-keyize"; Organizations.Organization createdOrganization = adminOrganizationService.create(new CreateWsRequest.Builder() - .setName(name) - .build()) - .getOrganization(); - assertThat(createdOrganization.getKey()).isEqualTo("foo-company-to-keyize"); + .setName(name) + .build()) + .getOrganization(); + assertThat(createdOrganization.getKey()).isEqualTo(expectedKey); verifySingleSearchResult(createdOrganization, name, null, null, null); + + // clean-up + adminOrganizationService.delete(expectedKey); } private void verifyNoExtraOrganization() { @@ -119,13 +213,13 @@ public class OrganizationIt { } private void verifySingleSearchResult(Organizations.Organization createdOrganization, String name, String description, String url, - String avatarUrl) { + String avatarUrl) { List organizations = anonymousOrganizationService.search(new SearchWsRequest.Builder().build()).getOrganizationsList(); assertThat(organizations).hasSize(2); Organizations.Organization searchedOrganization = organizations.stream() - .filter(organization -> !DEFAULT_ORGANIZATION_KEY.equals(organization.getKey())) - .findFirst() - .get(); + .filter(organization -> !DEFAULT_ORGANIZATION_KEY.equals(organization.getKey())) + .findFirst() + .get(); assertThat(searchedOrganization.getKey()).isEqualTo(createdOrganization.getKey()); assertThat(searchedOrganization.getName()).isEqualTo(name); if (description == null) { diff --git a/sonar-ws/src/main/java/org/sonarqube/ws/client/organization/OrganizationService.java b/sonar-ws/src/main/java/org/sonarqube/ws/client/organization/OrganizationService.java index df2e355e65b..ad3cd7beaf7 100644 --- a/sonar-ws/src/main/java/org/sonarqube/ws/client/organization/OrganizationService.java +++ b/sonar-ws/src/main/java/org/sonarqube/ws/client/organization/OrganizationService.java @@ -69,6 +69,6 @@ public class OrganizationService extends BaseService { PostRequest post = new PostRequest(path("delete")) .setParam("key", key); - call(post); + call(post).failIfNotSuccessful(); } } -- 2.39.5