]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7838 SONAR-7835 Return all permissions of matching users
authorJulien Lancelot <julien.lancelot@sonarsource.com>
Tue, 12 Jul 2016 07:03:14 +0000 (09:03 +0200)
committerStas Vilchik <vilchiks@gmail.com>
Tue, 12 Jul 2016 08:17:57 +0000 (10:17 +0200)
When searching for permissions users that match a given permission, instead of only returnin this permission we now return all user permissions

12 files changed:
server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java [deleted file]
server/sonar-server/src/main/java/org/sonar/server/permission/ws/GroupsAction.java
server/sonar-server/src/main/java/org/sonar/server/permission/ws/UsersAction.java
server/sonar-server/src/main/java/org/sonar/server/platform/platformlevel/PlatformLevel4.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/GroupsActionTest.java
server/sonar-server/src/test/java/org/sonar/server/permission/ws/UsersActionTest.java
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/resources/org/sonar/db/permission/PermissionMapper.xml
sonar-db/src/test/java/org/sonar/db/permission/GroupWithPermissionDaoTest.java
sonar-db/src/test/java/org/sonar/db/permission/UserWithPermissionDaoTest.java

diff --git a/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java b/server/sonar-server/src/main/java/org/sonar/server/permission/PermissionFinder.java
deleted file mode 100644 (file)
index c002069..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * SonarQube
- * Copyright (C) 2009-2016 SonarSource SA
- * mailto:contact AT sonarsource DOT com
- *
- * This program is free software; you can redistribute it and/or
- * modify it under the terms of the GNU Lesser General Public
- * License as published by the Free Software Foundation; either
- * version 3 of the License, or (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public License
- * along with this program; if not, write to the Free Software Foundation,
- * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
- */
-package org.sonar.server.permission;
-
-import com.google.common.collect.Ordering;
-import java.util.List;
-import java.util.stream.Collectors;
-import org.sonar.api.security.DefaultGroups;
-import org.sonar.api.server.ServerSide;
-import org.sonar.db.DbClient;
-import org.sonar.db.DbSession;
-import org.sonar.db.permission.PermissionDao;
-import org.sonar.db.permission.PermissionQuery;
-import org.sonar.db.user.GroupDao;
-import org.sonar.db.user.GroupDto;
-import org.sonar.db.user.GroupRoleDto;
-
-import static java.util.Collections.emptyList;
-
-@ServerSide
-public class PermissionFinder {
-
-  private final PermissionDao permissionDao;
-  private final GroupDao groupDao;
-
-  public PermissionFinder(DbClient dbClient) {
-    this.permissionDao = dbClient.permissionDao();
-    this.groupDao = dbClient.groupDao();
-  }
-
-  public List<GroupDto> findGroups(DbSession dbSession, PermissionQuery.Builder dbQuery) {
-    List<String> orderedNames = permissionDao.selectGroupNamesByPermissionQuery(dbSession, dbQuery.build());
-
-    List<GroupDto> groups = groupDao.selectByNames(dbSession, orderedNames);
-    if (orderedNames.contains(DefaultGroups.ANYONE)) {
-      groups.add(0, new GroupDto().setId(0L).setName(DefaultGroups.ANYONE));
-    }
-
-    return Ordering.explicit(orderedNames).onResultOf(GroupDto::getName).immutableSortedCopy(groups);
-  }
-
-  public List<GroupRoleDto> findGroupPermissions(DbSession dbSession, PermissionQuery.Builder dbQuery, List<GroupDto> groups) {
-    if (groups.isEmpty()) {
-      return emptyList();
-    }
-
-    List<String> names = groups.stream().map(GroupDto::getName).collect(Collectors.toList());
-    return permissionDao.selectGroupPermissionsByQuery(dbSession, dbQuery
-      .setGroupNames(names)
-      .withPermissionOnly()
-      .build());
-  }
-}
index 7a1ec19c5b849bcfe1ac175f01955f708e1bfe3a..f777d87dbd47d14cc2315e8c47ce6ab1bb4676cf 100644 (file)
@@ -21,9 +21,12 @@ 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 com.google.common.io.Resources;
 import java.util.List;
+import java.util.stream.Collectors;
+import org.sonar.api.security.DefaultGroups;
 import org.sonar.api.server.ws.Request;
 import org.sonar.api.server.ws.Response;
 import org.sonar.api.server.ws.WebService;
@@ -35,12 +38,12 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.permission.PermissionQuery;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.GroupRoleDto;
-import org.sonar.server.permission.PermissionFinder;
 import org.sonar.server.user.UserSession;
 import org.sonarqube.ws.WsPermissions.Group;
 import org.sonarqube.ws.WsPermissions.WsGroupsResponse;
 import org.sonarqube.ws.client.permission.GroupsWsRequest;
 
+import static java.util.Collections.emptyList;
 import static org.sonar.db.permission.PermissionQuery.DEFAULT_PAGE_SIZE;
 import static org.sonar.db.permission.PermissionQuery.RESULTS_MAX_SIZE;
 import static org.sonar.db.permission.PermissionQuery.SEARCH_QUERY_MIN_LENGTH;
@@ -57,13 +60,11 @@ import static org.sonarqube.ws.client.permission.PermissionsWsParameters.PARAM_P
 public class GroupsAction implements PermissionsWsAction {
   private final DbClient dbClient;
   private final UserSession userSession;
-  private final PermissionFinder permissionFinder;
   private final PermissionDependenciesFinder dependenciesFinder;
 
-  public GroupsAction(DbClient dbClient, UserSession userSession, PermissionFinder permissionFinder, PermissionDependenciesFinder dependenciesFinder) {
+  public GroupsAction(DbClient dbClient, UserSession userSession, PermissionDependenciesFinder dependenciesFinder) {
     this.dbClient = dbClient;
     this.userSession = userSession;
-    this.permissionFinder = permissionFinder;
     this.dependenciesFinder = dependenciesFinder;
   }
 
@@ -100,10 +101,10 @@ public class GroupsAction implements PermissionsWsAction {
       Optional<ComponentDto> project = dependenciesFinder.searchProject(dbSession, newOptionalWsProjectRef(request.getProjectId(), request.getProjectKey()));
       checkProjectAdminUserByComponentDto(userSession, project);
 
-      PermissionQuery.Builder dbQuery = buildPermissionQuery(request, project);
-      List<GroupDto> groups = permissionFinder.findGroups(dbSession, dbQuery);
-      int total = dbClient.permissionDao().countGroupsByPermissionQuery(dbSession, dbQuery.build());
-      List<GroupRoleDto> groupsWithPermission = permissionFinder.findGroupPermissions(dbSession, dbQuery, groups);
+      PermissionQuery dbQuery = buildPermissionQuery(request, project);
+      List<GroupDto> groups = findGroups(dbSession, dbQuery);
+      int total = dbClient.permissionDao().countGroupsByPermissionQuery(dbSession, dbQuery);
+      List<GroupRoleDto> groupsWithPermission = findGroupPermissions(dbSession, groups, project);
       return buildResponse(groups, groupsWithPermission, Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total));
     } finally {
       dbClient.closeSession(dbSession);
@@ -124,7 +125,7 @@ public class GroupsAction implements PermissionsWsAction {
     return groupsRequest;
   }
 
-  private static PermissionQuery.Builder buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) {
+  private static PermissionQuery buildPermissionQuery(GroupsWsRequest request, Optional<ComponentDto> project) {
     PermissionQuery.Builder permissionQuery = PermissionQuery.builder()
       .setPermission(request.getPermission())
       .setPageIndex(request.getPage())
@@ -136,7 +137,7 @@ public class GroupsAction implements PermissionsWsAction {
     if (request.getQuery() == null) {
       permissionQuery.withPermissionOnly();
     }
-    return permissionQuery;
+    return permissionQuery.build();
   }
 
   private static WsGroupsResponse buildResponse(List<GroupDto> groups, List<GroupRoleDto> groupPermissions, Paging paging) {
@@ -163,4 +164,21 @@ public class GroupsAction implements PermissionsWsAction {
 
     return response.build();
   }
+
+  private List<GroupDto> findGroups(DbSession dbSession, PermissionQuery dbQuery) {
+    List<String> orderedNames = dbClient.permissionDao().selectGroupNamesByPermissionQuery(dbSession, dbQuery);
+    List<GroupDto> groups = dbClient.groupDao().selectByNames(dbSession, orderedNames);
+    if (orderedNames.contains(DefaultGroups.ANYONE)) {
+      groups.add(0, new GroupDto().setId(0L).setName(DefaultGroups.ANYONE));
+    }
+    return Ordering.explicit(orderedNames).onResultOf(GroupDto::getName).immutableSortedCopy(groups);
+  }
+
+  private List<GroupRoleDto> findGroupPermissions(DbSession dbSession, List<GroupDto> groups, Optional<ComponentDto> project) {
+    if (groups.isEmpty()) {
+      return emptyList();
+    }
+    List<String> names = groups.stream().map(GroupDto::getName).collect(Collectors.toList());
+    return dbClient.permissionDao().selectGroupPermissionsByGroupNamesAndProject(dbSession, names, project.isPresent() ? project.get().getId() : null);
+  }
 }
index 065cb0157774f3044acb131f20e236ee6e5eac77..ae90264ab201f55a72cf2a56aabe1fecdd912add 100644 (file)
@@ -36,7 +36,6 @@ import org.sonar.db.component.ComponentDto;
 import org.sonar.db.permission.PermissionQuery;
 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;
@@ -61,13 +60,11 @@ public class UsersAction implements PermissionsWsAction {
 
   private final DbClient dbClient;
   private final UserSession userSession;
-  private final PermissionFinder permissionFinder;
   private final PermissionDependenciesFinder dependenciesFinder;
 
-  public UsersAction(DbClient dbClient, UserSession userSession, PermissionFinder permissionFinder, PermissionDependenciesFinder dependenciesFinder) {
+  public UsersAction(DbClient dbClient, UserSession userSession, PermissionDependenciesFinder dependenciesFinder) {
     this.dbClient = dbClient;
     this.userSession = userSession;
-    this.permissionFinder = permissionFinder;
     this.dependenciesFinder = dependenciesFinder;
   }
 
@@ -108,7 +105,7 @@ public class UsersAction implements PermissionsWsAction {
       PermissionQuery dbQuery = buildPermissionQuery(request, project);
       List<UserDto> users = findUsers(dbSession, dbQuery);
       int total = dbClient.permissionDao().countUsersByQuery(dbSession, dbQuery);
-      List<UserPermissionDto> userPermissions = findUserPermissions(dbSession, users);
+      List<UserPermissionDto> userPermissions = findUserPermissions(dbSession, users, project);
       Paging paging = Paging.forPageIndex(request.getPage()).withPageSize(request.getPageSize()).andTotal(total);
       return buildResponse(users, userPermissions, paging);
     } finally {
@@ -179,11 +176,11 @@ public class UsersAction implements PermissionsWsAction {
     return Ordering.explicit(orderedLogins).onResultOf(UserDto::getLogin).immutableSortedCopy(dbClient.userDao().selectByLogins(dbSession, orderedLogins));
   }
 
-  private List<UserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users) {
+  private List<UserPermissionDto> findUserPermissions(DbSession dbSession, List<UserDto> users, Optional<ComponentDto> project) {
     if (users.isEmpty()) {
       return emptyList();
     }
     List<String> logins = users.stream().map(UserDto::getLogin).collect(Collectors.toList());
-    return dbClient.permissionDao().selectUserPermissionsByLogins(dbSession, logins);
+    return dbClient.permissionDao().selectUserPermissionsByLoginsAnProject(dbSession, logins, project.isPresent() ? project.get().getId() : null);
   }
 }
index 72efb56c58012ca31e3af2c5f535835683cf5975..34f76578c2e73a9ef35bd36ea68782f8ac8aec82 100644 (file)
@@ -140,7 +140,6 @@ import org.sonar.server.notification.NotificationCenter;
 import org.sonar.server.notification.NotificationService;
 import org.sonar.server.notification.email.AlertsEmailTemplate;
 import org.sonar.server.notification.email.EmailNotificationChannel;
-import org.sonar.server.permission.PermissionFinder;
 import org.sonar.server.permission.PermissionService;
 import org.sonar.server.permission.PermissionUpdater;
 import org.sonar.server.permission.ws.PermissionsWsModule;
@@ -520,7 +519,6 @@ public class PlatformLevel4 extends PlatformLevel {
       PermissionRepository.class,
       PermissionService.class,
       PermissionUpdater.class,
-      PermissionFinder.class,
       PermissionsWsModule.class,
 
       // components
index c2e51e6291b2fd05299c1f89807ef339275d8254..a15f79ea141f5a43f969f63d8fd31dc4afaf2700 100644 (file)
@@ -39,7 +39,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.permission.PermissionFinder;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usergroups.ws.UserGroupFinder;
 import org.sonar.server.ws.WsActionTester;
@@ -81,11 +80,9 @@ public class GroupsActionTest {
   public void setUp() {
     dbClient = db.getDbClient();
     dbSession = db.getSession();
-    PermissionFinder permissionFinder = new PermissionFinder(dbClient);
     underTest = new GroupsAction(
       dbClient,
       userSession,
-      permissionFinder,
       new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes));
     ws = new WsActionTester(underTest);
 
index 4c413e74c75ed4056f5045487a4e23efc9717e62..869f3f8f6415d081586f95bcb0d0bea7bb02411e 100644 (file)
@@ -42,7 +42,6 @@ import org.sonar.server.component.ComponentFinder;
 import org.sonar.server.exceptions.BadRequestException;
 import org.sonar.server.exceptions.ForbiddenException;
 import org.sonar.server.exceptions.UnauthorizedException;
-import org.sonar.server.permission.PermissionFinder;
 import org.sonar.server.tester.UserSessionRule;
 import org.sonar.server.usergroups.ws.UserGroupFinder;
 import org.sonar.server.ws.WsActionTester;
@@ -85,9 +84,8 @@ public class UsersActionTest {
 
   @Before
   public void setUp() {
-    PermissionFinder permissionFinder = new PermissionFinder(dbClient);
     PermissionDependenciesFinder dependenciesFinder = new PermissionDependenciesFinder(dbClient, new ComponentFinder(dbClient), new UserGroupFinder(dbClient), resourceTypes);
-    underTest = new UsersAction(dbClient, userSession, permissionFinder, dependenciesFinder);
+    underTest = new UsersAction(dbClient, userSession, dependenciesFinder);
     ws = new WsActionTester(underTest);
 
     userSession.login("login").setGlobalPermissions(SYSTEM_ADMIN);
index a1d4b753793beb4815e6d6d1d8f48e78f5445e7a..b0c421962f674ba651da9ea09b699d8fa9ba4c84 100644 (file)
@@ -51,7 +51,7 @@ public class PermissionDao implements Dao {
 
   /**
    * @return a paginated list of users.
-   * @deprecated
+   * @deprecated use {@link #selectLoginsByPermissionQuery(DbSession, PermissionQuery)} or {@link #selectUserPermissionsByLoginsAnProject(DbSession, List, Long)} instead
    */
   @Deprecated
   public List<UserWithPermissionDto> selectUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId, int offset, int limit) {
@@ -71,10 +71,14 @@ public class PermissionDao implements Dao {
     return mapper(dbSession).countUsersByPermissionQuery(query);
   }
 
-  public List<UserPermissionDto> selectUserPermissionsByLogins(DbSession dbSession, List<String> logins) {
-    return executeLargeInputs(logins, mapper(dbSession)::selectUserPermissionsByLogins);
+  public List<UserPermissionDto> selectUserPermissionsByLoginsAnProject(DbSession dbSession, List<String> logins, @Nullable Long projectId) {
+    return executeLargeInputs(logins, l -> mapper(dbSession).selectUserPermissionsByLogins(l, projectId));
   }
 
+  /**
+   * @deprecated use {@link #countUsersByQuery(DbSession, PermissionQuery)} instead
+   */
+  @Deprecated
   public int countUsers(DbSession session, OldPermissionQuery query, @Nullable Long componentId) {
     Map<String, Object> params = usersParameters(query, componentId);
 
@@ -93,7 +97,9 @@ public class PermissionDao implements Dao {
    * Membership parameter from query is not taking into account in order to deal more easily with the 'Anyone' group
    *
    * @return a non paginated list of groups.
+   * @deprecated use {@link #selectGroupNamesByPermissionQuery(DbSession, PermissionQuery)} or {@link #selectGroupPermissionsByGroupNamesAndProject(DbSession, List, Long)} instead
    */
+  @Deprecated
   public List<GroupWithPermissionDto> selectGroups(DbSession session, OldPermissionQuery query, @Nullable Long componentId) {
     Map<String, Object> params = groupsParameters(query, componentId);
     return mapper(session).selectGroups(params);
@@ -128,8 +134,8 @@ public class PermissionDao implements Dao {
     return mapper(dbSession).countGroupsByPermissionQuery(query);
   }
 
-  public List<GroupRoleDto> selectGroupPermissionsByQuery(DbSession dbSession, PermissionQuery query) {
-    return mapper(dbSession).selectGroupPermissionByQuery(query);
+  public List<GroupRoleDto> selectGroupPermissionsByGroupNamesAndProject(DbSession dbSession, List<String> groupNames, @Nullable Long projectId) {
+    return executeLargeInputs(groupNames, groups -> mapper(dbSession).selectGroupPermissionByGroupNames(groups, projectId));
   }
 
   /**
index 2a1fc5cc11a481ed0b38ae1e5167882a5fccff7e..81f98091b6ccafce29c91d1fa98cde1e43c3f936 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.db.permission;
 
 import java.util.List;
 import java.util.Map;
+import javax.annotation.Nullable;
 import org.apache.ibatis.annotations.Param;
 import org.apache.ibatis.session.ResultHandler;
 import org.apache.ibatis.session.RowBounds;
@@ -37,7 +38,7 @@ public interface PermissionMapper {
 
   int countUsersByPermissionQuery(@Param("query") PermissionQuery query);
 
-  List<UserPermissionDto> selectUserPermissionsByLogins(@Param("logins") List<String> logins);
+  List<UserPermissionDto> selectUserPermissionsByLogins(@Param("logins") List<String> logins, @Nullable @Param("projectId") Long projectId);
 
   List<GroupWithPermissionDto> selectGroups(Map<String, Object> parameters);
 
@@ -47,7 +48,7 @@ public interface PermissionMapper {
 
   int countGroupsByPermissionQuery(@Param("query") PermissionQuery query);
 
-  List<GroupRoleDto> selectGroupPermissionByQuery(@Param("query") PermissionQuery query);
+  List<GroupRoleDto> selectGroupPermissionByGroupNames(@Param("groupNames") List<String> groupNames, @Nullable @Param("projectId") Long projectId);
 
   void usersCountByProjectIdAndPermission(Map<String, Object> parameters, ResultHandler resultHandler);
 
index c47fff65b9c6b11bbd82d11cbeaadab893065d84..3addc4babe090c38981b93919fe38234a41a3c35 100644 (file)
@@ -19,9 +19,6 @@
  */
 package org.sonar.db.permission;
 
-import com.google.common.collect.ImmutableList;
-import java.util.Collections;
-import java.util.List;
 import java.util.Locale;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
@@ -50,8 +47,6 @@ public class PermissionQuery {
   private final String searchQuery;
   private final String searchQueryToSql;
   private final boolean withPermissionOnly;
-  private final List<String> logins;
-  private final List<String> groupNames;
 
   private final int pageSize;
   private final int pageOffset;
@@ -65,8 +60,6 @@ public class PermissionQuery {
     this.searchQueryToSql = builder.searchQuery == null ? null : buildLikeValue(builder.searchQuery, WildcardPosition.BEFORE_AND_AFTER).toLowerCase(Locale.ENGLISH);
     this.pageSize = builder.pageSize;
     this.pageOffset = offset(builder.pageIndex, builder.pageSize);
-    this.logins = builder.logins == null ? Collections.emptyList() : ImmutableList.copyOf(builder.logins);
-    this.groupNames = builder.groupNames == null ? Collections.emptyList() : ImmutableList.copyOf(builder.groupNames);
   }
 
   @CheckForNull
@@ -105,14 +98,6 @@ public class PermissionQuery {
     return pageOffset;
   }
 
-  public List<String> getLogins() {
-    return logins;
-  }
-
-  public List<String> getGroupNames() {
-    return groupNames;
-  }
-
   public static Builder builder() {
     return new Builder();
   }
@@ -123,8 +108,6 @@ public class PermissionQuery {
     private String template;
     private String searchQuery;
     private boolean withPermissionOnly;
-    private List<String> logins;
-    private List<String> groupNames;
 
     private Integer pageIndex = DEFAULT_PAGE_INDEX;
     private Integer pageSize = DEFAULT_PAGE_SIZE;
@@ -169,22 +152,10 @@ public class PermissionQuery {
       return this;
     }
 
-    public Builder setLogins(@Nullable List<String> logins) {
-      this.logins = logins;
-      return this;
-    }
-
-    public Builder setGroupNames(@Nullable List<String> groupNames) {
-      this.groupNames = groupNames;
-      return this;
-    }
-
     public PermissionQuery build() {
       this.pageIndex = firstNonNull(pageIndex, DEFAULT_PAGE_INDEX);
       this.pageSize = firstNonNull(pageSize, DEFAULT_PAGE_SIZE);
       checkArgument(searchQuery == null || searchQuery.length() >= SEARCH_QUERY_MIN_LENGTH);
-      checkArgument(logins == null || !logins.isEmpty());
-      checkArgument(groupNames == null || !groupNames.isEmpty());
       return new PermissionQuery(this);
     }
   }
index ffe5974e41af14c58dc3c028bf617d353726a58c..4140eb5966783774de359bf8b89d5098747755d7 100644 (file)
       <foreach collection="logins" open="(" close=")" item="login" separator=",">
         #{login}
       </foreach>
+      <if test="projectId!=null">
+        AND ur.resource_id=#{projectId}
+      </if>
+      <if test="projectId==null">
+        AND ur.resource_id IS NULL
+      </if>
     </where>
   </select>
 
       <include refid="groupsByQuery" />) g
   </select>
 
-  <select id="selectGroupPermissionByQuery" parameterType="map" resultType="GroupRole">
-    select distinct gr.id as id, gr.group_id as groupId, gr.resource_id as resourceId, gr.permission as role
-    <include refid="groupsByQuery" />
-  </select>
-
   <sql id="groupsByQuery">
     from (
     select g.id as group_id, g.name as name, gr.role as permission, gr.resource_id as resource_id, gr.id as id
     ) gr
     left join projects p on gr.resource_id = p.id
     <where>
-      <if test="!query.groupNames.isEmpty()">
-        and gr.name in
-        <foreach collection="query.groupNames" open="(" close=")" item="name" separator=",">
-          #{name}
-        </foreach>
-      </if>
       <if test="query.searchQueryToSql != null">
         and lower(gr.name) like #{query.searchQueryToSql} ESCAPE '/'
       </if>
       </if>
     </where>
   </sql>
+
+  <select id="selectGroupPermissionByGroupNames" parameterType="map" resultType="GroupRole">
+    SELECT sub.id, sub.groupId, sub.resourceId, sub.role
+    FROM
+      (
+      SELECT gr.id AS id, gr.group_id AS groupId, gr.resource_id AS resourceId, gr.role AS role, g.name AS name
+      FROM group_roles gr
+      INNER JOIN groups g ON g.id=gr.group_id
+      UNION ALL
+      SELECT gr.id as id, 0 AS group_id, gr.resource_id AS resource_id, gr.role AS role, 'Anyone' AS name
+      FROM group_roles gr
+      WHERE gr.group_id is null
+      ) sub
+    <where>
+      sub.name IN
+      <foreach collection="groupNames" open="(" close=")" item="name" separator=",">
+        #{name}
+      </foreach>
+      <if test="projectId!=null">
+        AND sub.resourceId=#{projectId}
+      </if>
+      <if test="projectId==null">
+        AND sub.resourceId IS NULL
+      </if>
+    </where>
+  </select>
+
 </mapper>
index 9e0b104b7e706db6b2f2ab4277840098ab165210..0a3b0b1ebee60d8990ca81668d42fc6fe5d14531 100644 (file)
 package org.sonar.db.permission;
 
 import java.util.ArrayList;
-import java.util.Arrays;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.IntStream;
 import org.junit.Rule;
 import org.junit.Test;
-import org.sonar.api.security.DefaultGroups;
 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;
@@ -37,9 +35,10 @@ import org.sonar.db.user.GroupDbTester;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.GroupRoleDto;
 
-import static com.google.common.collect.Lists.newArrayList;
+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.security.DefaultGroups.ANYONE;
 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;
@@ -177,7 +176,7 @@ public class GroupWithPermissionDaoTest {
     permissionDb.addProjectPermissionToGroup(USER, group1.getId(), 456L);
 
     final List<CountByProjectAndPermissionDto> result = new ArrayList<>();
-    underTest.groupsCountByComponentIdAndPermission(dbSession, Arrays.asList(123L, 456L, 789L), context -> result.add((CountByProjectAndPermissionDto) context.getResultObject()));
+    underTest.groupsCountByComponentIdAndPermission(dbSession, asList(123L, 456L, 789L), context -> result.add((CountByProjectAndPermissionDto) context.getResultObject()));
 
     assertThat(result).hasSize(3);
     assertThat(result).extracting("permission").containsOnly(ADMIN, USER);
@@ -186,23 +185,45 @@ public class GroupWithPermissionDaoTest {
   }
 
   @Test
-  public void select_groups_by_query_ordered_by_group_names() {
-    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
-    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
-    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+  public void select_groups_by_query() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto());
+    GroupDto group2 = groupDb.insertGroup(newGroupDto());
+    GroupDto group3 = groupDb.insertGroup(newGroupDto());
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, null);
 
+    List<String> groupNames = underTest.selectGroupNamesByPermissionQuery(dbSession, PermissionQuery.builder().build());
+    assertThat(groupNames).containsOnly("Anyone", group1.getName(), group2.getName(), group3.getName());
+  }
+
+  @Test
+  public void select_groups_by_query_is_ordered_by_group_names() {
+    groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    groupDb.insertGroup(newGroupDto().setName("Group-3"));
+    groupDb.insertGroup(newGroupDto().setName("Group-1"));
     permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, null);
 
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder();
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-    List<GroupRoleDto> permissions = selectGroupPermissions(dbQuery);
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().build())).containsExactly("Anyone", "Group-1", "Group-2", "Group-3");
+  }
 
-    assertThat(groupNames).containsExactly("Anyone", "Group-1", "Group-2", "Group-3");
-    assertThat(countNames).isEqualTo(4);
-    assertThat(permissions).hasSize(4)
-      .extracting(GroupRoleDto::getGroupId)
-      .containsOnlyOnce(0L, group1.getId(), group2.getId(), group3.getId());
+  @Test
+  public void count_groups_by_query() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, null);
+    permissionDb.addGlobalPermissionToGroup(PROVISIONING, group1.getId());
+
+    assertThat(underTest.countGroupsByPermissionQuery(dbSession,
+      PermissionQuery.builder().build())).isEqualTo(4);
+    assertThat(underTest.countGroupsByPermissionQuery(dbSession,
+      PermissionQuery.builder().setPermission(PROVISIONING).build())).isEqualTo(1);
+    assertThat(underTest.countGroupsByPermissionQuery(dbSession,
+      PermissionQuery.builder().withPermissionOnly().build())).isEqualTo(2);
+    assertThat(underTest.countGroupsByPermissionQuery(dbSession,
+      PermissionQuery.builder().setSearchQuery("Group-").build())).isEqualTo(3);
+    assertThat(underTest.countGroupsByPermissionQuery(dbSession,
+      PermissionQuery.builder().setSearchQuery("Any").build())).isEqualTo(1);
   }
 
   @Test
@@ -213,26 +234,20 @@ public class GroupWithPermissionDaoTest {
 
     ComponentDto project = componentDb.insertComponent(newProjectDto());
 
-    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, group1.getId());
     permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, null);
     permissionDb.addGlobalPermissionToGroup(PROVISIONING, null);
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, group1.getId());
+    permissionDb.addGlobalPermissionToGroup(SYSTEM_ADMIN, group3.getId());
     permissionDb.addProjectPermissionToGroup(UserRole.ADMIN, group2.getId(), project.getId());
-    permissionDb.addGlobalPermissionToGroup(GlobalPermissions.SYSTEM_ADMIN, group3.getId());
-
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder()
-      .withPermissionOnly()
-      .setPermission(SCAN_EXECUTION);
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-    List<GroupRoleDto> permissions = selectGroupPermissions(dbQuery);
-
-    assertThat(groupNames).containsExactly(DefaultGroups.ANYONE, "Group-1");
-    assertThat(countNames).isEqualTo(2);
-    assertThat(permissions)
-      .extracting(GroupRoleDto::getRole, GroupRoleDto::getGroupId, GroupRoleDto::getResourceId)
-      .containsOnlyOnce(
-        tuple(SCAN_EXECUTION, 0L, null),
-        tuple(SCAN_EXECUTION, group1.getId(), null));
+
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().setPermission(SCAN_EXECUTION).build())).containsExactly(ANYONE, "Group-1");
+
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().setPermission(SYSTEM_ADMIN).build())).containsExactly("Group-3");
+
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().setPermission(PROVISIONING).build())).containsExactly(ANYONE);
   }
 
   @Test
@@ -246,93 +261,122 @@ public class GroupWithPermissionDaoTest {
 
     permissionDb.addProjectPermissionToGroup(SCAN_EXECUTION, group1.getId(), project.getId());
     permissionDb.addProjectPermissionToGroup(PROVISIONING, group1.getId(), project.getId());
+    permissionDb.addProjectPermissionToGroup(USER, null, project.getId());
+
     permissionDb.addProjectPermissionToGroup(SYSTEM_ADMIN, group1.getId(), anotherProject.getId());
     permissionDb.addProjectPermissionToGroup(SYSTEM_ADMIN, null, anotherProject.getId());
-    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, group2.getId());
     permissionDb.addProjectPermissionToGroup(SCAN_EXECUTION, group3.getId(), anotherProject.getId());
 
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder()
-      .setComponentUuid(project.uuid())
-      .withPermissionOnly();
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-    List<GroupRoleDto> permissions = selectGroupPermissions(dbQuery);
-
-    assertThat(groupNames).containsOnlyOnce(group1.getName());
-    assertThat(countNames).isEqualTo(1);
-    assertThat(permissions).hasSize(2)
-      .extracting(GroupRoleDto::getRole, GroupRoleDto::getGroupId, GroupRoleDto::getResourceId)
-      .containsOnlyOnce(
-        tuple(SCAN_EXECUTION, group1.getId(), project.getId()),
-        tuple(PROVISIONING, group1.getId(), project.getId()));
-  }
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, group2.getId());
 
