diff options
author | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-02-03 16:29:38 +0100 |
---|---|---|
committer | Sébastien Lesaint <sebastien.lesaint@sonarsource.com> | 2017-02-07 09:32:45 +0100 |
commit | ac69e7c18e1b4d86be4ea1085ef3b38c7bda531c (patch) | |
tree | f5a40b8a950087418a72e526eb42053fb9323120 /server | |
parent | a5a4c240f137a85aba33233c8a9bfa9db627ef5c (diff) | |
download | sonarqube-ac69e7c18e1b4d86be4ea1085ef3b38c7bda531c.tar.gz sonarqube-ac69e7c18e1b4d86be4ea1085ef3b38c7bda531c.zip |
SONAR-8735 add WS api/organizations/search_my_organizations
Diffstat (limited to 'server')
5 files changed, 266 insertions, 2 deletions
diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/OrganizationsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/OrganizationsWsModule.java index a0ab7987ab6..35e805df8eb 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/OrganizationsWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/OrganizationsWsModule.java @@ -32,7 +32,8 @@ public class OrganizationsWsModule extends Module { CreateAction.class, SearchAction.class, UpdateAction.class, - DeleteAction.class); + DeleteAction.class, + SearchMyOrganizationsAction.class); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchMyOrganizationsAction.java b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchMyOrganizationsAction.java new file mode 100644 index 00000000000..cbea63906cc --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/organization/ws/SearchMyOrganizationsAction.java @@ -0,0 +1,71 @@ +/* + * 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.sonar.api.server.ws.Request; +import org.sonar.api.server.ws.Response; +import org.sonar.api.server.ws.WebService; +import org.sonar.api.utils.text.JsonWriter; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.server.user.UserSession; + +import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; + +public class SearchMyOrganizationsAction implements OrganizationsAction { + private static final String ACTION = "search_my_organizations"; + + private final UserSession userSession; + private final DbClient dbClient; + + public SearchMyOrganizationsAction(UserSession userSession, DbClient dbClient) { + this.userSession = userSession; + this.dbClient = dbClient; + } + + @Override + public void define(WebService.NewController context) { + context.createAction(ACTION) + .setPost(false) + .setDescription("List keys of the organizations for which the currently authenticated user has the System Administer permission for.") + .setResponseExample(getClass().getResource("example-search_my_organization.json")) + .setInternal(true) + .setSince("6.3") + .setHandler(this); + } + + @Override + public void handle(Request request, Response response) throws Exception { + if (!userSession.isLoggedIn()) { + response.noContent(); + return; + } + + try (DbSession dbSession = dbClient.openSession(false); + JsonWriter jsonWriter = response.newJsonWriter()) { + jsonWriter.beginObject(); + jsonWriter.name("organizations").beginArray(); + dbClient.organizationDao().selectByPermission(dbSession, userSession.getUserId(), SYSTEM_ADMIN) + .forEach(dto -> jsonWriter.value(dto.getKey())); + jsonWriter.endArray(); + jsonWriter.endObject(); + } + } +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/organization/ws/example-search_my_organization.json b/server/sonar-server/src/main/resources/org/sonar/server/organization/ws/example-search_my_organization.json new file mode 100644 index 00000000000..4d2fe03957c --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/organization/ws/example-search_my_organization.json @@ -0,0 +1,6 @@ +{ + "organizations": [ + "my-org", + "foo-corp" + ] +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/OrganizationsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/OrganizationsWsModuleTest.java index 77f86e28501..fba235871c0 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/OrganizationsWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/OrganizationsWsModuleTest.java @@ -33,7 +33,7 @@ public class OrganizationsWsModuleTest { ComponentContainer container = new ComponentContainer(); underTest.configure(container); assertThat(container.getPicoContainer().getComponentAdapters()) - .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 6); + .hasSize(COMPONENTS_IN_EMPTY_COMPONENT_CONTAINER + 7); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMyOrganizationsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMyOrganizationsActionTest.java new file mode 100644 index 00000000000..ec55b7f8a27 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/organization/ws/SearchMyOrganizationsActionTest.java @@ -0,0 +1,186 @@ +/* + * 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.sonar.api.server.ws.WebService; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbTester; +import org.sonar.db.organization.OrganizationDto; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.UserDto; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.TestResponse; +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.test.JsonAssert.assertJson; + +public class SearchMyOrganizationsActionTest { + private static final String NO_ORGANIZATIONS_RESPONSE = "{\"organizations\": []}"; + + @Rule + public DbTester dbTester = DbTester.create(System2.INSTANCE); + @Rule + public UserSessionRule userSessionRule = UserSessionRule.standalone(); + + private DbClient dbClient = dbTester.getDbClient(); + + private WsActionTester underTest = new WsActionTester(new SearchMyOrganizationsAction(userSessionRule, dbClient)); + + @Test + public void verify_definition() { + WebService.Action def = underTest.getDef(); + + assertThat(def.key()).isEqualTo("search_my_organizations"); + assertThat(def.isPost()).isFalse(); + assertThat(def.isInternal()).isTrue(); + assertThat(def.since()).isEqualTo("6.3"); + assertThat(def.description()).isEqualTo("List keys of the organizations for which the currently authenticated user has the System Administer permission for."); + assertThat(def.responseExample()).isNotNull(); + + assertThat(def.params()).isEmpty(); + } + + @Test + public void verify_response_example() { + OrganizationDto organization1 = dbTester.organizations().insertForKey("my-org"); + OrganizationDto organization2 = dbTester.organizations().insertForKey("foo-corp"); + + UserDto user = dbTester.users().insertUser(); + dbTester.users().insertPermissionOnUser(organization1, user, SYSTEM_ADMIN); + dbTester.users().insertPermissionOnUser(organization2, user, SYSTEM_ADMIN); + + userSessionRule.logIn(user); + + TestResponse response = underTest.newRequest().execute(); + + assertJson(response.getInput()).isSimilarTo(underTest.getDef().responseExampleAsString()); + } + + @Test + public void returns_empty_response_when_user_is_not_logged_in() { + TestResponse response = underTest.newRequest().execute(); + + assertThat(response.getStatus()).isEqualTo(204); + assertThat(response.getInput()).isEmpty(); + } + + @Test + public void returns_empty_array_when_user_is_logged_in_and_has_no_permission_on_anything() { + userSessionRule.logIn(); + + TestResponse response = underTest.newRequest().execute(); + + assertJson(response.getInput()).isSimilarTo(NO_ORGANIZATIONS_RESPONSE); + } + + @Test + public void returns_organizations_of_authenticated_user_when_user_has_ADMIN_user_permission_on_some_organization() { + UserDto user = dbTester.users().insertUser(); + dbTester.users().insertPermissionOnUser(dbTester.getDefaultOrganization(), user, SYSTEM_ADMIN); + OrganizationDto organization1 = dbTester.organizations().insert(); + dbTester.users().insertPermissionOnUser(organization1, user, SYSTEM_ADMIN); + UserDto otherUser = dbTester.users().insertUser(); + OrganizationDto organization2 = dbTester.organizations().insert(); + dbTester.users().insertPermissionOnUser(organization2, otherUser, SYSTEM_ADMIN); + + userSessionRule.logIn(user); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo("{\"organizations\": [" + + "\"" + dbTester.getDefaultOrganization().getKey() + "\"," + + "\"" + organization1.getKey() + "\"" + + "]}"); + + userSessionRule.logIn(otherUser); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo("{\"organizations\": [" + + "\"" + organization2.getKey() + "\"" + + "]}"); + + userSessionRule.logIn(); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo(NO_ORGANIZATIONS_RESPONSE); + } + + @Test + public void returns_organizations_of_authenticated_user_when_user_has_ADMIN_group_permission_on_some_organization() { + UserDto user = dbTester.users().insertUser(); + GroupDto defaultGroup = dbTester.users().insertGroup(dbTester.getDefaultOrganization()); + dbTester.users().insertPermissionOnGroup(defaultGroup, SYSTEM_ADMIN); + dbTester.users().insertMember(defaultGroup, user); + OrganizationDto organization1 = dbTester.organizations().insert(); + GroupDto group1 = dbTester.users().insertGroup(organization1); + dbTester.users().insertPermissionOnGroup(group1, SYSTEM_ADMIN); + dbTester.users().insertMember(group1, user); + UserDto otherUser = dbTester.users().insertUser(); + OrganizationDto organization2 = dbTester.organizations().insert(); + GroupDto group2 = dbTester.users().insertGroup(organization2); + dbTester.users().insertPermissionOnGroup(group2, SYSTEM_ADMIN); + dbTester.users().insertMember(group2, otherUser); + + userSessionRule.logIn(user); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo("{\"organizations\": [" + + "\"" + dbTester.getDefaultOrganization().getKey() + "\"," + + "\"" + organization1.getKey() + "\"" + + "]}"); + + userSessionRule.logIn(otherUser); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo("{\"organizations\": [" + + "\"" + organization2.getKey() + "\"" + + "]}"); + + userSessionRule.logIn(); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo(NO_ORGANIZATIONS_RESPONSE); + } + + @Test + public void returns_organization_of_authenticated_user_only_for_ADMIN_permission() { + UserDto user = dbTester.users().insertUser(); + OrganizationDto organization1 = dbTester.organizations().insert(); + OrganizationDto organization2 = dbTester.organizations().insert(); + GroupDto group = dbTester.users().insertGroup(organization2); + dbTester.users().insertMember(group, user); + GlobalPermissions.ALL.stream() + .filter(s -> !s.equals(SYSTEM_ADMIN)) + .forEach(s -> { + dbTester.users().insertPermissionOnUser(organization1, user, s); + dbTester.users().insertPermissionOnGroup(group, s); + }); + + userSessionRule.logIn(user); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo(NO_ORGANIZATIONS_RESPONSE); + } + + @Test + public void do_not_return_organization_twice_if_user_has_ADMIN_permission_twice_or_more() { + UserDto user = dbTester.users().insertUser(); + OrganizationDto organization = dbTester.organizations().insert(); + GroupDto group1 = dbTester.users().insertGroup(organization); + dbTester.users().insertPermissionOnGroup(group1, SYSTEM_ADMIN); + dbTester.users().insertPermissionOnUser(organization, user, SYSTEM_ADMIN); + + userSessionRule.logIn(user); + assertJson(underTest.newRequest().execute().getInput()).isSimilarTo("{\"organizations\": [" + + "\"" + organization.getKey() + "\"" + + "]}"); + } +} |