Updates user permissions lookup to do one query instead of one query per user group
This commit is contained in:
@@ -28,17 +28,17 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <summary>
|
||||
/// Gets explicilty defined permissions for the group for specified entities
|
||||
/// </summary>
|
||||
/// <param name="groupId">Id of group</param>
|
||||
/// <param name="groupIds"></param>
|
||||
/// <param name="entityIds">Array of entity Ids, if empty will return permissions for the group for all entities</param>
|
||||
EntityPermissionCollection GetPermissionsForEntities(int groupId, params int[] entityIds);
|
||||
EntityPermissionCollection GetPermissions(int[] groupIds, params int[] entityIds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets explicilt and default permissions (if requested) permissions for the group for specified entities
|
||||
/// </summary>
|
||||
/// <param name="group">The group</param>
|
||||
/// <param name="groups"></param>
|
||||
/// <param name="fallbackToDefaultPermissions">If true will include the group's default permissions if no permissions are explicitly assigned</param>
|
||||
/// <param name="nodeIds">Array of entity Ids, if empty will return permissions for the group for all entities</param>
|
||||
EntityPermissionCollection GetPermissionsForEntities(IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds);
|
||||
EntityPermissionCollection GetPermissions(IReadOnlyUserGroup[] groups, bool fallbackToDefaultPermissions, params int[] nodeIds);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single group to any number of entities
|
||||
|
||||
@@ -39,43 +39,53 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <summary>
|
||||
/// Returns explicitly defined permissions for a user group for any number of nodes
|
||||
/// </summary>
|
||||
/// <param name="groupId"></param>
|
||||
/// <param name="groupIds">
|
||||
/// The group ids to lookup permissions for
|
||||
/// </param>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
public EntityPermissionCollection GetPermissionsForEntities(int groupId, params int[] entityIds)
|
||||
/// <remarks>
|
||||
/// This method will not support passing in more than 2000 group Ids
|
||||
/// </remarks>
|
||||
public EntityPermissionCollection GetPermissionsForEntities(int[] groupIds, params int[] entityIds)
|
||||
{
|
||||
var result = new EntityPermissionCollection();
|
||||
|
||||
if (entityIds.Length == 0)
|
||||
foreach (var groupOfGroupIds in groupIds.InGroupsOf(2000))
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserGroup2NodePermissionDto>(SqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => dto.UserGroupId == groupId, SqlSyntax);
|
||||
var permissions = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
foreach (var permission in ConvertToPermissionList(permissions))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//iterate in groups of 2000 since we don't want to exceed the max SQL param count
|
||||
foreach (var groupOfIds in entityIds.InGroupsOf(2000))
|
||||
{
|
||||
var ids = groupOfIds;
|
||||
//copy local
|
||||
var localIds = groupOfGroupIds.ToArray();
|
||||
|
||||
var sql = new Sql();
|
||||
if (entityIds.Length == 0)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserGroup2NodePermissionDto>(SqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => dto.UserGroupId == groupId && ids.Contains(dto.NodeId), SqlSyntax);
|
||||
.Where<UserGroup2NodePermissionDto>(dto => localIds.Contains(dto.UserGroupId), SqlSyntax);
|
||||
var permissions = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
foreach (var permission in ConvertToPermissionList(permissions))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
//iterate in groups of 2000 since we don't want to exceed the max SQL param count
|
||||
foreach (var groupOfEntityIds in entityIds.InGroupsOf(2000))
|
||||
{
|
||||
var ids = groupOfEntityIds;
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserGroup2NodePermissionDto>(SqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => localIds.Contains(dto.UserGroupId) && ids.Contains(dto.NodeId), SqlSyntax);
|
||||
var permissions = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
foreach (var permission in ConvertToPermissionList(permissions))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -91,42 +91,46 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
_userGroupWithUsersRepository.AddOrUpdate(new UserGroupWithUsers(userGroup, userIds));
|
||||
}
|
||||
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets explicilty defined permissions for the group for specified entities
|
||||
/// </summary>
|
||||
/// <param name="groupId">Id of group</param>
|
||||
/// <param name="groupIds"></param>
|
||||
/// <param name="entityIds">Array of entity Ids, if empty will return permissions for the group for all entities</param>
|
||||
public EntityPermissionCollection GetPermissionsForEntities(int groupId, params int[] entityIds)
|
||||
public EntityPermissionCollection GetPermissions(int[] groupIds, params int[] entityIds)
|
||||
{
|
||||
return _permissionRepository.GetPermissionsForEntities(groupId, entityIds);
|
||||
return _permissionRepository.GetPermissionsForEntities(groupIds, entityIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets explicilt and default permissions (if requested) permissions for the group for specified entities
|
||||
/// </summary>
|
||||
/// <param name="group">The group</param>
|
||||
/// <param name="groups"></param>
|
||||
/// <param name="fallbackToDefaultPermissions">If true will include the group's default permissions if no permissions are explicitly assigned</param>
|
||||
/// <param name="nodeIds">Array of entity Ids, if empty will return permissions for the group for all entities</param>
|
||||
public EntityPermissionCollection GetPermissionsForEntities(IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
|
||||
public EntityPermissionCollection GetPermissions(IReadOnlyUserGroup[] groups, bool fallbackToDefaultPermissions, params int[] nodeIds)
|
||||
{
|
||||
if (group == null) throw new ArgumentNullException("group");
|
||||
if (groups == null) throw new ArgumentNullException("groups");
|
||||
|
||||
var explicitPermissions = GetPermissionsForEntities(group.Id, nodeIds);
|
||||
var groupIds = groups.Select(x => x.Id).ToArray();
|
||||
var explicitPermissions = GetPermissions(groupIds, nodeIds);
|
||||
var result = new EntityPermissionCollection(explicitPermissions);
|
||||
|
||||
// If requested, and no permissions are assigned to a particular node, then we will fill in those permissions with the group's defaults
|
||||
if (fallbackToDefaultPermissions)
|
||||
{
|
||||
var missingIds = nodeIds.Except(result.Select(x => x.EntityId)).ToArray();
|
||||
if (missingIds.Length > 0)
|
||||
foreach (var group in groups)
|
||||
{
|
||||
foreach (var permission in missingIds
|
||||
.Select(i => new EntityPermission(group.Id, i, group.Permissions.ToArray(), isDefaultPermissions: true)))
|
||||
var missingIds = nodeIds.Except(result.Select(x => x.EntityId)).ToArray();
|
||||
if (missingIds.Length > 0)
|
||||
{
|
||||
result.Add(permission);
|
||||
foreach (var permission in missingIds
|
||||
.Select(i => new EntityPermission(group.Id, i, group.Permissions.ToArray(), isDefaultPermissions: true)))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -847,19 +847,19 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
|
||||
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
|
||||
public EntityPermissionCollection GetPermissions(IUser user, params int[] nodeIds)
|
||||
{
|
||||
//TODO: we don't need to run this query for each group assigned, we can do this in one query
|
||||
|
||||
{
|
||||
var result = new EntityPermissionCollection();
|
||||
|
||||
foreach (var group in user.Groups)
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
foreach (var permission in GetPermissions(group, true, nodeIds))
|
||||
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
|
||||
foreach (var permission in repository.GetPermissions(user.Groups.ToArray(), true, nodeIds))
|
||||
{
|
||||
result.Add(permission);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
@@ -879,7 +879,7 @@ namespace Umbraco.Core.Services
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
return repository.GetPermissionsForEntities(group, fallbackToDefaultPermissions, nodeIds);
|
||||
return repository.GetPermissions(new[] { group }, fallbackToDefaultPermissions, nodeIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -898,7 +898,7 @@ namespace Umbraco.Core.Services
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
return repository.GetPermissionsForEntities(group.ToReadOnlyGroup(), fallbackToDefaultPermissions, nodeIds);
|
||||
return repository.GetPermissions(new[] { group.ToReadOnlyGroup() }, fallbackToDefaultPermissions, nodeIds);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user