Gets implicit/inherited permissions 'working', well at least with one test, now need to test the rest.

This commit is contained in:
Shannon
2017-07-11 19:19:38 +10:00
parent 50a896a6cc
commit 53bce239c3
14 changed files with 585 additions and 243 deletions

View File

@@ -11,6 +11,14 @@ namespace Umbraco.Core.Models.Membership
{
EntityId = entityId;
AssignedPermissions = assignedPermissions;
IsDefaultPermissions = false;
}
public EntityPermission(int entityId, string[] assignedPermissions, bool isDefaultPermissions)
{
EntityId = entityId;
AssignedPermissions = assignedPermissions;
IsDefaultPermissions = isDefaultPermissions;
}
public int EntityId { get; private set; }
@@ -19,6 +27,14 @@ namespace Umbraco.Core.Models.Membership
/// The assigned permissions for the user/entity combo
/// </summary>
public string[] AssignedPermissions { get; private set; }
/// <summary>
/// True if the permissions assigned to this object are the group's default permissions and not explicitly defined permissions
/// </summary>
/// <remarks>
/// This will be the case when looking up entity permissions and falling back to the default permissions
/// </remarks>
public bool IsDefaultPermissions { get; private set; }
/// <summary>
/// Adds additional permissions to an existing instance of <see cref="EntityPermission"/>

View File

@@ -18,6 +18,14 @@ namespace Umbraco.Core.Models.Membership
/// </summary>
string Alias { get; }
/// <summary>
/// The set of default permissions
/// </summary>
/// <remarks>
/// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future.
/// </remarks>
IEnumerable<string> Permissions { get; set; }
IEnumerable<string> AllowedSections { get; }
}
}

View File

@@ -5,13 +5,15 @@ namespace Umbraco.Core.Models.Membership
{
public class ReadOnlyUserGroup : IReadOnlyUserGroup, IEquatable<ReadOnlyUserGroup>
{
public ReadOnlyUserGroup(int id, string name, string icon, int? startContentId, int? startMediaId, string @alias, IEnumerable<string> allowedSections)
public ReadOnlyUserGroup(int id, string name, string icon, int? startContentId, int? startMediaId, string @alias,
IEnumerable<string> allowedSections, IEnumerable<string> permissions)
{
Name = name;
Icon = icon;
Id = id;
Alias = alias;
AllowedSections = allowedSections;
Permissions = permissions;
//Zero is invalid and will be treated as Null
StartContentId = startContentId == 0 ? null : startContentId;
@@ -24,6 +26,14 @@ namespace Umbraco.Core.Models.Membership
public int? StartContentId { get; private set; }
public int? StartMediaId { get; private set; }
public string Alias { get; private set; }
/// <summary>
/// The set of default permissions
/// </summary>
/// <remarks>
/// By default each permission is simply a single char but we've made this an enumerable{string} to support a more flexible permissions structure in the future.
/// </remarks>
public IEnumerable<string> Permissions { get; set; }
public IEnumerable<string> AllowedSections { get; private set; }
public bool Equals(ReadOnlyUserGroup other)

View File

@@ -12,7 +12,7 @@ namespace Umbraco.Core.Models.Membership
/// </summary>
[Serializable]
[DataContract(IsReference = true)]
internal class UserGroup : Entity, IUserGroup
internal class UserGroup : Entity, IUserGroup, IReadOnlyUserGroup
{
private int? _startContentId;
private int? _startMediaId;

View File

@@ -7,12 +7,17 @@ namespace Umbraco.Core.Models.Membership
{
public static IReadOnlyUserGroup ToReadOnlyGroup(this IUserGroup group)
{
return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.AllowedSections);
//this will generally always be the case
var readonlyGroup = group as IReadOnlyUserGroup;
if (readonlyGroup != null) return readonlyGroup;
//otherwise create one
return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.AllowedSections, group.Permissions);
}
public static IReadOnlyUserGroup ToReadOnlyGroup(this UserGroupDto group)
{
return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.UserGroup2AppDtos.Select(x => x.AppAlias).ToArray());
return new ReadOnlyUserGroup(group.Id, group.Name, group.Icon, group.StartContentId, group.StartMediaId, group.Alias, group.UserGroup2AppDtos.Select(x => x.AppAlias).ToArray(), group.DefaultPermissions.ToCharArray().Select(x => x.ToString()));
}
}
}