-  @Test
-  public void select_groups_by_query_in_group_names() {
-    groupDb.insertGroup(newGroupDto().setName("group-name-1"));
-    groupDb.insertGroup(newGroupDto().setName("group-name-2"));
-    groupDb.insertGroup(newGroupDto().setName("another-group-name"));
-
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder().setGroupNames(newArrayList("group-name-1", "group-name-2"));
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-    List<GroupRoleDto> permissions = selectGroupPermissions(dbQuery);
-
-    assertThat(groupNames).containsOnlyOnce("group-name-1", "group-name-2");
-    assertThat(countNames).isEqualTo(2);
-    assertThat(permissions).hasSize(2);
+    PermissionQuery.Builder builderOnComponent = PermissionQuery.builder().setComponentUuid(project.uuid());
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      builderOnComponent.withPermissionOnly().build())).containsOnlyOnce(group1.getName());
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      builderOnComponent.setPermission(SCAN_EXECUTION).build())).containsOnlyOnce(group1.getName());
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      builderOnComponent.setPermission(USER).build())).containsOnlyOnce(ANYONE);
   }
 
   @Test
   public void select_groups_by_query_paginated() {
     IntStream.rangeClosed(0, 9).forEach(i -> groupDb.insertGroup(newGroupDto().setName(i + "-name")));
 
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder().setPageIndex(2).setPageSize(3);
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-
-    assertThat(groupNames).containsExactly("3-name", "4-name", "5-name");
-    assertThat(countNames).isEqualTo(10);
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().setPageIndex(2).setPageSize(3).build())).containsExactly("3-name", "4-name", "5-name");
   }
 
   @Test
   public void select_groups_by_query_with_search_query() {
     GroupDto group = groupDb.insertGroup(newGroupDto().setName("group-anyone"));
     groupDb.insertGroup(newGroupDto().setName("unknown"));
-
     permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, group.getId());
 
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder().setSearchQuery("any");
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-
-    assertThat(groupNames).containsOnlyOnce(DefaultGroups.ANYONE, "group-anyone");
-    assertThat(countNames).isEqualTo(2);
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().setSearchQuery("any").build())).containsOnlyOnce(ANYONE, "group-anyone");
   }
 
   @Test
   public void select_groups_by_query_does_not_return_anyone_when_group_roles_is_empty() {
     GroupDto group = groupDb.insertGroup();
 
-    PermissionQuery.Builder dbQuery = PermissionQuery.builder();
-    List<String> groupNames = selectGroupNames(dbQuery);
-    int countNames = countGroupNames(dbQuery);
-
-    assertThat(groupNames)
-      .doesNotContain(DefaultGroups.ANYONE)
-      .containsExactly(group.getName());
-    assertThat(countNames).isEqualTo(1);
+    assertThat(underTest.selectGroupNamesByPermissionQuery(dbSession,
+      PermissionQuery.builder().build()))
+        .doesNotContain(ANYONE)
+        .containsExactly(group.getName());
   }
 
