]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-9140 support public projects in ServerUserSession
authorSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Tue, 18 Apr 2017 15:27:01 +0000 (17:27 +0200)
committerSébastien Lesaint <sebastien.lesaint@sonarsource.com>
Thu, 27 Apr 2017 12:25:54 +0000 (14:25 +0200)
server/sonar-db-dao/src/main/java/org/sonar/core/permission/ProjectPermissions.java
server/sonar-db-dao/src/main/java/org/sonar/db/permission/AuthorizationDao.java
server/sonar-db-dao/src/main/resources/org/sonar/db/permission/AuthorizationMapper.xml
server/sonar-db-dao/src/test/java/org/sonar/db/user/UserDbTester.java
server/sonar-server/src/main/java/org/sonar/server/user/ServerUserSession.java
server/sonar-server/src/test/java/org/sonar/server/user/ServerUserSessionTest.java

index 6a4fb1f455dba0781e1783a0a5e82bb0eb295ed0..f0fa2864b5a20d67a12ac5291cd9feb65d0cde2e 100644 (file)
@@ -21,7 +21,9 @@ package org.sonar.core.permission;
 
 import com.google.common.base.Joiner;
 import com.google.common.collect.ImmutableList;
+import com.google.common.collect.ImmutableSet;
 import java.util.List;