View File

@@ -470,24 +470,24 @@ namespace Umbraco.Core.Persistence.Repositories
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.Any())
{
var userGroupPermissions = (
from perm in parentPermissions
from p in perm.AssignedPermissions
select new EntityPermissionSet.UserGroupPermission(perm.UserGroupId, p)).ToList();
////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;
}
// 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;
//}
//Create the Content specific data - cmsContent
var contentDto = dto.ContentVersionDto.ContentDto;

View File

@@ -35,82 +35,68 @@ namespace Umbraco.Core.Persistence.Repositories
}
/// <summary>
/// Returns permissions for a given group for any number of nodes
/// Returns explicitly defined permissions for a user group for any number of nodes
/// </summary>
/// <param name="groupId"></param>
/// <param name="entityIds"></param>
/// <returns></returns>
public IEnumerable<EntityPermission> GetPermissionsForEntities(int groupId, params int[] entityIds)
{
var entityIdKey = GetEntityIdKey(entityIds);
return _runtimeCache.GetCacheItem<IEnumerable<EntityPermission>>(
string.Format("{0}{1}{2}",
CacheKeys.UserGroupPermissionsCacheKey,
groupId,
entityIdKey),
() =>
{
var whereCriteria = GetPermissionsForEntitiesCriteria(groupId, entityIds);
var sql = new Sql();
sql.Select("*")
.From<UserGroup2NodePermissionDto>()
.Where(whereCriteria);
var result = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql).ToArray();
// ToArray() to ensure it's all fetched from the db once
return ConvertToPermissionList(result);
},
GetCacheTimeout(),
priority: GetCachePriority());
}
private static string GetEntityIdKey(int[] entityIds)
{
return string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));
}
private string GetPermissionsForEntitiesCriteria(int groupId, params int[] entityIds)
{
var whereBuilder = new StringBuilder();
whereBuilder.Append(_sqlSyntax.GetQuotedColumnName("userGroupId"));
whereBuilder.Append("=");
whereBuilder.Append(groupId);
if (entityIds.Any())
//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
foreach (var groupOfIds in entityIds.InGroupsOf(2000))
{
whereBuilder.Append(" AND ");
var ids = groupOfIds;
//where nodeId = @nodeId1 OR nodeId = @nodeId2, etc...
whereBuilder.Append("(");
for (var index = 0; index < entityIds.Length; index++)
{
var entityId = entityIds[index];
whereBuilder.Append(_sqlSyntax.GetQuotedColumnName("nodeId"));
whereBuilder.Append("=");
whereBuilder.Append(entityId);
if (index < entityIds.Length - 1)
{
whereBuilder.Append(" OR ");
}
}
whereBuilder.Append(")");
}
return whereBuilder.ToString();
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);
result.AddRange(ConvertToPermissionList(permissions));
}
return result;
//var entityIdKey = GetEntityIdKey(entityIds);
//return _runtimeCache.GetCacheItem<IEnumerable<EntityPermission>>(
// string.Format("{0}{1}{2}",
// CacheKeys.UserGroupPermissionsCacheKey,
// groupId,
// entityIdKey),
// () =>
// {
// var whereCriteria = GetPermissionsForEntitiesCriteria(groupId, entityIds);
// var sql = new Sql();
// sql.Select("*")
// .From<UserGroup2NodePermissionDto>()
// .Where(whereCriteria);
// var result = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
// return ConvertToPermissionList(result);
// },
// GetCacheTimeout(),
// priority: GetCachePriority());
}
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 string GetEntityIdKey(int[] entityIds)
//{
// return string.Join(",", entityIds.Select(x => x.ToString(CultureInfo.InvariantCulture)));
//}
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 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)
{
@@ -142,8 +128,7 @@ namespace Umbraco.Core.Persistence.Repositories
.Where<UserGroup2NodePermissionDto>(dto => dto.NodeId == entityId)
.OrderBy<UserGroup2NodePermissionDto>(dto => dto.NodeId);
var result = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql).ToArray();
// ToArray() to ensure it's all fetched from the db once
var result = _unitOfWork.Database.Fetch<UserGroup2NodePermissionDto>(sql);
return ConvertToPermissionList(result);
}