-  private List<String> selectGroupNames(PermissionQuery.Builder dbQuery) {
-    return underTest.selectGroupNamesByPermissionQuery(dbSession, dbQuery.build());
-  }
+  @Test
+  public void select_group_permissions_by_group_names_on_global_permissions() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, group1.getId());
+
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    ComponentDto project = componentDb.insertComponent(newProjectDto());
+    permissionDb.addProjectPermissionToGroup(UserRole.ADMIN, group2.getId(), project.getId());
+
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+    permissionDb.addGlobalPermissionToGroup(SYSTEM_ADMIN, group3.getId());
 
-  private int countGroupNames(PermissionQuery.Builder dbQuery) {
-    return underTest.countGroupsByPermissionQuery(dbSession, dbQuery.build());
+    // Anyone
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, null);
+    permissionDb.addGlobalPermissionToGroup(PROVISIONING, null);
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-1"), null))
+      .extracting(GroupRoleDto::getGroupId, GroupRoleDto::getRole, GroupRoleDto::getResourceId)
+      .containsOnly(tuple(group1.getId(), SCAN_EXECUTION, null));
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-2"), null)).isEmpty();
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-3"), null))
+      .extracting(GroupRoleDto::getGroupId, GroupRoleDto::getRole, GroupRoleDto::getResourceId)
+      .containsOnly(tuple(group3.getId(), SYSTEM_ADMIN, null));
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Anyone"), null))
+      .extracting(GroupRoleDto::getGroupId, GroupRoleDto::getRole, GroupRoleDto::getResourceId)
+      .containsOnly(
+        tuple(0L, SCAN_EXECUTION, null),
+        tuple(0L, PROVISIONING, null));
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-1", "Group-2", "Anyone"), null)).hasSize(3);
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Unknown"), null)).isEmpty();
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, Collections.emptyList(), null)).isEmpty();
   }
 