+import java.util.Set;
 import org.sonar.api.web.UserRole;
 
 /**
@@ -29,6 +31,10 @@ import org.sonar.api.web.UserRole;
  *
  */
 public final class ProjectPermissions {
+  /**
+   * Permissions which are implicitly available for any user, any group and to group "AnyOne" on public components.
+   */
+  public static final Set<String> PUBLIC_PERMISSIONS = ImmutableSet.of(UserRole.USER, UserRole.CODEVIEWER);
 
   /**
    * All the component permissions values, ordered from {@link UserRole#USER} to {@link GlobalPermissions#SCAN_EXECUTION}.
index 792556c951d09c85fc87b7a0fc9e65ba9b333ee5..8b3f481d8c2ccdacd364642fd459485deba2569d 100644 (file)
@@ -54,16 +54,22 @@ public class AuthorizationDao implements Dao {
   }
 
   /**
-   * Loads all the permissions granted to logged-in user for the specified project.
+   * Loads all the permissions granted to logged-in user for the specified project <strong>stored in *_ROLES
+   * tables</strong>.
    * An empty Set is returned if user has no permissions on the project.
+   *
+   * <strong>This method does not support public components</strong>
    */
   public Set<String> selectProjectPermissions(DbSession dbSession, String projectUuid, long userId) {
     return mapper(dbSession).selectProjectPermissions(projectUuid, userId);
   }
 
   /**
-   * Loads all the permissions granted to anonymous for the specified project.
+   * Loads all the permissions granted to anonymous for the specified project <strong>stored in *_ROLES
+   * tables</strong>.
    * An empty Set is returned if anonymous user has no permissions on the project.
+   *
+   * <strong>This method does not support public components</strong>
    */
   public Set<String> selectProjectPermissionsOfAnonymous(DbSession dbSession, String projectUuid) {
     return mapper(dbSession).selectProjectPermissionsOfAnonymous(projectUuid);
index e8f88ab6b0283824e82732ddb7443096474af42e..e27c899debb4a5f8a7def315d1447d855e405b96 100644 (file)
   </select>
 
   <select id="keepAuthorizedProjectIdsForUser" parameterType="map" resultType="long">
-    SELECT gr.resource_id
-    FROM group_roles gr
-    WHERE
-    gr.role=#{role,jdbcType=VARCHAR}
-    and (gr.group_id is null or exists (select 1 from groups_users gu where gu.user_id = #{userId, jdbcType=INTEGER} and gr.group_id = gu.group_id))
-    and
-    <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
-      gr.resource_id=#{element,jdbcType=BIGINT}
-    </foreach>
-    UNION
-    SELECT p.id
-    FROM user_roles ur
-    INNER JOIN projects p on p.id = ur.resource_id
-    WHERE
-    ur.role=#{role,jdbcType=VARCHAR}
-    and ur.user_id=#{userId,jdbcType=INTEGER} and
-    <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
-      p.id=#{element,jdbcType=BIGINT}
-    </foreach>
+    select
+      gr.resource_id
+    from
+      group_roles gr
+    where
+      gr.role=#{role,jdbcType=VARCHAR}
+      and (
+        gr.group_id is null
+        or exists (
+          select
+            1
+          from
+            groups_users gu
+          where
+            gu.user_id = #{userId, jdbcType=INTEGER}
+            and gr.group_id = gu.group_id
+        )
+      )
+      and <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
+            gr.resource_id=#{element,jdbcType=BIGINT}
+          </foreach>
+    union
+    select
+      p.id
+    from
+      user_roles ur
+    inner join projects p on
+      p.id = ur.resource_id
+    where
+      ur.role=#{role,jdbcType=VARCHAR}
+      and ur.user_id=#{userId,jdbcType=INTEGER}
+      and <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
+        p.id=#{element,jdbcType=BIGINT}
+      </foreach>
   </select>
 
   <select id="keepAuthorizedProjectIdsForAnonymous" parameterType="map" resultType="long">
-    SELECT gr.resource_id
-    FROM group_roles gr
-    WHERE
-    gr.role=#{role,jdbcType=VARCHAR}
-    and gr.group_id is null
-    and
-    <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
-      gr.resource_id=#{element,jdbcType=BIGINT}
-    </foreach>
+    select
+      gr.resource_id
+    from
+      group_roles gr
+    where
+      gr.role=#{role,jdbcType=VARCHAR}
+      and gr.group_id is null
+      and <foreach collection="componentIds" open="(" close=")" item="element" index="index" separator=" or ">
+            gr.resource_id=#{element,jdbcType=BIGINT}
+          </foreach>
   </select>
 
   <select id="keepAuthorizedUsersForRoleAndProject" parameterType="map" resultType="int">
-    SELECT gu.user_id
-    FROM groups_users gu
-    INNER JOIN group_roles gr ON gr.group_id=gu.group_id
+    SELECT
+      gu.user_id
+    FROM
+      groups_users gu
+    INNER JOIN group_roles gr ON
+      gr.group_id=gu.group_id
     WHERE
-    gr.resource_id=#{componentId,jdbcType=BIGINT}
-    AND gr.role=#{role,jdbcType=VARCHAR}
-    AND gu.user_id in
-    <foreach collection="userIds" open="(" close=")" item="id" separator=",">
-      #{id,jdbcType=BIGINT}
-    </foreach>
+      gr.resource_id=#{componentId,jdbcType=BIGINT}
+      AND gr.role=#{role,jdbcType=VARCHAR}
+      AND gu.user_id in <foreach collection="userIds" open="(" close=")" item="id" separator=",">
+        #{id,jdbcType=BIGINT}
+      </foreach>
     UNION
-    SELECT ur.user_id
-    FROM user_roles ur
+    SELECT
+      ur.user_id
+    FROM
+      user_roles ur
     WHERE
-    ur.resource_id=#{componentId,jdbcType=BIGINT}
-    AND ur.role=#{role,jdbcType=VARCHAR}
-    AND ur.user_id IN
-    <foreach collection="userIds" open="(" close=")" item="id" separator=",">
-      #{id,jdbcType=BIGINT}
-    </foreach>
+      ur.resource_id=#{componentId,jdbcType=BIGINT}
+      AND ur.role=#{role,jdbcType=VARCHAR}
+      AND ur.user_id IN
+        <foreach collection="userIds" open="(" close=")" item="id" separator=",">
+          #{id,jdbcType=BIGINT}
+        </foreach>
   </select>
 
   <select id="selectProjectPermissions" parameterType="map" resultType="String">
   </select>
 
   <sql id="sql_selectProjectPermissionsOfAnonymous">
-    select gr.role
-    from group_roles gr
-    inner join projects p on p.id = gr.resource_id
+    select
+      gr.role
+    from
+      group_roles gr
+    inner join projects p on
+      p.id = gr.resource_id
     where
-    p.uuid = #{projectUuid,jdbcType=VARCHAR} and
-    p.organization_uuid = gr.organization_uuid and
-    gr.group_id is null
+      p.uuid = #{projectUuid,jdbcType=VARCHAR}
+      and p.organization_uuid = gr.organization_uuid
+      and gr.group_id is null
   </sql>
 </mapper>
index e896b062bc0963b965add3b7a72ddc0de77f710b..3fa01eec830bd12e99d9f47ff19f61894b24a347 100644 (file)
@@ -223,6 +223,11 @@ public class UserDbTester {
     return dto;
   }
 
+  public void deleteProjectPermissionFromAnyone(ComponentDto project, String permission) {
+    db.getDbClient().groupPermissionDao().delete(db.getSession(), permission, project.getOrganizationUuid(), null, project.getId());
+    db.commit();
+  }
+
   public GroupPermissionDto insertProjectPermissionOnGroup(GroupDto group, String permission, ComponentDto project) {
     checkArgument(group.getOrganizationUuid().equals(project.getOrganizationUuid()), "Different organizations");
     GroupPermissionDto dto = new GroupPermissionDto()
index 48bff78747f734eee1fa9f5ab5d1517d2f85eb34..285fd96a48ad639bba9ed8bf2295afa89a053421 100644 (file)
@@ -21,6 +21,7 @@ package org.sonar.server.user;
 
 import com.google.common.base.Supplier;
 import com.google.common.base.Suppliers;
+import com.google.common.collect.ImmutableSet;
 import java.util.Collection;
 import java.util.Collections;
 import java.util.HashMap;
@@ -29,15 +30,16 @@ import java.util.Optional;
 import java.util.Set;
 import javax.annotation.CheckForNull;
 import javax.annotation.Nullable;
+import org.sonar.core.permission.ProjectPermissions;
 import org.sonar.core.util.stream.MoreCollectors;
 import org.sonar.db.DbClient;
 import org.sonar.db.DbSession;
 import org.sonar.db.component.ComponentDto;
+import org.sonar.db.permission.OrganizationPermission;
 import org.sonar.db.user.GroupDto;
 import org.sonar.db.user.UserDto;
 import org.sonar.server.organization.DefaultOrganizationProvider;
 import org.sonar.server.organization.OrganizationFlags;
-import org.sonar.db.permission.OrganizationPermission;
 
 import static com.google.common.collect.Maps.newHashMap;
 
@@ -157,11 +159,25 @@ public class ServerUserSession extends AbstractUserSession {
 
   private Set<String> loadProjectPermissions(String projectUuid) {
     try (DbSession dbSession = dbClient.openSession(false)) {
-      if (userDto != null && userDto.getId() != null) {
-        return dbClient.authorizationDao().selectProjectPermissions(dbSession, projectUuid, userDto.getId());
+      com.google.common.base.Optional<ComponentDto> component = dbClient.componentDao().selectByUuid(dbSession, projectUuid);
+      if (!component.isPresent()) {
+        return Collections.emptySet();
       }
-      return dbClient.authorizationDao().selectProjectPermissionsOfAnonymous(dbSession, projectUuid);
+      if (component.get().isPrivate()) {
+        return loadDbPermissions(dbSession, projectUuid);
+      }
+      ImmutableSet.Builder<String> builder = ImmutableSet.builder();
+      builder.addAll(ProjectPermissions.PUBLIC_PERMISSIONS);
+      builder.addAll(loadDbPermissions(dbSession, projectUuid));
+      return builder.build();
+    }
+  }
+
+  private Set<String> loadDbPermissions(DbSession dbSession, String projectUuid) {
+    if (userDto != null && userDto.getId() != null) {
+      return dbClient.authorizationDao().selectProjectPermissions(dbSession, projectUuid, userDto.getId());
     }
+    return dbClient.authorizationDao().selectProjectPermissionsOfAnonymous(dbSession, projectUuid);
   }
 
   @Override
index b366b6093d6b9f7c8fd5bdc273c45314dfb17ecd..1f7666662e275903e41d8877a9cebceb04ff2d02 100644 (file)
@@ -19,6 +19,7 @@
  */
 package org.sonar.server.user;
 
+import java.util.Random;
 import javax.annotation.Nullable;
 import org.junit.Before;
 import org.junit.Rule;
@@ -44,12 +45,12 @@ import static org.sonar.core.permission.GlobalPermissions.SYSTEM_ADMIN;
 import static org.sonar.db.permission.OrganizationPermission.ADMINISTER;
 import static org.sonar.db.permission.OrganizationPermission.PROVISION_PROJECTS;
 import static org.sonar.db.permission.OrganizationPermission.SCAN;
-import static org.sonar.db.user.UserTesting.newUserDto;
 
 public class ServerUserSessionTest {
   private static final String LOGIN = "marius";
 
-  private static final String PROJECT_UUID = "ABCD";
+  private static final String PUBLIC_PROJECT_UUID = "public project";
+  private static final String PRIVATE_PROJECT_UUID = "private project";
   private static final String FILE_KEY = "com.foo:Bar:BarFile.xoo";
   private static final String FILE_UUID = "BCDE";
   private static final UserDto ROOT_USER_DTO = new UserDto() {
@@ -69,18 +70,22 @@ public class ServerUserSessionTest {
   public ExpectedException expectedException = ExpectedException.none();
 
   private DbClient dbClient = db.getDbClient();
-  private UserDto userDto = newUserDto().setLogin(LOGIN);
+  private UserDto user;
+  private GroupDto groupOfUser;
   private TestOrganizationFlags organizationFlags = TestOrganizationFlags.standalone();
   private TestDefaultOrganizationProvider defaultOrganizationProvider = TestDefaultOrganizationProvider.from(db);
   private OrganizationDto organization;
-  private ComponentDto project;
+  private ComponentDto publicProject;
+  private ComponentDto privateProject;
 
   @Before
   public void setUp() throws Exception {
     organization = db.organizations().insert();
-    project = db.components().insertProject(organization, PROJECT_UUID);
-    db.components().insertComponent(ComponentTesting.newFileDto(project, null, FILE_UUID).setKey(FILE_KEY));
-    db.users().insertUser(userDto);
+    publicProject = db.components().insertProject(organization, PUBLIC_PROJECT_UUID);
+    privateProject = db.components().insertProject(organization, dto -> dto.setUuid(PRIVATE_PROJECT_UUID).setProjectUuid(PRIVATE_PROJECT_UUID).setPrivate(true));
+    db.components().insertComponent(ComponentTesting.newFileDto(publicProject, null, FILE_UUID).setKey(FILE_KEY));
+    user = db.users().insertUser(LOGIN);
+    groupOfUser = db.users().insertGroup(organization);
   }
 
   @Test
@@ -98,30 +103,30 @@ public class ServerUserSessionTest {
 
   @Test
   public void getGroups_is_empty_if_user_is_not_member_of_any_group() {
-    assertThat(newUserSession(userDto).getGroups()).isEmpty();
+    assertThat(newUserSession(user).getGroups()).isEmpty();
   }
 
   @Test
   public void getGroups_returns_the_groups_of_logged_in_user() {
     GroupDto group1 = db.users().insertGroup();
     GroupDto group2 = db.users().insertGroup();
-    db.users().insertMember(group1, userDto);
-    db.users().insertMember(group2, userDto);
+    db.users().insertMember(group1, user);
+    db.users().insertMember(group2, user);
 
-    assertThat(newUserSession(userDto).getGroups()).extracting(GroupDto::getId).containsOnly(group1.getId(), group2.getId());
+    assertThat(newUserSession(user).getGroups()).extracting(GroupDto::getId).containsOnly(group1.getId(), group2.getId());
   }
 
   @Test
   public void getGroups_keeps_groups_in_cache() {
     GroupDto group1 = db.users().insertGroup();
     GroupDto group2 = db.users().insertGroup();
-    db.users().insertMember(group1, userDto);
+    db.users().insertMember(group1, user);
 
-    ServerUserSession session = newUserSession(userDto);
+    ServerUserSession session = newUserSession(user);
     assertThat(session.getGroups()).extracting(GroupDto::getId).containsOnly(group1.getId());
 
     // membership updated but not cache
-    db.users().insertMember(group2, userDto);
+    db.users().insertMember(group2, user);
     assertThat(session.getGroups()).extracting(GroupDto::getId).containsOnly(group1.getId());
   }
 
@@ -132,17 +137,7 @@ public class ServerUserSessionTest {
   }
 
   @Test
-  public void hasComponentUuidPermission_returns_true_if_user_has_project_permission_for_given_uuid_in_db() {
-    addProjectPermissions(project, UserRole.USER);
-    UserSession session = newUserSession(userDto);
-
-    assertThat(session.hasComponentUuidPermission(UserRole.USER, FILE_UUID)).isTrue();
-    assertThat(session.hasComponentUuidPermission(UserRole.CODEVIEWER, FILE_UUID)).isFalse();
-    assertThat(session.hasComponentUuidPermission(UserRole.ADMIN, FILE_UUID)).isFalse();
-  }
-
-  @Test
-  public void hasComponentUuidPermission_returns_true_when_flag_is_true_on_UserDto_no_matter_if_user_has_project_permission_for_given_uuid() {
+  public void hasComponentUuidPermission_returns_true_when_flag_root_is_true_on_UserDto_no_matter_if_user_has_project_permission_for_given_uuid() {
     UserSession underTest = newUserSession(ROOT_USER_DTO);
 
     assertThat(underTest.hasComponentUuidPermission(UserRole.USER, FILE_UUID)).isTrue();
@@ -161,8 +156,8 @@ public class ServerUserSessionTest {
 
   @Test
   public void checkComponentUuidPermission_fails_with_FE_when_user_has_not_permission_for_specified_uuid_in_db() {
-    addProjectPermissions(project, UserRole.USER);
-    UserSession session = newUserSession(userDto);
+    addProjectPermissions(publicProject, UserRole.USER);
+    UserSession session = newUserSession(user);
 
     expectInsufficientPrivilegesForbiddenException();
 
@@ -199,10 +194,10 @@ public class ServerUserSessionTest {
   public void test_hasPermission_on_organization_for_logged_in_user() {
     OrganizationDto org = db.organizations().insert();
     ComponentDto project = db.components().insertProject(org);
-    db.users().insertPermissionOnUser(org, userDto, PROVISION_PROJECTS);
-    db.users().insertProjectPermissionOnUser(userDto, UserRole.ADMIN, project);
+    db.users().insertPermissionOnUser(org, user, PROVISION_PROJECTS);
+    db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, project);
 
-    UserSession session = newUserSession(userDto);
+    UserSession session = newUserSession(user);
     assertThat(session.hasPermission(PROVISION_PROJECTS, org.getUuid())).isTrue();
     assertThat(session.hasPermission(ADMINISTER, org.getUuid())).isFalse();
     assertThat(session.hasPermission(PROVISION_PROJECTS, "another-org")).isFalse();
@@ -222,16 +217,16 @@ public class ServerUserSessionTest {
   @Test
   public void hasPermission_on_organization_keeps_cache_of_permissions_of_logged_in_user() {
     OrganizationDto org = db.organizations().insert();
-    db.users().insertPermissionOnUser(org, userDto, PROVISIONING);
+    db.users().insertPermissionOnUser(org, user, PROVISIONING);
 
-    UserSession session = newUserSession(userDto);
+    UserSession session = newUserSession(user);
 
     // feed the cache
     assertThat(session.hasPermission(PROVISION_PROJECTS, org.getUuid())).isTrue();
 
     // change permissions without updating the cache
-    db.users().deletePermissionFromUser(org, userDto, PROVISION_PROJECTS);
-    db.users().insertPermissionOnUser(org, userDto, SCAN);
+    db.users().deletePermissionFromUser(org, user, PROVISION_PROJECTS);
+    db.users().insertPermissionOnUser(org, user, SCAN);
     assertThat(session.hasPermission(PROVISION_PROJECTS, org.getUuid())).isTrue();
     assertThat(session.hasPermission(ADMINISTER, org.getUuid())).isFalse();
     assertThat(session.hasPermission(SCAN, org.getUuid())).isFalse();
@@ -254,77 +249,171 @@ public class ServerUserSessionTest {
   }
 
   @Test
-  public void test_hasComponentPermission_with_anonymous_user() {
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_permissions_USER_and_CODEVIEWER_on_public_projects_without_permissions() {
+    ServerUserSession underTest = newAnonymousSession();
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject)).isTrue();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_permissions_USER_and_CODEVIEWER_on_public_projects_with_global_permissions() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnAnyone("p1", publicProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject)).isTrue();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_permissions_USER_and_CODEVIEWER_on_public_projects_with_group_permissions() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnGroup(db.users().insertGroup(organization), "p1", publicProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject)).isTrue();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_permissions_USER_and_CODEVIEWER_on_public_projects_with_user_permissions() {
     ServerUserSession underTest = newAnonymousSession();
-    ComponentDto project = db.components().insertProject();
-    db.users().insertProjectPermissionOnAnyone(UserRole.CODEVIEWER, project);
-    ComponentDto otherProject = db.components().insertProject();
+    db.users().insertProjectPermissionOnUser(db.users().insertUser(), "p1", publicProject);
 
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, project)).isTrue();
-    assertThat(underTest.hasComponentPermission(UserRole.ISSUE_ADMIN, project)).isFalse();
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, otherProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, publicProject)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, publicProject)).isTrue();
   }
 
   @Test
-  public void hasComponentPermission_returns_true_when_logged_in_user_has_permission_on_project_through_anyone() {
-    ServerUserSession underTest = newUserSession(userDto);
-    ComponentDto project = db.components().insertProject();
-    db.users().insertProjectPermissionOnAnyone(UserRole.CODEVIEWER, project);
-    ComponentDto otherProject = db.components().insertProject();
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_authenticated_user_for_permissions_USER_and_CODEVIEWER_on_private_projects_without_permissions() {
+    ServerUserSession underTest = newUserSession(user);
 
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, project)).isTrue();
-    assertThat(underTest.hasComponentPermission(UserRole.ISSUE_ADMIN, project)).isFalse();
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, otherProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, privateProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, privateProject)).isFalse();
   }
 
   @Test
-  public void hasComponentPermission_returns_true_when_logged_in_user_has_permission_on_project() {
-    ServerUserSession underTest = newUserSession(userDto);
-    ComponentDto project = db.components().insertProject();
-    db.users().insertProjectPermissionOnUser(userDto, UserRole.CODEVIEWER, project);
-    ComponentDto otherProject = db.components().insertProject();
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_authenticated_user_for_permissions_USER_and_CODEVIEWER_on_private_projects_with_global_permissions() {
+    ServerUserSession underTest = newUserSession(user);
+    db.users().insertProjectPermissionOnAnyone("p1", privateProject);
 
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, project)).isTrue();
-    assertThat(underTest.hasComponentPermission(UserRole.ISSUE_ADMIN, project)).isFalse();
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, otherProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, this.privateProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, this.privateProject)).isFalse();
   }
 
   @Test
-  public void hasComponentPermission_returns_true_when_logged_in_user_has_permission_on_project_through_group_membership() {
-    ServerUserSession underTest = newUserSession(userDto);
-    ComponentDto project = db.components().insertProject();
-    GroupDto group = db.users().insertGroup();
-    db.users().insertMember(group, userDto);
-    db.users().insertProjectPermissionOnGroup(group, UserRole.CODEVIEWER, project);
-    ComponentDto otherProject = db.components().insertProject();
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_authenticated_user_for_permissions_USER_and_CODEVIEWER_on_private_projects_with_group_permissions() {
+    ServerUserSession underTest = newUserSession(user);
+    db.users().insertProjectPermissionOnGroup(db.users().insertGroup(organization), "p1", privateProject);
 
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, project)).isTrue();
-    assertThat(underTest.hasComponentPermission(UserRole.ISSUE_ADMIN, project)).isFalse();
-    assertThat(underTest.hasComponentPermission(UserRole.CODEVIEWER, otherProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, privateProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, privateProject)).isFalse();
   }
 
   @Test
-  public void hasComponentPermission_keeps_cache_of_permissions_of_logged_in_user() {
-    ComponentDto project = db.components().insertProject();
-    db.users().insertProjectPermissionOnUser(userDto, UserRole.USER, project);
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_authenticated_user_for_permissions_USER_and_CODEVIEWER_on_private_projects_with_user_permissions() {
+    ServerUserSession underTest = newUserSession(user);
+    db.users().insertProjectPermissionOnUser(db.users().insertUser(), "p1", privateProject);
 
-    UserSession session = newUserSession(userDto);
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.USER, privateProject)).isFalse();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.CODEVIEWER, privateProject)).isFalse();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_inserted_permissions_on_group_AnyOne_on_public_projects() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnAnyone("p1", publicProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", publicProject)).isTrue();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_anonymous_user_for_inserted_permissions_on_group_AnyOne_on_private_projects() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnAnyone("p1", privateProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject)).isTrue();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_group_on_public_projects() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnGroup(groupOfUser, "p1", publicProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", publicProject)).isFalse();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_group_on_private_projects() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnGroup(groupOfUser, "p1", privateProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject)).isFalse();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_user_on_public_projects() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnUser(user, "p1", publicProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", publicProject)).isFalse();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_false_for_anonymous_user_for_inserted_permissions_on_user_on_private_projects() {
+    ServerUserSession underTest = newAnonymousSession();
+    db.users().insertProjectPermissionOnUser(user, "p1", privateProject);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "p1", privateProject)).isFalse();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_returns_true_for_any_project_or_permission_for_root_user() {
+    ServerUserSession underTest = newUserSession(ROOT_USER_DTO);
+
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, "does not matter", publicProject)).isTrue();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_keeps_cache_of_permissions_of_logged_in_user() {
+    db.users().insertProjectPermissionOnUser(user, UserRole.ADMIN, publicProject);
+
+    UserSession underTest = newUserSession(user);
+
+    // feed the cache
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject)).isTrue();
+
+    // change permissions without updating the cache
+    db.users().deletePermissionFromUser(publicProject, user, UserRole.ADMIN);
+    db.users().insertProjectPermissionOnUser(user, UserRole.ISSUE_ADMIN, publicProject);
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ISSUE_ADMIN, publicProject)).isFalse();
+  }
+
+  @Test
+  public void hasComponentPermissionByDtoOrUuid_keeps_cache_of_permissions_of_anonymous_user() {
+    db.users().insertProjectPermissionOnAnyone(UserRole.ADMIN, publicProject);
+
+    UserSession underTest = newAnonymousSession();
 
     // feed the cache
-    assertThat(session.hasComponentPermission(UserRole.USER, project)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject)).isTrue();
 
     // change permissions without updating the cache