View File

@@ -92,63 +92,63 @@ namespace Umbraco.Core.Services
/// <param name="user">User to retrieve permissions for</param>
/// <param name="nodeIds">Specifiying nothing will return all user permissions for all nodes</param>
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
/// <remarks>
/// > This is the ONLY one for permissions from 7.6!
/// </remarks>
IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds);
/// <summary>
/// Get permissions set for a group and optional node Ids
/// </summary>
/// <param name="groupAlias">Group to retrieve permissions for</param>
/// <param name="directlyAssignedOnly">
/// <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
/// </param>
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
IEnumerable<EntityPermission> GetPermissions(string groupAlias, bool directlyAssignedOnly, params int[] nodeIds);
IEnumerable<EntityPermission> GetPermissions(string groupAlias, bool fallbackToDefaultPermissions, params int[] nodeIds);
/// <summary>
/// Get permissions set for a group and optional node Ids
/// </summary>
/// <param name="group">Group to retrieve permissions for</param>
/// <param name="directlyAssignedOnly">
/// <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
/// </param>
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
IEnumerable<EntityPermission> GetPermissions(IUserGroup group, bool directlyAssignedOnly, params int[] nodeIds);
IEnumerable<EntityPermission> GetPermissions(IUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds);
/// <summary>
/// Gets the permissions for the provided user and path
/// </summary>
/// <param name="user">User to check permissions for</param>
/// <param name="path">Path to check permissions for</param>
/// <returns>String indicating permissions for provided user and path</returns>
string GetPermissionsForPath(IUser user, string path);
EntityPermissionSet GetPermissionsForPath(IUser user, string path);
/// <summary>
/// Gets the permissions for the provided group and path
/// </summary>
/// <param name="groupAlias">Group alias to check permissions for</param>
/// <param name="path">Path to check permissions for</param>
/// <param name="directlyAssignedOnly">
/// <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
/// </param>
/// <returns>String indicating permissions for provided user and path</returns>
string GetPermissionsForPath(string groupAlias, string path, bool directlyAssignedOnly = true);
EntityPermission GetPermissionsForPath(string groupAlias, string path, bool fallbackToDefaultPermissions = false);
/// <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="directlyAssignedOnly">
/// <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
/// </param>
/// <returns>String indicating permissions for provided user and path</returns>
string GetPermissionsForPath(IUserGroup group, string path, bool directlyAssignedOnly = true);
EntityPermission GetPermissionsForPath(IUserGroup group, string path, bool fallbackToDefaultPermissions = false);
/// <summary>
/// Replaces the same permission set for a single group to any number of entities

View File

