@@ -45,7 +45,7 @@ import org.sonarqube.ws.client.permission.RemoveGroupFromTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.RemoveProjectCreatorFromTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.RemoveUserFromTemplateWsRequest; | |||
import org.sonarqube.ws.client.permission.SearchTemplatesWsRequest; | |||
import org.sonarqube.ws.client.permission.OldUsersWsRequest; | |||
import org.sonarqube.ws.client.permission.UsersWsRequest; | |||
import util.QaOnly; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
@@ -106,8 +106,7 @@ public class PermissionSearchTest { | |||
assertThat(searchGlobalPermissionsWsResponse.getPermissionsList().get(0).getGroupsCount()).isEqualTo(2); | |||
WsPermissions.UsersWsResponse users = permissionsWsClient | |||
.users(new OldUsersWsRequest() | |||
.setPermission("admin")); | |||
.users(new UsersWsRequest().setPermission("admin")); | |||
assertThat(users.getUsersList()).extracting("login").contains(LOGIN); | |||
WsPermissions.WsGroupsResponse groupsResponse = permissionsWsClient |
@@ -35,9 +35,8 @@ 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.PermissionDao; | |||
import org.sonar.db.permission.OldPermissionQuery; | |||
import org.sonar.db.permission.UserWithPermissionDto; | |||
import org.sonar.db.permission.PermissionDao; | |||
import org.sonar.server.exceptions.NotFoundException; | |||
import static com.google.common.collect.Lists.newArrayList; | |||
@@ -55,12 +54,6 @@ public class PermissionFinder { | |||
this.permissionDao = dbClient.permissionDao(); | |||
} | |||
public List<UserWithPermissionDto> findUsersWithPermission(DbSession dbSession, OldPermissionQuery query) { | |||
Long componentId = componentId(query.component()); | |||
int limit = query.pageSize(); | |||
return permissionDao.selectUsers(dbSession, query, componentId, offset(query), limit); | |||
} | |||
/** | |||
* Paging for groups search is done in Java in order to correctly handle the 'Anyone' group | |||
*/ | |||
@@ -93,12 +86,6 @@ public class PermissionFinder { | |||
return pagedGroups(filteredDtos, paging); | |||
} | |||
private static int offset(OldPermissionQuery query) { | |||
int pageSize = query.pageSize(); | |||
int pageIndex = query.pageIndex(); | |||
return (pageIndex - 1) * pageSize; | |||
} | |||
private static List<GroupWithPermissionDto> filterMembership(List<GroupWithPermissionDto> dtos, OldPermissionQuery query) { | |||
return newArrayList(Iterables.filter(dtos, new GroupWithPermissionMatchQuery(query))); | |||
} |
@@ -48,7 +48,10 @@ public class PermissionRequestValidator { | |||
// static methods only | |||
} | |||
public static void validatePermission(String permission, Optional<WsProjectRef> projectRef) { | |||
public static void validatePermission(@Nullable String permission, Optional<WsProjectRef> projectRef) { | |||
if (permission == null) { | |||
return; | |||
} | |||
if (projectRef.isPresent()) { | |||
validateProjectPermission(permission); | |||
} else { |
@@ -46,6 +46,7 @@ public class PermissionsWsModule extends Module { | |||
RemoveGroupAction.class, | |||
RemoveUserAction.class, | |||
OldUsersAction.class, | |||
UsersAction.class, | |||
GroupsAction.class, | |||
SearchGlobalPermissionsAction.class, | |||
SearchProjectPermissionsAction.class, |
@@ -20,7 +20,11 @@ | |||
package org.sonar.server.permission.ws; | |||
import com.google.common.base.Optional; | |||
import com.google.common.collect.Multimap; | |||
import com.google.common.collect.Ordering; | |||
import com.google.common.collect.TreeMultimap; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import org.sonar.api.server.ws.Request; | |||
import org.sonar.api.server.ws.Response; | |||
import org.sonar.api.server.ws.WebService; | |||
@@ -29,24 +33,25 @@ 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.db.user.UserDto; | |||
import org.sonar.db.user.UserPermissionDto; | |||
import org.sonar.server.permission.PermissionFinder; | |||
import org.sonar.server.user.UserSession; | |||
import org.sonarqube.ws.WsPermissions; | |||
import org.sonarqube.ws.WsPermissions.UsersWsResponse; | |||
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 java.util.Collections.emptyList; | |||
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.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; | |||
import static org.sonar.server.ws.WsUtils.checkRequest; | |||
import static org.sonar.server.ws.WsUtils.writeProtobuf; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PERMISSION; | |||
import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_PROJECT_ID; | |||
@@ -80,7 +85,8 @@ public class UsersAction implements PermissionsWsAction { | |||
.setHandler(this); | |||
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) | |||
.setDescription("Limit search to user names that contain the supplied string. Must have at least %d characters.<br/>" + | |||
"When this parameter is not set, only users having at least one permission are returned.", SEARCH_QUERY_MIN_LENGTH) | |||
.setExampleValue("eri"); | |||
createPermissionParameter(action).setRequired(false); | |||
createProjectParameters(action); | |||
@@ -99,59 +105,85 @@ public class UsersAction implements PermissionsWsAction { | |||
try { | |||
Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, wsProjectRef); | |||
checkProjectAdminUserByComponentDto(userSession, project); | |||
OldPermissionQuery permissionQuery = buildPermissionQuery(request, project); | |||
Long projectIdIfPresent = project.isPresent() ? project.get().getId() : null; | |||
int total = dbClient.permissionDao().countUsers(dbSession, permissionQuery, projectIdIfPresent); | |||
List<UserWithPermissionDto> usersWithPermission = permissionFinder.findUsersWithPermission(dbSession, permissionQuery); | |||
return buildResponse(usersWithPermission, forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total)); | |||
PermissionQuery dbQuery = buildPermissionQuery(request, project); | |||
List<UserDto> users = findUsers(dbSession, dbQuery); | |||
int total = dbClient.permissionDao().countUsersByQuery(dbSession, dbQuery); | |||
List<UserPermissionDto> userPermissions = findUserPermissions(dbSession, users); | |||
Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total); | |||
return buildResponse(users, userPermissions, paging); | |||
} finally { | |||
dbClient.closeSession(dbSession); | |||
} | |||
} | |||
private static UsersWsRequest toUsersWsRequest(Request request) { | |||
return new UsersWsRequest() | |||
.setPermission(request.mandatoryParam(PARAM_PERMISSION)) | |||
UsersWsRequest usersRequest = new UsersWsRequest() | |||
.setPermission(request.param(PARAM_PERMISSION)) | |||
.setProjectId(request.param(PARAM_PROJECT_ID)) | |||
.setProjectKey(request.param(PARAM_PROJECT_KEY)) | |||
.setQuery(request.param(Param.TEXT_QUERY)) | |||
.setPage(request.mandatoryParamAsInt(Param.PAGE)) | |||
.setPageSize(request.mandatoryParamAsInt(Param.PAGE_SIZE)); | |||
String searchQuery = usersRequest.getQuery(); | |||
checkRequest(searchQuery == null || searchQuery.length() >= SEARCH_QUERY_MIN_LENGTH, | |||
"The '%s' parameter must have at least %d characters", Param.TEXT_QUERY, SEARCH_QUERY_MIN_LENGTH); | |||
return usersRequest; | |||
} | |||
private static UsersWsResponse buildResponse(List<UserWithPermissionDto> usersWithPermission, Paging paging) { | |||
UsersWsResponse.Builder userResponse = UsersWsResponse.newBuilder(); | |||
WsPermissions.User.Builder user = WsPermissions.User.newBuilder(); | |||
for (UserWithPermissionDto userWithPermission : usersWithPermission) { | |||
userResponse.addUsers( | |||
user | |||
.clear() | |||
.setLogin(userWithPermission.getLogin()) | |||
.setName(nullToEmpty(userWithPermission.getName())) | |||
.setEmail(nullToEmpty(userWithPermission.getEmail())) | |||
.setSelected(userWithPermission.getPermission() != null)); | |||
} | |||
private static UsersWsResponse buildResponse(List<UserDto> users, List<UserPermissionDto> userPermissions, Paging paging) { | |||
Multimap<Long, String> permissionsByUserId = TreeMultimap.create(); | |||
userPermissions.forEach(userPermission -> permissionsByUserId.put(userPermission.getUserId(), userPermission.getPermission())); | |||
UsersWsResponse.Builder response = UsersWsResponse.newBuilder(); | |||
users.forEach(user -> { | |||
WsPermissions.User.Builder userResponse = response.addUsersBuilder() | |||
.setLogin(user.getLogin()) | |||
.addAllPermissions(permissionsByUserId.get(user.getId())); | |||
userResponse.getPagingBuilder() | |||
.clear() | |||
if (user.getEmail() != null) { | |||
userResponse.setEmail(user.getEmail()); | |||
} | |||
if (user.getName() != null) { | |||
userResponse.setName(user.getName()); | |||
} | |||
}); | |||
response.getPagingBuilder() | |||
.setPageIndex(paging.pageIndex()) | |||
.setPageSize(paging.pageSize()) | |||
.setTotal(paging.total()) | |||
.build(); | |||
return userResponse.build(); | |||
return response.build(); | |||
} | |||
private static OldPermissionQuery buildPermissionQuery(UsersWsRequest request, Optional<ComponentDto> project) { | |||
OldPermissionQuery.Builder permissionQuery = OldPermissionQuery.builder() | |||
.permission(request.getPermission()) | |||
.pageIndex(request.getPage()) | |||
.pageSize(request.getPageSize()) | |||
.search(request.getQuery()); | |||
private static PermissionQuery buildPermissionQuery(UsersWsRequest request, Optional<ComponentDto> project) { | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder() | |||
.setPermission(request.getPermission()) | |||
.setPageIndex(request.getPage()) | |||
.setPageSize(request.getPageSize()) | |||
.setSearchQuery(request.getQuery()); | |||
if (project.isPresent()) { | |||
permissionQuery.component(project.get().getKey()); | |||
dbQuery.setComponentUuid(project.get().uuid()); | |||
} | |||
if (request.getQuery() == null) { | |||
dbQuery.withPermissionOnly(); | |||
} | |||
return permissionQuery.build(); | |||
return dbQuery.build(); | |||
} | |||
private List<UserDto> findUsers(DbSession dbSession, PermissionQuery dbQuery) { | |||
List<String> orderedLogins = dbClient.permissionDao().selectLoginsByPermissionQuery(dbSession, dbQuery); | |||
return Ordering.explicit(orderedLogins).onResultOf(UserDto::getLogin).immutableSortedCopy(dbClient.userDao().selectByLogins(dbSession, orderedLogins)); | |||
} | |||
private List<UserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users) { | |||
if (users.isEmpty()) { | |||
return emptyList(); | |||
} | |||
List<String> logins = users.stream().map(UserDto::getLogin).collect(Collectors.toList()); | |||
return dbClient.permissionDao().selectUserPermissionsByLogins(dbSession, logins); | |||
} | |||
} |
@@ -1,22 +1,28 @@ | |||
{ | |||
"paging": { | |||
"pageIndex": 1, | |||
"pageSize": 20, | |||
"total": 2 | |||
}, | |||
"users": [ | |||
{ | |||
"login": "admin", | |||
"name": "Administrator", | |||
"email": "admin@admin.com", | |||
"selected": true | |||
"permissions": [ | |||
"admin", | |||
"gateadmin", | |||
"profileadmin" | |||
] | |||
}, | |||
{ | |||
"login": "george.orwell", | |||
"name": "George Orwell", | |||
"email": "george.orwell@1984.net", | |||
"selected": true | |||
"permissions": [ | |||
"scan" | |||
] | |||
} | |||
], | |||
"paging": { | |||
"pageSize": 100, | |||
"total": 2, | |||
"pageIndex": 1 | |||
} | |||
] | |||
} | |||
@@ -20,6 +20,7 @@ | |||
package org.sonar.server.permission.ws; | |||
import org.junit.Before; | |||
import org.junit.Ignore; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.junit.rules.ExpectedException; | |||
@@ -82,6 +83,7 @@ public class OldUsersActionTest { | |||
} | |||
@Test | |||
@Ignore("will be deleted") | |||
public void search_for_users_with_response_example() { | |||
UserDto user1 = insertUser(new UserDto().setLogin("admin").setName("Administrator").setEmail("admin@admin.com")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("george.orwell").setName("George Orwell").setEmail("george.orwell@1984.net")); | |||
@@ -95,6 +97,7 @@ public class OldUsersActionTest { | |||
} | |||
@Test | |||
@Ignore("will be deleted") | |||
public void search_for_users_with_one_permission() { | |||
insertUsers(); | |||
String result = ws.newRequest().setParam("permission", "scan").execute().getInput(); |
@@ -29,6 +29,6 @@ public class PermissionsWsModuleTest { | |||
public void verify_count_of_added_components() { | |||
ComponentContainer container = new ComponentContainer(); | |||
new PermissionsWsModule().configure(container); | |||
assertThat(container.size()).isEqualTo(2 + 29); | |||
assertThat(container.size()).isEqualTo(2 + 30); | |||
} | |||
} |
@@ -47,8 +47,7 @@ import org.sonar.server.tester.UserSessionRule; | |||
import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.TestRequest; | |||
import org.sonar.server.ws.WsActionTester; | |||
import org.sonarqube.ws.WsPermissions; | |||
import org.sonarqube.ws.WsPermissions.UsersWsResponse; | |||
import org.sonarqube.ws.WsPermissions.OldUsersWsResponse; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
@@ -56,7 +55,7 @@ import static org.sonar.db.permission.template.PermissionTemplateTesting.newPerm | |||
import static org.sonar.db.permission.template.PermissionTemplateTesting.newPermissionTemplateUserDto; | |||
import static org.sonar.test.JsonAssert.assertJson; | |||
import static org.sonarqube.ws.MediaTypes.PROTOBUF; | |||
import static org.sonarqube.ws.WsPermissions.UsersWsResponse.parseFrom; | |||
import static org.sonarqube.ws.WsPermissions.OldUsersWsResponse.parseFrom; | |||
public class TemplateUsersActionTest { | |||
@@ -124,7 +123,7 @@ public class TemplateUsersActionTest { | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
UsersWsResponse response = parseFrom(responseStream); | |||
OldUsersWsResponse response = parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsExactly("login-1", "login-2"); | |||
} | |||
@@ -137,7 +136,7 @@ public class TemplateUsersActionTest { | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
UsersWsResponse response = parseFrom(responseStream); | |||
OldUsersWsResponse response = parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsOnly("login-1"); | |||
} | |||
@@ -150,7 +149,7 @@ public class TemplateUsersActionTest { | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = parseFrom(responseStream); | |||
OldUsersWsResponse response = OldUsersWsResponse.parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsExactly("login-1", "login-2", "login-3"); | |||
assertThat(response.getUsers(2).getSelected()).isFalse(); | |||
@@ -166,7 +165,7 @@ public class TemplateUsersActionTest { | |||
.setMediaType(PROTOBUF) | |||
.execute().getInputStream(); | |||
WsPermissions.UsersWsResponse response = parseFrom(responseStream); | |||
OldUsersWsResponse response = parseFrom(responseStream); | |||
assertThat(response.getUsersList()).extracting("login").containsOnly("login-2"); | |||
} |
@@ -31,8 +31,11 @@ import org.sonar.api.web.UserRole; | |||
import org.sonar.db.DbClient; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDbTester; | |||
import org.sonar.db.component.ComponentDto; | |||
import org.sonar.db.component.ResourceTypesRule; | |||
import org.sonar.db.permission.PermissionDbTester; | |||
import org.sonar.db.user.UserDbTester; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserPermissionDto; | |||
import org.sonar.server.component.ComponentFinder; | |||
@@ -45,7 +48,10 @@ import org.sonar.server.usergroups.ws.UserGroupFinder; | |||
import org.sonar.server.ws.WsActionTester; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.sonar.api.server.ws.WebService.Param.TEXT_QUERY; | |||
import static org.sonar.api.web.UserRole.ISSUE_ADMIN; | |||
import static org.sonar.core.permission.GlobalPermissions.QUALITY_GATE_ADMIN; | |||
import static org.sonar.core.permission.GlobalPermissions.QUALITY_PROFILE_ADMIN; | |||
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
@@ -65,10 +71,16 @@ public class UsersActionTest { | |||
@Rule | |||
public DbTester db = DbTester.create(System2.INSTANCE); | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
DbClient dbClient = db.getDbClient(); | |||
DbSession dbSession = db.getSession(); | |||
UserDbTester userDb = new UserDbTester(db); | |||
PermissionDbTester permissionDb = new PermissionDbTester(db); | |||
ComponentDbTester componentDbTester = new ComponentDbTester(db); | |||
WsActionTester ws; | |||
ResourceTypesRule resourceTypes = new ResourceTypesRule().setRootQualifiers(Qualifiers.PROJECT, Qualifiers.VIEW, "DEV"); | |||
UsersAction underTest; | |||
@Before | |||
@@ -83,49 +95,108 @@ public class UsersActionTest { | |||
@Test | |||
public void search_for_users_with_response_example() { | |||
UserDto user1 = insertUser(new UserDto().setLogin("admin").setName("Administrator").setEmail("admin@admin.com")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("george.orwell").setName("George Orwell").setEmail("george.orwell@1984.net")); | |||
insertUserRole(new UserPermissionDto().setPermission(SCAN_EXECUTION).setUserId(user1.getId())); | |||
insertUserRole(new UserPermissionDto().setPermission(SCAN_EXECUTION).setUserId(user2.getId())); | |||
dbSession.commit(); | |||
UserDto user2 = userDb.insertUser(new UserDto().setLogin("george.orwell").setName("George Orwell").setEmail("george.orwell@1984.net")); | |||
UserDto user1 = userDb.insertUser(new UserDto().setLogin("admin").setName("Administrator").setEmail("admin@admin.com")); | |||
permissionDb.addGlobalPermissionToUser(SCAN_EXECUTION, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(QUALITY_GATE_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(QUALITY_PROFILE_ADMIN, user1.getId()); | |||
String result = ws.newRequest().setParam("permission", "scan").execute().getInput(); | |||
String result = ws.newRequest().execute().getInput(); | |||
assertJson(result).isSimilarTo(getClass().getResource("users-example.json")); | |||
assertJson(result).withStrictArrayOrder().isSimilarTo(getClass().getResource("users-example.json")); | |||
} | |||
@Test | |||
public void search_for_users_with_one_permission() { | |||
insertUsers(); | |||
insertUsersHavingGlobalPermissions(); | |||
String result = ws.newRequest().setParam("permission", "scan").execute().getInput(); | |||
assertJson(result).isSimilarTo(getClass().getResource("UsersActionTest/users.json")); | |||
assertJson(result).withStrictArrayOrder().isSimilarTo(getClass().getResource("UsersActionTest/users.json")); | |||
} | |||
@Test | |||
public void search_for_users_with_permission_on_project() { | |||
dbClient.componentDao().insert(dbSession, newProjectDto("project-uuid").setKey("project-key")); | |||
ComponentDto project = dbClient.componentDao().selectOrFailByUuid(dbSession, "project-uuid"); | |||
UserDto user = insertUser(newUserDto().setLogin("project-user-login").setName("project-user-name")); | |||
userSession.login().addProjectUuidPermissions(SYSTEM_ADMIN, "project-uuid"); | |||
// User have permission on project | |||
ComponentDto project = componentDbTester.insertComponent(newProjectDto("project-uuid").setKey("project-key")); | |||
UserDto user = userDb.insertUser(newUserDto()); | |||
insertUserRole(new UserPermissionDto().setPermission(ISSUE_ADMIN).setUserId(user.getId()).setComponentId(project.getId())); | |||
// User have permission on another project | |||
ComponentDto anotherProject = componentDbTester.insertComponent(newProjectDto()); | |||
UserDto userHavePermissionOnAnotherProject = userDb.insertUser(newUserDto()); | |||
insertUserRole(new UserPermissionDto().setPermission(ISSUE_ADMIN).setUserId(userHavePermissionOnAnotherProject.getId()).setComponentId(anotherProject.getId())); | |||
// User has no permission | |||
UserDto withoutPermission = userDb.insertUser(newUserDto()); | |||
dbSession.commit(); | |||
userSession.login().addProjectUuidPermissions(SYSTEM_ADMIN, "project-uuid"); | |||
String result = ws.newRequest() | |||
.setParam(PARAM_PERMISSION, ISSUE_ADMIN) | |||
.setParam(PARAM_PROJECT_ID, "project-uuid") | |||
.execute().getInput(); | |||
assertThat(result).contains("project-user-login") | |||
.doesNotContain("login-1"); | |||
assertThat(result).contains(user.getLogin()) | |||
.doesNotContain(userHavePermissionOnAnotherProject.getLogin()) | |||
.doesNotContain(withoutPermission.getLogin()); | |||
} | |||
@Test | |||
public void search_only_for_users_with_permission_when_no_search_query() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
// User have permission on project | |||
ComponentDto project = componentDbTester.insertComponent(newProjectDto()); | |||
UserDto user = userDb.insertUser(newUserDto()); | |||
insertUserRole(new UserPermissionDto().setPermission(ISSUE_ADMIN).setUserId(user.getId()).setComponentId(project.getId())); | |||
// User has no permission | |||
UserDto withoutPermission = userDb.insertUser(newUserDto()); | |||
dbSession.commit(); | |||
String result = ws.newRequest() | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.execute().getInput(); | |||
assertThat(result).contains(user.getLogin()) | |||
.doesNotContain(withoutPermission.getLogin()); | |||
} | |||
@Test | |||
public void search_also_for_users_without_permission_when_search_query() { | |||
userSession.login().setGlobalPermissions(SYSTEM_ADMIN); | |||
// User have permission on project | |||
ComponentDto project = componentDbTester.insertComponent(newProjectDto()); | |||
UserDto user = userDb.insertUser(newUserDto("with-permission", "with-permission", null)); | |||
insertUserRole(new UserPermissionDto().setPermission(ISSUE_ADMIN).setUserId(user.getId()).setComponentId(project.getId())); | |||
// User has no permission | |||
UserDto withoutPermission = userDb.insertUser(newUserDto("without-permission", "without-permission", null)); | |||
UserDto anotherUser = userDb.insertUser(newUserDto("another-user", "another-user", null)); | |||
dbSession.commit(); | |||
String result = ws.newRequest() | |||
.setParam(PARAM_PROJECT_ID, project.uuid()) | |||
.setParam(TEXT_QUERY, "with") | |||
.execute().getInput(); | |||
assertThat(result).contains(user.getLogin()) | |||
.contains(withoutPermission.getLogin()) | |||
.doesNotContain(anotherUser.getLogin()); | |||
} | |||
@Test | |||
public void search_for_users_with_query_as_a_parameter() { | |||
insertUsers(); | |||
insertUsersHavingGlobalPermissions(); | |||
String result = ws.newRequest() | |||
.setParam("permission", "scan") | |||
.setParam(Param.TEXT_QUERY, "ame-1") | |||
.setParam(TEXT_QUERY, "ame-1") | |||
.execute().getInput(); | |||
assertThat(result).contains("login-1") | |||
@@ -135,10 +206,8 @@ public class UsersActionTest { | |||
@Test | |||
public void search_for_users_with_select_as_a_parameter() { | |||
insertUsers(); | |||
insertUsersHavingGlobalPermissions(); | |||
String result = ws.newRequest() | |||
.setParam("permission", "scan") | |||
.setParam(Param.SELECTED, SelectionMode.ALL.value()) | |||
.execute().getInput(); | |||
assertThat(result).contains("login-1", "login-2", "login-3"); | |||
@@ -154,13 +223,6 @@ public class UsersActionTest { | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_permission_parameter_is_not_filled() { | |||
expectedException.expect(IllegalArgumentException.class); | |||
ws.newRequest().execute(); | |||
} | |||
@Test | |||
public void fail_if_insufficient_privileges() { | |||
expectedException.expect(ForbiddenException.class); | |||
@@ -195,6 +257,14 @@ public class UsersActionTest { | |||
.execute(); | |||
} | |||
@Test | |||
public void fail_if_search_query_is_too_short() { | |||
expectedException.expect(BadRequestException.class); | |||
expectedException.expectMessage("The 'q' parameter must have at least 3 characters"); | |||
ws.newRequest().setParam(TEXT_QUERY, "ab").execute(); | |||
} | |||
private UserDto insertUser(UserDto userDto) { | |||
UserDto user = dbClient.userDao().insert(dbSession, userDto.setActive(true)); | |||
dbSession.commit(); | |||
@@ -206,13 +276,13 @@ public class UsersActionTest { | |||
dbSession.commit(); | |||
} | |||
private void insertUsers() { | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
private void insertUsersHavingGlobalPermissions() { | |||
UserDto user3 = insertUser(new UserDto().setLogin("login-3").setName("name-3").setEmail("email-3")); | |||
UserDto user2 = insertUser(new UserDto().setLogin("login-2").setName("name-2").setEmail("email-2")); | |||
UserDto user1 = insertUser(new UserDto().setLogin("login-1").setName("name-1").setEmail("email-1")); | |||
insertUserRole(new UserPermissionDto().setPermission(SCAN_EXECUTION).setUserId(user1.getId())); | |||
insertUserRole(new UserPermissionDto().setPermission(SCAN_EXECUTION).setUserId(user2.getId())); | |||
insertUserRole(new UserPermissionDto().setPermission(SYSTEM_ADMIN).setUserId(user3.getId())); | |||
insertUserRole(new UserPermissionDto().setPermission(SCAN_EXECUTION).setUserId(user2.getId())); | |||
dbSession.commit(); | |||
} | |||
} |
@@ -1,21 +1,25 @@ | |||
{ | |||
"paging": { | |||
"pageIndex": 1, | |||
"pageSize": 20, | |||
"total": 2 | |||
}, | |||
"users": [ | |||
{ | |||
"login": "login-1", | |||
"name": "name-1", | |||
"email": "email-1", | |||
"selected": true | |||
"permissions": [ | |||
"scan" | |||
] | |||
}, | |||
{ | |||
"login": "login-2", | |||
"name": "name-2", | |||
"email": "email-2", | |||
"selected": true | |||
"permissions": [ | |||
"scan" | |||
] | |||
} | |||
], | |||
"paging": { | |||
"pageSize": 100, | |||
"total": 2, | |||
"pageIndex": 1 | |||
} | |||
] | |||
} |
@@ -33,7 +33,7 @@ import org.sonar.db.MyBatis; | |||
import org.sonar.db.user.UserPermissionDto; | |||
import static com.google.common.collect.Maps.newHashMap; | |||
import static java.util.Collections.emptyList; | |||
import static org.sonar.db.DatabaseUtils.executeLargeInputs; | |||
import static org.sonar.db.DatabaseUtils.executeLargeInputsWithoutOutput; | |||
public class PermissionDao implements Dao { | |||
@@ -50,7 +50,7 @@ public class PermissionDao implements Dao { | |||
/** | |||
* @return a paginated list of users. | |||
* @deprecated use {@link #selectUserPermissionsByQuery(DbSession, PermissionQuery)} instead | |||
* @deprecated | |||
*/ | |||
@Deprecated | |||
public List<UserWithPermissionDto> selectUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId, int offset, int limit) { | |||
@@ -60,22 +60,18 @@ public class PermissionDao implements Dao { | |||
} | |||
/** | |||
* Each row returns <code>{@link UserRef}</code>, ordered by user names | |||
* 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 List<String> selectLoginsByPermissionQuery(DbSession dbSession, PermissionQuery query) { | |||
return mapper(dbSession).selectLoginsByPermissionQuery(query, new RowBounds(query.getPageOffset(), query.getPageSize())); | |||
} | |||
public int countUsersByQuery(DbSession dbSession, PermissionQuery query) { | |||
return mapper(dbSession).countUsersByQuery(query); | |||
return mapper(dbSession).countUsersByPermissionQuery(query); | |||
} | |||
public List<UserPermissionDto> selectUserPermissionsByQuery(DbSession dbSession, PermissionQuery query) { | |||
if (query.getLogins() != null && query.getLogins().isEmpty()) { | |||
return emptyList(); | |||
} | |||
return mapper(dbSession).selectUserPermissionsByQuery(query); | |||
public List<UserPermissionDto> selectUserPermissionsByLogins(DbSession dbSession, List<String> logins) { | |||
return executeLargeInputs(logins, mapper(dbSession)::selectUserPermissionsByLogins); | |||
} | |||
public int countUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId) { |
@@ -32,11 +32,11 @@ public interface PermissionMapper { | |||
int countUsers(Map<String, Object> parameters); | |||
void selectUsersByQuery(@Param("query") PermissionQuery query, RowBounds rowBounds, ResultHandler handler); | |||
List<String> selectLoginsByPermissionQuery(@Param("query") PermissionQuery query, RowBounds rowBounds); | |||
int countUsersByQuery(@Param("query") PermissionQuery query); | |||
int countUsersByPermissionQuery(@Param("query") PermissionQuery query); | |||
List<UserPermissionDto> selectUserPermissionsByQuery(@Param("query") PermissionQuery query); | |||
List<UserPermissionDto> selectUserPermissionsByLogins(@Param("logins") List<String> logins); | |||
List<GroupWithPermissionDto> selectGroups(Map<String, Object> parameters); | |||
@@ -166,7 +166,7 @@ public class PermissionQuery { | |||
public PermissionQuery build() { | |||
this.pageIndex = firstNonNull(pageIndex, DEFAULT_PAGE_INDEX); | |||
this.pageSize = firstNonNull(pageSize, DEFAULT_PAGE_SIZE); | |||
checkArgument(searchQuery == null || searchQuery.length() >= 3); | |||
checkArgument(searchQuery == null || searchQuery.length() >= SEARCH_QUERY_MIN_LENGTH); | |||
checkArgument(logins == null || !logins.isEmpty()); | |||
return new PermissionQuery(this); | |||
} |
@@ -1,34 +0,0 @@ | |||
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; | |||
} | |||
} |
@@ -102,6 +102,10 @@ public class UserDao implements Dao { | |||
return executeLargeInputs(logins, session.getMapper(UserMapper.class)::selectByLogins); | |||
} | |||
/** | |||
* @deprecated since 6.0 please use {@link #selectByLogins(DbSession, Collection)} instead | |||
*/ | |||
@Deprecated | |||
public List<UserDto> selectByLogins(Collection<String> logins) { | |||
DbSession session = mybatis.openSession(false); | |||
try { |
@@ -3,20 +3,17 @@ | |||
<mapper namespace="org.sonar.db.permission.PermissionMapper"> | |||
<!-- TODO delete when not used anymore --> | |||
<select id="selectUsers" parameterType="map" resultType="UserWithPermission"> | |||
SELECT u.login as login, u.name as name, u.email as email, user_role.role as permission | |||
<include refid="usersSelection"/> | |||
ORDER BY u.name | |||
</select> | |||
<!-- TODO delete when not used anymore --> | |||
<select id="countUsers" parameterType="map" resultType="int"> | |||
SELECT count(u.login) | |||
<include refid="usersSelection"/> | |||
</select> | |||
<!-- TODO delete when not used anymore --> | |||
<sql id="usersSelection"> | |||
FROM users u | |||
LEFT JOIN user_roles user_role ON user_role.user_id=u.id | |||
@@ -45,25 +42,23 @@ | |||
<sql id="userColumns"> | |||
<!-- lower(u.name) and u.id are present to order by with select distinct --> | |||
u.login as login, u.name as name, u.email as email, lower(u.name), u.id | |||
u.login as login, u.name as name, u.id | |||
</sql> | |||
<select id="selectUsersByQuery" parameterType="map" resultType="org.sonar.db.permission.UserRef"> | |||
select distinct <include refid="userColumns" /> | |||
<include refid="usersByQuery"/> | |||
<select id="selectLoginsByPermissionQuery" parameterType="map" resultType="string"> | |||
select u.login | |||
from ( | |||
select distinct <include refid="userColumns" /> | |||
<include refid="usersByQuery"/> | |||
) u | |||
order by lower(u.name), u.name, u.id | |||
</select> | |||
<select id="countUsersByQuery" parameterType="map" resultType="int"> | |||
<select id="countUsersByPermissionQuery" parameterType="map" resultType="int"> | |||
select count(1) | |||
from ( | |||
select distinct <include refid="userColumns" /> | |||
<include refid="usersByQuery"/>) | |||
</select> | |||
<select id="selectUserPermissionsByQuery" parameterType="map" resultType="UserRole"> | |||
select ur.user_id as userId, ur.resource_id as componentId, ur.role as permission | |||
<include refid="usersByQuery" /> | |||
<include refid="usersByQuery"/>) u | |||
</select> | |||
<sql id="usersByQuery"> | |||
@@ -72,12 +67,6 @@ | |||
left join projects p on ur.resource_id = p.id | |||
<where> | |||
and u.active = ${_true} | |||
<if test="query.logins != null"> | |||
and u.login in | |||
<foreach collection="query.logins" open="(" close=")" item="login" separator=","> | |||
#{login} | |||
</foreach> | |||
</if> | |||
<if test="query.searchQueryToSql != null"> | |||
and lower(u.name) like #{query.searchQueryToSql} ESCAPE '/' | |||
</if> | |||
@@ -88,7 +77,7 @@ | |||
and ur.resource_id is null | |||
</if> | |||
<if test="query.componentUuid!=null"> | |||
and ur.resource_id is not null | |||
and p.uuid=#{query.componentUuid} | |||
</if> | |||
<if test="query.permission!=null"> | |||
and ur.role=#{query.permission} | |||
@@ -97,6 +86,18 @@ | |||
</where> | |||
</sql> | |||
<select id="selectUserPermissionsByLogins" parameterType="map" resultType="UserRole"> | |||
SELECT ur.user_id AS userId, ur.resource_id AS componentId, ur.role AS permission | |||
FROM user_roles ur | |||
INNER JOIN users u ON u.id = ur.user_id AND u.active = ${_true} | |||
<where> | |||
u.login IN | |||
<foreach collection="logins" open="(" close=")" item="login" separator=","> | |||
#{login} | |||
</foreach> | |||
</where> | |||
</select> | |||
<select id="usersCountByProjectIdAndPermission" parameterType="map" | |||
resultType="org.sonar.db.permission.CountByProjectAndPermissionDto"> | |||
SELECT user_role.resource_id as componentId, user_role.role as permission, count(u.login) as count |
@@ -19,17 +19,13 @@ | |||
*/ | |||
package org.sonar.db.permission; | |||
import com.google.common.collect.Iterables; | |||
import java.util.ArrayList; | |||
import java.util.Arrays; | |||
import java.util.List; | |||
import java.util.stream.Collectors; | |||
import java.util.stream.IntStream; | |||
import javax.annotation.Nullable; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonar.api.utils.System2; | |||
import org.sonar.api.web.UserRole; | |||
import org.sonar.core.permission.GlobalPermissions; | |||
import org.sonar.db.DbSession; | |||
import org.sonar.db.DbTester; | |||
import org.sonar.db.component.ComponentDbTester; | |||
@@ -38,19 +34,20 @@ import org.sonar.db.user.UserDbTester; | |||
import org.sonar.db.user.UserDto; | |||
import org.sonar.db.user.UserPermissionDto; | |||
import static java.util.Collections.singletonList; | |||
import static java.util.Arrays.asList; | |||
import static org.assertj.core.api.Assertions.assertThat; | |||
import static org.assertj.core.api.Assertions.tuple; | |||
import static org.sonar.api.web.UserRole.ADMIN; | |||
import static org.sonar.api.web.UserRole.ISSUE_ADMIN; | |||
import static org.sonar.api.web.UserRole.USER; | |||
import static org.sonar.core.permission.GlobalPermissions.PROVISIONING; | |||
import static org.sonar.core.permission.GlobalPermissions.SCAN_EXECUTION; | |||
import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN; | |||
import static org.sonar.db.component.ComponentTesting.newProjectDto; | |||
import static org.sonar.db.user.UserTesting.newUserDto; | |||
public class UserWithPermissionDaoTest { | |||
private static final long COMPONENT_ID = 100L; | |||
@Rule | |||
public DbTester dbTester = DbTester.create(System2.INSTANCE); | |||
UserDbTester userDb = new UserDbTester(dbTester); | |||
@@ -61,178 +58,91 @@ public class UserWithPermissionDaoTest { | |||
PermissionDao underTest = new PermissionDao(dbTester.myBatis()); | |||
@Test | |||
public void select_all_users_for_project_permission() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions.xml"); | |||
OldPermissionQuery query = OldPermissionQuery.builder().permission("user").build(); | |||
List<UserWithPermissionDto> result = selectUsers(session, query, COMPONENT_ID); | |||
assertThat(result).hasSize(3); | |||
UserWithPermissionDto user1 = result.get(0); | |||
assertThat(user1.getLogin()).isEqualTo("user1"); | |||
assertThat(user1.getName()).isEqualTo("User1"); | |||
assertThat(user1.getPermission()).isNotNull(); | |||
UserWithPermissionDto user2 = result.get(1); | |||
assertThat(user2.getLogin()).isEqualTo("user2"); | |||
assertThat(user2.getName()).isEqualTo("User2"); | |||
assertThat(user2.getPermission()).isNotNull(); | |||
UserWithPermissionDto user3 = result.get(2); | |||
assertThat(user3.getLogin()).isEqualTo("user3"); | |||
assertThat(user3.getName()).isEqualTo("User3"); | |||
assertThat(user3.getPermission()).isNull(); | |||
} | |||
@Test | |||
public void select_all_users_for_global_permission() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions.xml"); | |||
OldPermissionQuery query = OldPermissionQuery.builder().permission("admin").build(); | |||
List<UserWithPermissionDto> result = selectUsers(session, query, null); | |||
assertThat(result).hasSize(3); | |||
UserWithPermissionDto user1 = result.get(0); | |||
assertThat(user1.getName()).isEqualTo("User1"); | |||
assertThat(user1.getPermission()).isNotNull(); | |||
UserWithPermissionDto user2 = result.get(1); | |||
assertThat(user2.getName()).isEqualTo("User2"); | |||
assertThat(user2.getPermission()).isNull(); | |||
UserWithPermissionDto user3 = result.get(2); | |||
assertThat(user3.getName()).isEqualTo("User3"); | |||
assertThat(user3.getPermission()).isNull(); | |||
} | |||
@Test | |||
public void select_only_user_with_permission() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions.xml"); | |||
// user1 and user2 have permission user | |||
assertThat(selectUsers(session, OldPermissionQuery.builder().permission("user").membership(OldPermissionQuery.IN).build(), COMPONENT_ID)).hasSize(2); | |||
} | |||
@Test | |||
public void select_only_user_without_permission() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions.xml"); | |||
public void select_logins_by_query() { | |||
UserDto user1 = userDb.insertUser(newUserDto()); | |||
UserDto user2 = userDb.insertUser(newUserDto()); | |||
UserDto user3 = userDb.insertUser(newUserDto()); | |||
UserDto user4 = userDb.insertUser(newUserDto()); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto()); | |||
// Only user3 has not the user permission | |||
assertThat(selectUsers(session, OldPermissionQuery.builder().permission("user").membership(OldPermissionQuery.OUT).build(), COMPONENT_ID)).hasSize(1); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(PROVISIONING, user3.getId()); | |||
permissionDb.addProjectPermissionToUser(USER, user4.getId(), project.getId()); | |||
assertThat(selectLoginsByQuery(PermissionQuery.builder().build())) | |||
.containsOnly(user1.getLogin(), user2.getLogin(), user3.getLogin(), user4.getLogin()); | |||
assertThat(selectLoginsByQuery(PermissionQuery.builder().setPermission(PROVISIONING).build())) | |||
.containsOnly(user3.getLogin()); | |||
assertThat(selectLoginsByQuery(PermissionQuery.builder().withPermissionOnly().setComponentUuid(project.uuid()).build())) | |||
.containsOnly(user4.getLogin()); | |||
} | |||
@Test | |||
public void search_by_user_name() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions.xml"); | |||
public void count_logins_by_query() { | |||
UserDto user1 = userDb.insertUser(newUserDto()); | |||
UserDto user2 = userDb.insertUser(newUserDto()); | |||
UserDto user3 = userDb.insertUser(newUserDto()); | |||
UserDto user4 = userDb.insertUser(newUserDto()); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto()); | |||
List<UserWithPermissionDto> result = selectUsers(session, OldPermissionQuery.builder().permission("user").search("SEr1").build(), COMPONENT_ID); | |||
assertThat(result).hasSize(1); | |||
assertThat(result.get(0).getName()).isEqualTo("User1"); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(PROVISIONING, user3.getId()); | |||
permissionDb.addProjectPermissionToUser(USER, user4.getId(), project.getId()); | |||
result = selectUsers(session, OldPermissionQuery.builder().permission("user").search("user").build(), COMPONENT_ID); | |||
assertThat(result).hasSize(3); | |||
assertThat(countUsersByQuery(PermissionQuery.builder().build())).isEqualTo(4); | |||
assertThat(countUsersByQuery(PermissionQuery.builder().setPermission(PROVISIONING).build())).isEqualTo(1); | |||
assertThat(countUsersByQuery(PermissionQuery.builder().withPermissionOnly().setComponentUuid(project.uuid()).build())).isEqualTo(1); | |||
} | |||
@Test | |||
public void select_only_enable_users() { | |||
dbTester.prepareDbUnit(getClass(), "select_only_enable_users.xml"); | |||
OldPermissionQuery query = OldPermissionQuery.builder().permission("user").build(); | |||
List<UserWithPermissionDto> result = selectUsers(session, query, COMPONENT_ID); | |||
assertThat(result).hasSize(3); | |||
// Disabled user should not be returned | |||
assertThat(Iterables.find(result, input -> input.getLogin().equals("disabledUser"), null)).isNull(); | |||
} | |||
@Test | |||
public void select_users() { | |||
UserDto user3 = userDb.insertUser(newUserDto().setName("3-name")); | |||
UserDto user2 = userDb.insertUser(newUserDto().setName("2-name")); | |||
UserDto user1 = userDb.insertUser(newUserDto().setName("1-name")); | |||
UserDto user4 = userDb.insertUser(newUserDto().setName("4-name")); | |||
public void select_logins_by_query_is_ordered_by_name() { | |||
UserDto user3 = userDb.insertUser(newUserDto().setName("3-name").setLogin("3-login")); | |||
UserDto user2 = userDb.insertUser(newUserDto().setName("2-name").setLogin("2-login")); | |||
UserDto user1 = userDb.insertUser(newUserDto().setName("1-name").setLogin("1-login")); | |||
UserDto user4 = userDb.insertUser(newUserDto().setName("4-name").setLogin("4-login")); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SYSTEM_ADMIN, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.PROVISIONING, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SYSTEM_ADMIN, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addProjectPermissionToUser(UserRole.USER, user4.getId(), project.getId()); | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder(); | |||
List<UserRef> users = selectUsersByQuery(dbQuery); | |||
int count = countUsersByQuery(dbQuery); | |||
List<UserPermissionDto> permissions = selectUserPermissionsByQuery(dbQuery); | |||
assertThat(users) | |||
.hasSize(4) | |||
.extracting(UserRef::getName) | |||
.containsExactly("1-name", "2-name", "3-name", "4-name"); | |||
assertThat(users.get(0)).extracting(UserRef::getEmail, UserRef::getLogin) | |||
.containsExactly(user1.getEmail(), user1.getLogin()); | |||
assertThat(count).isEqualTo(4); | |||
assertThat(permissions).hasSize(5).extracting(UserPermissionDto::getUserId, UserPermissionDto::getPermission) | |||
.containsOnlyOnce( | |||
tuple(user1.getId(), GlobalPermissions.SYSTEM_ADMIN), | |||
tuple(user2.getId(), GlobalPermissions.SYSTEM_ADMIN), | |||
tuple(user3.getId(), GlobalPermissions.SYSTEM_ADMIN), | |||
tuple(user3.getId(), GlobalPermissions.PROVISIONING), | |||
tuple(user4.getId(), UserRole.USER)); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(PROVISIONING, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addProjectPermissionToUser(USER, user4.getId(), project.getId()); | |||
assertThat(selectLoginsByQuery(PermissionQuery.builder().build())).containsExactly("1-login", "2-login", "3-login", "4-login"); | |||
} | |||
@Test | |||
public void select_users_paginated() { | |||
public void select_logins_are_paginated() { | |||
IntStream.rangeClosed(0, 9) | |||
.forEach(i -> userDb.insertUser(newUserDto().setName(i + "-name"))); | |||
.forEach(i -> userDb.insertUser(newUserDto().setName(i + "-name").setLogin(i + "-login"))); | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder().setPageIndex(2).setPageSize(3); | |||
List<UserRef> result = selectUsersByQuery(dbQuery); | |||
int count = countUsersByQuery(dbQuery); | |||
List<String> result = selectLoginsByQuery(dbQuery.build()); | |||
int count = countUsersByQuery(dbQuery.build()); | |||
assertThat(result).hasSize(3).extracting(UserRef::getName) | |||
.containsExactly("3-name", "4-name", "5-name"); | |||
assertThat(result).hasSize(3).containsOnlyOnce("3-login", "4-login", "5-login"); | |||
assertThat(count).isEqualTo(10); | |||
} | |||
@Test | |||
public void select_users_with_query() { | |||
userDb.insertUser(newUserDto().setName("1-name")); | |||
public void select_logins_with_query() { | |||
userDb.insertUser(newUserDto().setName("1-name").setLogin("1-login")); | |||
userDb.insertUser(newUserDto().setName("unknown")); | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder().setSearchQuery("nam"); | |||
List<UserRef> users = selectUsersByQuery(dbQuery); | |||
int count = countUsersByQuery(dbQuery); | |||
List<String> users = selectLoginsByQuery(dbQuery.build()); | |||
assertThat(users).hasSize(1); | |||
assertThat(users.get(0).getName()).isEqualTo("1-name"); | |||
assertThat(count).isEqualTo(1); | |||
} | |||
@Test | |||
public void select_user_permissions() { | |||
UserDto user = userDb.insertUser(newUserDto().setLogin("user-login")); | |||
UserDto anotherUser = userDb.insertUser(newUserDto().setLogin("another-login")); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto()); | |||
permissionDb.addProjectPermissionToUser(UserRole.ADMIN, user.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(UserRole.ADMIN, anotherUser.getId(), project.getId()); | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder() | |||
.setComponentUuid(project.uuid()) | |||
.setLogins(singletonList("user-login")) | |||
.withPermissionOnly(); | |||
List<UserPermissionDto> result = selectUserPermissionsByQuery(dbQuery); | |||
assertThat(result).hasSize(1); | |||
UserPermissionDto userPermission = result.get(0); | |||
assertThat(userPermission.getComponentId()).isEqualTo(project.getId()); | |||
assertThat(userPermission.getPermission()).isEqualTo(UserRole.ADMIN); | |||
assertThat(userPermission.getUserId()).isEqualTo(user.getId()); | |||
assertThat(users.get(0)).isEqualTo("1-login"); | |||
} | |||
@Test | |||
public void select_users_with_global_permissions() { | |||
public void select_logins_with_global_permissions() { | |||
UserDto user3 = userDb.insertUser(newUserDto().setName("3-name")); | |||
UserDto user2 = userDb.insertUser(newUserDto().setName("2-name")); | |||
UserDto user1 = userDb.insertUser(newUserDto().setName("1-name")); | |||
@@ -240,82 +150,73 @@ public class UserWithPermissionDaoTest { | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SCAN_EXECUTION, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.PROVISIONING, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SCAN_EXECUTION, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SYSTEM_ADMIN, user1.getId()); | |||
permissionDb.addGlobalPermissionToUser(SCAN_EXECUTION, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(PROVISIONING, user3.getId()); | |||
permissionDb.addGlobalPermissionToUser(SCAN_EXECUTION, user2.getId()); | |||
permissionDb.addGlobalPermissionToUser(SYSTEM_ADMIN, user1.getId()); | |||
// project permission | |||
permissionDb.addProjectPermissionToUser(GlobalPermissions.SCAN_EXECUTION, user4.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(SCAN_EXECUTION, user4.getId(), project.getId()); | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder() | |||
.setComponentUuid(null) | |||
.setPermission(GlobalPermissions.SCAN_EXECUTION) | |||
.setPermission(SCAN_EXECUTION) | |||
.withPermissionOnly(); | |||
List<UserRef> result = selectUsersByQuery(dbQuery); | |||
int count = countUsersByQuery(dbQuery); | |||
List<String> result = selectLoginsByQuery(dbQuery.build()); | |||
int count = countUsersByQuery(dbQuery.build()); | |||
assertThat(result).hasSize(2).extracting(UserRef::getName) | |||
.containsExactly("2-name", "3-name"); | |||
assertThat(result).hasSize(2).containsExactly(user2.getLogin(), user3.getLogin()); | |||
assertThat(count).isEqualTo(2); | |||
} | |||
@Test | |||
public void select_users_with_project_permissions() { | |||
UserDto user3 = userDb.insertUser(newUserDto().setName("3-name")); | |||
UserDto user2 = userDb.insertUser(newUserDto().setName("2-name")); | |||
UserDto user1 = userDb.insertUser(newUserDto().setName("1-name")); | |||
UserDto user4 = userDb.insertUser(newUserDto().setName("4-name")); | |||
public void select_logins_with_project_permissions() { | |||
// create reversed list of user | |||
List<UserDto> dbUsers = IntStream.rangeClosed(1, 4) | |||
.mapToObj(i -> userDb.insertUser(newUserDto().setName(i + "-name").setLogin(i + "-login"))) | |||
.collect(Collectors.toList()); | |||
ComponentDto project = componentDb.insertComponent(newProjectDto("project-uuid")); | |||
permissionDb.addProjectPermissionToUser(GlobalPermissions.SCAN_EXECUTION, user3.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(GlobalPermissions.PROVISIONING, user3.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(GlobalPermissions.SCAN_EXECUTION, user2.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(GlobalPermissions.SYSTEM_ADMIN, user1.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(SCAN_EXECUTION, dbUsers.get(0).getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(PROVISIONING, dbUsers.get(0).getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(SCAN_EXECUTION, dbUsers.get(1).getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(SYSTEM_ADMIN, dbUsers.get(2).getId(), project.getId()); | |||
// global permission | |||
permissionDb.addGlobalPermissionToUser(GlobalPermissions.SCAN_EXECUTION, user4.getId()); | |||
permissionDb.addGlobalPermissionToUser(SCAN_EXECUTION, dbUsers.get(3).getId()); | |||
PermissionQuery.Builder dbQuery = PermissionQuery.builder() | |||
.setComponentUuid(null) | |||
.setPermission(GlobalPermissions.SCAN_EXECUTION) | |||
.setPermission(SCAN_EXECUTION) | |||
.withPermissionOnly() | |||
.setComponentUuid(project.uuid()); | |||
List<UserRef> result = selectUsersByQuery(dbQuery); | |||
int count = countUsersByQuery(dbQuery); | |||
List<String> result = selectLoginsByQuery(dbQuery.build()); | |||
int count = countUsersByQuery(dbQuery.build()); | |||
assertThat(result).hasSize(2).extracting(UserRef::getName) | |||
.containsExactly("2-name", "3-name"); | |||
assertThat(result).hasSize(2).containsOnlyOnce(dbUsers.get(0).getLogin(), dbUsers.get(1).getLogin()); | |||
assertThat(count).isEqualTo(2); | |||
} | |||
@Test | |||
public void should_be_sorted_by_user_name() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions_should_be_sorted_by_user_name.xml"); | |||
public void select_user_permissions_by_logins() { | |||
UserDto firstUser = userDb.insertUser(newUserDto()); | |||
UserDto secondUser = userDb.insertUser(newUserDto()); | |||
UserDto thirdUser = userDb.insertUser(newUserDto()); | |||
List<UserWithPermissionDto> result = selectUsers(session, OldPermissionQuery.builder().permission("user").build(), COMPONENT_ID); | |||
assertThat(result).hasSize(3); | |||
assertThat(result.get(0).getName()).isEqualTo("User1"); | |||
assertThat(result.get(1).getName()).isEqualTo("User2"); | |||
assertThat(result.get(2).getName()).isEqualTo("User3"); | |||
} | |||
ComponentDto project = componentDb.insertComponent(newProjectDto()); | |||
permissionDb.addProjectPermissionToUser(ADMIN, firstUser.getId(), project.getId()); | |||
permissionDb.addProjectPermissionToUser(USER, secondUser.getId(), project.getId()); | |||
@Test | |||
public void should_be_paginated() { | |||
dbTester.prepareDbUnit(getClass(), "users_with_permissions.xml"); | |||
List<UserWithPermissionDto> result = underTest.selectUsers(session, OldPermissionQuery.builder().permission("user").build(), COMPONENT_ID, 0, 2); | |||
assertThat(result).hasSize(2); | |||
assertThat(result.get(0).getName()).isEqualTo("User1"); | |||
assertThat(result.get(1).getName()).isEqualTo("User2"); | |||
result = underTest.selectUsers(session, OldPermissionQuery.builder().permission("user").build(), COMPONENT_ID, 1, 2); | |||
assertThat(result).hasSize(2); | |||
assertThat(result.get(0).getName()).isEqualTo("User2"); | |||
assertThat(result.get(1).getName()).isEqualTo("User3"); | |||
result = underTest.selectUsers(session, OldPermissionQuery.builder().permission("user").build(), COMPONENT_ID, 2, 1); | |||
assertThat(result).hasSize(1); | |||
assertThat(result.get(0).getName()).isEqualTo("User3"); | |||
ComponentDto anotherProject = componentDb.insertComponent(newProjectDto()); | |||
permissionDb.addProjectPermissionToUser(ADMIN, thirdUser.getId(), anotherProject.getId()); | |||
List<UserPermissionDto> result = underTest.selectUserPermissionsByLogins(session, (asList(firstUser.getLogin(), secondUser.getLogin(), thirdUser.getLogin()))); | |||
assertThat(result) | |||
.extracting(UserPermissionDto::getUserId, UserPermissionDto::getPermission, UserPermissionDto::getComponentId) | |||
.containsOnly( | |||
tuple(firstUser.getId(), ADMIN, project.getId()), | |||
tuple(secondUser.getId(), USER, project.getId()), | |||
tuple(thirdUser.getId(), ADMIN, anotherProject.getId())); | |||
} | |||
@Test | |||
@@ -332,7 +233,7 @@ public class UserWithPermissionDaoTest { | |||
addPermissionToUser(USER, user1.getId(), 456L); | |||
final List<CountByProjectAndPermissionDto> result = new ArrayList<>(); | |||
underTest.usersCountByComponentIdAndPermission(dbTester.getSession(), Arrays.asList(123L, 456L, 789L), | |||
underTest.usersCountByComponentIdAndPermission(dbTester.getSession(), asList(123L, 456L, 789L), | |||
context -> result.add((CountByProjectAndPermissionDto) context.getResultObject())); | |||
assertThat(result).hasSize(3); | |||
assertThat(result).extracting("permission").containsOnly(ADMIN, USER); | |||
@@ -340,22 +241,12 @@ public class UserWithPermissionDaoTest { | |||
assertThat(result).extracting("count").containsOnly(3, 1); | |||
} | |||
private List<UserWithPermissionDto> selectUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId) { | |||
return underTest.selectUsers(session, query, componentId, 0, Integer.MAX_VALUE); | |||
} | |||
private List<UserRef> selectUsersByQuery(PermissionQuery.Builder query) { | |||
List<UserRef> result = new ArrayList<>(); | |||
underTest.selectUsersByQuery(session, query.build(), context -> result.add((UserRef) context.getResultObject())); | |||
return result; | |||
} | |||
private int countUsersByQuery(PermissionQuery.Builder query) { | |||
return underTest.countUsersByQuery(session, query.build()); | |||
private List<String> selectLoginsByQuery(PermissionQuery query) { | |||
return underTest.selectLoginsByPermissionQuery(session, query); | |||
} | |||
private List<UserPermissionDto> selectUserPermissionsByQuery(PermissionQuery.Builder query) { | |||
return underTest.selectUserPermissionsByQuery(session, query.build()); | |||
private int countUsersByQuery(PermissionQuery query) { | |||
return underTest.countUsersByQuery(session, query); | |||
} | |||
private void addPermissionToUser(String permission, long userId, long resourceId) { |
@@ -21,6 +21,7 @@ package org.sonarqube.ws.client.permission; | |||
import org.sonarqube.ws.WsPermissions; | |||
import org.sonarqube.ws.WsPermissions.CreateTemplateWsResponse; | |||
import org.sonarqube.ws.WsPermissions.OldUsersWsResponse; | |||
import org.sonarqube.ws.WsPermissions.SearchProjectPermissionsWsResponse; | |||
import org.sonarqube.ws.WsPermissions.SearchTemplatesWsResponse; | |||
import org.sonarqube.ws.WsPermissions.UpdateTemplateWsResponse; | |||
@@ -213,7 +214,7 @@ public class PermissionsService extends BaseService { | |||
.setParam(PARAM_PROJECT_KEY_PATTERN, request.getProjectKeyPattern()), UpdateTemplateWsResponse.parser()); | |||
} | |||
public UsersWsResponse users(OldUsersWsRequest request) { | |||
public OldUsersWsResponse oldUsers(OldUsersWsRequest request) { | |||
return call(new GetRequest(path("users")) | |||
.setParam(PARAM_PERMISSION, request.getPermission()) | |||
.setParam(PARAM_PROJECT_ID, request.getProjectId()) | |||
@@ -221,6 +222,16 @@ public class PermissionsService extends BaseService { | |||
.setParam("selected", request.getSelected()) | |||
.setParam("p", request.getPage()) | |||
.setParam("ps", request.getPageSize()) | |||
.setParam("q", request.getQuery()), OldUsersWsResponse.parser()); | |||
} | |||
public UsersWsResponse users(UsersWsRequest request) { | |||
return call(new GetRequest(path("users2")) | |||
.setParam(PARAM_PERMISSION, request.getPermission()) | |||
.setParam(PARAM_PROJECT_ID, request.getProjectId()) | |||
.setParam(PARAM_PROJECT_KEY, request.getProjectKey()) | |||
.setParam("p", request.getPage()) | |||
.setParam("ps", request.getPageSize()) | |||
.setParam("q", request.getQuery()), UsersWsResponse.parser()); | |||
} | |||
} |
@@ -116,7 +116,7 @@ message User { | |||
optional string login = 1; | |||
optional string name = 2; | |||
optional string email = 3; | |||
optional bool selected = 4; | |||
repeated string permissions = 4; | |||
} | |||
message Group { |
@@ -22,6 +22,7 @@ package org.sonarqube.ws.client.permission; | |||
import org.junit.Rule; | |||
import org.junit.Test; | |||
import org.sonarqube.ws.WsPermissions; | |||
import org.sonarqube.ws.WsPermissions.OldUsersWsResponse; | |||
import org.sonarqube.ws.client.GetRequest; | |||
import org.sonarqube.ws.client.PostRequest; | |||
import org.sonarqube.ws.client.ServiceTester; | |||
@@ -431,7 +432,7 @@ public class PermissionsServiceTest { | |||
@Test | |||
public void users_does_GET_on_Ws_users() { | |||
underTest.users(new OldUsersWsRequest() | |||
underTest.oldUsers(new OldUsersWsRequest() | |||
.setPermission(PERMISSION_VALUE) | |||
.setProjectId(PROJECT_ID_VALUE) | |||
.setProjectKey(PROJECT_KEY_VALUE) | |||
@@ -441,7 +442,7 @@ public class PermissionsServiceTest { | |||
.setQuery(QUERY_VALUE) | |||
); | |||
assertThat(serviceTester.getGetParser()).isSameAs(WsPermissions.UsersWsResponse.parser()); | |||
assertThat(serviceTester.getGetParser()).isSameAs(OldUsersWsResponse.parser()); | |||
GetRequest getRequest = serviceTester.getGetRequest(); | |||
serviceTester.assertThat(getRequest) | |||
.hasPath("users") |