From fc558542c4d6bbeb0b5f98314f9697c48d35a9a4 Mon Sep 17 00:00:00 2001 From: Teryk Bellahsene Date: Tue, 5 Jul 2016 14:53:32 +0200 Subject: [PATCH] SONAR-7835 Select users by query --- .../server/permission/PermissionFinder.java | 22 +- .../server/permission/ws/GroupsAction.java | 8 +- .../server/permission/ws/OldUsersAction.java | 8 +- .../ws/PermissionsWsParametersBuilder.java | 4 +- .../ws/SearchGlobalPermissionsAction.java | 10 +- .../permission/ws/TemplateGroupsAction.java | 10 +- .../permission/ws/TemplateUsersAction.java | 10 +- .../server/permission/ws/UsersAction.java | 19 +- .../ws/template/AddGroupToTemplateAction.java | 4 +- .../ws/template/AddUserToTemplateAction.java | 4 +- .../AddGroupToTemplateActionTest.java | 4 +- .../template/AddUserToTemplateActionTest.java | 4 +- .../ws/template/ApplyTemplateActionTest.java | 6 +- .../template/BulkApplyTemplateActionTest.java | 6 +- .../RemoveGroupFromTemplateActionTest.java | 4 +- .../RemoveUserFromTemplateActionTest.java | 4 +- .../db/permission/OldPermissionQuery.java | 206 ++++++++++++++++++ .../sonar/db/permission/PermissionDao.java | 30 ++- .../sonar/db/permission/PermissionMapper.java | 8 + .../sonar/db/permission/PermissionQuery.java | 149 +++++-------- .../db/permission/PermissionTemplateDao.java | 22 +- .../java/org/sonar/db/permission/UserRef.java | 34 +++ .../sonar/db/permission/PermissionMapper.xml | 62 ++++++ .../GroupWithPermissionDaoTest.java | 21 +- .../GroupWithPermissionTemplateDaoTest.java | 10 +- .../db/permission/OldPermissionQueryTest.java | 9 +- .../db/permission/PermissionDbTester.java | 53 +++++ .../permission/UserWithPermissionDaoTest.java | 202 +++++++++++++---- .../UserWithPermissionTemplateDaoTest.java | 22 +- 29 files changed, 700 insertions(+), 255 deletions(-) create mode 100644 sonar-db/src/main/java/org/sonar/db/permission/OldPermissionQuery.java create mode 100644 sonar-db/src/main/java/org/sonar/db/permission/UserRef.java rename server/sonar-server/src/test/java/org/sonar/server/permission/PermissionQueryTest.java => sonar-db/src/test/java/org/sonar/db/permission/OldPermissionQueryTest.java (86%) create mode 100644 sonar-db/src/test/java/org/sonar/db/permission/PermissionDbTester.java 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 554e24a0d7d..15949413fab 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 @@ -36,7 +36,7 @@ import org.sonar.db.component.ResourceDto; import org.sonar.db.component.ResourceQuery; import org.sonar.db.permission.GroupWithPermissionDto; import org.sonar.db.permission.PermissionDao; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.server.exceptions.NotFoundException; @@ -55,7 +55,7 @@ public class PermissionFinder { this.permissionDao = dbClient.permissionDao(); } - public List findUsersWithPermission(DbSession dbSession, PermissionQuery query) { + public List findUsersWithPermission(DbSession dbSession, OldPermissionQuery query) { Long componentId = componentId(query.component()); int limit = query.pageSize(); return permissionDao.selectUsers(dbSession, query, componentId, offset(query), limit); @@ -64,7 +64,7 @@ public class PermissionFinder { /** * Paging for groups search is done in Java in order to correctly handle the 'Anyone' group */ - public List findGroupsWithPermission(DbSession dbSession, PermissionQuery query) { + public List findGroupsWithPermission(DbSession dbSession, OldPermissionQuery query) { Long componentId = componentId(query.component()); return toGroupQueryResult(permissionDao.selectGroups(dbSession, query, componentId), query); } @@ -82,7 +82,7 @@ public class PermissionFinder { } } - private static List toGroupQueryResult(List dtos, PermissionQuery query) { + private static List toGroupQueryResult(List dtos, OldPermissionQuery query) { addAnyoneGroup(dtos, query); List filteredDtos = filterMembership(dtos, query); @@ -93,13 +93,13 @@ public class PermissionFinder { return pagedGroups(filteredDtos, paging); } - private static int offset(PermissionQuery query) { + private static int offset(OldPermissionQuery query) { int pageSize = query.pageSize(); int pageIndex = query.pageIndex(); return (pageIndex - 1) * pageSize; } - private static List filterMembership(List dtos, PermissionQuery query) { + private static List filterMembership(List dtos, OldPermissionQuery query) { return newArrayList(Iterables.filter(dtos, new GroupWithPermissionMatchQuery(query))); } @@ -107,7 +107,7 @@ public class PermissionFinder { * 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 groups, PermissionQuery query) { + private static void addAnyoneGroup(List groups, OldPermissionQuery query) { boolean hasAnyoneGroup = Iterables.any(groups, IsAnyoneGroup.INSTANCE); if (!hasAnyoneGroup && !GlobalPermissions.SYSTEM_ADMIN.equals(query.permission()) @@ -131,17 +131,17 @@ public class PermissionFinder { } private static class GroupWithPermissionMatchQuery implements Predicate { - private final PermissionQuery query; + private final OldPermissionQuery query; - public GroupWithPermissionMatchQuery(PermissionQuery query) { + public GroupWithPermissionMatchQuery(OldPermissionQuery query) { this.query = query; } @Override public boolean apply(@Nonnull GroupWithPermissionDto dto) { - if (PermissionQuery.IN.equals(query.membership())) { + if (OldPermissionQuery.IN.equals(query.membership())) { return dto.getPermission() != null; - } else if (PermissionQuery.OUT.equals(query.membership())) { + } else if (OldPermissionQuery.OUT.equals(query.membership())) { return dto.getPermission() == null; } return true; 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 index bf11e1f9813..4346b4ae2bf 100644 --- 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 @@ -31,7 +31,7 @@ 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.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.server.permission.PermissionFinder; import org.sonar.server.user.UserSession; import org.sonarqube.ws.Common; @@ -98,7 +98,7 @@ public class GroupsAction implements PermissionsWsAction { Optional project = dependenciesFinder.searchProject(dbSession, newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey())); checkProjectAdminUserByComponentDto(userSession, project); - PermissionQuery permissionQuery = buildPermissionQuery(request, project); + OldPermissionQuery permissionQuery = buildPermissionQuery(request, project); Long projectIdIfPresent = project.isPresent() ? project.get().getId() : null; int total = dbClient.permissionDao().countGroups(dbSession, permissionQuery.permission(), projectIdIfPresent); List groupsWithPermission = permissionFinder.findGroupsWithPermission(dbSession, permissionQuery); @@ -128,8 +128,8 @@ public class GroupsAction implements PermissionsWsAction { .setSelected(request.mandatoryParam(Param.SELECTED)); } - private static PermissionQuery buildPermissionQuery(GroupsWsRequest request, Optional project) { - PermissionQuery.Builder permissionQuery = PermissionQuery.builder() + private static OldPermissionQuery buildPermissionQuery(GroupsWsRequest request, Optional project) { + OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder() .permission(request.getPermission()) .pageIndex(request.getPage()) .pageSize(request.getPageSize()) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/OldUsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/OldUsersAction.java index 830964e8993..fbee4d1eb4d 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/OldUsersAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/OldUsersAction.java @@ -30,7 +30,7 @@ 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.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.server.permission.PermissionFinder; import org.sonar.server.user.UserSession; @@ -99,7 +99,7 @@ public class OldUsersAction implements PermissionsWsAction { try { Optional project = dependenciesFinder.searchProject(dbSession, wsProjectRef); checkProjectAdminUserByComponentDto(userSession, project); - PermissionQuery permissionQuery = buildPermissionQuery(request, project); + OldPermissionQuery permissionQuery = buildPermissionQuery(request, project); Long projectIdIfPresent = project.isPresent() ? project.get().getId() : null; int total = dbClient.permissionDao().countUsers(dbSession, permissionQuery, projectIdIfPresent); List usersWithPermission = permissionFinder.findUsersWithPermission(dbSession, permissionQuery); @@ -143,8 +143,8 @@ public class OldUsersAction implements PermissionsWsAction { return userResponse.build(); } - private static PermissionQuery buildPermissionQuery(OldUsersWsRequest request, Optional project) { - PermissionQuery.Builder permissionQuery = PermissionQuery.builder() + private static OldPermissionQuery buildPermissionQuery(OldUsersWsRequest request, Optional project) { + OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder() .permission(request.getPermission()) .pageIndex(request.getPage()) .pageSize(request.getPageSize()) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsParametersBuilder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsParametersBuilder.java index 4acfc3b4513..c616ae192fe 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsParametersBuilder.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsParametersBuilder.java @@ -58,8 +58,8 @@ public class PermissionsWsParametersBuilder { // static methods only } - public static void createPermissionParameter(NewAction action) { - action.createParam(PARAM_PERMISSION) + public static NewParam createPermissionParameter(NewAction action) { + return action.createParam(PARAM_PERMISSION) .setDescription(PERMISSION_PARAM_DESCRIPTION) .setRequired(true); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchGlobalPermissionsAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchGlobalPermissionsAction.java index 14321bdb43e..1dc976c2768 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchGlobalPermissionsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/SearchGlobalPermissionsAction.java @@ -26,7 +26,7 @@ import org.sonar.api.server.ws.WebService; import org.sonar.core.permission.GlobalPermissions; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.user.GroupMembershipQuery; import org.sonar.server.user.UserSession; import org.sonarqube.ws.WsPermissions.Permission; @@ -78,7 +78,7 @@ public class SearchGlobalPermissionsAction implements PermissionsWsAction { Permission.Builder permission = newBuilder(); for (String permissionKey : GlobalPermissions.ALL) { - PermissionQuery permissionQuery = permissionQuery(permissionKey); + OldPermissionQuery permissionQuery = permissionQuery(permissionKey); response.addPermissions( permission @@ -106,12 +106,12 @@ public class SearchGlobalPermissionsAction implements PermissionsWsAction { return dbClient.permissionDao().countGroups(dbSession, permissionKey, null); } - private int countUsers(DbSession dbSession, PermissionQuery permissionQuery) { + private int countUsers(DbSession dbSession, OldPermissionQuery permissionQuery) { return dbClient.permissionDao().countUsers(dbSession, permissionQuery, null); } - private static PermissionQuery permissionQuery(String permissionKey) { - return PermissionQuery.builder() + private static OldPermissionQuery permissionQuery(String permissionKey) { + return OldPermissionQuery.builder() .permission(permissionKey) .membership(GroupMembershipQuery.IN) .build(); diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateGroupsAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateGroupsAction.java index 94c3871665a..5e92540405f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateGroupsAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateGroupsAction.java @@ -28,7 +28,7 @@ import org.sonar.api.server.ws.WebService.SelectionMode; import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.server.user.UserSession; import org.sonarqube.ws.WsPermissions.Group; @@ -81,7 +81,7 @@ public class TemplateGroupsAction implements PermissionsWsAction { WsTemplateRef templateRef = WsTemplateRef.fromRequest(wsRequest); PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, templateRef); - PermissionQuery query = buildQuery(wsRequest, template); + OldPermissionQuery query = buildQuery(wsRequest, template); WsGroupsResponse groupsResponse = buildResponse(dbSession, query, template); writeProtobuf(groupsResponse, wsRequest, wsResponse); @@ -90,7 +90,7 @@ public class TemplateGroupsAction implements PermissionsWsAction { } } - private WsGroupsResponse buildResponse(DbSession dbSession, PermissionQuery query, PermissionTemplateDto template) { + private WsGroupsResponse buildResponse(DbSession dbSession, OldPermissionQuery query, PermissionTemplateDto template) { int total = dbClient.permissionTemplateDao().countGroups(dbSession, query, template.getId()); List groupsWithPermission = dbClient.permissionTemplateDao().selectGroups(dbSession, query, template.getId(), query.pageOffset(), query.pageSize()); @@ -109,10 +109,10 @@ public class TemplateGroupsAction implements PermissionsWsAction { return groupsResponse.build(); } - private static PermissionQuery buildQuery(Request request, PermissionTemplateDto template) { + private static OldPermissionQuery buildQuery(Request request, PermissionTemplateDto template) { String permission = validateProjectPermission(request.mandatoryParam(PARAM_PERMISSION)); - PermissionQuery.Builder permissionQuery = PermissionQuery.builder() + OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder() .permission(permission) .pageIndex(request.mandatoryParamAsInt(Param.PAGE)) .pageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateUsersAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateUsersAction.java index bd63a924e07..b115ad453f0 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateUsersAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/TemplateUsersAction.java @@ -27,7 +27,7 @@ import org.sonar.api.server.ws.WebService.Param; import org.sonar.api.server.ws.WebService.SelectionMode; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.server.user.UserSession; @@ -85,7 +85,7 @@ public class TemplateUsersAction implements PermissionsWsAction { WsTemplateRef templateRef = WsTemplateRef.fromRequest(wsRequest); PermissionTemplateDto template = dependenciesFinder.getTemplate(dbSession, templateRef); - PermissionQuery query = buildQuery(wsRequest, template); + OldPermissionQuery query = buildQuery(wsRequest, template); WsPermissions.OldUsersWsResponse templateUsersResponse = buildResponse(dbSession, query, template); writeProtobuf(templateUsersResponse, wsRequest, wsResponse); } finally { @@ -93,10 +93,10 @@ public class TemplateUsersAction implements PermissionsWsAction { } } - private static PermissionQuery buildQuery(Request wsRequest, PermissionTemplateDto template) { + private static OldPermissionQuery buildQuery(Request wsRequest, PermissionTemplateDto template) { String permission = validateProjectPermission(wsRequest.mandatoryParam(PARAM_PERMISSION)); - return PermissionQuery.builder() + return OldPermissionQuery.builder() .template(template.getUuid()) .permission(permission) .membership(fromSelectionModeToMembership(wsRequest.mandatoryParam(Param.SELECTED))) @@ -106,7 +106,7 @@ public class TemplateUsersAction implements PermissionsWsAction { .build(); } - private OldUsersWsResponse buildResponse(DbSession dbSession, PermissionQuery query, PermissionTemplateDto template) { + private OldUsersWsResponse buildResponse(DbSession dbSession, OldPermissionQuery query, PermissionTemplateDto template) { List usersWithPermission = dbClient.permissionTemplateDao().selectUsers(dbSession, query, template.getId(), query.pageOffset(), query.pageSize()); int total = dbClient.permissionTemplateDao().countUsers(dbSession, query, template.getId()); 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 40f50538e05..2950f8733eb 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 @@ -29,6 +29,7 @@ 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.OldPermissionQuery; import org.sonar.db.permission.PermissionQuery; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.server.permission.PermissionFinder; @@ -39,6 +40,8 @@ import org.sonarqube.ws.client.permission.UsersWsRequest; import static com.google.common.base.Strings.nullToEmpty; import static org.sonar.api.utils.Paging.forPageIndex; +import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; +import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE; import static org.sonar.server.permission.PermissionPrivilegeChecker.checkProjectAdminUserByComponentDto; import static org.sonar.server.permission.ws.PermissionRequestValidator.validatePermission; import static org.sonar.server.permission.ws.PermissionsWsParametersBuilder.createPermissionParameter; @@ -51,8 +54,6 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P public class UsersAction implements PermissionsWsAction { - private static final int MAX_SIZE = 100; - private final DbClient dbClient; private final UserSession userSession; private final PermissionFinder permissionFinder; @@ -73,13 +74,15 @@ public class UsersAction implements PermissionsWsAction { "This service defaults to global permissions, but can be limited to project permissions by providing project id or project key.
" + "This service defaults to all users, but can be limited to users with a specific permission by providing the desired permission.
" + "It requires administration permissions to access.") - .addPagingParams(20, MAX_SIZE) - .addSearchQuery("stas", "names") + .addPagingParams(DEFAULT_PAGE_SIZE, RESULTS_MAX_SIZE) .setInternal(true) .setResponseExample(getClass().getResource("users-example.json")) .setHandler(this); - createPermissionParameter(action); + action.createParam(Param.TEXT_QUERY) + .setDescription("Limit search to user names that contain the supplied string. Must have at least %d characters.", PermissionQuery.SEARCH_QUERY_MIN_LENGTH) + .setExampleValue("eri"); + createPermissionParameter(action).setRequired(false); createProjectParameters(action); } @@ -96,7 +99,7 @@ public class UsersAction implements PermissionsWsAction { try { Optional project = dependenciesFinder.searchProject(dbSession, wsProjectRef); checkProjectAdminUserByComponentDto(userSession, project); - PermissionQuery permissionQuery = buildPermissionQuery(request, project); + OldPermissionQuery permissionQuery = buildPermissionQuery(request, project); Long projectIdIfPresent = project.isPresent() ? project.get().getId() : null; int total = dbClient.permissionDao().countUsers(dbSession, permissionQuery, projectIdIfPresent); List usersWithPermission = permissionFinder.findUsersWithPermission(dbSession, permissionQuery); @@ -139,8 +142,8 @@ public class UsersAction implements PermissionsWsAction { return userResponse.build(); } - private static PermissionQuery buildPermissionQuery(UsersWsRequest request, Optional project) { - PermissionQuery.Builder permissionQuery = PermissionQuery.builder() + private static OldPermissionQuery buildPermissionQuery(UsersWsRequest request, Optional project) { + OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder() .permission(request.getPermission()) .pageIndex(request.getPage()) .pageSize(request.getPageSize()) diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java index 7415ff30426..ceddba001b5 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddGroupToTemplateAction.java @@ -25,7 +25,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.server.permission.ws.PermissionDependenciesFinder; @@ -110,7 +110,7 @@ public class AddGroupToTemplateAction implements PermissionsWsAction { private boolean groupAlreadyAdded(DbSession dbSession, long templateId, @Nullable GroupDto group, String permission) { String groupName = group == null ? ANYONE : group.getName(); - PermissionQuery permissionQuery = PermissionQuery.builder().membership(IN).permission(permission).build(); + OldPermissionQuery permissionQuery = OldPermissionQuery.builder().membership(IN).permission(permission).build(); return dbClient.permissionTemplateDao().hasGroup(dbSession, permissionQuery, templateId, groupName); } diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java index a6d895e5169..c0da46c0911 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java +++ b/server/sonar-server/src/main/java/org/sonar/server/permission/ws/template/AddUserToTemplateAction.java @@ -26,7 +26,7 @@ import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.WebService; import org.sonar.db.DbClient; import org.sonar.db.DbSession; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.db.user.UserDto; @@ -108,7 +108,7 @@ public class AddUserToTemplateAction implements PermissionsWsAction { } private boolean isUserAlreadyAdded(DbSession dbSession, long templateId, String userLogin, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + OldPermissionQuery permissionQuery = OldPermissionQuery.builder().permission(permission).membership(IN).build(); List usersWithPermission = dbClient.permissionTemplateDao().selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE); return from(usersWithPermission).anyMatch(new HasUserPredicate(userLogin)); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java index f94005ad729..4339c5421de 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddGroupToTemplateActionTest.java @@ -36,7 +36,7 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ResourceTypesRule; import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.server.component.ComponentFinder; @@ -238,7 +238,7 @@ public class AddGroupToTemplateActionTest { } private List getGroupNamesInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + OldPermissionQuery permissionQuery = OldPermissionQuery.builder().permission(permission).membership(IN).build(); return from(dbClient.permissionTemplateDao() .selectGroups(dbSession, permissionQuery, templateId)) .transform(GroupWithPermissionToGroupName.INSTANCE) diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java index d82607564d3..5574cad4d15 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/AddUserToTemplateActionTest.java @@ -34,7 +34,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ResourceTypesRule; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.db.user.UserDto; @@ -207,7 +207,7 @@ public class AddUserToTemplateActionTest { } private List getLoginsInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + OldPermissionQuery permissionQuery = OldPermissionQuery.builder().permission(permission).membership(IN).build(); return from(dbClient.permissionTemplateDao() .selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE)) .transform(UserWithPermissionToUserLogin.INSTANCE) diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java index 973e760cdf8..add9707d364 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/ApplyTemplateActionTest.java @@ -38,7 +38,7 @@ import org.sonar.db.DbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ResourceTypesRule; import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionRepository; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.permission.UserWithPermissionDto; @@ -301,8 +301,8 @@ public class ApplyTemplateActionTest { dbSession.commit(); } - private static PermissionQuery query(String permission) { - return PermissionQuery.builder().membership(IN).permission(permission).build(); + private static OldPermissionQuery query(String permission) { + return OldPermissionQuery.builder().membership(IN).permission(permission).build(); } private static class PermissionNotNull implements Predicate { diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java index 100e3843f93..753c03c5191 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/BulkApplyTemplateActionTest.java @@ -54,7 +54,7 @@ import org.sonar.db.component.ComponentDbTester; import org.sonar.db.component.ComponentDto; import org.sonar.db.component.ResourceTypesRule; import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionRepository; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.permission.UserWithPermissionDto; @@ -272,8 +272,8 @@ public class BulkApplyTemplateActionTest { dbSession.commit(); } - private static PermissionQuery query(String permission) { - return PermissionQuery.builder().membership(IN).permission(permission).build(); + private static OldPermissionQuery query(String permission) { + return OldPermissionQuery.builder().membership(IN).permission(permission).build(); } private static class PermissionNotNull implements Predicate { diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java index ad649dd0a38..9df6be6c954 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveGroupFromTemplateActionTest.java @@ -35,7 +35,7 @@ import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ResourceTypesRule; import org.sonar.db.permission.GroupWithPermissionDto; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.user.GroupDto; import org.sonar.server.component.ComponentFinder; @@ -245,7 +245,7 @@ public class RemoveGroupFromTemplateActionTest { } private List getGroupNamesInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + OldPermissionQuery permissionQuery = OldPermissionQuery.builder().permission(permission).membership(IN).build(); return from(dbClient.permissionTemplateDao() .selectGroups(dbSession, permissionQuery, templateId)) .transform(GroupWithPermissionToGroupName.INSTANCE) diff --git a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java index 770d3b4f2d9..764d4ad7bea 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/permission/ws/template/RemoveUserFromTemplateActionTest.java @@ -34,7 +34,7 @@ import org.sonar.db.DbClient; import org.sonar.db.DbSession; import org.sonar.db.DbTester; import org.sonar.db.component.ResourceTypesRule; -import org.sonar.db.permission.PermissionQuery; +import org.sonar.db.permission.OldPermissionQuery; import org.sonar.db.permission.PermissionTemplateDto; import org.sonar.db.permission.UserWithPermissionDto; import org.sonar.db.user.UserDto; @@ -231,7 +231,7 @@ public class RemoveUserFromTemplateActionTest { } private List getLoginsInTemplateAndPermission(long templateId, String permission) { - PermissionQuery permissionQuery = PermissionQuery.builder().permission(permission).membership(IN).build(); + OldPermissionQuery permissionQuery = OldPermissionQuery.builder().permission(permission).membership(IN).build(); return from(dbClient.permissionTemplateDao() .selectUsers(dbSession, permissionQuery, templateId, 0, Integer.MAX_VALUE)) .transform(UserWithPermissionToUserLogin.INSTANCE) diff --git a/sonar-db/src/main/java/org/sonar/db/permission/OldPermissionQuery.java b/sonar-db/src/main/java/org/sonar/db/permission/OldPermissionQuery.java new file mode 100644 index 00000000000..42f9c5bf03f --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/permission/OldPermissionQuery.java @@ -0,0 +1,206 @@ +/* + * 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.db.permission; + +import com.google.common.base.Preconditions; +import com.google.common.collect.ImmutableSet; +import java.util.Set; +import javax.annotation.CheckForNull; +import javax.annotation.Nullable; +import org.apache.commons.lang.StringUtils; + +import static com.google.common.base.Preconditions.checkNotNull; + +/** + * Query used to get users and groups from a permission + */ +public class OldPermissionQuery { + + public static final int DEFAULT_PAGE_INDEX = 1; + public static final int DEFAULT_PAGE_SIZE = 100; + + public static final String ANY = "ANY"; + public static final String IN = "IN"; + public static final String OUT = "OUT"; + public static final Set AVAILABLE_MEMBERSHIP = ImmutableSet.of(ANY, IN, OUT); + + private final String permission; + private final String component; + private final String template; + private final String membership; + private final String search; + + // for internal use in MyBatis + final String searchSql; + + // max results per page + private final int pageSize; + // index of selected page. Start with 1. + private final int pageIndex; + // offset. Starts with 0. + private final int pageOffset; + + private OldPermissionQuery(Builder builder) { + this.permission = builder.permission; + this.component = builder.component; + this.template = builder.template; + this.membership = builder.membership; + this.search = builder.search; + this.searchSql = searchToSql(search); + + this.pageSize = builder.pageSize; + this.pageIndex = builder.pageIndex; + this.pageOffset = (builder.pageIndex - 1) * builder.pageSize; + } + + private static String searchToSql(@Nullable String s) { + String sql = null; + if (s != null) { + sql = StringUtils.replace(StringUtils.upperCase(s), "%", "/%"); + sql = StringUtils.replace(sql, "_", "/_"); + sql = "%" + sql + "%"; + } + return sql; + } + + public String permission() { + return permission; + } + + /** + * Used only for permission template + */ + public String template() { + return template; + } + + /** + * Used on project permission + */ + @CheckForNull + public String component() { + return component; + } + + @CheckForNull + public String membership() { + return membership; + } + + @CheckForNull + public String search() { + return search; + } + + public int pageSize() { + return pageSize; + } + + public int pageOffset() { + return pageOffset; + } + + public int pageIndex() { + return pageIndex; + } + + public static Builder builder() { + return new Builder(); + } + + public static class Builder { + private String permission; + private String component; + private String template; + private String membership; + private String search; + + private Integer pageIndex = DEFAULT_PAGE_INDEX; + private Integer pageSize = DEFAULT_PAGE_SIZE; + + private Builder() { + } + + public Builder permission(String permission) { + this.permission = permission; + return this; + } + + public Builder template(String template) { + this.template = template; + return this; + } + + public Builder component(@Nullable String component) { + this.component = component; + return this; + } + + public Builder membership(@Nullable String membership) { + this.membership = membership; + return this; + } + + public Builder search(@Nullable String s) { + this.search = StringUtils.defaultIfBlank(s, null); + return this; + } + + public Builder pageSize(@Nullable Integer i) { + this.pageSize = i; + return this; + } + + public Builder pageIndex(@Nullable Integer i) { + this.pageIndex = i; + return this; + } + + private void initMembership() { + if (membership == null) { + membership = OldPermissionQuery.ANY; + } else { + Preconditions.checkArgument(AVAILABLE_MEMBERSHIP.contains(membership), + "Membership is not valid (got " + membership + "). Availables values are " + AVAILABLE_MEMBERSHIP); + } + } + + private void initPageSize() { + if (pageSize == null) { + pageSize = DEFAULT_PAGE_SIZE; + } + } + + private void initPageIndex() { + if (pageIndex == null) { + pageIndex = DEFAULT_PAGE_INDEX; + } + Preconditions.checkArgument(pageIndex > 0, "Page index must be greater than 0 (got " + pageIndex + ")"); + } + + public OldPermissionQuery build() { + checkNotNull(permission, "Permission cannot be null."); + initMembership(); + initPageIndex(); + initPageSize(); + return new OldPermissionQuery(this); + } + } +} 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 a365cd96b4f..dbf7d0f3831 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 @@ -30,6 +30,7 @@ import org.sonar.api.security.DefaultGroups; import org.sonar.db.Dao; import org.sonar.db.DbSession; import org.sonar.db.MyBatis; +import org.sonar.db.user.UserPermissionDto; import static com.google.common.collect.Maps.newHashMap; import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput; @@ -48,20 +49,37 @@ public class PermissionDao implements Dao { /** * @return a paginated list of users. + * @deprecated use {@link #selectUserPermissionsByQuery(DbSession, PermissionQuery)} instead */ - public List selectUsers(DbSession session, PermissionQuery query, @Nullable Long componentId, int offset, int limit) { + @Deprecated + public List selectUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId, int offset, int limit) { Map params = usersParameters(query, componentId); return mapper(session).selectUsers(params, new RowBounds(offset, limit)); } - public int countUsers(DbSession session, PermissionQuery query, @Nullable Long componentId) { + /** + * Each row returns {@link UserRef}, ordered by user names + */ + public void selectUsersByQuery(DbSession dbSession, PermissionQuery query, ResultHandler handler) { + mapper(dbSession).selectUsersByQuery(query, new RowBounds(query.getPageOffset(), query.getPageSize()), handler); + } + + public int countUsersByQuery(DbSession dbSession, PermissionQuery query) { + return mapper(dbSession).countUsersByQuery(query); + } + + public List selectUserPermissionsByQuery(DbSession dbSession, PermissionQuery query) { + return mapper(dbSession).selectUserPermissionsByQuery(query); + } + + public int countUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId) { Map params = usersParameters(query, componentId); return mapper(session).countUsers(params); } - private static Map usersParameters(PermissionQuery query, @Nullable Long componentId) { + private static Map usersParameters(OldPermissionQuery query, @Nullable Long componentId) { Map params = newHashMap(); params.put(QUERY_PARAMETER, query); params.put(COMPONENT_ID_PARAMETER, componentId); @@ -74,12 +92,12 @@ public class PermissionDao implements Dao { * * @return a non paginated list of groups. */ - public List selectGroups(DbSession session, PermissionQuery query, @Nullable Long componentId) { + public List selectGroups(DbSession session, OldPermissionQuery query, @Nullable Long componentId) { Map params = groupsParameters(query, componentId); return mapper(session).selectGroups(params); } - public List selectGroups(PermissionQuery query, @Nullable Long componentId) { + public List selectGroups(OldPermissionQuery query, @Nullable Long componentId) { DbSession session = myBatis.openSession(false); try { return selectGroups(session, query, componentId); @@ -128,7 +146,7 @@ public class PermissionDao implements Dao { }); } - private static Map groupsParameters(PermissionQuery query, @Nullable Long componentId) { + private static Map groupsParameters(OldPermissionQuery query, @Nullable Long componentId) { Map params = newHashMap(); params.put(QUERY_PARAMETER, query); params.put(COMPONENT_ID_PARAMETER, componentId); 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 949f2b1856a..f2b94da1b3f 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 @@ -21,8 +21,10 @@ package org.sonar.db.permission; import java.util.List; import java.util.Map; +import org.apache.ibatis.annotations.Param; import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.RowBounds; +import org.sonar.db.user.UserPermissionDto; public interface PermissionMapper { @@ -30,6 +32,12 @@ public interface PermissionMapper { int countUsers(Map parameters); + void selectUsersByQuery(@Param("query") PermissionQuery query, RowBounds rowBounds, ResultHandler handler); + + int countUsersByQuery(@Param("query") PermissionQuery query); + + List selectUserPermissionsByQuery(PermissionQuery query); + List selectGroups(Map parameters); int countGroups(Map parameters); diff --git a/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java b/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java index f5e705a874e..d58357d13bc 100644 --- a/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java +++ b/sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java @@ -19,187 +19,142 @@ */ package org.sonar.db.permission; -import com.google.common.base.Preconditions; -import com.google.common.collect.ImmutableSet; -import java.util.Set; +import java.util.Locale; import javax.annotation.CheckForNull; import javax.annotation.Nullable; -import org.apache.commons.lang.StringUtils; +import org.sonar.db.WildcardPosition; -import static com.google.common.base.Preconditions.checkNotNull; +import static com.google.common.base.MoreObjects.firstNonNull; +import static com.google.common.base.Preconditions.checkArgument; +import static org.apache.commons.lang.StringUtils.defaultIfBlank; +import static org.sonar.api.utils.Paging.offset; +import static org.sonar.db.DatabaseUtils.buildLikeValue; /** - * Query used to get users and groups from a permission + * Query used to get users and groups permissions */ public class PermissionQuery { + public static final int RESULTS_MAX_SIZE = 100; + public static final int SEARCH_QUERY_MIN_LENGTH = 3; + public static final int DEFAULT_PAGE_SIZE = 20; public static final int DEFAULT_PAGE_INDEX = 1; - public static final int DEFAULT_PAGE_SIZE = 100; - - public static final String ANY = "ANY"; - public static final String IN = "IN"; - public static final String OUT = "OUT"; - public static final Set AVAILABLE_MEMBERSHIP = ImmutableSet.of(ANY, IN, OUT); private final String permission; - private final String component; + private final String componentUuid; private final String template; - private final String membership; - private final String search; - - // for internal use in MyBatis - final String searchSql; + private final String searchQuery; + private final String searchQueryToSql; + private final boolean withPermissionOnly; - // max results per page private final int pageSize; - // index of selected page. Start with 1. - private final int pageIndex; - // offset. Starts with 0. private final int pageOffset; private PermissionQuery(Builder builder) { this.permission = builder.permission; - this.component = builder.component; + this.withPermissionOnly = builder.withPermissionOnly; + this.componentUuid = builder.componentUuid; this.template = builder.template; - this.membership = builder.membership; - this.search = builder.search; - this.searchSql = searchToSql(search); - + this.searchQuery = builder.searchQuery; + this.searchQueryToSql = builder.searchQuery == null ? null : buildLikeValue(builder.searchQuery, WildcardPosition.BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH); this.pageSize = builder.pageSize; - this.pageIndex = builder.pageIndex; - this.pageOffset = (builder.pageIndex - 1) * builder.pageSize; + this.pageOffset = offset(builder.pageIndex, builder.pageSize); } - private static String searchToSql(@Nullable String s) { - String sql = null; - if (s != null) { - sql = StringUtils.replace(StringUtils.upperCase(s), "%", "/%"); - sql = StringUtils.replace(sql, "_", "/_"); - sql = "%" + sql + "%"; - } - return sql; + @CheckForNull + public String getPermission() { + return permission; } - public String permission() { - return permission; + public boolean withPermissionOnly() { + return withPermissionOnly; } - /** - * Used only for permission template - */ public String template() { return template; } - /** - * Used on project permission - */ @CheckForNull - public String component() { - return component; + public String getComponentUuid() { + return componentUuid; } @CheckForNull - public String membership() { - return membership; + public String getSearchQuery() { + return searchQuery; } @CheckForNull - public String search() { - return search; + public String getSearchQueryToSql() { + return searchQueryToSql; } - public int pageSize() { + public int getPageSize() { return pageSize; } - public int pageOffset() { + public int getPageOffset() { return pageOffset; } - public int pageIndex() { - return pageIndex; - } - public static Builder builder() { return new Builder(); } public static class Builder { private String permission; - private String component; + private String componentUuid; private String template; - private String membership; - private String search; + private String searchQuery; + private boolean withPermissionOnly; private Integer pageIndex = DEFAULT_PAGE_INDEX; private Integer pageSize = DEFAULT_PAGE_SIZE; private Builder() { + // enforce method constructor } - public Builder permission(String permission) { + public Builder setPermission(@Nullable String permission) { this.permission = permission; return this; } - public Builder template(String template) { + public Builder setTemplate(@Nullable String template) { this.template = template; return this; } - public Builder component(@Nullable String component) { - this.component = component; + public Builder setComponentUuid(@Nullable String componentUuid) { + this.componentUuid = componentUuid; return this; } - public Builder membership(@Nullable String membership) { - this.membership = membership; + public Builder setSearchQuery(@Nullable String s) { + this.searchQuery = defaultIfBlank(s, null); return this; } - public Builder search(@Nullable String s) { - this.search = StringUtils.defaultIfBlank(s, null); + public Builder setPageIndex(@Nullable Integer i) { + this.pageIndex = i; return this; } - public Builder pageSize(@Nullable Integer i) { + public Builder setPageSize(@Nullable Integer i) { this.pageSize = i; return this; } - public Builder pageIndex(@Nullable Integer i) { - this.pageIndex = i; + public Builder withPermissionOnly() { + this.withPermissionOnly = true; return this; } - private void initMembership() { - if (membership == null) { - membership = PermissionQuery.ANY; - } else { - Preconditions.checkArgument(AVAILABLE_MEMBERSHIP.contains(membership), - "Membership is not valid (got " + membership + "). Availables values are " + AVAILABLE_MEMBERSHIP); - } - } - - private void initPageSize() { - if (pageSize == null) { - pageSize = DEFAULT_PAGE_SIZE; - } - } - - private void initPageIndex() { - if (pageIndex == null) { - pageIndex = DEFAULT_PAGE_INDEX; - } - Preconditions.checkArgument(pageIndex > 0, "Page index must be greater than 0 (got " + pageIndex + ")"); - } - public PermissionQuery build() { - checkNotNull(permission, "Permission cannot be null."); - initMembership(); - initPageIndex(); - initPageSize(); + this.pageIndex = firstNonNull(pageIndex, DEFAULT_PAGE_INDEX); + this.pageSize = firstNonNull(pageSize, DEFAULT_PAGE_SIZE); + checkArgument(searchQuery == null || searchQuery.length() >= 3); + checkArgument(!(withPermissionOnly && permission == null)); return new PermissionQuery(this); } } 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 f128410c8ae..71c2d3d79f6 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 @@ -60,7 +60,7 @@ public class PermissionTemplateDao implements Dao { /** * @return a paginated list of users. */ - public List selectUsers(PermissionQuery query, Long templateId, int offset, int limit) { + public List selectUsers(OldPermissionQuery query, Long templateId, int offset, int limit) { DbSession session = myBatis.openSession(false); try { return selectUsers(session, query, templateId, offset, limit); @@ -72,14 +72,14 @@ public class PermissionTemplateDao implements Dao { /** * @return a paginated list of users. */ - public List selectUsers(DbSession session, PermissionQuery query, Long templateId, int offset, int limit) { + public List selectUsers(DbSession session, OldPermissionQuery query, Long templateId, int offset, int limit) { Map params = newHashMap(); params.put(QUERY_PARAMETER, query); params.put(TEMPLATE_ID_PARAMETER, templateId); return mapper(session).selectUsers(params, new RowBounds(offset, limit)); } - public int countUsers(DbSession session, PermissionQuery query, Long templateId) { + public int countUsers(DbSession session, OldPermissionQuery query, Long templateId) { Map params = newHashMap(); params.put(QUERY_PARAMETER, query); params.put(TEMPLATE_ID_PARAMETER, templateId); @@ -87,7 +87,7 @@ public class PermissionTemplateDao implements Dao { } @VisibleForTesting - List selectUsers(PermissionQuery query, Long templateId) { + List selectUsers(OldPermissionQuery query, Long templateId) { return selectUsers(query, templateId, 0, Integer.MAX_VALUE); } @@ -96,16 +96,16 @@ 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) { + public List selectGroups(DbSession session, OldPermissionQuery query, Long templateId) { return selectGroups(session, query, templateId, 0, Integer.MAX_VALUE); } - public List selectGroups(DbSession session, PermissionQuery query, Long templateId, int offset, int limit) { + public List selectGroups(DbSession session, OldPermissionQuery query, Long templateId, int offset, int limit) { Map params = groupsParameters(query, templateId); return mapper(session).selectGroups(params, new RowBounds(offset, limit)); } - public List selectGroups(PermissionQuery query, Long templateId) { + public List selectGroups(OldPermissionQuery query, Long templateId) { DbSession session = myBatis.openSession(false); try { return selectGroups(session, query, templateId); @@ -114,11 +114,11 @@ public class PermissionTemplateDao implements Dao { } } - public int countGroups(DbSession session, PermissionQuery query, long templateId) { + public int countGroups(DbSession session, OldPermissionQuery query, long templateId) { return countGroups(session, query, templateId, null); } - private static int countGroups(DbSession session, PermissionQuery query, long templateId, @Nullable String groupName) { + private static int countGroups(DbSession session, OldPermissionQuery query, long templateId, @Nullable String groupName) { Map parameters = groupsParameters(query, templateId); if (groupName != null) { parameters.put("groupName", groupName.toUpperCase(Locale.ENGLISH)); @@ -126,11 +126,11 @@ public class PermissionTemplateDao implements Dao { return mapper(session).countGroups(parameters); } - public boolean hasGroup(DbSession session, PermissionQuery query, long templateId, String groupName) { + public boolean hasGroup(DbSession session, OldPermissionQuery query, long templateId, String groupName) { return countGroups(session, query, templateId, groupName) > 0; } - private static Map groupsParameters(PermissionQuery query, Long templateId) { + private static Map groupsParameters(OldPermissionQuery query, Long templateId) { Map params = newHashMap(); params.put(QUERY_PARAMETER, query); params.put(TEMPLATE_ID_PARAMETER, templateId); diff --git a/sonar-db/src/main/java/org/sonar/db/permission/UserRef.java b/sonar-db/src/main/java/org/sonar/db/permission/UserRef.java new file mode 100644 index 00000000000..4ffd4ff836b --- /dev/null +++ b/sonar-db/src/main/java/org/sonar/db/permission/UserRef.java @@ -0,0 +1,34 @@ +package org.sonar.db.permission; + +public class UserRef { + private String login; + private String email; + private String name; + + public String getLogin() { + return login; + } + + public UserRef setLogin(String login) { + this.login = login; + return this; + } + + public String getEmail() { + return email; + } + + public UserRef setEmail(String email) { + this.email = email; + return this; + } + + public String getName() { + return name; + } + + public UserRef setName(String name) { + this.name = name; + return this; + } +} 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 80630f5835f..f93c971998f 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 @@ -40,6 +40,68 @@ + + + + + u.login as login, u.name as name, u.email as email, lower(u.name), u.id + + + + + + from users u + left join user_roles ur ON ur.user_id=u.id + left join projects p on ur.resource_id = p.id + + and u.active = ${_true} + + and lower(u.name) like #{query.searchQueryToSql} ESCAPE '/' + + + + and ur.role is not null + + and ur.resource_id is null + + + and ur.resource_id is not null + + + and ur.role=#{query.permission} + + + + + + +