@@ -121,7 +121,7 @@ namespace Umbraco.Core.Services
Language = GlobalSettings.DefaultUILanguage,
Name = username,
RawPasswordValue = passwordValue,
Username = username,
Username = username,
IsLockedOut = false,
IsApproved = isApproved
};
@@ -208,11 +208,11 @@ namespace Umbraco.Core.Services
public void Delete(IUser membershipUser)
{
//disable
membershipUser.IsApproved = false;
membershipUser.IsApproved = false;
Save(membershipUser);
}
}
/// <summary>
/// This is simply a helper method which essentially just wraps the MembershipProvider's ChangePassword method
/// </summary>
@@ -616,12 +616,12 @@ namespace Umbraco.Core.Services
{
return repository.GetAllNotInGroup(groupId);
}
}
}
#endregion
#region Implementation of IUserService
/// <summary>
/// Gets an IProfile by User Id.
/// </summary>
@@ -706,8 +706,8 @@ namespace Umbraco.Core.Services
repository.AssignGroupPermission(groupId, permission, entityIds);
uow.Commit();
}
}
}
/// <summary>
/// Gets all UserGroups or those specified as parameters
/// </summary>
@@ -720,8 +720,8 @@ namespace Umbraco.Core.Services
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
return repository.GetAll(ids).OrderBy(x => x.Name);
}
}
}
public IEnumerable<IUserGroup> GetUserGroupsByAlias(params string[] aliases)
{
if (aliases.Length == 0) return Enumerable.Empty<IUserGroup>();
@@ -788,8 +788,8 @@ namespace Umbraco.Core.Services
}
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
repository.AddOrUpdateGroupWithUsers(userGroup, userIds);
repository.AddOrUpdateGroupWithUsers(userGroup, userIds);
uow.Commit();
if (raiseEvents)
@@ -838,8 +838,8 @@ namespace Umbraco.Core.Services
uow.Commit();
//TODO: Events?
}
}
}
/// <summary>
/// Get permissions set for a user and node Id
/// </summary>
@@ -848,16 +848,19 @@ namespace Umbraco.Core.Services
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
public IEnumerable<EntityPermission> GetPermissions(IUser user, params int[] nodeIds)
{
if (nodeIds.Length == 0)
return Enumerable.Empty<EntityPermission>();
var result = new List<EntityPermission>();
foreach (var group in user.Groups)
{
//TODO: This may perform horribly :/
foreach (var permission in GetPermissions(group.Alias, false, nodeIds))
foreach (var permission in GetPermissions(group, true, nodeIds))
{
AddOrAmendPermissionList(result, permission);
}
}
}
return result;
}
@@ -865,19 +868,57 @@ namespace Umbraco.Core.Services
/// Get permissions set for a group and node Id
/// </summary>
/// <param name="groupAlias">Group to retrieve permissions for</param>
/// <param name="directlyAssignedOnly">
/// <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
/// </param>
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
public IEnumerable<EntityPermission> GetPermissions(string groupAlias, bool directlyAssignedOnly, params int[] nodeIds)
{
public IEnumerable<EntityPermission> GetPermissions(string groupAlias, bool fallbackToDefaultPermissions, params int[] nodeIds)
{
if (nodeIds.Length == 0)
return Enumerable.Empty<EntityPermission>();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
var group = repository.Get(groupAlias);
return GetPermissionsInternal(repository, group, directlyAssignedOnly, nodeIds);
if (group == null) throw new InvalidOperationException("No group found with alias " + groupAlias);
return GetPermissionsInternal(repository, group.ToReadOnlyGroup(), fallbackToDefaultPermissions, nodeIds);
}
}
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>();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
return GetPermissionsInternal(repository, group, fallbackToDefaultPermissions, nodeIds);
}
}
private IEnumerable<EntityPermission> GetPermissions(int groupId, bool fallbackToDefaultPermissions, params int[] nodeIds)
{
if (nodeIds.Length == 0)
return Enumerable.Empty<EntityPermission>();
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
if (fallbackToDefaultPermissions == false)
{
//if fallbackToDefaultPermissions is false, we don't have to lookup the group
return repository.GetPermissionsForEntities(groupId, nodeIds);
}
var group = repository.Get(groupId);
if (group == null) throw new InvalidOperationException("No group found with id " + groupId);
return GetPermissionsInternal(repository, group.ToReadOnlyGroup(), true, nodeIds);
}
}
@@ -885,35 +926,40 @@ namespace Umbraco.Core.Services
/// Get permissions set for a group and optional node Ids
/// </summary>
/// <param name="group">Group to retrieve permissions for</param>
/// <param name="directlyAssignedOnly">
/// <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
/// </param>
/// <param name="nodeIds">Specifiying nothing will return all permissions for all nodes</param>
/// <returns>An enumerable list of <see cref="EntityPermission"/></returns>
public IEnumerable<EntityPermission> GetPermissions(IUserGroup group, bool directlyAssignedOnly, params int[] nodeIds)
public IEnumerable<EntityPermission> GetPermissions(IUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
{
if (group == null) throw new ArgumentNullException("group");
using (var uow = UowProvider.GetUnitOfWork(readOnly: true))
{
var repository = RepositoryFactory.CreateUserGroupRepository(uow);
return GetPermissionsInternal(repository, group, directlyAssignedOnly, nodeIds);
return GetPermissionsInternal(repository, group.ToReadOnlyGroup(), fallbackToDefaultPermissions, nodeIds);
}
}
private IEnumerable<EntityPermission> GetPermissionsInternal(IUserGroupRepository repository, IUserGroup group, bool directlyAssignedOnly, params int[] nodeIds)
}
private static IEnumerable<EntityPermission> GetPermissionsInternal(IUserGroupRepository repository, IReadOnlyUserGroup group, bool fallbackToDefaultPermissions, params int[] nodeIds)
{
if (group == null) throw new ArgumentNullException("group");
if (nodeIds.Length == 0)
return Enumerable.Empty<EntityPermission>();
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 (directlyAssignedOnly == false)
if (fallbackToDefaultPermissions)
{
var missingIds = nodeIds.Except(result.Select(x => x.EntityId)).ToList();
if (missingIds.Any())
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())));
.Select(i => new EntityPermission(i, group.Permissions.ToArray(), isDefaultPermissions: true)));
}
}
return result;
@@ -946,91 +992,163 @@ namespace Umbraco.Core.Services
/// </summary>
/// <param name="user">User to check permissions for</param>
/// <param name="path">Path to check permissions for</param>
/// <returns>String indicating permissions for provided user and path</returns>
public string GetPermissionsForPath(IUser user, string path)
{
var assignedPermissions = GetPermissionsForGroupsAndPath(user.Groups.Select(x => x.Alias), path);
return GetAggregatePermissions(assignedPermissions);
public EntityPermissionSet GetPermissionsForPath(IUser user, string path)
{
var nodeIds = GetIdsFromPath(path);
if (nodeIds.Length == 0)
return null;
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 null;
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="path">Path to check permissions for</param>
/// <returns>List of strings indicating permissions for each groups</returns>
private IEnumerable<string> GetPermissionsForGroupsAndPath(IEnumerable<string> groups, string path)
/// <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 => GetPermissionsForPath(g, path, directlyAssignedOnly: false))
.ToList();
}
/// <summary>
/// Aggregates a set of permissions strings to return a unique permissions string containing the most permissive set
/// </summary>
/// <param name="assignedPermissions">List of permission strings</param>
/// <returns>Single permission string</returns>
private static string GetAggregatePermissions(IEnumerable<string> assignedPermissions)
{
return string.Join(string.Empty, assignedPermissions
.SelectMany(s => s.ToCharArray())
.Distinct());
}
.Select(g => new
{
group = g.Id,
permissions = GetPermissionsForPath(g, pathIds, fallbackToDefaultPermissions: true)
})
.ToDictionary(x => x.group, x => x.permissions);
}
/// <summary>
/// Gets the permissions for the provided group and path
/// </summary>
/// <param name="groupAlias">User to check permissions for</param>
/// <param name="path">Path to check permissions for</param>
/// <param name="directlyAssignedOnly">
/// <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
/// </param>
/// <returns>String indicating permissions for provided user and path</returns>
public string GetPermissionsForPath(string groupAlias, string path, bool directlyAssignedOnly = true)
public EntityPermission GetPermissionsForPath(string groupAlias, string path, bool fallbackToDefaultPermissions = false)
{
var nodeId = GetNodeIdFromPath(path);
var permission = GetPermissions(groupAlias, directlyAssignedOnly, nodeId)
.FirstOrDefault();
return permission != null
? string.Join(string.Empty, permission.AssignedPermissions)
: string.Empty;
}
var nodeIds = GetIdsFromPath(path);
//get permissions for all nodes in the path
var permissions = GetPermissions(groupAlias, fallbackToDefaultPermissions, nodeIds);
return GetPermissionsForPath(permissions, nodeIds, fallbackToDefaultPermissions);
}
/// <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="directlyAssignedOnly">
/// <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
/// </param>
/// <returns>String indicating permissions for provided user and path</returns>
public string GetPermissionsForPath(IUserGroup group, string path, bool directlyAssignedOnly = true)
public EntityPermission GetPermissionsForPath(IUserGroup group, string path, bool fallbackToDefaultPermissions = false)
{
var nodeId = GetNodeIdFromPath(path);
var permission = GetPermissions(group, directlyAssignedOnly, nodeId)
.FirstOrDefault();
return permission != null
? string.Join(string.Empty, permission.AssignedPermissions)
: string.Empty;
var nodeIds = GetIdsFromPath(path);
return GetPermissionsForPath(group.ToReadOnlyGroup(), nodeIds, fallbackToDefaultPermissions);
}
private EntityPermission GetPermissionsForPath(IReadOnlyUserGroup group, int[] pathIds, bool fallbackToDefaultPermissions = false)
{
//get permissions for all nodes in the path
var permissions = GetPermissions(group, fallbackToDefaultPermissions, pathIds);
return GetPermissionsForPath(permissions, pathIds, fallbackToDefaultPermissions);
}
//private EntityPermission GetPermissionsForPath(int groupId, string path, bool fallbackToDefaultPermissions = false)
//{
// var nodeIds = GetIdsFromPath(path);
// //get permissions for all nodes in the path
// var permissions = GetPermissions(groupId, fallbackToDefaultPermissions, nodeIds);
// return GetPermissionsForPath(permissions, groupId, nodeIds, fallbackToDefaultPermissions);
//}
/// <summary>
/// Returns the permissions for the path ids
/// </summary>
/// <param name="pathPermissions"></param>
/// <param name="pathIds">Must be ordered deepest to shallowest (right to left)</param>
/// <param name="fallbackToDefaultPermissions"></param>
/// <returns></returns>
private static EntityPermission GetPermissionsForPath(
IEnumerable<EntityPermission> pathPermissions,
int[] pathIds,
bool fallbackToDefaultPermissions = false)
{
//get permissions for all nodes in the path
var permissionsByEntityId = pathPermissions.ToDictionary(x => x.EntityId, x => x);
//then the permissions assigned to the path will be the 'deepest' node found that has permissions
foreach (var id in pathIds)
{
EntityPermission permission;
if (permissionsByEntityId.TryGetValue(id, out permission))
{
//don't return the default permissions if that is the one assigned here (we'll do that below if nothing was found)
if (permission.IsDefaultPermissions == false)
return permission;
}
}
//if we've made it here it means that no implicit/inherited permissions were found so we return the defaults if that is specified
if (fallbackToDefaultPermissions == false)
return null;
return permissionsByEntityId[pathIds[0]];
}
/// <summary>
/// Parses a path to find the lowermost node id
/// Convert a path to node ids in the order from right to left (deepest to shallowest)
/// </summary>
/// <param name="path">Path as string</param>
/// <returns>Node id</returns>
private static int GetNodeIdFromPath(string path)
/// <param name="path"></param>
/// <returns></returns>
private int[] GetIdsFromPath(string path)
{
return path.Contains(",")
? int.Parse(path.Substring(path.LastIndexOf(",", StringComparison.Ordinal) + 1))
: int.Parse(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>
///// Parses a path to find the lowermost node id
///// </summary>
///// <param name="path">Path as string</param>
///// <returns>Node id</returns>
//private static int GetNodeIdFromPath(string path)
//{
// return path.Contains(",")
// ? int.Parse(path.Substring(path.LastIndexOf(",", StringComparison.Ordinal) + 1))
// : int.Parse(path);
//}
/// <summary>
/// Checks in a set of permissions associated with a user for those related to a given nodeId
/// </summary>

View File

@@ -135,11 +135,11 @@ namespace Umbraco.Tests.Persistence.Repositories
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
var hasPropertiesContentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
content1 = MockedContent.CreateSimpleContent(hasPropertiesContentType);
content1 = MockedContent.CreateSimpleContent(hasPropertiesContentType);
contentTypeRepository.AddOrUpdate(hasPropertiesContentType);
repository.AddOrUpdate(content1);
unitOfWork.Commit();
repository.AddOrUpdate(content1);
unitOfWork.Commit();
}
var versionDtos = new List<ContentVersionDto>();
@@ -167,7 +167,7 @@ namespace Umbraco.Tests.Persistence.Repositories
VersionId = version,
WriterUserId = 0,
UpdateDate = versionDate,
TemplateId = content1.Template == null || content1.Template.Id <= 0 ? null : (int?) content1.Template.Id
TemplateId = content1.Template == null || content1.Template.Id <= 0 ? null : (int?)content1.Template.Id
});
}
@@ -188,7 +188,7 @@ namespace Umbraco.Tests.Persistence.Repositories
Assert.AreEqual(contentItem.Version, versionDtos.Single(x => x.Id == versionDtos.Max(y => y.Id)).VersionId);
var allVersions = repository.GetAllVersions(content[0].Id);
var allKnownVersions = versionDtos.Select(x => x.VersionId).Union(new[]{ content1.Version }).ToArray();
var allKnownVersions = versionDtos.Select(x => x.VersionId).Union(new[] { content1.Version }).ToArray();
Assert.IsTrue(allKnownVersions.ContainsAll(allVersions.Select(x => x.Version)));
Assert.IsTrue(allVersions.Select(x => x.Version).ContainsAll(allKnownVersions));
}
@@ -547,9 +547,9 @@ namespace Umbraco.Tests.Persistence.Repositories
var userGroup = MockedUserGroup.CreateUserGroup("1");
repository.AddOrUpdate(userGroup);
unitOfWork.Commit();
}
ContentTypeRepository contentTypeRepository;
}
ContentTypeRepository contentTypeRepository;
using (var repository = CreateRepository(unitOfWork, out contentTypeRepository))
{
var contentType = MockedContentTypes.CreateSimpleContentType("umbTextpage1", "Textpage");
@@ -563,7 +563,7 @@ namespace Umbraco.Tests.Persistence.Repositories
unitOfWork.Commit();
// Act
repository.AssignEntityPermission(parentPage, 'A', new [] { 1 });
repository.AssignEntityPermission(parentPage, 'A', new[] { 1 });
var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage);
repository.AddOrUpdate(childPage);
unitOfWork.Commit();

