/* * SonarQube * Copyright (C) 2009-2017 SonarSource SA * mailto:info 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.db.permission; import java.util.Collection; import java.util.Set; import javax.annotation.Nullable; import org.sonar.db.Dao; import org.sonar.db.DbSession; import static org.sonar.db.DatabaseUtils.executeLargeInputs; import static org.sonar.db.DatabaseUtils.executeLargeInputsIntoSet; /** * The SQL requests used to verify authorization (the permissions * granted to users) * * @see GroupPermissionDao for CRUD of table group_roles * @see UserPermissionDao for CRUD of table user_roles */ public class AuthorizationDao implements Dao { /** * Loads all the permissions granted to logged-in user for the specified organization */ public Set<String> selectOrganizationPermissions(DbSession dbSession, String organizationUuid, int userId) { return mapper(dbSession).selectOrganizationPermissions(organizationUuid, userId); } /** * Loads all the permissions granted to anonymous user for the specified organization */ public Set<String> selectOrganizationPermissionsOfAnonymous(DbSession dbSession, String organizationUuid) { return mapper(dbSession).selectOrganizationPermissionsOfAnonymous(organizationUuid); } /** * 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 <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); } /** * The number of users who will still have the permission if the group {@code excludedGroupId} * is deleted. The anyone virtual group is not taken into account. */ public int countUsersWithGlobalPermissionExcludingGroup(DbSession dbSession, String organizationUuid, String permission, int excludedGroupId) { return mapper(dbSession).countUsersWithGlobalPermissionExcludingGroup(organizationUuid, permission, excludedGroupId); } /** * The number of users who will still have the permission if the user {@code excludedUserId} * is deleted. The anyone virtual group is not taken into account. */ public int countUsersWithGlobalPermissionExcludingUser(DbSession dbSession, String organizationUuid, String permission, int excludedUserId) { return mapper(dbSession).countUsersWithGlobalPermissionExcludingUser(organizationUuid, permission, excludedUserId); } /** * The number of users who will still have the permission if the user {@code userId} * is removed from group {@code groupId}. The anyone virtual group is not taken into account. * Contrary to {@link #countUsersWithGlobalPermissionExcludingUser(DbSession, String, String, int)}, user * still exists and may have the permission directly or through other groups. */ public int countUsersWithGlobalPermissionExcludingGroupMember(DbSession dbSession, String organizationUuid, String permission, int groupId, int userId) { return mapper(dbSession).countUsersWithGlobalPermissionExcludingGroupMember(organizationUuid, permission, groupId, userId); } /** * The number of users who will still have the permission if the permission {@code permission} * is removed from user {@code userId}. The anyone virtual group is not taken into account. * Contrary to {@link #countUsersWithGlobalPermissionExcludingUser(DbSession, String, String, int)}, user * still exists and may have the permission through groups. */ public int countUsersWithGlobalPermissionExcludingUserPermission(DbSession dbSession, String organizationUuid, String permission, int userId) { return mapper(dbSession).countUsersWithGlobalPermissionExcludingUserPermission(organizationUuid, permission, userId); } /** * The UUIDs of all the organizations in which the specified user has the specified global permission. An empty * set is returned if user or permission do not exist. An empty set is also returned if the user is not involved * in any organization. * <br/> * Group membership is taken into account. Anonymous privileges are ignored. */ public Set<String> selectOrganizationUuidsOfUserWithGlobalPermission(DbSession dbSession, int userId, String permission) { return mapper(dbSession).selectOrganizationUuidsOfUserWithGlobalPermission(userId, permission); } /** * @deprecated replaced by {@link #keepAuthorizedProjectUuids(DbSession, Collection, Integer, String)} */ @Deprecated public Set<Long> keepAuthorizedProjectIds(DbSession dbSession, Collection<Long> componentIds, @Nullable Integer userId, String permission) { return executeLargeInputsIntoSet( componentIds, partition -> { if (userId == null) { return mapper(dbSession).keepAuthorizedProjectIdsForAnonymous(permission, partition); } return mapper(dbSession).keepAuthorizedProjectIdsForUser(userId, permission, partition); }, partitionSize -> partitionSize / 2); } public Set<String> keepAuthorizedProjectUuids(DbSession dbSession, Collection<String> projectUuids, @Nullable Integer userId, String permission) { return executeLargeInputsIntoSet( projectUuids, partition -> { if (userId == null) { return mapper(dbSession).keepAuthorizedProjectUuidsForAnonymous(permission, partition); } return mapper(dbSession).keepAuthorizedProjectUuidsForUser(userId, permission, partition); }, partitionSize -> partitionSize / 2); } /** * Keep only authorized user that have the given permission on a given project. * Please Note that if the permission is 'Anyone' is NOT taking into account by this method. */ public Collection<Integer> keepAuthorizedUsersForRoleAndProject(DbSession dbSession, Collection<Integer> userIds, String role, long projectId) { return executeLargeInputs( userIds, partitionOfIds -> mapper(dbSession).keepAuthorizedUsersForRoleAndProject(role, projectId, partitionOfIds), partitionSize -> partitionSize / 3); } private static AuthorizationMapper mapper(DbSession dbSession) { return dbSession.getMapper(AuthorizationMapper.class); } }