Skip to content

Commit

Permalink
SONAR-7838 SONAR-7835 Return all permissions of matching users
Browse files Browse the repository at this point in the history
When searching for permissions users that match a given permission, instead of only returnin this permission we now return all user permissions
  • Loading branch information
julienlancelot authored and stas-vilchik committed Jul 12, 2016
1 parent 4517fd6 commit 0fbbe80
Show file tree
Hide file tree
Showing 12 changed files with 253 additions and 240 deletions.

This file was deleted.

Expand Up @@ -21,9 +21,12 @@


import com.google.common.base.Optional; import com.google.common.base.Optional;
import com.google.common.collect.Multimap; import com.google.common.collect.Multimap;
import com.google.common.collect.Ordering;
import com.google.common.collect.TreeMultimap; import com.google.common.collect.TreeMultimap;
import com.google.common.io.Resources; import com.google.common.io.Resources;
import java.util.List; import java.util.List;
import java.util.stream.Collectors;
import org.sonar.api.security.DefaultGroups;
import org.sonar.api.server.ws.Request; import org.sonar.api.server.ws.Request;
import org.sonar.api.server.ws.Response; import org.sonar.api.server.ws.Response;
import org.sonar.api.server.ws.WebService; import org.sonar.api.server.ws.WebService;
Expand All @@ -35,12 +38,12 @@
import org.sonar.db.permission.PermissionQuery; import org.sonar.db.permission.PermissionQuery;
import org.sonar.db.user.GroupDto; import org.sonar.db.user.GroupDto;
import org.sonar.db.user.GroupRoleDto; import org.sonar.db.user.GroupRoleDto;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.user.UserSession; import org.sonar.server.user.UserSession;
import org.sonarqube.ws.WsPermissions.Group; import org.sonarqube.ws.WsPermissions.Group;
import org.sonarqube.ws.WsPermissions.WsGroupsResponse; import org.sonarqube.ws.WsPermissions.WsGroupsResponse;
import org.sonarqube.ws.client.permission.GroupsWsRequest; import org.sonarqube.ws.client.permission.GroupsWsRequest;


import static java.util.Collections.emptyList;
import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE; 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.RESULTS_MAX_SIZE;
import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH; import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH;
Expand All @@ -57,13 +60,11 @@
public class GroupsAction implements PermissionsWsAction { public class GroupsAction implements PermissionsWsAction {
private final DbClient dbClient; private final DbClient dbClient;
private final UserSession userSession; private final UserSession userSession;
private final PermissionFinder permissionFinder;
private final PermissionDependenciesFinder dependenciesFinder; private final PermissionDependenciesFinder dependenciesFinder;


public GroupsAction(DbClient dbClient, UserSession userSession, PermissionFinder permissionFinder, PermissionDependenciesFinder dependenciesFinder) { public GroupsAction(DbClient dbClient, UserSession userSession, PermissionDependenciesFinder dependenciesFinder) {
this.dbClient = dbClient; this.dbClient = dbClient;
this.userSession = userSession; this.userSession = userSession;
this.permissionFinder = permissionFinder;
this.dependenciesFinder = dependenciesFinder; this.dependenciesFinder = dependenciesFinder;
} }


Expand Down Expand Up @@ -100,10 +101,10 @@ private WsGroupsResponse doHandle(GroupsWsRequest request) {
Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey())); Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()));
checkProjectAdminUserByComponentDto(userSession, project); checkProjectAdminUserByComponentDto(userSession, project);


PermissionQuery.Builder dbQuery = buildPermissionQuery(request, project); PermissionQuery dbQuery = buildPermissionQuery(request, project);
List<GroupDto> groups = permissionFinder.findGroups(dbSession, dbQuery); List<GroupDto> groups = findGroups(dbSession, dbQuery);
int total = dbClient.permissionDao().countGroupsByPermissionQuery(dbSession, dbQuery.build()); int total = dbClient.permissionDao().countGroupsByPermissionQuery(dbSession, dbQuery);
List<GroupRoleDto> groupsWithPermission = permissionFinder.findGroupPermissions(dbSession, dbQuery, groups); List<GroupRoleDto> groupsWithPermission = findGroupPermissions(dbSession, groups, project);
return buildResponse(groups, groupsWithPermission, Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total)); return buildResponse(groups, groupsWithPermission, Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total));
} finally { } finally {
dbClient.closeSession(dbSession); dbClient.closeSession(dbSession);
Expand All @@ -124,7 +125,7 @@ private static GroupsWsRequest toGroupsWsRequest(Request request) {
return groupsRequest; return groupsRequest;
} }


