*/
package org.sonar.server.permission;
-import com.google.common.base.Predicate;
-import com.google.common.collect.Iterables;
-import java.util.Collection;
+import com.google.common.collect.Ordering;
import java.util.List;
-import javax.annotation.Nonnull;
-import javax.annotation.Nullable;
+import java.util.stream.Collectors;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.server.ServerSide;
-import org.sonar.api.utils.Paging;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
-import org.sonar.db.component.ResourceDao;
-import org.sonar.db.component.ResourceDto;
-import org.sonar.db.component.ResourceQuery;
-import org.sonar.db.permission.GroupWithPermissionDto;
-import org.sonar.db.permission.OldPermissionQuery;
import org.sonar.db.permission.PermissionDao;
-import org.sonar.server.exceptions.NotFoundException;
+import org.sonar.db.permission.PermissionQuery;
+import org.sonar.db.user.GroupDao;
+import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.GroupRoleDto;
-import static com.google.common.collect.Lists.newArrayList;
-import static org.apache.commons.lang.StringUtils.containsIgnoreCase;
-import static org.sonar.api.utils.Paging.forPageIndex;
+import static java.util.Collections.emptyList;
@ServerSide
public class PermissionFinder {
private final PermissionDao permissionDao;
- private final ResourceDao resourceDao;
+ private final GroupDao groupDao;
public PermissionFinder(DbClient dbClient) {
- this.resourceDao = dbClient.resourceDao();
this.permissionDao = dbClient.permissionDao();
+ this.groupDao = dbClient.groupDao();
}
- /**
- * Paging for groups search is done in Java in order to correctly handle the 'Anyone' group
- */
- public List<GroupWithPermissionDto> findGroupsWithPermission(DbSession dbSession, OldPermissionQuery query) {
- Long componentId = componentId(query.component());
- return toGroupQueryResult(permissionDao.selectGroups(dbSession, query, componentId), query);
- }
-
- @Nullable
- private Long componentId(@Nullable String componentKey) {
- if (componentKey == null) {
- return null;
- } else {
- ResourceDto resourceDto = resourceDao.selectResource(ResourceQuery.create().setKey(componentKey));
- if (resourceDto == null) {
- throw new NotFoundException(String.format("Project '%s' does not exist", componentKey));
- }
- return resourceDto.getId();
- }
- }
-
- private static List<GroupWithPermissionDto> toGroupQueryResult(List<GroupWithPermissionDto> dtos, OldPermissionQuery query) {
- addAnyoneGroup(dtos, query);
- List<GroupWithPermissionDto> filteredDtos = filterMembership(dtos, query);
-
- Paging paging = forPageIndex(query.pageIndex())
- .withPageSize(query.pageSize())
- .andTotal(filteredDtos.size());
-
- return pagedGroups(filteredDtos, paging);
- }
-
- private static List<GroupWithPermissionDto> filterMembership(List<GroupWithPermissionDto> dtos, OldPermissionQuery query) {
- return newArrayList(Iterables.filter(dtos, new GroupWithPermissionMatchQuery(query)));
- }
+ public List<GroupDto> findGroups(DbSession dbSession, PermissionQuery.Builder dbQuery) {
+ List<String> orderedNames = permissionDao.selectGroupNamesByPermissionQuery(dbSession, dbQuery.build());
- /**
- * As the anyone group does not exists in db, it's not returned when it has not the permission.
- * We have to manually add it at the begin of the list, if it matched the search text
- */
- private static void addAnyoneGroup(List<GroupWithPermissionDto> groups, OldPermissionQuery query) {
- boolean hasAnyoneGroup = Iterables.any(groups, IsAnyoneGroup.INSTANCE);
- if (!hasAnyoneGroup
- && !GlobalPermissions.SYSTEM_ADMIN.equals(query.permission())
- && (query.search() == null || containsIgnoreCase(DefaultGroups.ANYONE, query.search()))) {
- groups.add(0, new GroupWithPermissionDto().setName(DefaultGroups.ANYONE));
+ List<GroupDto> groups = groupDao.selectByNames(dbSession, orderedNames);
+ if (orderedNames.contains(DefaultGroups.ANYONE)) {
+ groups.add(0, new GroupDto().setId(0L).setName(DefaultGroups.ANYONE));
}
- }
- private static List<GroupWithPermissionDto> pagedGroups(Collection<GroupWithPermissionDto> dtos, Paging paging) {
- List<GroupWithPermissionDto> groups = newArrayList();
- int index = 0;
- for (GroupWithPermissionDto dto : dtos) {
- if (index >= paging.offset() && groups.size() < paging.pageSize()) {
- groups.add(dto);
- } else if (groups.size() >= paging.pageSize()) {
- break;
- }
- index++;
- }
- return groups;
+ return Ordering.explicit(orderedNames).onResultOf(GroupDto::getName).immutableSortedCopy(groups);
}
- private static class GroupWithPermissionMatchQuery implements Predicate<GroupWithPermissionDto> {
- private final OldPermissionQuery query;
-
- public GroupWithPermissionMatchQuery(OldPermissionQuery query) {
- this.query = query;
+ public List<GroupRoleDto> findGroupPermissions(DbSession dbSession, PermissionQuery.Builder dbQuery, List<GroupDto> groups) {
+ if (groups.isEmpty()) {
+ return emptyList();
}
- @Override
- public boolean apply(@Nonnull GroupWithPermissionDto dto) {
- if (OldPermissionQuery.IN.equals(query.membership())) {
- return dto.getPermission() != null;
- } else if (OldPermissionQuery.OUT.equals(query.membership())) {
- return dto.getPermission() == null;
- }
- return true;
- }
- }
-
- private enum IsAnyoneGroup implements Predicate<GroupWithPermissionDto> {
- INSTANCE;
-
- @Override
- public boolean apply(@Nonnull GroupWithPermissionDto group) {
- return group.getName().equals(DefaultGroups.ANYONE);
- }
+ List<String> names = groups.stream().map(GroupDto::getName).collect(Collectors.toList());
+ return permissionDao.selectGroupPermissionsByQuery(dbSession, dbQuery
+ .setGroupNames(names)
+ .withPermissionOnly()
+ .build());
}
}
package org.sonar.server.permission.ws;
import com.google.common.base.Optional;
+import com.google.common.collect.Multimap;
+import com.google.common.collect.TreeMultimap;
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.server.ws.WebService.Param;
-import org.sonar.api.server.ws.WebService.SelectionMode;
+import org.sonar.api.utils.Paging;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.component.ComponentDto;
-import org.sonar.db.permission.GroupWithPermissionDto;
-import org.sonar.db.permission.OldPermissionQuery;
+import org.sonar.db.permission.PermissionQuery;
+import org.sonar.db.user.GroupDto;
+import org.sonar.db.user.GroupRoleDto;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.Common;
import org.sonarqube.ws.WsPermissions.Group;
import org.sonarqube.ws.WsPermissions.WsGroupsResponse;
import org.sonarqube.ws.client.permission.GroupsWsRequest;
-import static com.google.common.base.MoreObjects.firstNonNull;
+import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
+import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE;
+import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentDto;
-import static org.sonar.server.permission.ws.PermissionQueryParser.fromSelectionModeToMembership;
-import static org.sonar.server.permission.ws.PermissionRequestValidator.validateGlobalPermission;
-import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
+import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectParameters;
import static org.sonar.server.permission.ws.WsProjectRef.newOptionalWsProjectRef;
WebService.NewAction action = context.createAction("groups")
.setSince("5.2")
.setInternal(true)
- .setDescription(String.format("Lists the groups that have been explicitly granted the specified permission. <br />" +
- "This service defaults to global permissions, but can be limited to project permissions by providing a project id or project key. <br />" +
- "If the query parameter '%s' is specified, the '%s' parameter is forced to '%s'. <br />" +
- "It requires administration permissions to access.",
- Param.TEXT_QUERY, Param.SELECTED, SelectionMode.ALL.value()))
- .addPagingParams(100)
- .addSearchQuery("sonar", "names")
- .addSelectionModeParam()
+ .setDescription("Lists the groups with their permissions.<br>" +
+ "This service defaults to global permissions, but can be limited to project permissions by providing project id or project key.<br> " +
+ "This service defaults to all groups, but can be limited to groups with a specific permission by providing the desired permission.<br>" +
+ "It requires administration permissions to access.")
+ .addPagingParams(DEFAULT_PAGE_SIZE, RESULTS_MAX_SIZE)
+ .addSearchQuery("sonar", "names").setDescription("Limit search to group names that contain the supplied string. Must have at least %d characters.<br/>" +
+ "When this parameter is not set, only groups having at least one permission are returned.", SEARCH_QUERY_MIN_LENGTH)
.setResponseExample(Resources.getResource(getClass(), "groups-example.json"))
.setHandler(this);
- createPermissionParameter(action);
+ createPermissionParameter(action)
+ .setRequired(false);
createProjectParameters(action);
}
Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()));
checkProjectAdminUserByComponentDto(userSession, project);
- OldPermissionQuery permissionQuery = buildPermissionQuery(request, project);
- Long projectIdIfPresent = project.isPresent() ? project.get().getId() : null;
- int total = dbClient.permissionDao().countGroups(dbSession, permissionQuery.permission(), projectIdIfPresent);
- List<GroupWithPermissionDto> groupsWithPermission = permissionFinder.findGroupsWithPermission(dbSession, permissionQuery);
- return buildResponse(groupsWithPermission, request, total);
+ PermissionQuery.Builder dbQuery = buildPermissionQuery(request, project);
+ List<GroupDto> groups = permissionFinder.findGroups(dbSession, dbQuery);
+ int total = dbClient.permissionDao().countGroupsByPermissionQuery(dbSession, dbQuery.build());
+ List<GroupRoleDto> groupsWithPermission = permissionFinder.findGroupPermissions(dbSession, dbQuery, groups);
+ return buildResponse(groups, groupsWithPermission, Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total));
} finally {
dbClient.closeSession(dbSession);
}
}
private static GroupsWsRequest toGroupsWsRequest(Request request) {
- String permission = request.mandatoryParam(PARAM_PERMISSION);
- String projectUuid = request.param(PARAM_PROJECT_ID);
- String projectKey = request.param(PARAM_PROJECT_KEY);
- if (newOptionalWsProjectRef(projectUuid, projectKey).isPresent()) {
- validateProjectPermission(permission);
- } else {
- validateGlobalPermission(permission);
- }
-
- return new GroupsWsRequest()
- .setPermission(permission)
- .setProjectId(projectUuid)
- .setProjectKey(projectKey)
+ GroupsWsRequest groupsRequest = new GroupsWsRequest()
+ .setPermission(request.param(PARAM_PERMISSION))
+ .setProjectId(request.param(PARAM_PROJECT_ID))
+ .setProjectKey(request.param(PARAM_PROJECT_KEY))
.setPage(request.mandatoryParamAsInt(Param.PAGE))
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE))
- .setQuery(request.param(Param.TEXT_QUERY))
- .setSelected(request.mandatoryParam(Param.SELECTED));
+ .setQuery(request.param(Param.TEXT_QUERY));
+
+ Optional<WsProjectRef> wsProjectRef = newOptionalWsProjectRef(groupsRequest.getProjectId(), groupsRequest.getProjectKey());
+ validatePermission(groupsRequest.getPermission(), wsProjectRef);
+ return groupsRequest;
}
- private static OldPermissionQuery buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) {
- OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder()
- .permission(request.getPermission())
- .pageIndex(request.getPage())
- .pageSize(request.getPageSize())
- .membership(fromSelectionModeToMembership(firstNonNull(request.getSelected(), SelectionMode.SELECTED.value())))
- .search(request.getQuery());
+ private static PermissionQuery.Builder buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) {
+ PermissionQuery.Builder permissionQuery = PermissionQuery.builder()
+ .setPermission(request.getPermission())
+ .setPageIndex(request.getPage())
+ .setPageSize(request.getPageSize())
+ .setSearchQuery(request.getQuery());
if (project.isPresent()) {
- permissionQuery.component(project.get().getKey());
+ permissionQuery.setComponentUuid(project.get().uuid());
}
-
- return permissionQuery.build();
+ if (request.getQuery() == null) {
+ permissionQuery.withPermissionOnly();
+ }
+ return permissionQuery;
}
- private static WsGroupsResponse buildResponse(List<GroupWithPermissionDto> groupsWithPermission, GroupsWsRequest permissionRequest, int total) {
- WsGroupsResponse.Builder groupsResponse = WsGroupsResponse.newBuilder();
- Group.Builder group = Group.newBuilder();
- Common.Paging.Builder paging = Common.Paging.newBuilder();
-
- for (GroupWithPermissionDto groupWithPermission : groupsWithPermission) {
- group
- .clear()
- .setName(groupWithPermission.getName())
- .setSelected(groupWithPermission.getPermission() != null);
- // anyone group return with id = 0
- if (groupWithPermission.getId() != 0) {
- group.setId(String.valueOf(groupWithPermission.getId()));
+ private static WsGroupsResponse buildResponse(List<GroupDto> groups, List<GroupRoleDto> groupPermissions, Paging paging) {
+ Multimap<Long, String> permissionsByGroupId = TreeMultimap.create();
+ groupPermissions.forEach(groupPermission -> permissionsByGroupId.put(groupPermission.getGroupId(), groupPermission.getRole()));
+ WsGroupsResponse.Builder response = WsGroupsResponse.newBuilder();
+
+ groups.forEach(group -> {
+ Group.Builder wsGroup = response.addGroupsBuilder()
+ .setName(group.getName());
+ if (group.getId() != 0L) {
+ wsGroup.setId(String.valueOf(group.getId()));
}
- if (groupWithPermission.getDescription() != null) {
- group.setDescription(groupWithPermission.getDescription());
+ if (group.getDescription() != null) {
+ wsGroup.setDescription(group.getDescription());
}
+ wsGroup.addAllPermissions(permissionsByGroupId.get(group.getId()));
+ });
- groupsResponse.addGroups(group);
- }
-
- groupsResponse.setPaging(
- paging
- .setPageIndex(permissionRequest.getPage())
- .setPageSize(permissionRequest.getPageSize())
- .setTotal(total));
+ response.getPagingBuilder()
+ .setPageIndex(paging.pageIndex())
+ .setPageSize(paging.pageSize())
+ .setTotal(paging.total());
- return groupsResponse.build();
+ return response.build();
}
}
import org.sonar.db.permission.OldPermissionQuery;
import org.sonar.db.permission.template.PermissionTemplateDto;
import org.sonar.server.user.UserSession;
-import org.sonarqube.ws.WsPermissions.Group;
-import org.sonarqube.ws.WsPermissions.WsGroupsResponse;
+import org.sonarqube.ws.WsPermissions.OldGroup;
+import org.sonarqube.ws.WsPermissions.WsTemplateGroupsResponse;
import static org.sonar.server.permission.PermissionPrivilegeChecker.checkGlobalAdminUser;
import static org.sonar.server.permission.ws.PermissionQueryParser.fromSelectionModeToMembership;
import static org.sonar.server.permission.ws.PermissionRequestValidator.validateProjectPermission;
-import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createProjectPermissionParameter;
import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createTemplateParameters;
import static org.sonar.server.ws.WsUtils.writeProtobuf;
+import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION;
public class TemplateGroupsAction implements PermissionsWsAction {
private final DbClient dbClient;
PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, templateRef);
OldPermissionQuery query = buildQuery(wsRequest, template);
- WsGroupsResponse groupsResponse = buildResponse(dbSession, query, template);
+ WsTemplateGroupsResponse groupsResponse = buildResponse(dbSession, query, template);
writeProtobuf(groupsResponse, wsRequest, wsResponse);
} finally {
}
}
- private WsGroupsResponse buildResponse(DbSession dbSession, OldPermissionQuery query, PermissionTemplateDto template) {
+ private WsTemplateGroupsResponse buildResponse(DbSession dbSession, OldPermissionQuery query, PermissionTemplateDto template) {
int total = dbClient.permissionTemplateDao().countGroups(dbSession, query, template.getId());
List<GroupWithPermissionDto> groupsWithPermission = dbClient.permissionTemplateDao().selectGroups(dbSession, query, template.getId(), query.pageOffset(), query.pageSize());
- WsGroupsResponse.Builder groupsResponse = WsGroupsResponse.newBuilder();
+ WsTemplateGroupsResponse.Builder groupsResponse = WsTemplateGroupsResponse.newBuilder();
for (GroupWithPermissionDto groupWithPermission : groupsWithPermission) {
groupsResponse.addGroups(groupDtoToGroupResponse(groupWithPermission));
return permissionQuery.build();
}
- private static Group groupDtoToGroupResponse(GroupWithPermissionDto groupDto) {
- Group.Builder groupBuilder = Group.newBuilder();
+ private static OldGroup groupDtoToGroupResponse(GroupWithPermissionDto groupDto) {
+ OldGroup.Builder groupBuilder = OldGroup.newBuilder();
groupBuilder
.setName(groupDto.getName())
.setSelected(groupDto.getPermission() != null);
{
+ "paging": {
+ "pageIndex": 1,
+ "pageSize": 100,
+ "total": 3
+ },
"groups": [
{
"name": "Anyone",
- "selected": true
+ "permissions": []
},
{
"id": "1",
"name": "sonar-administrators",
"description": "System administrators",
- "selected": true
+ "permissions": []
},
{
"id": "2",
"name": "sonar-users",
"description": "Any new users created will automatically join this group",
- "selected": true
+ "permissions": []
}
- ],
- "paging": {
- "pageIndex": 1,
- "pageSize": 100,
- "total": 3
- }
+ ]
}
import org.junit.rules.ExpectedException;
import org.sonar.api.resources.Qualifiers;
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.api.web.UserRole;
-import org.sonar.core.permission.GlobalPermissions;
import org.sonar.db.DbClient;
import org.sonar.db.DbSession;
import org.sonar.db.DbTester;
import org.sonar.server.ws.WsActionTester;
import static org.assertj.core.api.Assertions.assertThat;
-import static org.sonar.api.server.ws.WebService.Param.SELECTED;
+import static org.sonar.api.server.ws.WebService.Param.PAGE;
+import static org.sonar.api.server.ws.WebService.Param.PAGE_SIZE;
+import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY;
+import static org.sonar.api.web.UserRole.ADMIN;
import static org.sonar.api.web.UserRole.ISSUE_ADMIN;
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION;
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID;
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_KEY;
-
public class GroupsActionTest {
@Rule
public UserSessionRule userSession = UserSessionRule.standalone();
@Rule
public DbTester db = DbTester.create(System2.INSTANCE);
+
ComponentDbTester componentDb = new ComponentDbTester(db);
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV");
GroupDto group3 = insertGroup(new GroupDto().setName("group-3-name").setDescription("group-3-description"));
insertGroupRole(new GroupRoleDto().setGroupId(group1.getId()).setRole(SCAN_EXECUTION));
insertGroupRole(new GroupRoleDto().setGroupId(group2.getId()).setRole(SCAN_EXECUTION));
+ insertGroupRole(new GroupRoleDto().setGroupId(null).setRole(SCAN_EXECUTION));
insertGroupRole(new GroupRoleDto().setGroupId(group3.getId()).setRole(SYSTEM_ADMIN));
}
@Test
public void search_with_selection() {
String result = ws.newRequest()
- .setParam(PARAM_PERMISSION, GlobalPermissions.SCAN_EXECUTION)
- .setParam(SELECTED, SelectionMode.ALL.value())
- .execute().getInput();
-
- assertThat(result).containsSequence(DefaultGroups.ANYONE, "group-1", "group-2", "group-3");
- }
-
- @Test
- public void search_with_admin_does_not_return_anyone() {
- String result = ws.newRequest()
- .setParam(PARAM_PERMISSION, GlobalPermissions.SYSTEM_ADMIN)
- .setParam(SELECTED, SelectionMode.ALL.value())
+ .setParam(PARAM_PERMISSION, SCAN_EXECUTION)
.execute().getInput();
- assertThat(result).containsSequence("group-1", "group-2", "group-3")
- .doesNotContain(DefaultGroups.ANYONE);
+ assertThat(result).containsSequence(DefaultGroups.ANYONE, "group-1", "group-2");
}
@Test
public void search_groups_with_pagination() {
String result = ws.newRequest()
- .setParam(PARAM_PERMISSION, "scan")
- .setParam(Param.PAGE_SIZE, "1")
- .setParam(Param.PAGE, "2")
+ .setParam(PARAM_PERMISSION, SCAN_EXECUTION)
+ .setParam(PAGE_SIZE, "1")
+ .setParam(PAGE, "3")
.execute().getInput();
assertThat(result).contains("group-2")
@Test
public void search_groups_with_query() {
String result = ws.newRequest()
- .setParam(PARAM_PERMISSION, "scan")
- .setParam(Param.TEXT_QUERY, "group-")
+ .setParam(PARAM_PERMISSION, SCAN_EXECUTION)
+ .setParam(TEXT_QUERY, "group-")
.execute().getInput();
assertThat(result)
@Test
public void search_groups_with_project_permissions() {
- dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key"));
- ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, "project-uuid");
+ userSession.login().addProjectUuidPermissions(ADMIN, "project-uuid");
+
+ ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid"));
GroupDto group = insertGroup(new GroupDto().setName("project-group-name"));
insertGroupRole(new GroupRoleDto()
.setGroupId(group.getId())
.setRole(ISSUE_ADMIN)
.setResourceId(project.getId()));
- userSession.login().addProjectUuidPermissions(UserRole.ADMIN, "project-uuid");
+
+ ComponentDto anotherProject = componentDb.insertComponent(newProjectDto());
+ GroupDto anotherGroup = insertGroup(new GroupDto().setName("another-project-group-name"));
+ insertGroupRole(new GroupRoleDto()
+ .setGroupId(anotherGroup.getId())
+ .setRole(ISSUE_ADMIN)
+ .setResourceId(anotherProject.getId()));
+
+ GroupDto groupWithoutPermission = insertGroup(new GroupDto().setName("group-without-permission"));
+
+ String result = ws.newRequest()
+ .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
+ .setParam(PARAM_PROJECT_ID, "project-uuid")
+ .execute().getInput();
+
+ assertThat(result).contains(group.getName())
+ .doesNotContain(anotherGroup.getName())
+ .doesNotContain(groupWithoutPermission.getName());
+ }
+
+ @Test
+ public void return_only_for_groups_with_permission_when_no_search_query() {
+ userSession.login().setGlobalPermissions(SYSTEM_ADMIN);
+
+ ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid"));
+ GroupDto group = insertGroup(new GroupDto().setName("group-with-permission"));
+ insertGroupRole(new GroupRoleDto()
+ .setGroupId(group.getId())
+ .setRole(ISSUE_ADMIN)
+ .setResourceId(project.getId()));
+
+ GroupDto groupWithoutPermission = insertGroup(new GroupDto().setName("group-without-permission"));
+ GroupDto anotherGroup = insertGroup(new GroupDto().setName("another-group"));
+
+ String result = ws.newRequest()
+ .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
+ .setParam(PARAM_PROJECT_ID, "project-uuid")
+ .setParam(TEXT_QUERY, "group-with")
+ .execute().getInput();
+
+ assertThat(result).contains(group.getName())
+ .doesNotContain(groupWithoutPermission.getName())
+ .doesNotContain(anotherGroup.getName());
+ }
+
+ @Test
+ public void return_also_for_groups_without_permission_when_search_query() {
+ userSession.login().setGlobalPermissions(SYSTEM_ADMIN);
+
+ ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid"));
+ GroupDto group = insertGroup(new GroupDto().setName("project-group-name"));
+ insertGroupRole(new GroupRoleDto()
+ .setGroupId(group.getId())
+ .setRole(ISSUE_ADMIN)
+ .setResourceId(project.getId()));
+
+ GroupDto groupWithoutPermission = insertGroup(new GroupDto().setName("group-without-permission"));
String result = ws.newRequest()
.setParam(PARAM_PERMISSION, ISSUE_ADMIN)
.execute().getInput();
assertThat(result).contains("project-group-name")
- .doesNotContain("group-1")
- .doesNotContain("group-2")
- .doesNotContain("group-3");
+ .doesNotContain(groupWithoutPermission.getName());
}
@Test
expectedException.expect(BadRequestException.class);
ws.newRequest()
- .setParam(PARAM_PERMISSION, UserRole.ISSUE_ADMIN)
+ .setParam(PARAM_PERMISSION, ISSUE_ADMIN)
.execute();
}
.execute();
}
- @Test
- public void fail_if_permission_is_not_specified() {
- expectedException.expect(IllegalArgumentException.class);
-
- ws.newRequest()
- .execute();
- }
-
@Test
public void fail_if_project_uuid_and_project_key_are_provided() {
expectedException.expect(BadRequestException.class);
{
+ "paging": {
+ "pageIndex": 1,
+ "pageSize": 20,
+ "total": 3
+ },
"groups": [
+ {
+ "name": "Anyone",
+ "permissions": [
+ "scan"
+ ]
+ },
{
"name": "group-1-name",
"description": "group-1-description",
- "selected": true
+ "permissions": [
+ "scan"
+ ]
},
{
"name": "group-2-name",
"description": "group-2-description",
- "selected": true
+ "permissions": [
+ "scan"
+ ]
}
- ],
- "paging": {
- "pageIndex": 1,
- "pageSize": 100,
- "total": 2
- }
+ ]
}
}
public Builder setPermission(@Nullable String permission) {
+ this.withPermissionOnly = permission != null;
this.permission = permission;
return this;
}
import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
-import static java.util.Objects.requireNonNull;
-
public class GroupsWsRequest {
private String permission;
private String projectId;
private Integer page;
private Integer pageSize;
private String query;
- private String selected;
+ @CheckForNull
public String getPermission() {
return permission;
}
- public GroupsWsRequest setPermission(String permission) {
- this.permission = requireNonNull(permission, "permission must not be null");
+ public GroupsWsRequest setPermission(@Nullable String permission) {
+ this.permission = permission;
return this;
}
this.query = query;
return this;
}
-
- public String getSelected() {
- return selected;
- }
-
- public GroupsWsRequest setSelected(String selected) {
- this.selected = requireNonNull(selected, "selected must not be null");
- return this;
- }
}
.setParam(PARAM_PROJECT_KEY, request.getProjectKey())
.setParam("p", request.getPage())
.setParam("ps", request.getPageSize())
- .setParam("selected", request.getSelected())
.setParam("q", request.getQuery());
return call(get, WsPermissions.WsGroupsResponse.parser());
}
}
// WS api/permissions/groups for internal use only
-// and WS api/permissions/template_groups for internal use only
message WsGroupsResponse {
optional sonarqube.ws.commons.Paging paging = 1;
repeated Group groups = 2;
}
+// WS api/permissions/template_groups for internal use only
+message WsTemplateGroupsResponse {
+ optional sonarqube.ws.commons.Paging paging = 1;
+ repeated OldGroup groups = 2;
+}
+
message WsSearchGlobalPermissionsResponse {
repeated Permission permissions = 1;
}
repeated string permissions = 4;
}
-message Group {
+message OldGroup {
optional string id = 1;
optional string name = 2;
optional string description = 3;
optional bool selected = 4;
}
+
+message Group {
+ optional string id = 1;
+ optional string name = 2;
+ optional string description = 3;
+ repeated string permissions = 4;
+}
.setProjectKey(PROJECT_KEY_VALUE)
.setPage(PAGE_VALUE)
.setPageSize(PAGE_SIZE_VALUE)
- .setSelected(SELECTED_VALUE)
.setQuery(QUERY_VALUE));
assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.WsGroupsResponse.parser());
.hasParam(PARAM_PROJECT_KEY, PROJECT_KEY_VALUE)
.hasParam(PARAM_P, PAGE_VALUE)
.hasParam(PARAM_PS, PAGE_SIZE_VALUE)
- .hasParam(PARAM_SELECTED, SELECTED_VALUE)
.hasParam(PARAM_Q, QUERY_VALUE)
.andNoOtherParam();
}