Gets inherited permissions working, adds lots of unit tests, few more tests to write now.
This commit is contained in:
@@ -0,0 +1,54 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Umbraco.Core.Models.EntityBase;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an <see cref="IContent"/> -> user group & permission key value pair collection
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This implements <see cref="IAggregateRoot"/> purely so it can be used with the repository layer which is why it's explicitly implemented.
|
||||
/// </remarks>
|
||||
public class ContentPermissionSet : EntityPermissionSet, IAggregateRoot
|
||||
{
|
||||
private readonly IContent _content;
|
||||
|
||||
public ContentPermissionSet(IContent content, IEnumerable<EntityPermission> permissionsSet)
|
||||
: base(content.Id, permissionsSet)
|
||||
{
|
||||
_content = content;
|
||||
}
|
||||
|
||||
public override int EntityId
|
||||
{
|
||||
get { return _content.Id; }
|
||||
}
|
||||
|
||||
#region Explicit implementation of IAggregateRoot
|
||||
int IEntity.Id
|
||||
{
|
||||
get { return EntityId; }
|
||||
set { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
bool IEntity.HasIdentity
|
||||
{
|
||||
get { return EntityId > 0; }
|
||||
}
|
||||
|
||||
Guid IEntity.Key { get; set; }
|
||||
|
||||
DateTime IEntity.CreateDate { get; set; }
|
||||
|
||||
DateTime IEntity.UpdateDate { get; set; }
|
||||
|
||||
DateTime? IDeletableEntity.DeletedDate { get; set; }
|
||||
|
||||
object IDeepCloneable.DeepClone()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -7,21 +7,24 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// </summary>
|
||||
public class EntityPermission
|
||||
{
|
||||
public EntityPermission(int entityId, string[] assignedPermissions)
|
||||
public EntityPermission(int groupId, int entityId, string[] assignedPermissions)
|
||||
{
|
||||
UserGroupId = groupId;
|
||||
EntityId = entityId;
|
||||
AssignedPermissions = assignedPermissions;
|
||||
IsDefaultPermissions = false;
|
||||
}
|
||||
|
||||
public EntityPermission(int entityId, string[] assignedPermissions, bool isDefaultPermissions)
|
||||
public EntityPermission(int groupId, int entityId, string[] assignedPermissions, bool isDefaultPermissions)
|
||||
{
|
||||
UserGroupId = groupId;
|
||||
EntityId = entityId;
|
||||
AssignedPermissions = assignedPermissions;
|
||||
IsDefaultPermissions = isDefaultPermissions;
|
||||
}
|
||||
|
||||
public int EntityId { get; private set; }
|
||||
public int UserGroupId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The assigned permissions for the user/entity combo
|
||||
@@ -50,7 +53,9 @@ namespace Umbraco.Core.Models.Membership
|
||||
AssignedPermissions = newPermissions
|
||||
.Distinct()
|
||||
.ToArray();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,60 +1,56 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents an entity -> user group & permission key value pair collection
|
||||
/// </summary>
|
||||
/// </summary>
|
||||
public class EntityPermissionSet
|
||||
{
|
||||
/// <summary>
|
||||
/// The entity id with permissions assigned
|
||||
/// Returns an empty permission set
|
||||
/// </summary>
|
||||
public int EntityId { get; private set; }
|
||||
/// <returns></returns>
|
||||
public static EntityPermissionSet Empty()
|
||||
{
|
||||
return new EntityPermissionSet(-1, new EntityPermission[0]);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The key/value pairs of user group id & single permission
|
||||
/// </summary>
|
||||
public IEnumerable<UserGroupPermission> PermissionsSet { get; private set; }
|
||||
|
||||
public EntityPermissionSet(int entityId, IEnumerable<UserGroupPermission> permissionsSet)
|
||||
public EntityPermissionSet(int entityId, IEnumerable<EntityPermission> permissionsSet)
|
||||
{
|
||||
EntityId = entityId;
|
||||
PermissionsSet = permissionsSet;
|
||||
}
|
||||
|
||||
public class UserGroupPermission
|
||||
/// <summary>
|
||||
/// The entity id with permissions assigned
|
||||
/// </summary>
|
||||
public virtual int EntityId { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// The key/value pairs of user group id & single permission
|
||||
/// </summary>
|
||||
public IEnumerable<EntityPermission> PermissionsSet { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns the aggregte permissions in the permission set
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
/// <remarks>
|
||||
/// This value is only calculated once
|
||||
/// </remarks>
|
||||
public IEnumerable<string> GetAllPermissions()
|
||||
{
|
||||
public UserGroupPermission(int groupId, string permission)
|
||||
{
|
||||
UserGroupId = groupId;
|
||||
Permission = permission;
|
||||
}
|
||||
|
||||
public int UserGroupId { get; private set; }
|
||||
|
||||
public string Permission { get; private set; }
|
||||
|
||||
protected bool Equals(UserGroupPermission other)
|
||||
{
|
||||
return UserGroupId == other.UserGroupId && string.Equals(Permission, other.Permission);
|
||||
}
|
||||
|
||||
public override bool Equals(object obj)
|
||||
{
|
||||
if (ReferenceEquals(null, obj)) return false;
|
||||
if (ReferenceEquals(this, obj)) return true;
|
||||
if (obj.GetType() != this.GetType()) return false;
|
||||
return Equals((UserGroupPermission) obj);
|
||||
}
|
||||
|
||||
public override int GetHashCode()
|
||||
{
|
||||
unchecked
|
||||
{
|
||||
return (UserGroupId * 397) ^ Permission.GetHashCode();
|
||||
}
|
||||
}
|
||||
return _calculatedPermissions ?? (_calculatedPermissions =
|
||||
PermissionsSet.SelectMany(x => x.AssignedPermissions).Distinct().ToArray());
|
||||
}
|
||||
|
||||
private string[] _calculatedPermissions;
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a user group -> entity permission
|
||||
/// </summary>
|
||||
public class UserGroupEntityPermission : EntityPermission
|
||||
{
|
||||
public UserGroupEntityPermission(int groupId, int entityId, string[] assignedPermissions)
|
||||
: base(entityId, assignedPermissions)
|
||||
{
|
||||
UserGroupId = groupId;
|
||||
}
|
||||
|
||||
public int UserGroupId { get; private set; }
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,31 @@
|
||||
using System;
|
||||
using Umbraco.Core.Configuration.UmbracoSettings;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Override the base content repository so we can change the node object type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It would be nicer if we could separate most of this down into a smaller version of the ContentRepository class, however to do that
|
||||
/// requires quite a lot of work since we'd need to re-organize the interhitance quite a lot or create a helper class to perform a lot of the underlying logic.
|
||||
///
|
||||
/// TODO: Create a helper method to contain most of the underlying logic for the ContentRepository
|
||||
/// </remarks>
|
||||
internal class ContentBlueprintRepository : ContentRepository
|
||||
{
|
||||
public ContentBlueprintRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider syntaxProvider, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection)
|
||||
: base(work, cacheHelper, logger, syntaxProvider, contentTypeRepository, templateRepository, tagRepository, contentSection)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { return Constants.ObjectTypes.DocumentBlueprintGuid; }
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -20,28 +20,6 @@ using Umbraco.Core.Persistence.UnitOfWork;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
/// <summary>
|
||||
/// Override the base content repository so we can change the node object type
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// It would be nicer if we could separate most of this down into a smaller version of the ContentRepository class, however to do that
|
||||
/// requires quite a lot of work since we'd need to re-organize the interhitance quite a lot or create a helper class to perform a lot of the underlying logic.
|
||||
///
|
||||
/// TODO: Create a helper method to conain most of the underlying logic for the ContentRepository
|
||||
/// </remarks>
|
||||
internal class ContentBlueprintRepository : ContentRepository
|
||||
{
|
||||
public ContentBlueprintRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider syntaxProvider, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection) : base(work, cacheHelper, logger, syntaxProvider, contentTypeRepository, templateRepository, tagRepository, contentSection)
|
||||
{
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { return Constants.ObjectTypes.DocumentBlueprintGuid; }
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Represents a repository for doing CRUD operations for <see cref="IContent"/>
|
||||
/// </summary>
|
||||
@@ -50,9 +28,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
private readonly IContentTypeRepository _contentTypeRepository;
|
||||
private readonly ITemplateRepository _templateRepository;
|
||||
private readonly ITagRepository _tagRepository;
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
private readonly ContentPreviewRepository<IContent> _contentPreviewRepository;
|
||||
private readonly ContentXmlRepository<IContent> _contentXmlRepository;
|
||||
private readonly PermissionRepository<IContent> _permissionRepository;
|
||||
|
||||
public ContentRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider syntaxProvider, IContentTypeRepository contentTypeRepository, ITemplateRepository templateRepository, ITagRepository tagRepository, IContentSection contentSection)
|
||||
: base(work, cacheHelper, logger, syntaxProvider, contentSection)
|
||||
@@ -63,10 +41,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
_contentTypeRepository = contentTypeRepository;
|
||||
_templateRepository = templateRepository;
|
||||
_tagRepository = tagRepository;
|
||||
_cacheHelper = cacheHelper;
|
||||
_contentPreviewRepository = new ContentPreviewRepository<IContent>(work, CacheHelper.NoCache, logger, syntaxProvider);
|
||||
_contentXmlRepository = new ContentXmlRepository<IContent>(work, CacheHelper.NoCache, logger, syntaxProvider);
|
||||
|
||||
_permissionRepository = new PermissionRepository<IContent>(UnitOfWork, cacheHelper, Logger, SqlSyntax);
|
||||
|
||||
EnsureUniqueNaming = true;
|
||||
}
|
||||
|
||||
@@ -468,26 +446,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
entity.Id = nodeDto.NodeId; //Set Id on entity to ensure an Id is set
|
||||
entity.Path = nodeDto.Path;
|
||||
entity.SortOrder = sortOrder;
|
||||
entity.Level = level;
|
||||
|
||||
////Assign the same permissions to it as the parent node
|
||||
//// http://issues.umbraco.org/issue/U4-2161
|
||||
//var permissionsRepo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
//var parentPermissions = permissionsRepo.GetPermissionsForEntity(entity.ParentId).ToArray();
|
||||
////if there are parent permissions then assign them, otherwise leave null and permissions will become the
|
||||
//// user's default permissions.
|
||||
//if (parentPermissions.Length > 0)
|
||||
//{
|
||||
// var userGroupPermissions = (
|
||||
// from perm in parentPermissions
|
||||
// from p in perm.AssignedPermissions
|
||||
// select new EntityPermissionSet.UserGroupPermission(perm.UserGroupId, p)).ToList();
|
||||
|
||||
// permissionsRepo.ReplaceEntityPermissions(new EntityPermissionSet(entity.Id, userGroupPermissions));
|
||||
// //flag the entity's permissions changed flag so we can track those changes.
|
||||
// //Currently only used for the cache refreshers to detect if we should refresh all user permissions cache.
|
||||
// ((Content)entity).PermissionsChanged = true;
|
||||
//}
|
||||
entity.Level = level;
|
||||
|
||||
//Create the Content specific data - cmsContent
|
||||
var contentDto = dto.ContentVersionDto.ContentDto;
|
||||
@@ -863,8 +822,7 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
|
||||
public void ReplaceContentPermissions(EntityPermissionSet permissionSet)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
repo.ReplaceEntityPermissions(permissionSet);
|
||||
_permissionRepository.ReplaceEntityPermissions(permissionSet);
|
||||
}
|
||||
|
||||
public void ClearPublished(IContent content)
|
||||
@@ -880,21 +838,19 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
/// <param name="permission"></param>
|
||||
/// <param name="groupIds"></param>
|
||||
public void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> groupIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
repo.AssignEntityPermission(entity, permission, groupIds);
|
||||
{
|
||||
_permissionRepository.AssignEntityPermission(entity, permission, groupIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions directly assigned to the content item for all user groups
|
||||
/// Gets the explicit list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<UserGroupEntityPermission> GetPermissionsForEntity(int entityId)
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
return repo.GetPermissionsForEntity(entityId);
|
||||
}
|
||||
return _permissionRepository.GetPermissionsForEntity(entityId);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Adds/updates content/published xml
|
||||
@@ -906,6 +862,15 @@ order by umbracoNode.{2}, umbracoNode.parentID, umbracoNode.sortOrder",
|
||||
_contentXmlRepository.AddOrUpdate(new ContentXmlEntity<IContent>(content, xml));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to add/update a permission for a content item
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
public void AddOrUpdatePermissions(ContentPermissionSet permission)
|
||||
{
|
||||
_permissionRepository.AddOrUpdate(permission);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to remove the content xml for a content item
|
||||
/// </summary>
|
||||
|
||||
@@ -57,11 +57,18 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
void AssignEntityPermission(IContent entity, char permission, IEnumerable<int> groupIds);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the list of permissions for the content item
|
||||
/// Gets the explicit list of permissions for the content item
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<UserGroupEntityPermission> GetPermissionsForEntity(int entityId);
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId);
|
||||
|
||||
///// <summary>
|
||||
///// Gets the implicit/inherited list of permissions for the content item
|
||||
///// </summary>
|
||||
///// <param name="path"></param>
|
||||
///// <returns></returns>
|
||||
//IEnumerable<EntityPermission> GetPermissionsForPath(string path);
|
||||
|
||||
/// <summary>
|
||||
/// Used to add/update published xml for the content item
|
||||
@@ -70,6 +77,12 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="xml"></param>
|
||||
void AddOrUpdateContentXml(IContent content, Func<IContent, XElement> xml);
|
||||
|
||||
/// <summary>
|
||||
/// Used to add/update a permission for a content item
|
||||
/// </summary>
|
||||
/// <param name="permission"></param>
|
||||
void AddOrUpdatePermissions(ContentPermissionSet permission);
|
||||
|
||||
/// <summary>
|
||||
/// Used to remove the content xml for a content item
|
||||
/// </summary>
|
||||
|
||||
@@ -32,6 +32,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entityIds">Array of entity Ids, if empty will return permissions for the group for all entities</param>
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntities(int groupId, 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="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>
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntities(IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds);
|
||||
|
||||
/// <summary>
|
||||
/// Replaces the same permission set for a single group to any number of entities
|
||||
/// </summary>
|
||||
@@ -47,6 +55,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="permission">Permissions as enumerable list of <see cref="char"/></param>
|
||||
/// <param name="entityIds">Specify the nodes to replace permissions for</param>
|
||||
void AssignGroupPermission(int groupId, char permission, params int[] entityIds);
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -12,6 +12,9 @@ using Umbraco.Core.Persistence.SqlSyntax;
|
||||
using Umbraco.Core.Persistence.UnitOfWork;
|
||||
using CacheKeys = Umbraco.Core.Cache.CacheKeys;
|
||||
using Umbraco.Core.Cache;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Persistence.Querying;
|
||||
|
||||
namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
@@ -19,19 +22,18 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// A repository that exposes functionality to modify assigned permissions to a node
|
||||
/// </summary>
|
||||
/// <typeparam name="TEntity"></typeparam>
|
||||
internal class PermissionRepository<TEntity>
|
||||
/// <remarks>
|
||||
/// This repo implements the base <see cref="PetaPocoRepositoryBase{TId,TEntity}"/> class so that permissions can be queued to be persisted
|
||||
/// like the normal repository pattern but the standard repository Get commands don't apply and will throw <see cref="NotImplementedException"/>
|
||||
/// </remarks>
|
||||
internal class PermissionRepository<TEntity> : PetaPocoRepositoryBase<int, ContentPermissionSet>
|
||||
where TEntity : class, IAggregateRoot
|
||||
{
|
||||
private readonly IScopeUnitOfWork _unitOfWork;
|
||||
private readonly IRuntimeCacheProvider _runtimeCache;
|
||||
private readonly ISqlSyntaxProvider _sqlSyntax;
|
||||
|
||||
internal PermissionRepository(IScopeUnitOfWork unitOfWork, CacheHelper cache, ISqlSyntaxProvider sqlSyntax)
|
||||
public PermissionRepository(IScopeUnitOfWork work, CacheHelper cache, ILogger logger, ISqlSyntaxProvider sqlSyntax)
|
||||
: base(work, cache, logger, sqlSyntax)
|
||||
{
|
||||
_unitOfWork = unitOfWork;
|
||||
//Make this repository use an isolated cache
|
||||
_runtimeCache = cache.IsolatedRuntimeCache.GetOrCreateCache<EntityPermission>();
|
||||
_sqlSyntax = sqlSyntax;
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -41,7 +43,6 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntities(int groupId, params int[] entityIds)
|
||||
{
|
||||
//var whereCriteria = GetPermissionsForEntitiesCriteria(groupId, entityIds);
|
||||
var result = new List<EntityPermission>();
|
||||
//iterate in groups of 2000 since we don't want to exceed the max SQL param count
|
||||
@@ -51,9 +52,9 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserGroup2NodePermissionDto>(_sqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => dto.UserGroupId == groupId && ids.Contains(dto.NodeId), _sqlSyntax);
|
||||
var permissions = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
.From<UserGroup2NodePermissionDto>(SqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => dto.UserGroupId == groupId && ids.Contains(dto.NodeId), SqlSyntax);
|
||||
var permissions = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
result.AddRange(ConvertToPermissionList(permissions));
|
||||
}
|
||||
return result;
|
||||
@@ -73,62 +74,62 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
// sql.Select("*")
|
||||
// .From<UserGroup2NodePermissionDto>()
|
||||
// .Where(whereCriteria);
|
||||
// var result = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
// var result = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
// return ConvertToPermissionList(result);
|
||||
// },
|
||||
// GetCacheTimeout(),
|
||||
// priority: GetCachePriority());
|
||||
}
|
||||
|
||||
//private static string GetEntityIdKey(int[] entityIds)
|
||||
//{
|
||||
// return string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));
|
||||
//}
|
||||
|
||||
//private static TimeSpan GetCacheTimeout()
|
||||
//{
|
||||
// //Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will only have this exist in cache for 20 minutes,
|
||||
// // then it will refresh from the database.
|
||||
// return new TimeSpan(0, 20, 0);
|
||||
//}
|
||||
|
||||
//private static CacheItemPriority GetCachePriority()
|
||||
//{
|
||||
// //Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will make this priority below average
|
||||
// return CacheItemPriority.BelowNormal;
|
||||
//}
|
||||
|
||||
private static IEnumerable<UserGroupEntityPermission> ConvertToPermissionList(IEnumerable<UserGroup2NodePermissionDto> result)
|
||||
}
|
||||
|
||||
//private static string GetEntityIdKey(int[] entityIds)
|
||||
//{
|
||||
// return string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));
|
||||
//}
|
||||
|
||||
//private static TimeSpan GetCacheTimeout()
|
||||
//{
|
||||
// //Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will only have this exist in cache for 20 minutes,
|
||||
// // then it will refresh from the database.
|
||||
// return new TimeSpan(0, 20, 0);
|
||||
//}
|
||||
|
||||
//private static CacheItemPriority GetCachePriority()
|
||||
//{
|
||||
// //Since this cache can be quite large (http://issues.umbraco.org/issue/U4-2161) we will make this priority below average
|
||||
// return CacheItemPriority.BelowNormal;
|
||||
//}
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions directly assigned to the content items for all user groups
|
||||
/// </summary>
|
||||
/// <param name="entityIds"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntities(int[] entityIds)
|
||||
{
|
||||
var permissions = new List<UserGroupEntityPermission>();
|
||||
var nodePermissions = result.GroupBy(x => x.NodeId);
|
||||
foreach (var np in nodePermissions)
|
||||
{
|
||||
var userGroupPermissions = np.GroupBy(x => x.UserGroupId);
|
||||
foreach (var permission in userGroupPermissions)
|
||||
{
|
||||
var perms = permission.Select(x => x.Permission).ToArray();
|
||||
permissions.Add(new UserGroupEntityPermission(permission.Key, permission.First().NodeId, perms));
|
||||
}
|
||||
}
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserGroup2NodePermissionDto>(SqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => entityIds.Contains(dto.NodeId), SqlSyntax)
|
||||
.OrderBy<UserGroup2NodePermissionDto>(dto => dto.NodeId, SqlSyntax);
|
||||
|
||||
return permissions;
|
||||
}
|
||||
var result = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
return ConvertToPermissionList(result);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions directly assigned to the content item for all user groups
|
||||
/// </summary>
|
||||
/// <param name="entityId"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<UserGroupEntityPermission> GetPermissionsForEntity(int entityId)
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(int entityId)
|
||||
{
|
||||
var sql = new Sql();
|
||||
sql.Select("*")
|
||||
.From<UserGroup2NodePermissionDto>()
|
||||
.Where<UserGroup2NodePermissionDto>(dto => dto.NodeId == entityId)
|
||||
.OrderBy<UserGroup2NodePermissionDto>(dto => dto.NodeId);
|
||||
.From<UserGroup2NodePermissionDto>(SqlSyntax)
|
||||
.Where<UserGroup2NodePermissionDto>(dto => dto.NodeId == entityId, SqlSyntax)
|
||||
.OrderBy<UserGroup2NodePermissionDto>(dto => dto.NodeId, SqlSyntax);
|
||||
|
||||
var result = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
var result = UnitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
|
||||
return ConvertToPermissionList(result);
|
||||
}
|
||||
|
||||
@@ -143,7 +144,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </remarks>
|
||||
public void ReplacePermissions(int groupId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
var db = UnitOfWork.Database;
|
||||
|
||||
//we need to batch these in groups of 2000 so we don't exceed the max 2100 limit
|
||||
var sql = "DELETE FROM umbracoUserGroup2NodePermission WHERE userGroupId = @groupId AND nodeId in (@nodeIds)";
|
||||
@@ -166,10 +167,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
}
|
||||
}
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(toInsert, _sqlSyntax);
|
||||
UnitOfWork.Database.BulkInsertRecords(toInsert, SqlSyntax);
|
||||
|
||||
//Raise the event
|
||||
_unitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<UserGroupEntityPermission>(ConvertToPermissionList(toInsert), false));
|
||||
UnitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<EntityPermission>(ConvertToPermissionList(toInsert), false));
|
||||
|
||||
}
|
||||
|
||||
@@ -181,7 +182,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entityIds"></param>
|
||||
public void AssignPermission(int groupId, char permission, params int[] entityIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
var db = UnitOfWork.Database;
|
||||
var sql = "DELETE FROM umbracoUserGroup2NodePermission WHERE userGroupId = @groupId AND permission=@permission AND nodeId in (@entityIds)";
|
||||
db.Execute(sql,
|
||||
new
|
||||
@@ -198,10 +199,10 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
UserGroupId = groupId
|
||||
}).ToArray();
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, _sqlSyntax);
|
||||
UnitOfWork.Database.BulkInsertRecords(actions, SqlSyntax);
|
||||
|
||||
//Raise the event
|
||||
_unitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<UserGroupEntityPermission>(ConvertToPermissionList(actions), false));
|
||||
UnitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<EntityPermission>(ConvertToPermissionList(actions), false));
|
||||
|
||||
}
|
||||
|
||||
@@ -213,7 +214,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="groupIds"></param>
|
||||
public void AssignEntityPermission(TEntity entity, char permission, IEnumerable<int> groupIds)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
var db = UnitOfWork.Database;
|
||||
var sql = "DELETE FROM umbracoUserGroup2NodePermission WHERE nodeId = @nodeId AND permission = @permission AND userGroupId in (@groupIds)";
|
||||
db.Execute(sql,
|
||||
new
|
||||
@@ -230,15 +231,15 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
UserGroupId = id
|
||||
}).ToArray();
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, _sqlSyntax);
|
||||
UnitOfWork.Database.BulkInsertRecords(actions, SqlSyntax);
|
||||
|
||||
//Raise the event
|
||||
_unitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<UserGroupEntityPermission>(ConvertToPermissionList(actions), false));
|
||||
UnitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<EntityPermission>(ConvertToPermissionList(actions), false));
|
||||
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Assigns permissions to an entity for multiple users/permission entries
|
||||
/// Assigns permissions to an entity for multiple group/permission entries
|
||||
/// </summary>
|
||||
/// <param name="permissionSet">
|
||||
/// </param>
|
||||
@@ -247,25 +248,118 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// </remarks>
|
||||
public void ReplaceEntityPermissions(EntityPermissionSet permissionSet)
|
||||
{
|
||||
var db = _unitOfWork.Database;
|
||||
var sql = "DELETE FROM umbracoUserGroup2NodePermission WHERE nodeId = @nodeId";
|
||||
db.Execute(sql, new { nodeId = permissionSet.EntityId });
|
||||
|
||||
var actions = permissionSet.PermissionsSet.Select(p => new UserGroup2NodePermissionDto
|
||||
{
|
||||
NodeId = permissionSet.EntityId,
|
||||
Permission = p.Permission,
|
||||
UserGroupId = p.UserGroupId
|
||||
}).ToArray();
|
||||
var db = UnitOfWork.Database;
|
||||
var sql = "DELETE FROM umbracoUserGroup2NodePermission WHERE nodeId = @nodeId";
|
||||
db.Execute(sql, new { nodeId = permissionSet.EntityId });
|
||||
|
||||
var toInsert = new List<UserGroup2NodePermissionDto>();
|
||||
foreach (var entityPermission in permissionSet.PermissionsSet)
|
||||
{
|
||||
foreach (var permission in entityPermission.AssignedPermissions)
|
||||
{
|
||||
toInsert.Add(new UserGroup2NodePermissionDto
|
||||
{
|
||||
NodeId = permissionSet.EntityId,
|
||||
Permission = permission,
|
||||
UserGroupId = entityPermission.UserGroupId
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
UnitOfWork.Database.BulkInsertRecords(toInsert, SqlSyntax);
|
||||
|
||||
//Raise the event
|
||||
UnitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<EntityPermission>(permissionSet.PermissionsSet, false));
|
||||
|
||||
|
||||
_unitOfWork.Database.BulkInsertRecords(actions, _sqlSyntax);
|
||||
|
||||
//Raise the event
|
||||
_unitOfWork.Events.Dispatch(AssignedPermissions, this, new SaveEventArgs<UserGroupEntityPermission>(ConvertToPermissionList(actions), false));
|
||||
|
||||
|
||||
}
|
||||
|
||||
public static event TypedEventHandler<PermissionRepository<TEntity>, SaveEventArgs<UserGroupEntityPermission>> AssignedPermissions;
|
||||
|
||||
#region Not implemented (don't need to for the purposes of this repo)
|
||||
protected override ContentPermissionSet PerformGet(int id)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override IEnumerable<ContentPermissionSet> PerformGetAll(params int[] ids)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override IEnumerable<ContentPermissionSet> PerformGetByQuery(IQuery<ContentPermissionSet> query)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override Sql GetBaseQuery(bool isCount)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override string GetBaseWhereClause()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
return new List<string>();
|
||||
}
|
||||
|
||||
protected override Guid NodeObjectTypeId
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
protected override void PersistDeletedItem(ContentPermissionSet entity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
/// <summary>
|
||||
/// Used to add or update entity permissions during a content item being updated
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
protected override void PersistNewItem(ContentPermissionSet entity)
|
||||
{
|
||||
//does the same thing as update
|
||||
PersistUpdatedItem(entity);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Used to add or update entity permissions during a content item being updated
|
||||
/// </summary>
|
||||
/// <param name="entity"></param>
|
||||
protected override void PersistUpdatedItem(ContentPermissionSet entity)
|
||||
{
|
||||
var asAggregateRoot = (IAggregateRoot)entity;
|
||||
if (asAggregateRoot.HasIdentity == false)
|
||||
{
|
||||
throw new InvalidOperationException("Cannot create permissions for an entity without an Id");
|
||||
}
|
||||
|
||||
ReplaceEntityPermissions(entity);
|
||||
}
|
||||
|
||||
private static IEnumerable<EntityPermission> ConvertToPermissionList(IEnumerable<UserGroup2NodePermissionDto> result)
|
||||
{
|
||||
var permissions = new List<EntityPermission>();
|
||||
var nodePermissions = result.GroupBy(x => x.NodeId);
|
||||
foreach (var np in nodePermissions)
|
||||
{
|
||||
var userGroupPermissions = np.GroupBy(x => x.UserGroupId);
|
||||
foreach (var permission in userGroupPermissions)
|
||||
{
|
||||
var perms = permission.Select(x => x.Permission).ToArray();
|
||||
permissions.Add(new EntityPermission(permission.Key, np.Key, perms));
|
||||
}
|
||||
}
|
||||
|
||||
return permissions;
|
||||
}
|
||||
|
||||
public static event TypedEventHandler<PermissionRepository<TEntity>, SaveEventArgs<EntityPermission>> AssignedPermissions;
|
||||
}
|
||||
}
|
||||
@@ -66,7 +66,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
return Database.Fetch<TDto>(sql).Select(ConvertToEntity);
|
||||
}
|
||||
|
||||
protected override sealed IEnumerable<TEntity> PerformGetByQuery(IQuery<TEntity> query)
|
||||
protected sealed override IEnumerable<TEntity> PerformGetByQuery(IQuery<TEntity> query)
|
||||
{
|
||||
var sqlClause = GetBaseQuery(false);
|
||||
var translator = new SqlTranslator<TEntity>(sqlClause, query);
|
||||
@@ -76,22 +76,22 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
|
||||
#region Not implemented and not required
|
||||
|
||||
protected override sealed IEnumerable<string> GetDeleteClauses()
|
||||
protected sealed override IEnumerable<string> GetDeleteClauses()
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override sealed Guid NodeObjectTypeId
|
||||
protected sealed override Guid NodeObjectTypeId
|
||||
{
|
||||
get { throw new NotImplementedException(); }
|
||||
}
|
||||
|
||||
protected override sealed void PersistNewItem(TEntity entity)
|
||||
protected sealed override void PersistNewItem(TEntity entity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
protected override sealed void PersistUpdatedItem(TEntity entity)
|
||||
protected sealed override void PersistUpdatedItem(TEntity entity)
|
||||
{
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
@@ -22,12 +22,14 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
{
|
||||
private readonly CacheHelper _cacheHelper;
|
||||
private readonly UserGroupWithUsersRepository _userGroupWithUsersRepository;
|
||||
private readonly PermissionRepository<IContent> _permissionRepository;
|
||||
|
||||
public UserGroupRepository(IScopeUnitOfWork work, CacheHelper cacheHelper, ILogger logger, ISqlSyntaxProvider sqlSyntax)
|
||||
: base(work, cacheHelper, logger, sqlSyntax)
|
||||
{
|
||||
_cacheHelper = cacheHelper;
|
||||
_userGroupWithUsersRepository = new UserGroupWithUsersRepository(this, work, cacheHelper, logger, sqlSyntax);
|
||||
_permissionRepository = new PermissionRepository<IContent>(work, _cacheHelper, logger, sqlSyntax);
|
||||
}
|
||||
|
||||
public const string GetByAliasCacheKeyPrefix = "UserGroupRepository_GetByAlias_";
|
||||
@@ -97,8 +99,33 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entityIds">Array of entity Ids, if empty will return permissions for the group for all entities</param>
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntities(int groupId, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
return repo.GetPermissionsForEntities(groupId, entityIds);
|
||||
return _permissionRepository.GetPermissionsForEntities(groupId, 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="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 IEnumerable<EntityPermission> GetPermissionsForEntities(IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
|
||||
{
|
||||
if (group == null) throw new ArgumentNullException("group");
|
||||
|
||||
var explicitPermissions = GetPermissionsForEntities(group.Id, nodeIds);
|
||||
var result = new List<EntityPermission>(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)
|
||||
{
|
||||
result.AddRange(missingIds
|
||||
.Select(i => new EntityPermission(group.Id, i, group.Permissions.ToArray(), isDefaultPermissions: true)));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -109,8 +136,7 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entityIds">Specify the nodes to replace permissions for. If nothing is specified all permissions are removed.</param>
|
||||
public void ReplaceGroupPermissions(int groupId, IEnumerable<char> permissions, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
repo.ReplacePermissions(groupId, permissions, entityIds);
|
||||
_permissionRepository.ReplacePermissions(groupId, permissions, entityIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -121,9 +147,8 @@ namespace Umbraco.Core.Persistence.Repositories
|
||||
/// <param name="entityIds">Specify the nodes to replace permissions for</param>
|
||||
public void AssignGroupPermission(int groupId, char permission, params int[] entityIds)
|
||||
{
|
||||
var repo = new PermissionRepository<IContent>(UnitOfWork, _cacheHelper, SqlSyntax);
|
||||
repo.AssignPermission(groupId, permission, entityIds);
|
||||
}
|
||||
_permissionRepository.AssignPermission(groupId, permission, entityIds);
|
||||
}
|
||||
|
||||
#region Overrides of RepositoryBase<int,IUserType>
|
||||
|
||||
|
||||
@@ -130,11 +130,11 @@ namespace Umbraco.Core.Services
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions directly assigned to the content item for all user groups
|
||||
/// Returns implicit/inherited permissions assigned to the content item for all user groups
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
public IEnumerable<UserGroupEntityPermission> GetPermissionsForEntity(IContent content)
|
||||
public IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content)
|
||||
{
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
@@ -1671,9 +1671,21 @@ namespace Umbraco.Core.Services
|
||||
// Update the create author and last edit author
|
||||
copy.CreatorId = userId;
|
||||
copy.WriterId = userId;
|
||||
|
||||
//get the current permissions, if there are any explicit ones they need to be copied
|
||||
var currentPermissions = GetPermissionsForEntity(content)
|
||||
.Where(x => x.IsDefaultPermissions == false).ToArray();
|
||||
|
||||
repository.AddOrUpdate(copy);
|
||||
repository.AddOrUpdatePreviewXml(copy, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
|
||||
repository.AddOrUpdatePreviewXml(copy, c => _entitySerializer.Serialize(this, _dataTypeService, _userService, c));
|
||||
|
||||
//add permissions
|
||||
if (currentPermissions.Length > 0)
|
||||
{
|
||||
var permissionSet = new ContentPermissionSet(copy, currentPermissions);
|
||||
repository.AddOrUpdatePermissions(permissionSet);
|
||||
}
|
||||
|
||||
uow.Commit(); // todo - this should flush, not commit
|
||||
|
||||
//Special case for the associated tags
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="contentId"></param>
|
||||
public static void RemoveContentPermissions(this IContentService contentService, int contentId)
|
||||
{
|
||||
contentService.ReplaceContentPermissions(new EntityPermissionSet(contentId, Enumerable.Empty<EntityPermissionSet.UserGroupPermission>()));
|
||||
contentService.ReplaceContentPermissions(new EntityPermissionSet(contentId, Enumerable.Empty<EntityPermission>()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -151,11 +151,11 @@ namespace Umbraco.Core.Services
|
||||
void AssignContentPermission(IContent entity, char permission, IEnumerable<int> groupIds);
|
||||
|
||||
/// <summary>
|
||||
/// Returns permissions directly assigned to the content item for all user groups
|
||||
/// Returns implicit/inherited permissions assigned to the content item for all user groups
|
||||
/// </summary>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
IEnumerable<UserGroupEntityPermission> GetPermissionsForEntity(IContent content);
|
||||
IEnumerable<EntityPermission> GetPermissionsForEntity(IContent content);
|
||||
|
||||
bool SendToPublication(IContent content, int userId = 0);
|
||||
|
||||
|
||||
@@ -102,8 +102,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="group">Group to retrieve permissions for</param>
|
||||
/// <param name="fallbackToDefaultPermissions">
|
||||
/// Flag indicating if we want to get just the permissions directly assigned for the group and path,
|
||||
/// or fall back to the group's default permissions when nothing is directly assigned
|
||||
/// Flag indicating if we want to include the default group permissions for each result if there are not explicit permissions set
|
||||
/// </param>
|
||||
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
|
||||
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
|
||||
@@ -114,16 +113,15 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="user">User to check permissions for</param>
|
||||
/// <param name="path">Path to check permissions for</param>
|
||||
EntityPermissionSet GetPermissionsForPath(IUser user, string path);
|
||||
|
||||
EntityPermissionSet GetPermissionsForPath(IUser user, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the permissions for the provided group and path
|
||||
/// </summary>
|
||||
/// <param name="group">Group to check permissions for</param>
|
||||
/// <param name="path">Path to check permissions for</param>
|
||||
/// <param name="fallbackToDefaultPermissions">
|
||||
/// Flag indicating if we want to get just the permissions directly assigned for the group and path,
|
||||
/// or fall back to the group's default permissions when nothing is directly assigned
|
||||
/// Flag indicating if we want to include the default group permissions for each result if there are not explicit permissions set
|
||||
/// </param>
|
||||
EntityPermission GetPermissionsForPath(IUserGroup group, string path, bool fallbackToDefaultPermissions = false);
|
||||
|
||||
|
||||
@@ -865,21 +865,18 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="group">Group to retrieve permissions for</param>
|
||||
/// <param name="fallbackToDefaultPermissions">
|
||||
/// Flag indicating if we want to get just the permissions directly assigned for the group and path,
|
||||
/// or fall back to the group's default permissions when nothing is directly assigned
|
||||
/// Flag indicating if we want to include the default group permissions for each result if there are not explicit permissions set
|
||||
/// </param>
|
||||
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
|
||||
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
|
||||
private IEnumerable<EntityPermission> GetPermissions(IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
|
||||
{
|
||||
if (group == null) throw new ArgumentNullException("group");
|
||||
if (nodeIds.Length == 0)
|
||||
return Enumerable.Empty<EntityPermission>();
|
||||
|
||||
if (group == null) throw new ArgumentNullException("group");
|
||||
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
return GetPermissionsInternal(repository, group, fallbackToDefaultPermissions, nodeIds);
|
||||
return repository.GetPermissionsForEntities(group, fallbackToDefaultPermissions, nodeIds);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -888,8 +885,7 @@ namespace Umbraco.Core.Services
|
||||
/// </summary>
|
||||
/// <param name="group">Group to retrieve permissions for</param>
|
||||
/// <param name="fallbackToDefaultPermissions">
|
||||
/// Flag indicating if we want to get just the permissions directly assigned for the group and path,
|
||||
/// or fall back to the group's default permissions when nothing is directly assigned
|
||||
/// Flag indicating if we want to include the default group permissions for each result if there are not explicit permissions set
|
||||
/// </param>
|
||||
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
|
||||
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
|
||||
@@ -899,28 +895,8 @@ namespace Umbraco.Core.Services
|
||||
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
|
||||
{
|
||||
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
|
||||
return GetPermissionsInternal(repository, group.ToReadOnlyGroup(), fallbackToDefaultPermissions, nodeIds);
|
||||
return repository.GetPermissionsForEntities(group.ToReadOnlyGroup(), fallbackToDefaultPermissions, nodeIds);
|
||||
}
|
||||
}
|
||||
|
||||
private static IEnumerable<EntityPermission> GetPermissionsInternal(IUserGroupRepository repository, IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
|
||||
{
|
||||
if (group == null) throw new ArgumentNullException("group");
|
||||
|
||||
var explicitPermissions = repository.GetPermissionsForEntities(group.Id, nodeIds);
|
||||
var result = new List<EntityPermission>(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)
|
||||
{
|
||||
result.AddRange(missingIds
|
||||
.Select(i => new EntityPermission(i, group.Permissions.ToArray(), isDefaultPermissions: true)));
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -952,49 +928,18 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="path">Path to check permissions for</param>
|
||||
public EntityPermissionSet GetPermissionsForPath(IUser user, string path)
|
||||
{
|
||||
var nodeIds = GetIdsFromPath(path);
|
||||
var nodeIds = path.GetIdsFromPathReversed();
|
||||
|
||||
if (nodeIds.Length == 0)
|
||||
return EntityPermissionSet.Empty();
|
||||
|
||||
var permissionsByGroup = GetPermissionsForGroupsAndPath(user.Groups, nodeIds);
|
||||
|
||||
// not sure this will ever happen, it shouldn't since this should return defaults, but maybe those are empty?
|
||||
if (permissionsByGroup.Count == 0)
|
||||
return EntityPermissionSet.Empty();
|
||||
|
||||
var entityId = nodeIds[0];
|
||||
|
||||
var groupPermissions = new List<EntityPermissionSet.UserGroupPermission>();
|
||||
foreach (var entityPermission in permissionsByGroup)
|
||||
{
|
||||
var groupId = entityPermission.Key;
|
||||
foreach (var assignedPermission in entityPermission.Value.AssignedPermissions)
|
||||
{
|
||||
groupPermissions.Add(new EntityPermissionSet.UserGroupPermission(groupId, assignedPermission));
|
||||
}
|
||||
}
|
||||
|
||||
var permissionSet = new EntityPermissionSet(entityId, groupPermissions);
|
||||
return permissionSet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the permissions assigned to each group for a given path
|
||||
/// </summary>
|
||||
/// <param name="groups">List of groups associated with the user</param>
|
||||
/// <param name="pathIds">Path to check permissions for</param>
|
||||
/// <returns>A dictionary of group ids and their associated node permissions</returns>
|
||||
private IDictionary<int, EntityPermission> GetPermissionsForGroupsAndPath(IEnumerable<IReadOnlyUserGroup> groups, int[] pathIds)
|
||||
{
|
||||
return groups
|
||||
.Select(g => new
|
||||
{
|
||||
group = g.Id,
|
||||
permissions = GetPermissionsForPath(g, pathIds, fallbackToDefaultPermissions: true)
|
||||
})
|
||||
.ToDictionary(x => x.group, x => x.permissions);
|
||||
}
|
||||
//collect all permissions structures for all nodes for all groups belonging to the user
|
||||
var groupPermissions = user.Groups
|
||||
.Select(g => GetPermissionsForPath(g, nodeIds, fallbackToDefaultPermissions: true))
|
||||
.ToArray();
|
||||
|
||||
return CalculatePermissionsForPathForUser(groupPermissions, nodeIds);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the permissions for the provided group and path
|
||||
@@ -1002,13 +947,12 @@ namespace Umbraco.Core.Services
|
||||
/// <param name="group">Group to check permissions for</param>
|
||||
/// <param name="path">Path to check permissions for</param>
|
||||
/// <param name="fallbackToDefaultPermissions">
|
||||
/// Flag indicating if we want to get just the permissions directly assigned for the group and path,
|
||||
/// or fall back to the group's default permissions when nothing is directly assigned
|
||||
/// Flag indicating if we want to include the default group permissions for each result if there are not explicit permissions set
|
||||
/// </param>
|
||||
/// <returns>String indicating permissions for provided user and path</returns>
|
||||
public EntityPermission GetPermissionsForPath(IUserGroup group, string path, bool fallbackToDefaultPermissions = false)
|
||||
{
|
||||
var nodeIds = GetIdsFromPath(path);
|
||||
var nodeIds = path.GetIdsFromPathReversed();
|
||||
return GetPermissionsForPath(group.ToReadOnlyGroup(), nodeIds, fallbackToDefaultPermissions);
|
||||
}
|
||||
|
||||
@@ -1016,17 +960,91 @@ namespace Umbraco.Core.Services
|
||||
{
|
||||
//get permissions for all nodes in the path
|
||||
var permissions = GetPermissions(group, fallbackToDefaultPermissions, pathIds);
|
||||
return GetPermissionsForPath(permissions, pathIds, fallbackToDefaultPermissions);
|
||||
}
|
||||
|
||||
return GetPermissionsForPathForGroup(permissions, pathIds, fallbackToDefaultPermissions);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the permissions for the path ids
|
||||
/// This performs the calculations for inherited nodes based on this http://issues.umbraco.org/issue/U4-10075#comment=67-40085
|
||||
/// </summary>
|
||||
/// <param name="pathPermissions"></param>
|
||||
/// <param name="pathIds">Must be ordered deepest to shallowest (right to left)</param>
|
||||
/// <param name="fallbackToDefaultPermissions"></param>
|
||||
/// <param name="groupPermissions"></param>
|
||||
/// <param name="pathIds"></param>
|
||||
/// <returns></returns>
|
||||
private static EntityPermission GetPermissionsForPath(
|
||||
internal static EntityPermissionSet CalculatePermissionsForPathForUser(
|
||||
EntityPermission[] groupPermissions,
|
||||
int[] pathIds)
|
||||
{
|
||||
// not sure this will ever happen, it shouldn't since this should return defaults, but maybe those are empty?
|
||||
if (groupPermissions.Length == 0 || pathIds.Length == 0)
|
||||
return EntityPermissionSet.Empty();
|
||||
|
||||
//The actual entity id being looked at (deepest part of the path)
|
||||
var entityId = pathIds[0];
|
||||
|
||||
var resultPermissions = new List<EntityPermission>();
|
||||
|
||||
//create a grouped by dictionary of another grouped by dictionary
|
||||
var permissionsByGroup = groupPermissions
|
||||
.GroupBy(x => x.UserGroupId)
|
||||
.ToDictionary(
|
||||
x => x.Key,
|
||||
x => x.GroupBy(a => a.EntityId).ToDictionary(a => a.Key, a => a.ToArray()));
|
||||
|
||||
//iterate through each group
|
||||
foreach (var byGroup in permissionsByGroup)
|
||||
{
|
||||
var added = false;
|
||||
|
||||
//iterate deepest to shallowest
|
||||
foreach (var pathId in pathIds)
|
||||
{
|
||||
EntityPermission[] permissionsForNodeAndGroup;
|
||||
if (byGroup.Value.TryGetValue(pathId, out permissionsForNodeAndGroup) == false)
|
||||
continue;
|
||||
|
||||
//In theory there will only be one EntityPermission in this group
|
||||
// but there's nothing stopping the logic of this method
|
||||
// from having more so we deal with it here
|
||||
foreach (var entityPermission in permissionsForNodeAndGroup)
|
||||
{
|
||||
if (entityPermission.IsDefaultPermissions == false)
|
||||
{
|
||||
//explicit permision found so we'll append it and move on, of course if there was two explicit permissions
|
||||
//found for this group the ones after this one wouldn't matter but considering there should only be one per
|
||||
//group anyways, that is fine.
|
||||
resultPermissions.Add(entityPermission);
|
||||
added = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//if the permission has been added for this group and this branch then we can exit this loop
|
||||
if (added)
|
||||
break;
|
||||
}
|
||||
|
||||
if (added == false && byGroup.Value.Count > 0)
|
||||
{
|
||||
//if there was no explicit permissions assigned in this branch for this group, then we will
|
||||
//add the group's default permissions
|
||||
resultPermissions.Add(byGroup.Value[entityId][0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
var permissionSet = new EntityPermissionSet(entityId, resultPermissions);
|
||||
return permissionSet;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns the resulting permission set for a group for the path based on all permissions provided for the branch
|
||||
/// </summary>
|
||||
/// <param name="pathPermissions">The collective set of permissions provided to calculate the resulting permissions set for the path</param>
|
||||
/// <param name="pathIds">Must be ordered deepest to shallowest (right to left)</param>
|
||||
/// <param name="fallbackToDefaultPermissions">
|
||||
/// Flag indicating if we want to include the default group permissions for each result if there are not explicit permissions set
|
||||
/// </param>
|
||||
/// <returns></returns>
|
||||
internal static EntityPermission GetPermissionsForPathForGroup(
|
||||
IEnumerable<EntityPermission> pathPermissions,
|
||||
int[] pathIds,
|
||||
bool fallbackToDefaultPermissions = false)
|
||||
@@ -1051,24 +1069,8 @@ namespace Umbraco.Core.Services
|
||||
return null;
|
||||
|
||||
return permissionsByEntityId[pathIds[0]];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a path to node ids in the order from right to left (deepest to shallowest)
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
private int[] GetIdsFromPath(string path)
|
||||
{
|
||||
var nodeIds = path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => x.TryConvertTo<int>())
|
||||
.Where(x => x.Success)
|
||||
.Select(x => x.Result)
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Checks in a set of permissions associated with a user for those related to a given nodeId
|
||||
/// </summary>
|
||||
|
||||
@@ -41,6 +41,22 @@ namespace Umbraco.Core
|
||||
ToCSharpEscapeChars[escape[0]] = escape[1];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Convert a path to node ids in the order from right to left (deepest to shallowest)
|
||||
/// </summary>
|
||||
/// <param name="path"></param>
|
||||
/// <returns></returns>
|
||||
internal static int[] GetIdsFromPathReversed(this string path)
|
||||
{
|
||||
var nodeIds = path.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries)
|
||||
.Select(x => x.TryConvertTo<int>())
|
||||
.Where(x => x.Success)
|
||||
.Select(x => x.Result)
|
||||
.Reverse()
|
||||
.ToArray();
|
||||
return nodeIds;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Removes new lines and tabs
|
||||
/// </summary>
|
||||
|
||||
@@ -345,6 +345,7 @@
|
||||
<Compile Include="HashCodeHelper.cs" />
|
||||
<Compile Include="IHttpContextAccessor.cs" />
|
||||
<Compile Include="Models\EntityBase\IDeletableEntity.cs" />
|
||||
<Compile Include="Models\Membership\ContentPermissionSet.cs" />
|
||||
<Compile Include="Models\Membership\IReadOnlyUserGroup.cs" />
|
||||
<Compile Include="Models\Membership\ReadOnlyUserGroup.cs" />
|
||||
<Compile Include="Models\Membership\UserGroupExtensions.cs" />
|
||||
@@ -456,7 +457,6 @@
|
||||
<Compile Include="Models\IServerRegistration.cs" />
|
||||
<Compile Include="Models\IXsltFile.cs" />
|
||||
<Compile Include="Models\Mapping\MappingExpressionExtensions.cs" />
|
||||
<Compile Include="Models\Membership\UserGroupEntityPermission.cs" />
|
||||
<Compile Include="Models\Membership\IUserGroup.cs" />
|
||||
<Compile Include="Models\MigrationEntry.cs" />
|
||||
<Compile Include="Models\PartialViewType.cs" />
|
||||
@@ -588,6 +588,7 @@
|
||||
<Compile Include="Persistence\Relators\UserGroupSectionRelator.cs" />
|
||||
<Compile Include="Persistence\Repositories\AuditRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\BaseQueryType.cs" />
|
||||
<Compile Include="Persistence\Repositories\ContentBlueprintRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\EntityContainerRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\DomainRepository.cs" />
|
||||
<Compile Include="Persistence\Repositories\ExternalLoginRepository.cs" />
|
||||
|
||||
@@ -533,48 +533,7 @@ namespace Umbraco.Tests.Persistence.Repositories
|
||||
Assert.AreEqual(dateValue, persistedTextpage.GetValue(dateTimePropertyAlias));
|
||||
Assert.AreEqual(persistedTextpage.GetValue(dateTimePropertyAlias), textpage.GetValue(dateTimePropertyAlias));
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ensures_Permissions_Are_Set_If_Parent_Entity_Permissions_Exist()
|
||||
{
|
||||
// Arrange
|
||||
var provider = new PetaPocoUnitOfWorkProvider(Logger);
|
||||
var unitOfWork = provider.GetUnitOfWork();
|
||||
|
||||
using (var repository = CreateUserGroupRepository(unitOfWork))
|
||||
{
|
||||
var userGroup = MockedUserGroup.CreateUserGroup("1");
|
||||
repository.AddOrUpdate(userGroup);
|
||||
unitOfWork.Commit();
|
||||
}
|
||||
|
||||
ContentTypeRepository contentTypeRepository;
|
||||
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
|
||||
{
|
||||
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
|
||||
contentType.AllowedContentTypes = new List<ContentTypeSort>
|
||||
{
|
||||
new ContentTypeSort(new Lazy<int>(() => contentType.Id), 0, contentType.Alias)
|
||||
};
|
||||
var parentPage = MockedContent.CreateSimpleContent(contentType);
|
||||
contentTypeRepository.AddOrUpdate(contentType);
|
||||
repository.AddOrUpdate(parentPage);
|
||||
unitOfWork.Commit();
|
||||
|
||||
// Act
|
||||
repository.AssignEntityPermission(parentPage, 'A', new[] { 1 });
|
||||
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
|
||||
repository.AddOrUpdate(childPage);
|
||||
unitOfWork.Commit();
|
||||
|
||||
// Assert
|
||||
var permissions = repository.GetPermissionsForEntity(childPage.Id);
|
||||
Assert.AreEqual(1, permissions.Count());
|
||||
Assert.AreEqual("A", permissions.Single().AssignedPermissions.First());
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Can_Perform_Add_On_ContentRepository()
|
||||
|
||||
@@ -1459,7 +1459,7 @@ namespace Umbraco.Tests.Services
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ensures_Permissions_Are_Set_On_Copied_Entity_To_Parent_Without_Permissions()
|
||||
public void Ensures_Permissions_Are_Retained_For_Copied_Descendants_With_Explicit_Permissions()
|
||||
{
|
||||
// Arrange
|
||||
var userGroup = MockedUserGroup.CreateUserGroup("1");
|
||||
@@ -1472,27 +1472,28 @@ namespace Umbraco.Tests.Services
|
||||
};
|
||||
ServiceContext.ContentTypeService.Save(contentType);
|
||||
|
||||
var parentPage = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage);
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage, 'A', new[] { 1 });
|
||||
var parentPage = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage);
|
||||
|
||||
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
|
||||
ServiceContext.ContentService.Save(childPage);
|
||||
|
||||
//Ok, now copy, what should happen is the childPage will not have any permissions assigned since it's new parent
|
||||
//doesn't have any assigned
|
||||
ServiceContext.ContentService.Save(childPage);
|
||||
//assign explicit permissions to the child
|
||||
ServiceContext.ContentService.AssignContentPermission(childPage, 'A', new[] { userGroup.Id });
|
||||
|
||||
//Ok, now copy, what should happen is the childPage will retain it's own permissions
|
||||
var parentPage2 = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage2);
|
||||
|
||||
var copy = ServiceContext.ContentService.Copy(childPage, parentPage2.Id, false, true);
|
||||
|
||||
//Re-get the permissions, since there was none assigned to the new parent, the child shouldn't have any directly assigned
|
||||
var copyPermissions = ServiceContext.ContentService.GetPermissionsForEntity(copy);
|
||||
Assert.AreEqual(0, copyPermissions.Count());
|
||||
//get the permissions and verify
|
||||
var permissions = ServiceContext.UserService.GetPermissionsForPath(userGroup, copy.Path, fallbackToDefaultPermissions: true);
|
||||
Assert.AreEqual(1, permissions.AssignedPermissions.Length);
|
||||
Assert.AreEqual("A", permissions.AssignedPermissions[0]);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ensures_Permissions_Are_Set_On_Copied_Entity_To_Parent_With_Permissions()
|
||||
public void Ensures_Permissions_Are_Inherited_For_Copied_Descendants()
|
||||
{
|
||||
// Arrange
|
||||
var userGroup = MockedUserGroup.CreateUserGroup("1");
|
||||
@@ -1507,88 +1508,8 @@ namespace Umbraco.Tests.Services
|
||||
|
||||
var parentPage = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage);
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage, 'A', new[] { 1 });
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage, 'A', new[] { userGroup.Id });
|
||||
|
||||
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
|
||||
ServiceContext.ContentService.Save(childPage);
|
||||
|
||||
//Ok, now copy, what should happen is the childPage will have it's new parent permissions copied over
|
||||
var parentPage2 = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage2);
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage2, 'B', new[] { 1 });
|
||||
|
||||
var copy = ServiceContext.ContentService.Copy(childPage, parentPage2.Id, false, true);
|
||||
|
||||
//Re-get the permissions, since there was none assigned to the new parent, the child shouldn't have any directly assigned
|
||||
var copyPermissions = ServiceContext.ContentService.GetPermissionsForEntity(copy);
|
||||
Assert.AreEqual(1, copyPermissions.Count());
|
||||
Assert.AreEqual("B", copyPermissions.Single().AssignedPermissions.First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ensures_Permissions_Are_Set_On_Copied_Descendants_To_Parent_With_Permissions()
|
||||
{
|
||||
// Arrange
|
||||
var userGroup = MockedUserGroup.CreateUserGroup("1");
|
||||
ServiceContext.UserService.Save(userGroup);
|
||||
|
||||
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
|
||||
contentType.AllowedContentTypes = new List<ContentTypeSort>
|
||||
{
|
||||
new ContentTypeSort(new Lazy<int>(() => contentType.Id), 0, contentType.Alias)
|
||||
};
|
||||
ServiceContext.ContentTypeService.Save(contentType);
|
||||
|
||||
var parentPage = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage);
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage, 'A', new[] { 1 });
|
||||
|
||||
var childPage1 = MockedContent.CreateSimpleContent(contentType, "child1", parentPage);
|
||||
ServiceContext.ContentService.Save(childPage1);
|
||||
var childPage2 = MockedContent.CreateSimpleContent(contentType, "child2", childPage1);
|
||||
ServiceContext.ContentService.Save(childPage2);
|
||||
var childPage3 = MockedContent.CreateSimpleContent(contentType, "child3", childPage2);
|
||||
ServiceContext.ContentService.Save(childPage3);
|
||||
|
||||
//Ok, now copy, what should happen is the childPage will have it's new parent permissions copied over
|
||||
var parentPage2 = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage2);
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage2, 'B', new[] { 1 });
|
||||
|
||||
var copy = ServiceContext.ContentService.Copy(childPage1, parentPage2.Id, false, true);
|
||||
|
||||
//Re-get the permissions, since there was none assigned to the new parent, the child shouldn't have any directly assigned
|
||||
var copyPermissions = ServiceContext.ContentService.GetPermissionsForEntity(copy);
|
||||
Assert.AreEqual(1, copyPermissions.Count());
|
||||
Assert.AreEqual("B", copyPermissions.Single().AssignedPermissions.First());
|
||||
|
||||
var descendants = ServiceContext.ContentService.GetDescendants(copy).ToArray();
|
||||
Assert.AreEqual(2, descendants.Length);
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
var permissions = ServiceContext.ContentService.GetPermissionsForEntity(descendant);
|
||||
Assert.AreEqual(1, permissions.Count());
|
||||
Assert.AreEqual("B", permissions.Single().AssignedPermissions.First());
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Ensures_Permissions_Are_Set_On_Descendants_When_Permissions_Added()
|
||||
{
|
||||
// Arrange
|
||||
var userGroup = MockedUserGroup.CreateUserGroup("1");
|
||||
ServiceContext.UserService.Save(userGroup);
|
||||
|
||||
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
|
||||
contentType.AllowedContentTypes = new List<ContentTypeSort>
|
||||
{
|
||||
new ContentTypeSort(new Lazy<int>(() => contentType.Id), 0, contentType.Alias)
|
||||
};
|
||||
ServiceContext.ContentTypeService.Save(contentType);
|
||||
|
||||
var parentPage = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage);
|
||||
var childPage1 = MockedContent.CreateSimpleContent(contentType, "child1", parentPage);
|
||||
ServiceContext.ContentService.Save(childPage1);
|
||||
var childPage2 = MockedContent.CreateSimpleContent(contentType, "child2", childPage1);
|
||||
@@ -1596,37 +1517,33 @@ namespace Umbraco.Tests.Services
|
||||
var childPage3 = MockedContent.CreateSimpleContent(contentType, "child3", childPage2);
|
||||
ServiceContext.ContentService.Save(childPage3);
|
||||
|
||||
//ensure there are no permissions on any node
|
||||
|
||||
var permissions = ServiceContext.ContentService.GetPermissionsForEntity(parentPage);
|
||||
Assert.AreEqual(0, permissions.Count());
|
||||
|
||||
//Verify that the children have the inherited permissions
|
||||
var descendants = ServiceContext.ContentService.GetDescendants(parentPage).ToArray();
|
||||
Assert.AreEqual(3, descendants.Length);
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
permissions = ServiceContext.ContentService.GetPermissionsForEntity(descendant);
|
||||
Assert.AreEqual(0, permissions.Count());
|
||||
var permissions = ServiceContext.UserService.GetPermissionsForPath(userGroup, descendant.Path, fallbackToDefaultPermissions:true);
|
||||
Assert.AreEqual(1, permissions.AssignedPermissions.Length);
|
||||
Assert.AreEqual("A", permissions.AssignedPermissions[0]);
|
||||
}
|
||||
|
||||
//Ok, now assign permissions to the parent, all descenents should get these right?
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage, 'A', new[] { 1 });
|
||||
|
||||
//re-test
|
||||
|
||||
permissions = ServiceContext.ContentService.GetPermissionsForEntity(parentPage);
|
||||
Assert.AreEqual(1, permissions.Count());
|
||||
Assert.AreEqual("A", permissions.Single().AssignedPermissions.First());
|
||||
//create a new parent with a new permission structure
|
||||
var parentPage2 = MockedContent.CreateSimpleContent(contentType);
|
||||
ServiceContext.ContentService.Save(parentPage2);
|
||||
ServiceContext.ContentService.AssignContentPermission(parentPage2, 'B', new[] { userGroup.Id });
|
||||
|
||||
descendants = ServiceContext.ContentService.GetDescendants(parentPage).ToArray();
|
||||
//Now copy, what should happen is the child pages will now have permissions inherited from the new parent
|
||||
var copy = ServiceContext.ContentService.Copy(childPage1, parentPage2.Id, false, true);
|
||||
|
||||
descendants = ServiceContext.ContentService.GetDescendants(parentPage2).ToArray();
|
||||
Assert.AreEqual(3, descendants.Length);
|
||||
|
||||
foreach (var descendant in descendants)
|
||||
{
|
||||
permissions = ServiceContext.ContentService.GetPermissionsForEntity(descendant);
|
||||
Assert.AreEqual(1, permissions.Count());
|
||||
Assert.AreEqual("A", permissions.Single().AssignedPermissions.First());
|
||||
var permissions = ServiceContext.UserService.GetPermissionsForPath(userGroup, descendant.Path, fallbackToDefaultPermissions: true);
|
||||
Assert.AreEqual(1, permissions.AssignedPermissions.Length);
|
||||
Assert.AreEqual("B", permissions.AssignedPermissions[0]);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
@@ -10,6 +11,7 @@ using Umbraco.Core.Persistence.Querying;
|
||||
using Umbraco.Tests.TestHelpers;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Tests.Services
|
||||
{
|
||||
@@ -151,7 +153,7 @@ namespace Umbraco.Tests.Services
|
||||
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
|
||||
|
||||
// Act
|
||||
var permissions = userService.GetPermissions(userGroup, true, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id)
|
||||
var permissions = userService.GetPermissions(userGroup, true, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id)
|
||||
.ToArray();
|
||||
|
||||
//assert
|
||||
@@ -161,6 +163,132 @@ namespace Umbraco.Tests.Services
|
||||
Assert.AreEqual(17,permissions[2].AssignedPermissions.Length);
|
||||
}
|
||||
|
||||
[Test]
|
||||
|
||||
[Test]
|
||||
public void Calculate_Permissions_For_User_For_Path_1()
|
||||
{
|
||||
//see: http://issues.umbraco.org/issue/U4-10075#comment=67-40085
|
||||
// for an overview of what this is testing
|
||||
|
||||
const string path = "-1,1,2,3,4";
|
||||
var pathIds = path.GetIdsFromPathReversed();
|
||||
|
||||
const int groupA = 7;
|
||||
const int groupB = 8;
|
||||
const int groupC = 9;
|
||||
|
||||
var userGroups = new Dictionary<int, string[]>
|
||||
{
|
||||
{groupA, new[] {"S", "D", "F"}},
|
||||
{groupB, new[] {"S", "D", "G", "K"}},
|
||||
{groupC, new[] {"F", "G"}}
|
||||
};
|
||||
|
||||
var permissions = new []
|
||||
{
|
||||
new EntityPermission(groupA, 1, userGroups[groupA], isDefaultPermissions:true),
|
||||
new EntityPermission(groupA, 2, userGroups[groupA], isDefaultPermissions:true),
|
||||
new EntityPermission(groupA, 3, userGroups[groupA], isDefaultPermissions:true),
|
||||
new EntityPermission(groupA, 4, userGroups[groupA], isDefaultPermissions:true),
|
||||
|
||||
new EntityPermission(groupB, 1, userGroups[groupB], isDefaultPermissions:true),
|
||||
new EntityPermission(groupB, 2, new []{"F", "R"}, isDefaultPermissions:false),
|
||||
new EntityPermission(groupB, 3, userGroups[groupB], isDefaultPermissions:true),
|
||||
new EntityPermission(groupB, 4, userGroups[groupB], isDefaultPermissions:true),
|
||||
|
||||
new EntityPermission(groupC, 1, userGroups[groupC], isDefaultPermissions:true),
|
||||
new EntityPermission(groupC, 2, userGroups[groupC], isDefaultPermissions:true),
|
||||
new EntityPermission(groupC, 3, new []{"Q", "Z"}, isDefaultPermissions:false),
|
||||
new EntityPermission(groupC, 4, userGroups[groupC], isDefaultPermissions:true),
|
||||
};
|
||||
|
||||
//Permissions for Id 4
|
||||
var result = UserService.CalculatePermissionsForPathForUser(permissions, pathIds);
|
||||
Assert.AreEqual(4, result.EntityId);
|
||||
var allPermissions = result.GetAllPermissions().ToArray();
|
||||
Assert.AreEqual(6, allPermissions.Length, string.Join(",", allPermissions));
|
||||
Assert.IsTrue(allPermissions.ContainsAll(new[] { "S", "D", "F", "R", "Q", "Z" }));
|
||||
|
||||
//Permissions for Id 3
|
||||
result = UserService.CalculatePermissionsForPathForUser(permissions, pathIds.Skip(1).ToArray());
|
||||
Assert.AreEqual(3, result.EntityId);
|
||||
allPermissions = result.GetAllPermissions().ToArray();
|
||||
Assert.AreEqual(6, allPermissions.Length, string.Join(",", allPermissions));
|
||||
Assert.IsTrue(allPermissions.ContainsAll(new[] { "S", "D", "F", "R", "Q", "Z" }));
|
||||
|
||||
//Permissions for Id 2
|
||||
result = UserService.CalculatePermissionsForPathForUser(permissions, pathIds.Skip(2).ToArray());
|
||||
Assert.AreEqual(2, result.EntityId);
|
||||
allPermissions = result.GetAllPermissions().ToArray();
|
||||
Assert.AreEqual(5, allPermissions.Length, string.Join(",", allPermissions));
|
||||
Assert.IsTrue(allPermissions.ContainsAll(new[] { "S", "D", "F", "G", "R" }));
|
||||
|
||||
//Permissions for Id 1
|
||||
result = UserService.CalculatePermissionsForPathForUser(permissions, pathIds.Skip(3).ToArray());
|
||||
Assert.AreEqual(1, result.EntityId);
|
||||
allPermissions = result.GetAllPermissions().ToArray();
|
||||
Assert.AreEqual(5, allPermissions.Length, string.Join(",", allPermissions));
|
||||
Assert.IsTrue(allPermissions.ContainsAll(new[] { "S", "D", "F", "G", "K" }));
|
||||
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Determine_Deepest_Explicit_Permissions_For_Group_For_Path_1()
|
||||
{
|
||||
var path = "-1,1,2,3";
|
||||
var pathIds = path.GetIdsFromPathReversed();
|
||||
var defaults = new[] {"A", "B"};
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(9876, 1, defaults, isDefaultPermissions:true),
|
||||
new EntityPermission(9876, 2, new []{"B","C", "D"}, isDefaultPermissions:false),
|
||||
new EntityPermission(9876, 3, defaults, isDefaultPermissions:true)
|
||||
};
|
||||
var result = UserService.GetPermissionsForPathForGroup(permissions, pathIds, fallbackToDefaultPermissions: true);
|
||||
Assert.AreEqual(3, result.AssignedPermissions.Length);
|
||||
Assert.IsFalse(result.IsDefaultPermissions);
|
||||
Assert.IsTrue(result.AssignedPermissions.ContainsAll(new[] { "B", "C", "D" }));
|
||||
Assert.AreEqual(2, result.EntityId);
|
||||
Assert.AreEqual(9876, result.UserGroupId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Determine_Deepest_Explicit_Permissions_For_Group_For_Path_2()
|
||||
{
|
||||
var path = "-1,1,2,3";
|
||||
var pathIds = path.GetIdsFromPathReversed();
|
||||
var defaults = new[] { "A", "B", "C" };
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(9876, 1, defaults, isDefaultPermissions:true),
|
||||
new EntityPermission(9876, 2, defaults, isDefaultPermissions:true),
|
||||
new EntityPermission(9876, 3, defaults, isDefaultPermissions:true)
|
||||
};
|
||||
var result = UserService.GetPermissionsForPathForGroup(permissions, pathIds, fallbackToDefaultPermissions:false);
|
||||
Assert.IsNull(result);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Determine_Deepest_Explicit_Permissions_For_Group_For_Path_3()
|
||||
{
|
||||
var path = "-1,1,2,3";
|
||||
var pathIds = path.GetIdsFromPathReversed();
|
||||
var defaults = new[] { "A", "B" };
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(9876, 1, defaults, isDefaultPermissions:true),
|
||||
new EntityPermission(9876, 2, defaults, isDefaultPermissions:true),
|
||||
new EntityPermission(9876, 3, defaults, isDefaultPermissions:true)
|
||||
};
|
||||
var result = UserService.GetPermissionsForPathForGroup(permissions, pathIds, fallbackToDefaultPermissions: true);
|
||||
Assert.AreEqual(2, result.AssignedPermissions.Length);
|
||||
Assert.IsTrue(result.IsDefaultPermissions);
|
||||
Assert.IsTrue(result.AssignedPermissions.ContainsAll(defaults));
|
||||
Assert.AreEqual(3, result.EntityId);
|
||||
Assert.AreEqual(9876, result.UserGroupId);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Get_User_Implicit_Permissions()
|
||||
{
|
||||
|
||||
@@ -50,7 +50,8 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var contentService = contentServiceMock.Object;
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>();
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234,5678")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act/assert
|
||||
@@ -73,7 +74,8 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var contentService = contentServiceMock.Object;
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>();
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
@@ -100,9 +102,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1234, new string[]{ "A", "B", "C" })
|
||||
new EntityPermission(9876, 1234, new string[]{ "A", "B", "C" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234,5678")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
@@ -129,9 +132,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1234, new string[]{ "A", "F", "C" })
|
||||
new EntityPermission(9876, 1234, new string[]{ "A", "F", "C" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, 1234)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1,1234,5678")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
@@ -217,9 +221,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1234, new string[]{ "A" })
|
||||
new EntityPermission(9876, 1234, new string[]{ "A" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, -1)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
@@ -241,9 +246,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1234, new string[]{ "A" })
|
||||
new EntityPermission(9876, 1234, new string[]{ "A" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, -1)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-1")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
@@ -264,10 +270,12 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1234, new string[]{ "A" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, -20)).Returns(permissions);
|
||||
{
|
||||
new EntityPermission(9876, 1234, new string[]{ "A" })
|
||||
};
|
||||
var permissionSet = new EntityPermissionSet(-20, permissions);
|
||||
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-20")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
@@ -289,9 +297,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
var userServiceMock = new Mock<IUserService>();
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1234, new string[]{ "A" })
|
||||
new EntityPermission(9876, 1234, new string[]{ "A" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, -20)).Returns(permissions);
|
||||
var permissionSet = new EntityPermissionSet(1234, permissions);
|
||||
userServiceMock.Setup(x => x.GetPermissionsForPath(user, "-20")).Returns(permissionSet);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
//act
|
||||
|
||||
@@ -112,10 +112,10 @@ namespace Umbraco.Tests.Web.Controllers
|
||||
//we're only assigning 3 nodes browse permissions so that is what we expect as a result
|
||||
var permissions = new List<EntityPermission>
|
||||
{
|
||||
new EntityPermission(1, new string[]{ "F" }),
|
||||
new EntityPermission(2, new string[]{ "F" }),
|
||||
new EntityPermission(3, new string[]{ "F" }),
|
||||
new EntityPermission(4, new string[]{ "A" })
|
||||
new EntityPermission(9876, 1, new string[]{ "F" }),
|
||||
new EntityPermission(9876, 2, new string[]{ "F" }),
|
||||
new EntityPermission(9876, 3, new string[]{ "F" }),
|
||||
new EntityPermission(9876, 4, new string[]{ "A" })
|
||||
};
|
||||
userServiceMock.Setup(x => x.GetPermissions(user, ids)).Returns(permissions);
|
||||
var userService = userServiceMock.Object;
|
||||
|
||||
@@ -599,10 +599,13 @@ namespace Umbraco.Web.Cache
|
||||
|
||||
#region User/permissions event handlers
|
||||
|
||||
static void CacheRefresherEventHandler_AssignedPermissions(PermissionRepository<IContent> sender, SaveEventArgs<UserGroupEntityPermission> e)
|
||||
static void CacheRefresherEventHandler_AssignedPermissions(PermissionRepository<IContent> sender, SaveEventArgs<EntityPermission> e)
|
||||
{
|
||||
var groupIds = e.SavedEntities.Select(x => x.UserGroupId).Distinct();
|
||||
groupIds.ForEach(x => DistributedCache.Instance.RefreshUserGroupPermissionsCache(x));
|
||||
foreach (var groupId in groupIds)
|
||||
{
|
||||
DistributedCache.Instance.RefreshUserGroupPermissionsCache(groupId);
|
||||
}
|
||||
}
|
||||
|
||||
static void PermissionDeleted(UserGroupPermission sender, DeleteEventArgs e)
|
||||
|
||||
@@ -1076,17 +1076,21 @@ namespace Umbraco.Web.Editors
|
||||
return false;
|
||||
}
|
||||
|
||||
if (permissionsToCheck == null || permissionsToCheck.Any() == false)
|
||||
if (permissionsToCheck == null || permissionsToCheck.Length == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var permission = userService.GetPermissions(user, nodeId).FirstOrDefault();
|
||||
|
||||
//get the implicit/inherited permissions for the user for this path,
|
||||
//if there is no content item for this id, than just use the id as the path (i.e. -1 or -20)
|
||||
var path = contentItem != null ? contentItem.Path : nodeId.ToString();
|
||||
var permission = userService.GetPermissionsForPath(user, path);
|
||||
|
||||
var allowed = true;
|
||||
foreach (var p in permissionsToCheck)
|
||||
{
|
||||
if (permission == null || permission.AssignedPermissions.Contains(p.ToString(CultureInfo.InvariantCulture)) == false)
|
||||
if (permission == null
|
||||
|| permission.GetAllPermissions().Contains(p.ToString(CultureInfo.InvariantCulture)) == false)
|
||||
{
|
||||
allowed = false;
|
||||
}
|
||||
|
||||
@@ -572,7 +572,7 @@ namespace umbraco.BusinessLogic
|
||||
|
||||
var userService = ApplicationContext.Current.Services.UserService;
|
||||
return string.Join("",
|
||||
userService.GetPermissionsForPath(UserEntity, path).PermissionsSet.SelectMany(x => x.Permission));
|
||||
userService.GetPermissionsForPath(UserEntity, path).GetAllPermissions());
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user