-  private List<GroupRoleDto> selectGroupPermissions(PermissionQuery.Builder dbQuery) {
-    return underTest.selectGroupPermissionsByQuery(dbSession, dbQuery.build());
+  @Test
+  public void select_group_permissions_by_group_names_on_project_permissions() {
+    GroupDto group1 = groupDb.insertGroup(newGroupDto().setName("Group-1"));
+    permissionDb.addGlobalPermissionToGroup(PROVISIONING, group1.getId());
+
+    GroupDto group2 = groupDb.insertGroup(newGroupDto().setName("Group-2"));
+    ComponentDto project = componentDb.insertComponent(newProjectDto());
+    permissionDb.addProjectPermissionToGroup(USER, group2.getId(), project.getId());
+
+    GroupDto group3 = groupDb.insertGroup(newGroupDto().setName("Group-3"));
+    permissionDb.addProjectPermissionToGroup(USER, group3.getId(), project.getId());
+
+    // Anyone group
+    permissionDb.addGlobalPermissionToGroup(SCAN_EXECUTION, null);
+    permissionDb.addProjectPermissionToGroup(PROVISIONING, null, project.getId());
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-1"), project.getId())).isEmpty();
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-2"), project.getId()))
+      .extracting(GroupRoleDto::getGroupId, GroupRoleDto::getRole, GroupRoleDto::getResourceId)
+      .containsOnly(tuple(group2.getId(), USER, project.getId()));
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-3"), project.getId()))
+      .extracting(GroupRoleDto::getGroupId, GroupRoleDto::getRole, GroupRoleDto::getResourceId)
+      .containsOnly(tuple(group3.getId(), USER, project.getId()));
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Anyone"), project.getId()))
+      .extracting(GroupRoleDto::getGroupId, GroupRoleDto::getRole, GroupRoleDto::getResourceId)
+      .containsOnly(tuple(0L, PROVISIONING, project.getId()));
+
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-1", "Group-2", "Anyone"), project.getId())).hasSize(2);
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Unknown"), project.getId())).isEmpty();
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, asList("Group-1"), 123L)).isEmpty();
+    assertThat(underTest.selectGroupPermissionsByGroupNamesAndProject(dbSession, Collections.emptyList(), project.getId())).isEmpty();
   }