-    db.users().deletePermissionFromUser(project, userDto, UserRole.USER);
-    db.users().insertProjectPermissionOnUser(userDto, UserRole.ADMIN, project);
-    assertThat(session.hasComponentPermission(UserRole.USER, project)).isTrue();
-    assertThat(session.hasComponentPermission(UserRole.ADMIN, project)).isFalse();
+    db.users().deleteProjectPermissionFromAnyone(publicProject, UserRole.ADMIN);
+    db.users().insertProjectPermissionOnAnyone(UserRole.ISSUE_ADMIN, publicProject);
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ADMIN, publicProject)).isTrue();
+    assertThat(hasComponentPermissionByDtoOrUuid(underTest, UserRole.ISSUE_ADMIN, publicProject)).isFalse();
+  }
+
+  private boolean hasComponentPermissionByDtoOrUuid(UserSession underTest, String permission, ComponentDto component) {
+    return new Random().nextBoolean() ? underTest.hasComponentPermission(permission, component) : underTest.hasComponentUuidPermission(permission, component.uuid());
   }
 
   @Test
   public void isSystemAdministrator_returns_true_if_org_feature_is_enabled_and_user_is_root() {
     organizationFlags.setEnabled(true);
-    userDto = db.users().makeRoot(userDto);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeRoot(user);
+    UserSession session = newUserSession(user);
 
     assertThat(session.isSystemAdministrator()).isTrue();
   }
