From 966ceab8329ba91c481c25deae55d7cf8266ee3d Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Wed, 5 Aug 2015 17:40:47 +0200 Subject: SONAR-6482 WS permissions/groups list permission's groups --- .../permission/GroupWithPermissionQueryResult.java | 16 +- .../sonar/server/permission/PermissionFinder.java | 16 +- .../sonar/server/permission/ws/GroupsAction.java | 131 ++ .../server/permission/ws/PermissionsWsModule.java | 3 +- .../sonar/server/permission/ws/UsersAction.java | 2 +- .../sonar/server/ws/WsResponseCommonFormat.java | 3 - .../sonar/server/permission/ws/groups-example.json | 25 + .../sonar/server/permission/ws/users-example.json | 2 +- .../server/permission/PermissionFinderTest.java | 19 +- .../server/permission/ws/GroupsActionTest.java | 168 ++ .../permission/ws/PermissionsWsModuleTest.java | 2 +- .../default_page_size_is_100.json | 3 +- .../SearchActionMediumTest/deprecated_paging.json | 3 +- .../ws/SearchActionMediumTest/empty_result.json | 3 +- .../permission/ws/GroupsActionTest/groups.json | 19 + .../permission/ws/UsersActionTest/users.json | 2 +- .../sonar/core/permission/GroupWithPermission.java | 10 + .../db/permission/GroupWithPermissionDto.java | 10 + .../org/sonar/db/permission/PermissionDao.java | 27 +- .../org/sonar/db/permission/PermissionMapper.java | 4 +- .../sonar/db/permission/PermissionTemplateDao.java | 26 +- .../db/permission/PermissionTemplateMapper.java | 2 + .../org/sonar/db/permission/PermissionMapper.xml | 39 +- .../db/permission/PermissionTemplateMapper.xml | 24 + .../db/permission/GroupWithPermissionDaoTest.java | 31 +- .../GroupWithPermissionTemplateDaoTest.java | 16 +- .../src/main/gen-java/org/sonarqube/ws/Common.java | 112 +- .../gen-java/org/sonarqube/ws/Permissions.java | 1895 +++++++++++++++++++- sonar-ws/src/main/protobuf/ws-commons.proto | 1 - sonar-ws/src/main/protobuf/ws-permissions.proto | 16 +- 30 files changed, 2403 insertions(+), 227 deletions(-) create mode 100644 server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java create mode 100644 server/sonar-server/src/main/resources/org/sonar/server/permission/ws/groups-example.json create mode 100644 server/sonar-server/src/test/java/org/sonar/server/permission/ws/GroupsActionTest.java create mode 100644 server/sonar-server/src/test/resources/org/sonar/server/permission/ws/GroupsActionTest/groups.json diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/GroupWithPermissionQueryResult.java b/server/sonar-server/src/main/java/org/sonar/server/permission/GroupWithPermissionQueryResult.java index 5058b7552e3..99a4d9b0dd5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/GroupWithPermissionQueryResult.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/GroupWithPermissionQueryResult.java @@ -19,18 +19,19 @@ */ package org.sonar.server.permission; -import org.sonar.core.permission.GroupWithPermission; - import java.util.List; +import org.sonar.core.permission.GroupWithPermission; public class GroupWithPermissionQueryResult { - private List groups; - private boolean hasMoreResults; + private final List groups; + private final int total; + private final boolean hasMoreResults; - public GroupWithPermissionQueryResult(List groups, boolean hasMoreResults) { + public GroupWithPermissionQueryResult(List groups, int total) { this.groups = groups; - this.hasMoreResults = hasMoreResults; + this.total = total; + this.hasMoreResults = total > groups.size(); } public List groups() { @@ -41,4 +42,7 @@ public class GroupWithPermissionQueryResult { return hasMoreResults; } + public int total() { + return total; + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java index c9aa9271405..4b6659dac68 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java @@ -91,7 +91,12 @@ public class PermissionFinder { */ public GroupWithPermissionQueryResult findGroupsWithPermission(PermissionQuery query) { Long componentId = componentId(query.component()); - return toGroupQueryResult(permissionDao.selectGroups(query, componentId), query); + DbSession dbSession = dbClient.openSession(false); + try { + return toGroupQueryResult(permissionDao.selectGroups(dbSession, query, componentId), query); + } finally { + dbClient.closeSession(dbSession); + } } /** @@ -99,7 +104,12 @@ public class PermissionFinder { */ public GroupWithPermissionQueryResult findGroupsWithPermissionTemplate(PermissionQuery query) { Long permissionTemplateId = templateId(query.template()); - return toGroupQueryResult(permissionTemplateDao.selectGroups(query, permissionTemplateId), query); + DbSession dbSession = dbClient.openSession(false); + try { + return toGroupQueryResult(permissionTemplateDao.selectGroups(dbSession, query, permissionTemplateId), query); + } finally { + dbClient.closeSession(dbSession); + } } private static UserWithPermissionQueryResult toUserQueryResult(List dtos, int total) { @@ -133,7 +143,7 @@ public class PermissionFinder { Paging paging = Paging.create(query.pageSize(), query.pageIndex(), filteredDtos.size()); List pagedGroups = pagedGroups(filteredDtos, paging); - return new GroupWithPermissionQueryResult(pagedGroups, paging.hasNextPage()); + return new GroupWithPermissionQueryResult(pagedGroups, filteredDtos.size()); } private Long templateId(String templateKey) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java new file mode 100644 index 00000000000..a8850b6fb62 --- /dev/null +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java @@ -0,0 +1,131 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.permission.ws; + +import com.google.common.io.Resources; +import java.util.List; +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.core.permission.GlobalPermissions; +import org.sonar.core.permission.GroupWithPermission; +import org.sonar.core.util.ProtobufJsonFormat; +import org.sonar.db.permission.PermissionQuery; +import org.sonar.server.permission.GroupWithPermissionQueryResult; +import org.sonar.server.permission.PermissionFinder; +import org.sonar.server.plugins.MimeTypes; +import org.sonar.server.user.UserSession; +import org.sonarqube.ws.Common; +import org.sonarqube.ws.Permissions; + +import static com.google.common.base.Objects.firstNonNull; +import static org.sonar.server.permission.PermissionQueryParser.toMembership; + +public class GroupsAction implements PermissionsWsAction { + private final UserSession userSession; + private final PermissionFinder permissionFinder; + + public GroupsAction(UserSession userSession, PermissionFinder permissionFinder) { + this.userSession = userSession; + this.permissionFinder = permissionFinder; + } + + @Override + public void define(WebService.NewController context) { + WebService.NewAction action = context.createAction("groups") + .setSince("5.2") + .setInternal(true) + .setDescription(String.format("List permission's groups.
" + + "If the query parameter '%s' is specified, the '%s' parameter is '%s'.", + WebService.Param.TEXT_QUERY, WebService.Param.SELECTED, WebService.SelectionMode.ALL.value())) + .addPagingParams(100) + .addSearchQuery("sonar", "names") + .addSelectionModeParam() + .setResponseExample(Resources.getResource(getClass(), "groups-example.json")) + .setHandler(this); + + action.createParam("permission") + .setExampleValue("scan") + .setRequired(true) + .setPossibleValues(GlobalPermissions.ALL); + } + + @Override + public void handle(Request request, Response response) throws Exception { + String permission = request.mandatoryParam("permission"); + String selected = request.param(WebService.Param.SELECTED); + int page = request.mandatoryParamAsInt(WebService.Param.PAGE); + int pageSize = request.mandatoryParamAsInt(WebService.Param.PAGE_SIZE); + String query = request.param(WebService.Param.TEXT_QUERY); + if (query != null) { + selected = WebService.SelectionMode.ALL.value(); + } + + userSession + .checkLoggedIn() + .checkGlobalPermission(GlobalPermissions.SYSTEM_ADMIN); + + PermissionQuery.Builder permissionQuery = PermissionQuery.builder() + .permission(permission) + .pageIndex(page) + .pageSize(pageSize) + .membership(toMembership(firstNonNull(selected, WebService.SelectionMode.SELECTED.value()))); + if (query != null) { + permissionQuery.search(query); + } + + GroupWithPermissionQueryResult groupsResult = permissionFinder.findGroupsWithPermission(permissionQuery.build()); + List groupsWithPermission = groupsResult.groups(); + + Permissions.GroupsResponse.Builder groupsResponse = Permissions.GroupsResponse.newBuilder(); + Permissions.GroupsResponse.Group.Builder group = Permissions.GroupsResponse.Group.newBuilder(); + Common.Paging.Builder paging = Common.Paging.newBuilder(); + + for (GroupWithPermission groupWithPermission : groupsWithPermission) { + group + .clear() + .setName(groupWithPermission.name()) + .setSelected(groupWithPermission.hasPermission()); + // anyone group return with id = 0 + if (groupWithPermission.id() != 0) { + group.setId(String.valueOf(groupWithPermission.id())); + } + if (groupWithPermission.description() != null) { + group.setDescription(groupWithPermission.description()); + } + + groupsResponse.addGroups(group); + } + + groupsResponse.setPaging( + paging + .setPageIndex(page) + .setPageSize(pageSize) + .setTotal(groupsResult.total()) + ); + + response.stream().setMediaType(MimeTypes.JSON); + JsonWriter json = response.newJsonWriter(); + ProtobufJsonFormat.write(groupsResponse.build(), json); + json.close(); + } +} diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java index b69487adaa8..d3c243a95af 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java @@ -31,6 +31,7 @@ public class PermissionsWsModule extends Module { AddUserAction.class, RemoveGroupAction.class, RemoveUserAction.class, - UsersAction.class); + UsersAction.class, + GroupsAction.class); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java index fc3cafe0e2d..e6681f9488e 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java @@ -112,7 +112,7 @@ public class UsersAction implements PermissionsWsAction { userResponse.setPaging( paging .clear() - .setPages(page) + .setPageIndex(page) .setPageSize(pageSize) .setTotal(usersResult.total()) ); diff --git a/server/sonar-server/src/main/java/org/sonar/server/ws/WsResponseCommonFormat.java b/server/sonar-server/src/main/java/org/sonar/server/ws/WsResponseCommonFormat.java index 0abcf579c23..f2379011fe3 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/ws/WsResponseCommonFormat.java +++ b/server/sonar-server/src/main/java/org/sonar/server/ws/WsResponseCommonFormat.java @@ -19,11 +19,9 @@ */ package org.sonar.server.ws; -import com.google.common.base.Strings; import org.sonar.api.resources.Language; import org.sonar.api.resources.Languages; import org.sonar.api.utils.Paging; -import org.sonar.db.component.ComponentDto; import org.sonar.db.rule.RuleDto; import org.sonar.db.user.UserDto; import org.sonarqube.ws.Common; @@ -41,7 +39,6 @@ public class WsResponseCommonFormat { public Common.Paging.Builder formatPaging(Paging paging) { return Common.Paging.newBuilder() .setPageIndex(paging.pageIndex()) - .setPages(paging.pages()) .setPageSize(paging.pageSize()) .setTotal(paging.total()); } diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/groups-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/groups-example.json new file mode 100644 index 00000000000..f6bef5229f2 --- /dev/null +++ b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/groups-example.json @@ -0,0 +1,25 @@ +{ + "groups": [ + { + "name": "Anyone", + "selected": true + }, + { + "id": "1", + "name": "sonar-administrators", + "description": "System administrators", + "selected": true + }, + { + "id": "2", + "name": "sonar-users", + "description": "Any new users created will automatically join this group", + "selected": true + } + ], + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 3 + } +} diff --git a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/users-example.json b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/users-example.json index b4bd9daa6b3..c8aaccb45a0 100644 --- a/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/users-example.json +++ b/server/sonar-server/src/main/resources/org/sonar/server/permission/ws/users-example.json @@ -14,7 +14,7 @@ "paging": { "pageSize": 100, "total": 2, - "pages": 1 + "pageIndex": 1 } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionFinderTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionFinderTest.java index 440878a0c8b..534bb11d8ac 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionFinderTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/PermissionFinderTest.java @@ -153,19 +153,20 @@ public class PermissionFinderTest { @Test public void find_groups() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn( newArrayList(new GroupWithPermissionDto().setName("users").setPermission("user")) ); GroupWithPermissionQueryResult result = underTest.findGroupsWithPermission( PermissionQuery.builder().permission("user").membership(PermissionQuery.IN).build()); + assertThat(result.groups()).hasSize(1); assertThat(result.hasMoreResults()).isFalse(); } @Test public void find_groups_should_be_paginated() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn(newArrayList( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn(newArrayList( new GroupWithPermissionDto().setName("Anyone").setPermission("user"), new GroupWithPermissionDto().setName("Admin").setPermission("user"), new GroupWithPermissionDto().setName("Users").setPermission(null), @@ -191,12 +192,12 @@ public class PermissionFinderTest { .permission("user") .pageSize(2) .pageIndex(3) - .build()).hasMoreResults()).isFalse(); + .build()).hasMoreResults()).isTrue(); } @Test public void find_groups_should_filter_membership() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn(newArrayList( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn(newArrayList( new GroupWithPermissionDto().setName("Anyone").setPermission("user"), new GroupWithPermissionDto().setName("Admin").setPermission("user"), new GroupWithPermissionDto().setName("Users").setPermission(null), @@ -214,7 +215,7 @@ public class PermissionFinderTest { @Test public void find_groups_with_added_anyone_group() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn( newArrayList(new GroupWithPermissionDto().setName("users").setPermission("user")) ); @@ -228,7 +229,7 @@ public class PermissionFinderTest { @Test public void find_groups_without_adding_anyone_group_when_search_text_do_not_matched() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn( newArrayList(new GroupWithPermissionDto().setName("users").setPermission("user")) ); @@ -240,7 +241,7 @@ public class PermissionFinderTest { @Test public void find_groups_with_added_anyone_group_when_search_text_matched() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn( newArrayList(new GroupWithPermissionDto().setName("MyAnyGroup").setPermission("user")) ); @@ -251,7 +252,7 @@ public class PermissionFinderTest { @Test public void find_groups_without_adding_anyone_group_when_out_membership_selected() { - when(permissionDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn( + when(permissionDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn( newArrayList(new GroupWithPermissionDto().setName("users").setPermission("user")) ); @@ -292,7 +293,7 @@ public class PermissionFinderTest { public void find_groups_from_permission_template() { when(permissionTemplateDao.selectTemplateByKey(anyString())).thenReturn(new PermissionTemplateDto().setId(1L).setKee("my_template")); - when(permissionTemplateDao.selectGroups(any(PermissionQuery.class), anyLong())).thenReturn( + when(permissionTemplateDao.selectGroups(any(DbSession.class), any(PermissionQuery.class), anyLong())).thenReturn( newArrayList(new GroupWithPermissionDto().setName("users").setPermission("user")) ); diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/GroupsActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/GroupsActionTest.java new file mode 100644 index 00000000000..094df809f61 --- /dev/null +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/GroupsActionTest.java @@ -0,0 +1,168 @@ +/* + * SonarQube, open source software quality management tool. + * Copyright (C) 2008-2014 SonarSource + * mailto:contact AT sonarsource DOT com + * + * SonarQube 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. + * + * SonarQube 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.permission.ws; + +import com.google.common.io.Resources; +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.ExpectedException; +import org.sonar.api.security.DefaultGroups; +import org.sonar.api.server.ws.WebService.Param; +import org.sonar.api.server.ws.WebService.SelectionMode; +import org.sonar.api.utils.System2; +import org.sonar.core.permission.GlobalPermissions; +import org.sonar.db.DbClient; +import org.sonar.db.DbSession; +import org.sonar.db.DbTester; +import org.sonar.db.user.GroupDto; +import org.sonar.db.user.GroupRoleDto; +import org.sonar.server.exceptions.ForbiddenException; +import org.sonar.server.exceptions.UnauthorizedException; +import org.sonar.server.permission.PermissionFinder; +import org.sonar.server.tester.UserSessionRule; +import org.sonar.server.ws.WsActionTester; +import org.sonar.test.DbTests; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.sonar.test.JsonAssert.assertJson; + +@Category(DbTests.class) +public class GroupsActionTest { + + @Rule + public ExpectedException expectedException = ExpectedException.none(); + @Rule + public UserSessionRule userSession = UserSessionRule.standalone(); + @Rule + public DbTester db = DbTester.create(System2.INSTANCE); + + DbClient dbClient; + DbSession dbSession; + WsActionTester ws; + PermissionFinder permissionFinder; + + GroupsAction underTest; + + @Before + public void setUp() { + dbClient = db.getDbClient(); + dbSession = db.getSession(); + permissionFinder = new PermissionFinder(dbClient); + userSession.login("login").setGlobalPermissions(GlobalPermissions.SYSTEM_ADMIN); + underTest = new GroupsAction(userSession, permissionFinder); + ws = new WsActionTester(underTest); + + GroupDto group1 = dbClient.groupDao().insert(dbSession, new GroupDto() + .setName("group-1-name") + .setDescription("group-1-description")); + GroupDto group2 = dbClient.groupDao().insert(dbSession, new GroupDto() + .setName("group-2-name") + .setDescription("group-2-description")); + GroupDto group3 = dbClient.groupDao().insert(dbSession, new GroupDto() + .setName("group-3-name") + .setDescription("group-3-description")); + dbClient.roleDao().insertGroupRole(dbSession, new GroupRoleDto() + .setGroupId(group1.getId()) + .setRole(GlobalPermissions.SCAN_EXECUTION)); + dbClient.roleDao().insertGroupRole(dbSession, new GroupRoleDto() + .setGroupId(group2.getId()) + .setRole(GlobalPermissions.SCAN_EXECUTION)); + dbClient.roleDao().insertGroupRole(dbSession, new GroupRoleDto() + .setGroupId(group3.getId()) + .setRole(GlobalPermissions.SYSTEM_ADMIN)); + dbSession.commit(); + } + + @Test + public void search_for_groups_with_one_permission() { + String result = ws.newRequest() + .setParam("permission", "scan") + .execute().getInput(); + + assertJson(result).isSimilarTo(Resources.getResource(getClass(), "GroupsActionTest/groups.json")); + } + + @Test + public void search_with_selection() { + String result = ws.newRequest() + .setParam("permission", "scan") + .setParam("selected", SelectionMode.ALL.value()) + .execute().getInput(); + + assertThat(result).containsSequence(DefaultGroups.ANYONE, "group-1", "group-2", "group-3"); + } + + @Test + public void search_groups_with_pagination() { + String result = ws.newRequest() + .setParam("permission", "scan") + .setParam(Param.PAGE_SIZE, "1") + .setParam(Param.PAGE, "2") + .execute().getInput(); + + assertThat(result).contains("group-2") + .doesNotContain("group-1") + .doesNotContain("group-3"); + } + + @Test + public void search_groups_with_query() { + String result = ws.newRequest() + .setParam("permission", "scan") + .setParam(Param.TEXT_QUERY, "group-") + .execute().getInput(); + + assertThat(result) + .contains("group-1", "group-2", "group-3") + .doesNotContain(DefaultGroups.ANYONE); + + } + + @Test + public void fail_if_not_logged_in() { + expectedException.expect(UnauthorizedException.class); + userSession.anonymous(); + + ws.newRequest() + .setParam("permission", "scan") + .execute(); + } + + @Test + public void fail_if_insufficient_privileges() { + expectedException.expect(ForbiddenException.class); + userSession.login("login"); + + ws.newRequest() + .setParam("permission", "scan") + .execute(); + } + + @Test + public void fail_if_permission_is_not_specified() { + expectedException.expect(IllegalArgumentException.class); + + ws.newRequest() + .execute(); + } +} diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java index f85654d5c1f..0b5afc3f979 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java @@ -30,6 +30,6 @@ public class PermissionsWsModuleTest { public void verify_count_of_added_components() { ComponentContainer container = new ComponentContainer(); new PermissionsWsModule().configure(container); - assertThat(container.size()).isEqualTo(8); + assertThat(container.size()).isEqualTo(9); } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json index 55e445b3297..13af5a2ede8 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/default_page_size_is_100.json @@ -5,7 +5,6 @@ "paging": { "pageIndex": 1, "pageSize": 100, - "total": 0, - "pages": 0 + "total": 0 } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/deprecated_paging.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/deprecated_paging.json index 35ed37d52a4..f996885b3cd 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/deprecated_paging.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/deprecated_paging.json @@ -2,7 +2,6 @@ "paging": { "pageIndex": 2, "pageSize": 9, - "total": 12, - "pages": 2 + "total": 12 } } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json index 0448735ef0c..acda7495d25 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/issue/ws/SearchActionMediumTest/empty_result.json @@ -5,8 +5,7 @@ "paging": { "pageIndex": 1, "pageSize": 100, - "total": 0, - "pages": 0 + "total": 0 }, "issues": [] } diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/GroupsActionTest/groups.json b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/GroupsActionTest/groups.json new file mode 100644 index 00000000000..f48cdd22d7b --- /dev/null +++ b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/GroupsActionTest/groups.json @@ -0,0 +1,19 @@ +{ + "groups": [ + { + "name": "group-1-name", + "description": "group-1-description", + "selected": true + }, + { + "name": "group-2-name", + "description": "group-2-description", + "selected": true + } + ], + "paging": { + "pageIndex": 1, + "pageSize": 100, + "total": 2 + } +} diff --git a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/UsersActionTest/users.json b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/UsersActionTest/users.json index a3ecb8c0729..6be0c984be2 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/UsersActionTest/users.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/permission/ws/UsersActionTest/users.json @@ -14,6 +14,6 @@ "paging": { "pageSize": 100, "total": 2, - "pages": 1 + "pageIndex": 1 } } diff --git a/sonar-db/src/main/java/org/sonar/core/permission/GroupWithPermission.java b/sonar-db/src/main/java/org/sonar/core/permission/GroupWithPermission.java index 0dcc1d7ce1d..29f3a296c2b 100644 --- a/sonar-db/src/main/java/org/sonar/core/permission/GroupWithPermission.java +++ b/sonar-db/src/main/java/org/sonar/core/permission/GroupWithPermission.java @@ -27,10 +27,20 @@ import org.apache.commons.lang.builder.ToStringStyle; public class GroupWithPermission { + private long id; private String name; private String description; private boolean hasPermission; + public long id() { + return id; + } + + public GroupWithPermission setId(Long id) { + this.id = id; + return this; + } + public String name() { return name; } diff --git a/sonar-db/src/main/java/org/sonar/db/permission/GroupWithPermissionDto.java b/sonar-db/src/main/java/org/sonar/db/permission/GroupWithPermissionDto.java index 2dbcd04203c..3df694d5814 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/GroupWithPermissionDto.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/GroupWithPermissionDto.java @@ -26,10 +26,19 @@ import org.sonar.core.permission.GroupWithPermission; public class GroupWithPermissionDto { + private long id; private String name; private String permission; private String description; + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } + public String getName() { return name; } @@ -61,6 +70,7 @@ public class GroupWithPermissionDto { public GroupWithPermission toGroupWithPermission() { return new GroupWithPermission() + .setId(id) .setName(name) .setDescription(description) .hasPermission(permission != null); diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java index ae1ae1b65da..033a7fa5cc4 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java @@ -71,20 +71,33 @@ public class PermissionDao implements Dao { * * @return a non paginated list of groups. */ + public List selectGroups(DbSession session, PermissionQuery query, @Nullable Long componentId) { + Map params = groupsParameters(query, componentId); + return mapper(session).selectGroups(params); + } + public List selectGroups(PermissionQuery query, @Nullable Long componentId) { - SqlSession session = myBatis.openSession(false); + DbSession session = myBatis.openSession(false); try { - Map params = newHashMap(); - params.put(QUERY_PARAMETER, query); - params.put(COMPONENT_ID_PARAMETER, componentId); - params.put("anyoneGroup", DefaultGroups.ANYONE); - - return mapper(session).selectGroups(params); + return selectGroups(session, query, componentId); } finally { MyBatis.closeQuietly(session); } } + public int countGroups(DbSession session, PermissionQuery query, @Nullable Long componentId) { + Map parameters = groupsParameters(query, componentId); + return mapper(session).countGroups(parameters); + } + + private static Map groupsParameters(PermissionQuery query, @Nullable Long componentId) { + Map params = newHashMap(); + params.put(QUERY_PARAMETER, query); + params.put(COMPONENT_ID_PARAMETER, componentId); + params.put("anyoneGroup", DefaultGroups.ANYONE); + return params; + } + private PermissionMapper mapper(SqlSession session) { return session.getMapper(PermissionMapper.class); } diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java index 0bf57813c53..8fa088809fe 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java @@ -28,7 +28,9 @@ public interface PermissionMapper { List selectUsers(Map parameters, RowBounds rowBounds); + int countUsers(Map parameters); + List selectGroups(Map parameters); - int countUsers(Map parameters); + int countGroups(Map parameters); } diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateDao.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateDao.java index 30945f54e72..e94b7484353 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateDao.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateDao.java @@ -89,19 +89,33 @@ public class PermissionTemplateDao implements Dao { * Membership parameter from query is not taking into account in order to deal more easily with the 'Anyone' group. * @return a non paginated list of groups. */ + public List selectGroups(DbSession session, PermissionQuery query, Long templateId) { + Map params = groupsParamaters(query, templateId); + return mapper(session).selectGroups(params); + } + public List selectGroups(PermissionQuery query, Long templateId) { - SqlSession session = myBatis.openSession(false); + DbSession session = myBatis.openSession(false); try { - Map params = newHashMap(); - params.put(QUERY_PARAMETER, query); - params.put(TEMPLATE_ID_PARAMETER, templateId); - params.put("anyoneGroup", DefaultGroups.ANYONE); - return mapper(session).selectGroups(params); + return selectGroups(session, query, templateId); } finally { MyBatis.closeQuietly(session); } } + public int countGroups(DbSession session, PermissionQuery query, Long templateId) { + Map parameters = groupsParamaters(query, templateId); + return mapper(session).countGroups(parameters); + } + + private Map groupsParamaters(PermissionQuery query, Long templateId) { + Map params = newHashMap(); + params.put(QUERY_PARAMETER, query); + params.put(TEMPLATE_ID_PARAMETER, templateId); + params.put("anyoneGroup", DefaultGroups.ANYONE); + return params; + } + @CheckForNull public PermissionTemplateDto selectTemplateByKey(DbSession session, String templateKey) { return mapper(session).selectByKey(templateKey); diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateMapper.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateMapper.java index be35219518e..bd3aaeb3afa 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateMapper.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionTemplateMapper.java @@ -60,4 +60,6 @@ public interface PermissionTemplateMapper { List selectUsers(Map params, RowBounds rowBounds); int countUsers(Map params); + + int countGroups(Map parameters); } diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml index a2e01badf9b..99d8dd14ea4 100644 --- a/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml @@ -41,8 +41,8 @@ + diff --git a/sonar-db/src/main/resources/org/sonar/db/permission/PermissionTemplateMapper.xml b/sonar-db/src/main/resources/org/sonar/db/permission/PermissionTemplateMapper.xml index 5ca9eb2859f..260baeb1d90 100644 --- a/sonar-db/src/main/resources/org/sonar/db/permission/PermissionTemplateMapper.xml +++ b/sonar-db/src/main/resources/org/sonar/db/permission/PermissionTemplateMapper.xml @@ -123,6 +123,30 @@ ORDER BY groups.name + +