View File

@@ -1458,6 +1458,178 @@ namespace Umbraco.Tests.Services
Assert.That(contents.Any(), Is.False);
}
[Test]
public void Ensures_Permissions_Are_Set_On_Copied_Entity_To_Parent_Without_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 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
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());
}
[Test]
public void Ensures_Permissions_Are_Set_On_Copied_Entity_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 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);
ServiceContext.ContentService.Save(childPage2);
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());
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());
}
//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());
descendants = ServiceContext.ContentService.GetDescendants(parentPage).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());
}
}
[Test]
public void Can_Empty_RecycleBin_With_Content_That_Has_All_Related_Data()
{

View File

@@ -4,14 +4,10 @@ using System.Security.Cryptography;
using System.Text;
using NUnit.Framework;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers.Entities;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core.Persistence.Querying;
using Umbraco.Core.Services;
using Umbraco.Tests.TestHelpers;
using Umbraco.Tests.TestHelpers.Entities;
using umbraco.BusinessLogic.Actions;
using Umbraco.Core;
using Umbraco.Core.Persistence.DatabaseModelDefinitions;
@@ -37,7 +33,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void UserService_Get_User_Permissions_For_Unassigned_Permission_Nodes()
public void Get_User_Permissions_For_Unassigned_Permission_Nodes()
{
// Arrange
var userService = ServiceContext.UserService;
@@ -55,17 +51,18 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentService.Save(content);
// Act
var permissions = userService.GetPermissions(user, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id);
var permissions = userService.GetPermissions(user, content[0].Id, content[1].Id, content[2].Id)
.ToArray();
//assert
Assert.AreEqual(3, permissions.Count());
Assert.AreEqual(17, permissions.ElementAt(0).AssignedPermissions.Count());
Assert.AreEqual(17, permissions.ElementAt(1).AssignedPermissions.Count());
Assert.AreEqual(17, permissions.ElementAt(2).AssignedPermissions.Count());
Assert.AreEqual(3, permissions.Length);
Assert.AreEqual(17, permissions[0].AssignedPermissions.Length);
Assert.AreEqual(17, permissions[1].AssignedPermissions.Length);
Assert.AreEqual(17, permissions[2].AssignedPermissions.Length);
}
[Test]
public void UserService_Get_User_Permissions_For_Assigned_Permission_Nodes()
public void Get_User_Permissions_For_Assigned_Permission_Nodes()
{
// Arrange
var userService = ServiceContext.UserService;
@@ -99,7 +96,7 @@ namespace Umbraco.Tests.Services
}
[Test]
public void UserService_Get_UserGroup_Assigned_Permissions()
public void Get_UserGroup_Assigned_Permissions()
{
// Arrange
var userService = ServiceContext.UserService;
@@ -121,38 +118,6 @@ namespace Umbraco.Tests.Services
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(2), ActionBrowse.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);
//assert
Assert.AreEqual(3, permissions.Count());
Assert.AreEqual(3, permissions.ElementAt(0).AssignedPermissions.Length);
Assert.AreEqual(2, permissions.ElementAt(1).AssignedPermissions.Length);
Assert.AreEqual(1, permissions.ElementAt(2).AssignedPermissions.Length);
}
[Test]
public void UserService_Get_UserGroup_Assigned_And_Default_Permissions()
{
// Arrange
var userService = ServiceContext.UserService;
var userGroup = CreateTestUserGroup();
var contentType = MockedContentTypes.CreateSimpleContentType();
ServiceContext.ContentTypeService.Save(contentType);
var content = new[]
{
MockedContent.CreateSimpleContent(contentType),
MockedContent.CreateSimpleContent(contentType),
MockedContent.CreateSimpleContent(contentType)
};
ServiceContext.ContentService.Save(content);
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionMove.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
// Act
var permissions = userService.GetPermissions(userGroup, false, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id);
@@ -160,7 +125,69 @@ namespace Umbraco.Tests.Services
Assert.AreEqual(3, permissions.Count());
Assert.AreEqual(3, permissions.ElementAt(0).AssignedPermissions.Length);
Assert.AreEqual(2, permissions.ElementAt(1).AssignedPermissions.Length);
Assert.AreEqual(17, permissions.ElementAt(2).AssignedPermissions.Length);
Assert.AreEqual(1, permissions.ElementAt(2).AssignedPermissions.Length);
}
[Test]
public void Get_UserGroup_Assigned_And_Default_Permissions()
{
// Arrange
var userService = ServiceContext.UserService;
var userGroup = CreateTestUserGroup();
var contentType = MockedContentTypes.CreateSimpleContentType();
ServiceContext.ContentTypeService.Save(contentType);
var content = new[]
{
MockedContent.CreateSimpleContent(contentType),
MockedContent.CreateSimpleContent(contentType),
MockedContent.CreateSimpleContent(contentType)
};
ServiceContext.ContentService.Save(content);
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionDelete.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionMove.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
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)
.ToArray();
//assert
Assert.AreEqual(3, permissions.Length);
Assert.AreEqual(3, permissions[0].AssignedPermissions.Length);
Assert.AreEqual(2, permissions[1].AssignedPermissions.Length);
Assert.AreEqual(17,permissions[2].AssignedPermissions.Length);
}
[Test]
public void Get_User_Implicit_Permissions()
{
// Arrange
var userService = ServiceContext.UserService;
var userGroup = CreateTestUserGroup();
var contentType = MockedContentTypes.CreateSimpleContentType();
ServiceContext.ContentTypeService.Save(contentType);
var parent = MockedContent.CreateSimpleContent(contentType);
ServiceContext.ContentService.Save(parent);
var child1 = MockedContent.CreateSimpleContent(contentType, "child1", parent);
ServiceContext.ContentService.Save(child1);
var child2 = MockedContent.CreateSimpleContent(contentType, "child2", child1);
ServiceContext.ContentService.Save(child2);
ServiceContext.ContentService.AssignContentPermission(parent, ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(parent, ActionDelete.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(parent, ActionMove.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(parent, ActionBrowse.Instance.Letter, new int[] { userGroup.Id });
ServiceContext.ContentService.AssignContentPermission(parent, ActionDelete.Instance.Letter, new int[] { userGroup.Id });
// Act
var permissions = userService.GetPermissionsForPath(userGroup, child2.Path);
//assert
Assert.AreEqual(3, permissions.AssignedPermissions.Length);
}
[Test]

View File

@@ -89,7 +89,7 @@ namespace umbraco.dialogs
if (a.CanBePermissionAssigned == false) continue;
var permissions = userService.GetPermissionsForPath(group, _node.Path);
if (permissions.Contains(a.Letter))
if (permissions.AssignedPermissions.Contains(a.Letter.ToString()))
{
chk.Checked = true;
}

View File

@@ -571,7 +571,8 @@ namespace umbraco.BusinessLogic
if (_lazyId.HasValue) SetupUser(_lazyId.Value);
var userService = ApplicationContext.Current.Services.UserService;
return userService.GetPermissionsForPath(UserEntity, path);
return string.Join("",
userService.GetPermissionsForPath(UserEntity, path).PermissionsSet.SelectMany(x => x.Permission));
}
/// <summary>