private static PermissionQuery.Builder buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) { private static PermissionQuery buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) {
PermissionQuery.Builder permissionQuery = PermissionQuery.builder() PermissionQuery.Builder permissionQuery = PermissionQuery.builder()
.setPermission(request.getPermission()) .setPermission(request.getPermission())
.setPageIndex(request.getPage()) .setPageIndex(request.getPage())
Expand All @@ -136,7 +137,7 @@ private static PermissionQuery.Builder buildPermissionQuery(GroupsWsRequest requ
if (request.getQuery() == null) { if (request.getQuery() == null) {
permissionQuery.withPermissionOnly(); permissionQuery.withPermissionOnly();
} }
return permissionQuery; return permissionQuery.build();
} }


private static WsGroupsResponse buildResponse(List<GroupDto> groups, List<GroupRoleDto> groupPermissions, Paging paging) { private static WsGroupsResponse buildResponse(List<GroupDto> groups, List<GroupRoleDto> groupPermissions, Paging paging) {
Expand All @@ -163,4 +164,21 @@ private static WsGroupsResponse buildResponse(List<GroupDto> groups, List<GroupR


return response.build(); return response.build();
} }

private List<GroupDto> findGroups(DbSession dbSession, PermissionQuery dbQuery) {
List<String> orderedNames = dbClient.permissionDao().selectGroupNamesByPermissionQuery(dbSession, dbQuery);
List<GroupDto> groups = dbClient.groupDao().selectByNames(dbSession, orderedNames);
if (orderedNames.contains(DefaultGroups.ANYONE)) {
groups.add(0, new GroupDto().setId(0L).setName(DefaultGroups.ANYONE));
}
return Ordering.explicit(orderedNames).onResultOf(GroupDto::getName).immutableSortedCopy(groups);
}

private List<GroupRoleDto> findGroupPermissions(DbSession dbSession, List<GroupDto> groups, Optional<ComponentDto> project) {
if (groups.isEmpty()) {
return emptyList();
}
List<String> names = groups.stream().map(GroupDto::getName).collect(Collectors.toList());
return dbClient.permissionDao().selectGroupPermissionsByGroupNamesAndProject(dbSession, names, project.isPresent() ? project.get().getId() : null);
}
} }
Expand Up @@ -36,7 +36,6 @@
import org.sonar.db.permission.PermissionQuery; import org.sonar.db.permission.PermissionQuery;
import org.sonar.db.user.UserDto; import org.sonar.db.user.UserDto;
import org.sonar.db.user.UserPermissionDto; import org.sonar.db.user.UserPermissionDto;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.user.UserSession; import org.sonar.server.user.UserSession;
import org.sonarqube.ws.WsPermissions; import org.sonarqube.ws.WsPermissions;
import org.sonarqube.ws.WsPermissions.UsersWsResponse; import org.sonarqube.ws.WsPermissions.UsersWsResponse;
Expand All @@ -61,13 +60,11 @@ public class UsersAction implements PermissionsWsAction {


private final DbClient dbClient; private final DbClient dbClient;
private final UserSession userSession; private final UserSession userSession;
private final PermissionFinder permissionFinder;
private final PermissionDependenciesFinder dependenciesFinder; private final PermissionDependenciesFinder dependenciesFinder;


public UsersAction(DbClient dbClient, UserSession userSession, PermissionFinder permissionFinder, PermissionDependenciesFinder dependenciesFinder) { public UsersAction(DbClient dbClient, UserSession userSession, PermissionDependenciesFinder dependenciesFinder) {
this.dbClient = dbClient; this.dbClient = dbClient;
this.userSession = userSession; this.userSession = userSession;
this.permissionFinder = permissionFinder;
this.dependenciesFinder = dependenciesFinder; this.dependenciesFinder = dependenciesFinder;
} }


Expand Down Expand Up @@ -108,7 +105,7 @@ private UsersWsResponse doHandle(UsersWsRequest request) {
PermissionQuery dbQuery = buildPermissionQuery(request, project); PermissionQuery dbQuery = buildPermissionQuery(request, project);
List<UserDto> users = findUsers(dbSession, dbQuery); List<UserDto> users = findUsers(dbSession, dbQuery);
int total = dbClient.permissionDao().countUsersByQuery(dbSession, dbQuery); int total = dbClient.permissionDao().countUsersByQuery(dbSession, dbQuery);
List<UserPermissionDto> userPermissions = findUserPermissions(dbSession, users); List<UserPermissionDto> userPermissions = findUserPermissions(dbSession, users, project);
Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total); Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total);
return buildResponse(users, userPermissions, paging); return buildResponse(users, userPermissions, paging);
} finally { } finally {
Expand Down Expand Up @@ -179,11 +176,11 @@ private List<UserDto> findUsers(DbSession dbSession, PermissionQuery dbQuery) {
return Ordering.explicit(orderedLogins).onResultOf(UserDto::getLogin).immutableSortedCopy(dbClient.userDao().selectByLogins(dbSession, orderedLogins)); return Ordering.explicit(orderedLogins).onResultOf(UserDto::getLogin).immutableSortedCopy(dbClient.userDao().selectByLogins(dbSession, orderedLogins));
} }