+
 }
index 1ac2d22028791d93b195b4a10177660085639952..a6963d1a349a3d34803c7ccf225b12ddbc9acd90 100644 (file)
@@ -20,6 +20,7 @@
 package org.sonar.db.permission;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.List;
 import java.util.stream.Collectors;
 import java.util.stream.IntStream;
@@ -35,6 +36,7 @@ import org.sonar.db.user.UserDto;
 import org.sonar.db.user.UserPermissionDto;
 
 import static java.util.Arrays.asList;
+import static java.util.Collections.singletonList;
 import static org.assertj.core.api.Assertions.assertThat;
 import static org.assertj.core.api.Assertions.tuple;
 import static org.sonar.api.web.UserRole.ADMIN;
@@ -197,26 +199,55 @@ public class UserWithPermissionDaoTest {
   }
 
   @Test
-  public void select_user_permissions_by_logins() {
+  public void select_user_permissions_by_logins_with_global_permissions() {
     UserDto firstUser = userDb.insertUser(newUserDto());
+    permissionDb.addGlobalPermissionToUser(ADMIN, firstUser.getId());
+
     UserDto secondUser = userDb.insertUser(newUserDto());
+    permissionDb.addGlobalPermissionToUser(USER, secondUser.getId());
+
     UserDto thirdUser = userDb.insertUser(newUserDto());
+    ComponentDto project = componentDb.insertComponent(newProjectDto());
+    permissionDb.addProjectPermissionToUser(ADMIN, thirdUser.getId(), project.getId());
 
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, (asList(firstUser.getLogin(), secondUser.getLogin(), thirdUser.getLogin())), null))
+      .extracting(UserPermissionDto::getUserId, UserPermissionDto::getPermission, UserPermissionDto::getComponentId)
+      .containsOnly(
+        tuple(firstUser.getId(), ADMIN, null),
+        tuple(secondUser.getId(), USER, null));
+
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, singletonList(thirdUser.getLogin()), null)).isEmpty();
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, singletonList("unknown"), null)).isEmpty();
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, Collections.emptyList(), null)).isEmpty();
+  }
+
+  @Test
+  public void select_user_permissions_by_logins_with_project_permissions() {
+    UserDto firstUser = userDb.insertUser(newUserDto());
     ComponentDto project = componentDb.insertComponent(newProjectDto());
     permissionDb.addProjectPermissionToUser(ADMIN, firstUser.getId(), project.getId());
+
+    UserDto secondUser = userDb.insertUser(newUserDto());
     permissionDb.addProjectPermissionToUser(USER, secondUser.getId(), project.getId());
 
+    UserDto thirdUser = userDb.insertUser(newUserDto());
     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)
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, (asList(firstUser.getLogin(), secondUser.getLogin(), thirdUser.getLogin())), project.getId()))
       .extracting(UserPermissionDto::getUserId, UserPermissionDto::getPermission, UserPermissionDto::getComponentId)
       .containsOnly(
         tuple(firstUser.getId(), ADMIN, project.getId()),
-        tuple(secondUser.getId(), USER, project.getId()),
+        tuple(secondUser.getId(), USER, project.getId()));
+
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, (asList(firstUser.getLogin(), secondUser.getLogin(), thirdUser.getLogin())), anotherProject.getId()))
+      .extracting(UserPermissionDto::getUserId, UserPermissionDto::getPermission, UserPermissionDto::getComponentId)
+      .containsOnly(
         tuple(thirdUser.getId(), ADMIN, anotherProject.getId()));
+
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, singletonList(thirdUser.getLogin()), project.getId())).isEmpty();
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, singletonList("unknown"), project.getId())).isEmpty();
+    assertThat(underTest.selectUserPermissionsByLoginsAnProject(session, Collections.emptyList(), project.getId())).isEmpty();
   }
 
   @Test