@@ -332,8 +421,8 @@ public class ServerUserSessionTest {
   @Test
   public void isSystemAdministrator_returns_false_if_org_feature_is_enabled_and_user_is_not_root() {
     organizationFlags.setEnabled(true);
-    userDto = db.users().makeNotRoot(userDto);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeNotRoot(user);
+    UserSession session = newUserSession(user);
 
     assertThat(session.isSystemAdministrator()).isFalse();
   }
@@ -341,9 +430,9 @@ public class ServerUserSessionTest {
   @Test
   public void isSystemAdministrator_returns_false_if_org_feature_is_enabled_and_user_is_administrator_of_default_organization() {
     organizationFlags.setEnabled(true);
-    userDto = db.users().makeNotRoot(userDto);
-    db.users().insertPermissionOnUser(db.getDefaultOrganization(), userDto, SYSTEM_ADMIN);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeNotRoot(user);
+    db.users().insertPermissionOnUser(db.getDefaultOrganization(), user, SYSTEM_ADMIN);
+    UserSession session = newUserSession(user);
 
     assertThat(session.isSystemAdministrator()).isFalse();
   }
@@ -351,9 +440,9 @@ public class ServerUserSessionTest {
   @Test
   public void isSystemAdministrator_returns_true_if_org_feature_is_disabled_and_user_is_administrator_of_default_organization() {
     organizationFlags.setEnabled(false);
-    userDto = db.users().makeNotRoot(userDto);
-    db.users().insertPermissionOnUser(db.getDefaultOrganization(), userDto, SYSTEM_ADMIN);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeNotRoot(user);
+    db.users().insertPermissionOnUser(db.getDefaultOrganization(), user, SYSTEM_ADMIN);
+    UserSession session = newUserSession(user);
 
     assertThat(session.isSystemAdministrator()).isTrue();
   }
@@ -361,9 +450,9 @@ public class ServerUserSessionTest {
   @Test
   public void isSystemAdministrator_returns_false_if_org_feature_is_disabled_and_user_is_not_administrator_of_default_organization() {
     organizationFlags.setEnabled(true);
-    userDto = db.users().makeNotRoot(userDto);
-    db.users().insertPermissionOnUser(db.getDefaultOrganization(), userDto, PROVISIONING);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeNotRoot(user);
+    db.users().insertPermissionOnUser(db.getDefaultOrganization(), user, PROVISIONING);
+    UserSession session = newUserSession(user);
 
     assertThat(session.isSystemAdministrator()).isFalse();
   }
@@ -371,13 +460,13 @@ public class ServerUserSessionTest {
   @Test
   public void keep_isSystemAdministrator_flag_in_cache() {
     organizationFlags.setEnabled(false);
-    userDto = db.users().makeNotRoot(userDto);
-    db.users().insertPermissionOnUser(db.getDefaultOrganization(), userDto, SYSTEM_ADMIN);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeNotRoot(user);
+    db.users().insertPermissionOnUser(db.getDefaultOrganization(), user, SYSTEM_ADMIN);
+    UserSession session = newUserSession(user);
 
     session.checkIsSystemAdministrator();
 
-    db.getDbClient().userDao().deactivateUserById(db.getSession(), userDto.getId());
+    db.getDbClient().userDao().deactivateUserById(db.getSession(), user.getId());
     db.commit();
 
     // should fail but succeeds because flag is kept in cache
@@ -387,8 +476,8 @@ public class ServerUserSessionTest {
   @Test
   public void checkIsSystemAdministrator_succeeds_if_system_administrator() {
     organizationFlags.setEnabled(true);
-    userDto = db.users().makeRoot(userDto);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeRoot(user);
+    UserSession session = newUserSession(user);
 
     session.checkIsSystemAdministrator();
   }
@@ -396,8 +485,8 @@ public class ServerUserSessionTest {
   @Test
   public void checkIsSystemAdministrator_throws_ForbiddenException_if_not_system_administrator() {
     organizationFlags.setEnabled(true);
-    userDto = db.users().makeNotRoot(userDto);
-    UserSession session = newUserSession(userDto);
+    user = db.users().makeNotRoot(user);
+    UserSession session = newUserSession(user);
 
     expectedException.expect(ForbiddenException.class);
     expectedException.expectMessage("Insufficient privileges");
@@ -420,9 +509,9 @@ public class ServerUserSessionTest {
   private void addPermissions(@Nullable ComponentDto component, String... permissions) {
     for (String permission : permissions) {
       if (component == null) {
-        db.users().insertPermissionOnUser(userDto, OrganizationPermission.fromKey(permission));
+        db.users().insertPermissionOnUser(user, OrganizationPermission.fromKey(permission));
       } else {
-        db.users().insertProjectPermissionOnUser(userDto, permission, component);
+        db.users().insertProjectPermissionOnUser(user, permission, component);
       }
     }
   }