From bf7bc4d21303fc3b3bd9f85c13198f6d017e2f28 Mon Sep 17 00:00:00 2001 From: Julien Lancelot Date: Tue, 27 Nov 2018 12:19:11 +0100 Subject: [PATCH] SONARCLOUD-211 Return alm info in api/organizations/search only when member is set to true --- .../server/organization/ws/SearchAction.java | 2 +- .../server/ui/ws/OrganizationAction.java | 17 +++- .../organization/ws/SearchActionTest.java | 28 +++++- .../server/ui/ws/OrganizationActionTest.java | 87 ++++++++++++------- 4 files changed, 94 insertions(+), 40 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchAction.java b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchAction.java index 4ce33233fae..6b05f8cdb05 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchAction.java @@ -164,7 +164,7 @@ public class SearchAction implements OrganizationsWsAction { setNullable(organization.getDescription(), builder::setDescription); setNullable(organization.getUrl(), builder::setUrl); setNullable(organization.getAvatarUrl(), builder::setAvatar); - if (organizationAlmBinding != null) { + if (onlyMembershipOrganizations && organizationAlmBinding != null) { builder.setAlm(Organization.Alm.newBuilder() .setKey(organizationAlmBinding.getAlm().getId()) .setUrl(organizationAlmBinding.getUrl())); diff --git a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java index caf938d3dd6..41c03075768 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ui/ws/OrganizationAction.java @@ -20,6 +20,7 @@ package org.sonar.server.ui.ws; import java.util.List; +import java.util.Optional; import org.sonar.api.resources.Qualifiers; import org.sonar.api.server.ws.Change; import org.sonar.api.server.ws.Request; @@ -29,6 +30,7 @@ import org.sonar.api.utils.text.JsonWriter; import org.sonar.api.web.page.Page; import org.sonar.db.DbClient; import org.sonar.db.DbSession; +import org.sonar.db.alm.OrganizationAlmBindingDto; import org.sonar.db.component.ComponentQuery; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.organization.BillingValidations; @@ -101,13 +103,13 @@ public class OrganizationAction implements NavigationWsAction { JsonWriter json = response.newJsonWriter(); json.beginObject(); - writeOrganization(json, organization, newProjectPrivate); + writeOrganization(json, organization, dbClient.organizationAlmBindingDao().selectByOrganization(dbSession, organization), newProjectPrivate); json.endObject() .close(); } } - private void writeOrganization(JsonWriter json, OrganizationDto organization, boolean newProjectPrivate) { + private void writeOrganization(JsonWriter json, OrganizationDto organization, Optional organizationAlmBinding, boolean newProjectPrivate) { json.name("organization") .beginObject() .prop("isDefault", organization.getKey().equals(defaultOrganizationProvider.get().getKey())) @@ -116,6 +118,7 @@ public class OrganizationAction implements NavigationWsAction { .prop("canUpdateProjectsVisibilityToPrivate", userSession.hasPermission(ADMINISTER, organization) && billingValidations.canUpdateProjectVisibilityToPrivate(new BillingValidations.Organization(organization.getKey(), organization.getUuid()))); + writeAlm(json, organizationAlmBinding); json.name("pages"); writePages(json, pageRepository.getOrganizationPages(false)); if (userSession.hasPermission(ADMINISTER, organization)) { @@ -133,4 +136,14 @@ public class OrganizationAction implements NavigationWsAction { .endObject()); json.endArray(); } + + private static void writeAlm(JsonWriter json, Optional organizationAlmBindingOpt) { + organizationAlmBindingOpt.ifPresent( + organizationAlmBinding -> json + .name("alm") + .beginObject() + .prop("key", organizationAlmBinding.getAlm().getId()) + .prop("url", organizationAlmBinding.getUrl()) + .endObject()); + } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchActionTest.java index f3ad38c2e87..3fc1fdf99b0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchActionTest.java @@ -261,13 +261,17 @@ public class SearchActionTest { } @Test - public void return_alm_info() { + public void return_alm_info_when_member_parameter_is_set_to_true() { + UserDto user = db.users().insertUser(); + userSession.logIn(user); OrganizationDto organization = db.organizations().insert(); AlmAppInstallDto almAppInstall = db.alm().insertAlmAppInstall(); OrganizationAlmBindingDto organizationAlmBinding = db.alm().insertOrganizationAlmBinding(organization, almAppInstall); OrganizationDto organizationNotBoundToAlm = db.organizations().insert(); + db.organizations().addMember(organization, user); + db.organizations().addMember(organizationNotBoundToAlm, user); - SearchWsResponse result = call(ws.newRequest()); + SearchWsResponse result = call(ws.newRequest().setParam("member", "true")); Map orgByKey = result.getOrganizationsList().stream().collect(toMap(Organization::getKey, identity())); assertThat(orgByKey.get(organization.getKey()).getAlm().getKey()).isEqualTo(organizationAlmBinding.getAlm().getId()); @@ -275,15 +279,31 @@ public class SearchActionTest { assertThat(orgByKey.get(organizationNotBoundToAlm.getKey()).hasAlm()).isEqualTo(false); } + @Test + public void do_not_return_alm_info_when_no_member_parameter() { + OrganizationDto organization = db.organizations().insert(); + AlmAppInstallDto almAppInstall = db.alm().insertAlmAppInstall(); + OrganizationAlmBindingDto organizationAlmBinding = db.alm().insertOrganizationAlmBinding(organization, almAppInstall); + OrganizationDto organizationNotBoundToAlm = db.organizations().insert(); + + SearchWsResponse result = call(ws.newRequest()); + + assertThat(result.getOrganizationsList()) + .extracting(Organization::getKey, Organization::hasAlm) + .containsExactlyInAnyOrder( + tuple(organization.getKey(), false), + tuple(organizationNotBoundToAlm.getKey(), false)); + } + @Test public void return_subscription_info_when_member_parameter_is_set_to_true() { UserDto user = db.users().insertUser(); + userSession.logIn(user); OrganizationDto organization1 = db.organizations().insert(o -> o.setSubscription(FREE)); OrganizationDto organization2 = db.organizations().insert(o -> o.setSubscription(PAID)); OrganizationDto organization3 = db.organizations().insert(o -> o.setSubscription(PAID)); db.organizations().addMember(organization1, user); db.organizations().addMember(organization2, user); - userSession.logIn(user); SearchWsResponse result = call(ws.newRequest().setParam("member", "true")); @@ -295,7 +315,7 @@ public class SearchActionTest { } @Test - public void subscription_info_is_not_returned_when_no_member_parameter() { + public void do_not_return_subscription_info_when_no_member_parameter() { UserDto user = db.users().insertUser(); OrganizationDto organization1 = db.organizations().insert(o -> o.setSubscription(FREE)); OrganizationDto organization2 = db.organizations().insert(o -> o.setSubscription(PAID)); diff --git a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java index 01dcf780d63..d96395597cd 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/ui/ws/OrganizationActionTest.java @@ -33,6 +33,8 @@ import org.sonar.core.platform.PluginInfo; import org.sonar.core.platform.PluginRepository; import org.sonar.db.DbClient; import org.sonar.db.DbTester; +import org.sonar.db.alm.AlmAppInstallDto; +import org.sonar.db.alm.OrganizationAlmBindingDto; import org.sonar.db.organization.OrganizationDto; import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.organization.BillingValidations; @@ -95,7 +97,10 @@ public class OrganizationActionTest { OrganizationDto organization = db.organizations().insert(); db.organizations().setNewProjectPrivate(organization, true); userSession.logIn().addPermission(PROVISION_PROJECTS, organization); - assertJson(executeRequest(organization).getInput()).isSimilarTo("{\"organization\": {\"projectVisibility\": \"private\"}}"); + + TestResponse response = executeRequest(organization); + + assertJson(response.getInput()).isSimilarTo("{\"organization\": {\"projectVisibility\": \"private\"}}"); } @Test @@ -103,7 +108,10 @@ public class OrganizationActionTest { OrganizationDto organization = db.organizations().insert(); db.organizations().setNewProjectPrivate(organization, false); userSession.logIn().addPermission(PROVISION_PROJECTS, organization); - assertJson(executeRequest(organization).getInput()).isSimilarTo("{\"organization\": {\"projectVisibility\": \"public\"}}"); + + TestResponse response = executeRequest(organization); + + assertJson(response.getInput()).isSimilarTo("{\"organization\": {\"projectVisibility\": \"public\"}}"); } @Test @@ -124,61 +132,75 @@ public class OrganizationActionTest { } @Test - public void return_subscription_flag() { + public void return_FREE_subscription_flag() { OrganizationDto freeOrganization = db.organizations().insert(o -> o.setSubscription(FREE)); - assertJson(executeRequest(freeOrganization).getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"FREE\"}}"); - - OrganizationDto sonarQubeOrganization = db.organizations().insert(o -> o.setSubscription(SONARQUBE)); - assertJson(executeRequest(sonarQubeOrganization).getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"SONARQUBE\"}}"); - OrganizationDto paidOrganization = db.organizations().insert(o -> o.setSubscription(PAID)); + TestResponse response = executeRequest(freeOrganization); - userSession.logIn() - .addMembership(paidOrganization); - - assertJson(executeRequest(paidOrganization).getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"PAID\"}}"); - } - - @Test - public void do_not_throws_FE_when_not_member_on_free_organization() { - OrganizationDto freeOrganization = db.organizations().insert(o -> o.setSubscription(FREE)); - executeRequest(freeOrganization).getInput(); + assertJson(response.getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"FREE\"}}"); } @Test - public void do_not_throws_FE_when_not_member_on_sonarqube_organization() { + public void return_SONARQUBE_subscription_flag() { OrganizationDto sonarQubeOrganization = db.organizations().insert(o -> o.setSubscription(SONARQUBE)); - executeRequest(sonarQubeOrganization).getInput(); + + TestResponse response = executeRequest(sonarQubeOrganization); + + assertJson(response.getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"SONARQUBE\"}}"); } @Test - public void throws_FE_when_not_member_on_private_organization() { + public void return_PAID_subscription_flag() { OrganizationDto paidOrganization = db.organizations().insert(o -> o.setSubscription(PAID)); + userSession.logIn().addMembership(paidOrganization); - expectedException.expect(ForbiddenException.class); - expectedException.expectMessage("You're not member of organization"); - assertJson(executeRequest(paidOrganization).getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"PAID\"}}"); + TestResponse response = executeRequest(paidOrganization); + + assertJson(response.getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"PAID\"}}"); } @Test - public void do_no_throws_FE_when_not_member_on_private_organization_with_public_project() { + public void return_PAID_subscription_flag_when_not_member_on_private_organization_with_public_project() { OrganizationDto paidOrganization = db.organizations().insert(o -> o.setSubscription(PAID)); db.components().insertPublicProject(paidOrganization); + userSession.anonymous(); + + TestResponse response = executeRequest(paidOrganization); - assertJson(executeRequest(paidOrganization).getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"PAID\"}}"); + assertJson(response.getInput()).isSimilarTo("{\"organization\": {\"subscription\": \"PAID\"}}"); } @Test - public void return_information_when_member_of_the_organization() { + public void throw_FE_when_not_member_on_private_organization_and_no_public_project() { OrganizationDto paidOrganization = db.organizations().insert(o -> o.setSubscription(PAID)); - userSession.logIn() - .addMembership(paidOrganization); + db.components().insertPrivateProject(paidOrganization); + + expectedException.expect(ForbiddenException.class); + expectedException.expectMessage("You're not member of organization"); - executeRequest(paidOrganization).getInput(); + executeRequest(paidOrganization); } @Test - public void fails_with_IAE_if_parameter_organization_is_not_specified() { + public void return_alm_binding() { + OrganizationDto organization = db.organizations().insert(); + AlmAppInstallDto almAppInstall = db.alm().insertAlmAppInstall(); + OrganizationAlmBindingDto organizationAlmBinding = db.alm().insertOrganizationAlmBinding(organization, almAppInstall); + + TestResponse response = executeRequest(organization); + + assertJson(response.getInput()).isSimilarTo("{\"organization\": " + + " {" + + " \"alm\": {" + + " \"key\": \"" + organizationAlmBinding.getAlm().getId() + "\"," + + " \"url\": \"" + organizationAlmBinding.getUrl() + "\"" + + " }" + + " }" + + "}"); + } + + @Test + public void fail_with_IAE_if_parameter_organization_is_not_specified() { expectedException.expect(IllegalArgumentException.class); expectedException.expectMessage("The 'organization' parameter is missing"); @@ -197,8 +219,7 @@ public class OrganizationActionTest { TestResponse response = executeRequest(organization); - assertJson(response.getInput()) - .isSimilarTo(ws.getDef().responseExampleAsString()); + assertJson(response.getInput()).isSimilarTo(ws.getDef().responseExampleAsString()); } @Test -- 2.39.5