]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7835 WS permissions/users return permissions in response
authorTeryk Bellahsene <teryk.bellahsene@sonarsource.com>
Wed, 6 Jul 2016 00:02:47 +0000 (02:02 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Tue, 12 Jul 2016 08:16:53 +0000 (10:16 +0200)
21 files changed:
it/it-tests/src/test/java/it/authorisation/PermissionSearchTest.java
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionRequestValidator.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/PermissionsWsModule.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java
server/sonar-server/src/main/resources/org/sonar/server/permission/ws/users-example.json
server/sonar-server/src/test/java/org/sonar/server/permission/ws/OldUsersActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/PermissionsWsModuleTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/TemplateUsersActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java
server/sonar-server/src/test/resources/org/sonar/server/permission/ws/UsersActionTest/users.json
sonar-db/src/main/java/org/sonar/db/permission/PermissionDao.java
sonar-db/src/main/java/org/sonar/db/permission/PermissionMapper.java
sonar-db/src/main/java/org/sonar/db/permission/PermissionQuery.java
sonar-db/src/main/java/org/sonar/db/permission/UserRef.java [deleted file]
sonar-db/src/main/java/org/sonar/db/user/UserDao.java
sonar-db/src/main/resources/org/sonar/db/permission/PermissionMapper.xml
sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java
sonar-ws/src/main/java/org/sonarqube/ws/client/permission/PermissionsService.java
sonar-ws/src/main/protobuf/ws-permissions.proto
sonar-ws/src/test/java/org/sonarqube/ws/client/permission/PermissionsServiceTest.java

index 24e0fede38b49051f92d4676425ea5c02d805c29..7f9fb8c7b6131d0533e67f3304fcbd6cf2c7183a 100644 (file)
@@ -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
index 15949413fabbb482f8b4440b222a5e06b9e3d5c1..05d3804e9a03a1b315f5385b5a300d81dc3a0add 100644 (file)
@@ -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)));
   }
index f452212ceeb3cb5dddd1b19d15576082a5de46b8..bcf598e7228240786abd8ff64af143c731de8d8e 100644 (file)
@@ -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 {
index c4fe7ff6e0868e41656d0125f2dd0a2cf4500093..c2d512854079dbaea581e91c3a04b19a7bf42481 100644 (file)
@@ -46,6 +46,7 @@ public class PermissionsWsModule extends Module {
       RemoveGroupAction.class,
       RemoveUserAction.class,
       OldUsersAction.class,
+      UsersAction.class,
       GroupsAction.class,
       SearchGlobalPermissionsAction.class,
       SearchProjectPermissionsAction.class,
index 2950f8733ebd9773a364d674ab18dd34a65eb8fe..3fc29983a57d04be98f836e0eb332d546f90f295 100644 (file)
 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);
   }
 }
index 5f13cd532860ffc199c838a097fff691b296ed4b..eef7bf0f1fe337360a4f0e07d88b2737355aca3d 100644 (file)
@@ -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
-  }
+  ]
 }
 
index e31df437d104cd7ee085710b90cf2b031c768dea..5bf5c3c9e51ccaf0455b10d6d901517905d45b44 100644 (file)
@@ -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();
index d238645c924cbc1143f6c3429d22b5745638fcd3..9e1b74355da78d032e4de937e17ade8312af5341 100644 (file)
@@ -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);
   }
 }
index d0f12b2c021f716373f0e858388de18e81ee5f75..1adc1b4fcd65b22f8e188f0c603bdd1368a00f63 100644 (file)
@@ -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");
   }
index 64856ffb8be79ea4bdb0ba492ef3f7da4ba62185..4c413e74c75ed4056f5045487a4e23efc9717e62 100644 (file)
@@ -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();
   }
 }
index 364dff3cf5ae38cd95f9d8d5452abd02865eb032..29534a49dc77641f2ccb99d750787ea1235d7a9b 100644 (file)
@@ -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
-  }
+  ]
 }
index 9f4426021d77abc24e1d34e6a99d5df878538889..7f5eafaffd418336e0ac82192d996fba4575825e 100644 (file)
@@ -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) {
index cad5ff80c40075eb7adb73501c85ff350d111503..02b2415b9a196c212a83b2f8ea9f35319bd7c70c 100644 (file)
@@ -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);
 
index 1d76a9dd426c452822917cd21d6266e1edc44013..cff95938144ef78d9000a1bbe118a7e8db416238 100644 (file)
@@ -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);
     }
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
deleted file mode 100644 (file)
index 4ffd4ff..0000000
+++ /dev/null
@@ -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;
-  }
-}
index b2029c369a119fe7c6263ebfa7c832f8244851a6..5bcecc2c691960e8ed363661b07e456e1538fb5e 100644 (file)
@@ -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 {
index 79297f8659d49d2e667a9ef30af79be942186a97..e9e37c92933aa0ab223cd9b9f89d48b2c6f118fb 100644 (file)
@@ -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
 
   <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">
         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}
     </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
index 093ed971150d3fdc36a260bbc6afd2e22a7a2ab1..1ac2d22028791d93b195b4a10177660085639952 100644 (file)
  */
 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) {
index 2ce33d1fef667c4712bb64525aef986a80d128e2..697747e82199a5db2968752681ab8a9df068b22a 100644 (file)
@@ -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());
   }
 }
index 7477ee25d34c3b259853182326368b7b69c53be2..ceb2a559dade27d2a42d8b270d7336d825c387e2 100644 (file)
@@ -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 {
index f9bdee7f197e27587faeb09f80da81278c892dac..d0e4e0a52e6a019c4cf6fb0fa746aa7922605709 100644 (file)
@@ -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")