private List<UserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users) { private List<UserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users, Optional<ComponentDto> project) {
if (users.isEmpty()) { if (users.isEmpty()) {
return emptyList(); return emptyList();
} }
List<String> logins = users.stream().map(UserDto::getLogin).collect(Collectors.toList()); List<String> logins = users.stream().map(UserDto::getLogin).collect(Collectors.toList());
return dbClient.permissionDao().selectUserPermissionsByLogins(dbSession, logins); return dbClient.permissionDao().selectUserPermissionsByLoginsAnProject(dbSession, logins, project.isPresent() ? project.get().getId() : null);
} }
} }
Expand Up @@ -140,7 +140,6 @@
import org.sonar.server.notification.NotificationService; import org.sonar.server.notification.NotificationService;
import org.sonar.server.notification.email.AlertsEmailTemplate; import org.sonar.server.notification.email.AlertsEmailTemplate;
import org.sonar.server.notification.email.EmailNotificationChannel; import org.sonar.server.notification.email.EmailNotificationChannel;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.permission.PermissionService; import org.sonar.server.permission.PermissionService;
import org.sonar.server.permission.PermissionUpdater; import org.sonar.server.permission.PermissionUpdater;
import org.sonar.server.permission.ws.PermissionsWsModule; import org.sonar.server.permission.ws.PermissionsWsModule;
Expand Down Expand Up @@ -520,7 +519,6 @@ protected void configureLevel() {
PermissionRepository.class, PermissionRepository.class,
PermissionService.class, PermissionService.class,
PermissionUpdater.class, PermissionUpdater.class,
PermissionFinder.class,
PermissionsWsModule.class, PermissionsWsModule.class,


// components // components
Expand Down
Expand Up @@ -39,7 +39,6 @@
import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.tester.UserSessionRule; import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.usergroups.ws.UserGroupFinder; import org.sonar.server.usergroups.ws.UserGroupFinder;
import org.sonar.server.ws.WsActionTester; import org.sonar.server.ws.WsActionTester;
Expand Down Expand Up @@ -81,11 +80,9 @@ public class GroupsActionTest {
public void setUp() { public void setUp() {
dbClient = db.getDbClient(); dbClient = db.getDbClient();
dbSession = db.getSession(); dbSession = db.getSession();
PermissionFinder permissionFinder = new PermissionFinder(dbClient);
underTest = new GroupsAction( underTest = new GroupsAction(
dbClient, dbClient,
userSession, userSession,
permissionFinder,
new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes)); new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes));
ws = new WsActionTester(underTest); ws = new WsActionTester(underTest);


Expand Down
Expand Up @@ -42,7 +42,6 @@
import org.sonar.server.exceptions.BadRequestException; import org.sonar.server.exceptions.BadRequestException;
import org.sonar.server.exceptions.ForbiddenException; import org.sonar.server.exceptions.ForbiddenException;
import org.sonar.server.exceptions.UnauthorizedException; import org.sonar.server.exceptions.UnauthorizedException;
import org.sonar.server.permission.PermissionFinder;
import org.sonar.server.tester.UserSessionRule; import org.sonar.server.tester.UserSessionRule;
import org.sonar.server.usergroups.ws.UserGroupFinder; import org.sonar.server.usergroups.ws.UserGroupFinder;
import org.sonar.server.ws.WsActionTester; import org.sonar.server.ws.WsActionTester;
Expand Down Expand Up @@ -85,9 +84,8 @@ public class UsersActionTest {


@Before @Before
public void setUp() { public void setUp() {
PermissionFinder permissionFinder = new PermissionFinder(dbClient);
PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes); PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes);
underTest = new UsersAction(dbClient, userSession, permissionFinder, dependenciesFinder); underTest = new UsersAction(dbClient, userSession, dependenciesFinder);
ws = new WsActionTester(underTest); ws = new WsActionTester(underTest);


userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN); userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN);
Expand Down
16 changes: 11 additions & 5 deletions sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java
Expand Up @@ -51,7 +51,7 @@ public PermissionDao(MyBatis myBatis) {


/** /**
* @return a paginated list of users. * @return a paginated list of users.
* @deprecated * @deprecated use {@link #selectLoginsByPermissionQuery(DbSession, PermissionQuery)} or {@link #selectUserPermissionsByLoginsAnProject(DbSession, List, Long)} instead
*/ */
@Deprecated @Deprecated
public List<UserWithPermissionDto> selectUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId, int offset, int limit) { public List<UserWithPermissionDto> selectUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId, int offset, int limit) {
Expand All @@ -71,10 +71,14 @@ public int countUsersByQuery(DbSession dbSession, PermissionQuery query) {
return mapper(dbSession).countUsersByPermissionQuery(query); return mapper(dbSession).countUsersByPermissionQuery(query);
} }


public List<UserPermissionDto> selectUserPermissionsByLogins(DbSession dbSession, List<String> logins) { public List<UserPermissionDto> selectUserPermissionsByLoginsAnProject(DbSession dbSession, List<String> logins, @Nullable Long projectId) {
return executeLargeInputs(logins, mapper(dbSession)::selectUserPermissionsByLogins); return executeLargeInputs(logins, l -> mapper(dbSession).selectUserPermissionsByLogins(l, projectId));
} }


/**
* @deprecated use {@link #countUsersByQuery(DbSession, PermissionQuery)} instead
*/
@Deprecated
public int countUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId) { public int countUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId) {
Map<String, Object> params = usersParameters(query, componentId); Map<String, Object> params = usersParameters(query, componentId);


Expand All @@ -93,7 +97,9 @@ private static Map<String, Object> usersParameters(OldPermissionQuery query, @Nu
* Membership parameter from query is not taking into account in order to deal more easily with the 'Anyone' group * 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. * @return a non paginated list of groups.
* @deprecated use {@link #selectGroupNamesByPermissionQuery(DbSession, PermissionQuery)} or {@link #selectGroupPermissionsByGroupNamesAndProject(DbSession, List, Long)} instead
*/ */
@Deprecated
public List<GroupWithPermissionDto> selectGroups(DbSession session, OldPermissionQuery query, @Nullable Long componentId) { public List<GroupWithPermissionDto> selectGroups(DbSession session, OldPermissionQuery query, @Nullable Long componentId) {
Map<String, Object> params = groupsParameters(query, componentId); Map<String, Object> params = groupsParameters(query, componentId);
return mapper(session).selectGroups(params); return mapper(session).selectGroups(params);
Expand Down Expand Up @@ -128,8 +134,8 @@ public int countGroupsByPermissionQuery(DbSession dbSession, PermissionQuery que
return mapper(dbSession).countGroupsByPermissionQuery(query); return mapper(dbSession).countGroupsByPermissionQuery(query);
} }


public List<GroupRoleDto> selectGroupPermissionsByQuery(DbSession dbSession, PermissionQuery query) { public List<GroupRoleDto> selectGroupPermissionsByGroupNamesAndProject(DbSession dbSession, List<String> groupNames, @Nullable Long projectId) {
return mapper(dbSession).selectGroupPermissionByQuery(query); return executeLargeInputs(groupNames, groups -> mapper(dbSession).selectGroupPermissionByGroupNames(groups, projectId));
} }


/** /**
Expand Down
Expand Up @@ -21,6 +21,7 @@


import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import javax.annotation.Nullable;
import org.apache.ibatis.annotations.Param; import org.apache.ibatis.annotations.Param;
import org.apache.ibatis.session.ResultHandler; import org.apache.ibatis.session.ResultHandler;
import org.apache.ibatis.session.RowBounds; import org.apache.ibatis.session.RowBounds;
Expand All @@ -37,7 +38,7 @@ public interface PermissionMapper {


int countUsersByPermissionQuery(@Param("query") PermissionQuery query); int countUsersByPermissionQuery(@Param("query") PermissionQuery query);


List<UserPermissionDto> selectUserPermissionsByLogins(@Param("logins") List<String> logins); List<UserPermissionDto> selectUserPermissionsByLogins(@Param("logins") List<String> logins, @Nullable @Param("projectId") Long projectId);


List<GroupWithPermissionDto> selectGroups(Map<String, Object> parameters); List<GroupWithPermissionDto> selectGroups(Map<String, Object> parameters);


Expand All @@ -47,7 +48,7 @@ public interface PermissionMapper {


int countGroupsByPermissionQuery(@Param("query") PermissionQuery query); int countGroupsByPermissionQuery(@Param("query") PermissionQuery query);


List<GroupRoleDto> selectGroupPermissionByQuery(@Param("query") PermissionQuery query); List<GroupRoleDto> selectGroupPermissionByGroupNames(@Param("groupNames") List<String> groupNames, @Nullable @Param("projectId") Long projectId);


void usersCountByProjectIdAndPermission(Map<String, Object> parameters, ResultHandler resultHandler); void usersCountByProjectIdAndPermission(Map<String, Object> parameters, ResultHandler resultHandler);


Expand Down

0 comments on commit 0fbbe80

Please sign in to comment.