diff --git a/src/Umbraco.Core/Models/Membership/EntityPermission.cs b/src/Umbraco.Core/Models/Membership/EntityPermission.cs new file mode 100644 index 0000000000..a4ee6420c1 --- /dev/null +++ b/src/Umbraco.Core/Models/Membership/EntityPermission.cs @@ -0,0 +1,24 @@ +namespace Umbraco.Core.Models.Membership +{ + /// + /// Represents a user -> entity permission + /// + public class EntityPermission + { + public EntityPermission(object userId, int entityId, string[] assignedPermissions) + { + UserId = userId; + EntityId = entityId; + AssignedPermissions = assignedPermissions; + } + + public object UserId { get; private set; } + public int EntityId { get; private set; } + + /// + /// The assigned permissions for the user/entity combo + /// + public string[] AssignedPermissions { get; private set; } + } + +} \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs index b30e2fe209..6721790f5b 100644 --- a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs @@ -35,9 +35,8 @@ namespace Umbraco.Core.Persistence.Factories Email = dto.Email, Language = dto.UserLanguage, DefaultToLiveEditing = dto.DefaultToLiveEditing, - DefaultPermissions = dto.DefaultPermissions.IsNullOrWhiteSpace() - ? Enumerable.Empty() - : dto.DefaultPermissions.ToCharArray().Select(x => x.ToString(CultureInfo.InvariantCulture)) + //NOTE: The default permission come from the user type's default permissions + DefaultPermissions = _userType.Permissions }; foreach (var app in dto.User2AppDtos) @@ -67,7 +66,6 @@ namespace Umbraco.Core.Persistence.Factories UserLanguage = entity.Language, UserName = entity.Name, Type = short.Parse(entity.UserType.Id.ToString(CultureInfo.InvariantCulture)), - DefaultPermissions = entity.DefaultPermissions == null ? "" : string.Join("", entity.DefaultPermissions), User2AppDtos = new List() }; diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index 80352ae0dd..bbbb85fdb2 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -6,6 +6,7 @@ using Umbraco.Core.Configuration; using Umbraco.Core.IO; using Umbraco.Core.Models; using Umbraco.Core.Models.EntityBase; +using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence.Caching; using Umbraco.Core.Persistence.Factories; @@ -262,17 +263,19 @@ namespace Umbraco.Core.Persistence.Repositories //Assign the same permissions to it as the parent node - // http://issues.umbraco.org/issue/U4-2161 - var parentPermissions = GetPermissionsForEntity(entity.ParentId).ToArray(); + // http://issues.umbraco.org/issue/U4-2161 + var permissionsRepo = new PermissionRepository(UnitOfWork); + 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 userPermissions = parentPermissions.Select( - permissionDto => new KeyValuePair>( - permissionDto.UserId, - permissionDto.Permission.ToCharArray().Select(x => x.ToString(CultureInfo.InvariantCulture)))); - AssignEntityPermissions(entity, userPermissions); + var userPermissions = ( + from perm in parentPermissions + from p in perm.AssignedPermissions + select new Tuple(perm.UserId, p)).ToList(); + + permissionsRepo.AssignEntityPermissions(entity, userPermissions); //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; @@ -524,6 +527,18 @@ namespace Umbraco.Core.Persistence.Repositories return GetByVersion(dto.ContentVersionDto.VersionId); } + public void AssignEntityPermissions(IContent entity, char permission, IEnumerable userIds) + { + var repo = new PermissionRepository(UnitOfWork); + repo.AssignEntityPermissions(entity, permission, userIds); + } + + public IEnumerable GetPermissionsForEntity(int entityId) + { + var repo = new PermissionRepository(UnitOfWork); + return repo.GetPermissionsForEntity(entityId); + } + #endregion /// diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs index b650696575..06beebda9e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Umbraco.Core.Models; +using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Querying; namespace Umbraco.Core.Persistence.Repositories @@ -21,5 +22,9 @@ namespace Umbraco.Core.Persistence.Repositories /// Query to execute against published versions /// An enumerable list of IEnumerable GetByPublishedVersion(IQuery query); + + void AssignEntityPermissions(IContent entity, char permission, IEnumerable userIds); + + IEnumerable GetPermissionsForEntity(int entityId); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs index 6772992863..d57fc6535a 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs @@ -8,10 +8,6 @@ namespace Umbraco.Core.Persistence.Repositories { internal interface IUserRepository : IRepositoryQueryable { - //IProfile GetProfileById(int id); - //IProfile GetProfileByUserName(string username); - //IUser GetUserByUserName(string username); - /// /// Gets the count of items based on a complex query /// @@ -42,5 +38,14 @@ namespace Umbraco.Core.Persistence.Repositories /// /// IEnumerable GetPagedResultsByQuery(IQuery query, int pageIndex, int pageSize, out int totalRecords, Expression> orderBy); + + + /// + /// Gets the user permissions for the specified entities + /// + /// + /// + /// + IEnumerable GetUserPermissionsForEntities(object userId, params int[] entityIds); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs index 04dab367dc..615b8bace4 100644 --- a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Dynamic; +using System.Globalization; using System.Linq; using System.Text; using Umbraco.Core.Models; @@ -18,46 +19,107 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - internal abstract class PermissionRepository : PetaPocoRepositoryBase + internal class PermissionRepository where TEntity : class, IAggregateRoot { - protected PermissionRepository(IDatabaseUnitOfWork work) - : base(work) - { - } + private readonly IDatabaseUnitOfWork _unitOfWork; - protected PermissionRepository(IDatabaseUnitOfWork work, IRepositoryCacheProvider cache) - : base(work, cache) + internal PermissionRepository(IDatabaseUnitOfWork unitOfWork) { - } - - protected internal IEnumerable GetPermissionsForEntity(int entityId) - { - var sql = new Sql(); - sql.Select("*") - .From() - .Where(dto => dto.NodeId == entityId); - return Database.Fetch(sql); + _unitOfWork = unitOfWork; } /// - /// Assigns permissions to an entity for multiple users + /// Returns permissions for a given user for any number of nodes + /// + /// + /// + /// + internal IEnumerable GetUserPermissionsForEntities(object userId, params int[] entityIds) + { + var whereBuilder = new StringBuilder(); + + //where userId = @userId AND + whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("userId")); + whereBuilder.Append("="); + whereBuilder.Append(userId); + whereBuilder.Append(" AND "); + + //where nodeId = @nodeId1 OR nodeId = @nodeId2, etc... + whereBuilder.Append("("); + for (var index = 0; index < entityIds.Length; index++) + { + var entityId = entityIds[index]; + whereBuilder.Append(SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("nodeId")); + whereBuilder.Append("="); + whereBuilder.Append(entityId); + if (index < entityIds.Length - 1) + { + whereBuilder.Append(" OR "); + } + } + whereBuilder.Append(")"); + + var sql = new Sql(); + sql.Select("*") + .From() + .Where(whereBuilder.ToString()); + + //ToArray() to ensure it's all fetched from the db once. + var result = _unitOfWork.Database.Fetch(sql).ToArray(); + return ConvertToPermissionList(result); + } + + /// + /// Returns permissions for all users for a given entity + /// + /// + /// + internal IEnumerable GetPermissionsForEntity(int entityId) + { + var sql = new Sql(); + sql.Select("*") + .From() + .Where(dto => dto.NodeId == entityId) + .OrderBy(dto => dto.NodeId); + + //ToArray() to ensure it's all fetched from the db once. + var result = _unitOfWork.Database.Fetch(sql).ToArray(); + return ConvertToPermissionList(result); + } + + private IEnumerable ConvertToPermissionList(IEnumerable result) + { + var permissions = new List(); + var nodePermissions = result.GroupBy(x => x.NodeId); + foreach (var np in nodePermissions) + { + var userPermissions = np.GroupBy(x => x.UserId); + foreach (var up in userPermissions) + { + var perms = up.Select(x => x.Permission).ToArray(); + permissions.Add(new EntityPermission(up.Key, up.First().NodeId, perms)); + } + } + return permissions; + } + + /// + /// Assigns one permission to an entity for multiple users /// /// - /// - /// A list of permissions to assign - currently in Umbraco each permission is a single char but this list of strings allows for flexibility in the future - /// + /// /// - protected internal void AssignEntityPermissions(TEntity entity, IEnumerable permissions, IEnumerable userIds) + internal void AssignEntityPermissions(TEntity entity, char permission, IEnumerable userIds) { var actions = userIds.Select(id => new User2NodePermissionDto - { - NodeId = entity.Id, - Permission = string.Join("",permissions), - UserId = (int)id - }); + { + NodeId = entity.Id, + Permission = permission.ToString(CultureInfo.InvariantCulture), + UserId = (int)id + }); - Database.BulkInsertRecords(actions); + _unitOfWork.Database.BulkInsertRecords(actions); } /// @@ -65,31 +127,29 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - /// A key/value pair list containing a userId and a permission to assign, currently in Umbraco each permission is a single char but this list of strings allows for flexibility in the future + /// A key/value pair list containing a userId and a permission to assign /// - protected internal void AssignEntityPermissions(TEntity entity, IEnumerable>> userPermissions) + internal void AssignEntityPermissions(TEntity entity, IEnumerable> userPermissions) { var actions = userPermissions.Select(p => new User2NodePermissionDto { NodeId = entity.Id, - Permission = string.Join("", p.Value), - UserId = (int)p.Key + Permission = p.Item2, + UserId = (int)p.Item1 }); - Database.BulkInsertRecords(actions); + _unitOfWork.Database.BulkInsertRecords(actions); } /// /// Replace permissions for an entity for multiple users /// /// - /// - /// A list of permissions to assign - currently in Umbraco each permission is a single char but this list of strings allows for flexibility in the future - /// + /// /// - protected internal void ReplaceEntityPermissions(TEntity entity, IEnumerable permissions, IEnumerable userIds) - { - Database.Update( + internal void ReplaceEntityPermissions(TEntity entity, string permissions, IEnumerable userIds) + { + _unitOfWork.Database.Update( GenerateReplaceEntityPermissionsSql(entity.Id, permissions, userIds.ToArray())); } @@ -97,55 +157,35 @@ namespace Umbraco.Core.Persistence.Repositories /// An overload to replace entity permissions and all replace all descendant permissions /// /// - /// - /// A list of permissions to assign - currently in Umbraco each permission is a single char but this list of strings allows for flexibility in the future - /// + /// /// /// A callback to get the descendant Ids of the current entity /// /// - protected internal void ReplaceEntityPermissions(TEntity entity, IEnumerable permissions, Func> getDescendantIds, IEnumerable userIds) + internal void ReplaceEntityPermissions(TEntity entity, string permissions, Func> getDescendantIds, IEnumerable userIds) { - Database.Update( + _unitOfWork.Database.Update( GenerateReplaceEntityPermissionsSql( - new[] {entity.Id}.Concat(getDescendantIds(entity)).ToArray(), - permissions, + new[] { entity.Id }.Concat(getDescendantIds(entity)).ToArray(), + permissions, userIds.ToArray())); } - /// - /// - /// - /// - /// - /// A list of permissions to assign - currently in Umbraco each permission is a single char but this list of strings allows for flexibility in the future - /// - /// - /// - internal static string GenerateReplaceEntityPermissionsSql(int entityId, IEnumerable permissions, object[] userIds) + internal static string GenerateReplaceEntityPermissionsSql(int entityId, string permissions, object[] userIds) { - return GenerateReplaceEntityPermissionsSql(new[] {entityId}, permissions, userIds); + return GenerateReplaceEntityPermissionsSql(new[] { entityId }, permissions, userIds); } - /// - /// - /// - /// - /// - /// A list of permissions to assign - currently in Umbraco each permission is a single char but this list of strings allows for flexibility in the future - /// - /// - /// - internal static string GenerateReplaceEntityPermissionsSql(int[] entityIds, IEnumerable permissions, object[] userIds) + internal static string GenerateReplaceEntityPermissionsSql(int[] entityIds, string permissions, object[] userIds) { //create the "SET" clause of the update statement var sqlSet = string.Format("SET {0}={1}", SqlSyntaxContext.SqlSyntaxProvider.GetQuotedColumnName("permission"), - SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(string.Join("", permissions))); + SqlSyntaxContext.SqlSyntaxProvider.GetQuotedValue(permissions)); //build the nodeIds part of the where clause var sqlNodeWhere = BuildOrClause(entityIds, "nodeId"); - + //build up the userIds part of the where clause var userWhereBuilder = BuildOrClause(userIds, "userId"); @@ -174,5 +214,6 @@ namespace Umbraco.Core.Persistence.Repositories userWhereBuilder.Append(")"); return userWhereBuilder.ToString(); } + } } \ No newline at end of file diff --git a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs index 5e18ce4d8a..e5074758b7 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs @@ -19,7 +19,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// Represents the UserRepository for doing CRUD operations for /// - internal class UserRepository : PermissionRepository, IUserRepository + internal class UserRepository : PetaPocoRepositoryBase, IUserRepository { private readonly IUserTypeRepository _userTypeRepository; @@ -304,6 +304,18 @@ namespace Umbraco.Core.Persistence.Repositories return result.OrderBy(orderBy.Compile()); } + /// + /// Returns permissions for a given user for any number of nodes + /// + /// + /// + /// + public IEnumerable GetUserPermissionsForEntities(object userId, params int[] entityIds) + { + var repo = new PermissionRepository(UnitOfWork); + return repo.GetUserPermissionsForEntities(userId, entityIds); + } + #endregion private IEnumerable ConvertFromDtos(IEnumerable dtos) diff --git a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs index d6a4d3843e..1b3ff63eea 100644 --- a/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs +++ b/src/Umbraco.Core/Persistence/Repositories/VersionableRepositoryBase.cs @@ -8,7 +8,7 @@ using Umbraco.Core.Persistence.UnitOfWork; namespace Umbraco.Core.Persistence.Repositories { - internal abstract class VersionableRepositoryBase : PermissionRepository + internal abstract class VersionableRepositoryBase : PetaPocoRepositoryBase where TEntity : class, IAggregateRoot { protected VersionableRepositoryBase(IDatabaseUnitOfWork work) : base(work) diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 443b2839d9..e937560d79 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -57,6 +57,17 @@ namespace Umbraco.Core.Services _repositoryFactory = repositoryFactory; } + //TODO: There are various ways to expose permission setting on this service, we just need to list out the different ways we'll need to + // be able to acheive this for the core, for now this is here so I can run a unit test. + internal void AssignContentPermissions(IContent entity, char permission, IEnumerable userIds) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateContentRepository(uow)) + { + repository.AssignEntityPermissions(entity, permission, userIds); + } + } + /// /// Creates an object using the alias of the /// that this Content should based on. diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs index 4b82c01257..840cd9a685 100644 --- a/src/Umbraco.Core/Services/IUserService.cs +++ b/src/Umbraco.Core/Services/IUserService.cs @@ -1,3 +1,4 @@ +using System.Collections.Generic; using System.Web; using Umbraco.Core.Models.Membership; @@ -50,5 +51,13 @@ namespace Umbraco.Core.Services /// /// void DeleteSectionFromAllUsers(string sectionAlias); + + /// + /// Returns a list of the sections that the user is allowed access to + /// + /// + IEnumerable GetUserSections(IUser user); + + IEnumerable GetPermissions(IUser user, params int[] nodeIds); } } \ No newline at end of file diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index ac58c5a4a9..eb7b9cb6db 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -434,6 +434,54 @@ namespace Umbraco.Core.Services } } + /// + /// Returns the user's applications that they are allowed to access + /// + /// + /// + public IEnumerable GetUserSections(IUser user) + { + //TODO: We need to cache this result + + var uow = _uowProvider.GetUnitOfWork(); + var sql = new Sql(); + sql.Select("app").From() + .Where(dto => dto.UserId == (int)user.Id); + return uow.Database.Fetch(sql); + } + + /// + /// Returns permissions for a given user for any number of nodes + /// + /// + /// + /// + /// + /// If no permissions are found for a particular entity then the user's default permissions will be applied + /// + public IEnumerable GetPermissions(IUser user, params int[] nodeIds) + { + var uow = _uowProvider.GetUnitOfWork(); + using (var repository = _repositoryFactory.CreateUserRepository(uow)) + { + var explicitPermissions = repository.GetUserPermissionsForEntities(user.Id, nodeIds); + + //if no permissions are assigned to a particular node then we will fill in those permissions with the user's defaults + var result = new List(explicitPermissions); + var missingIds = nodeIds.Except(result.Select(x => x.EntityId)); + foreach (var id in missingIds) + { + result.Add( + new EntityPermission( + user.Id, + id, + user.DefaultPermissions.ToArray())); + } + + return result; + } + } + #endregion /// diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj index 27792b168c..b0d3da50ed 100644 --- a/src/Umbraco.Core/Umbraco.Core.csproj +++ b/src/Umbraco.Core/Umbraco.Core.csproj @@ -191,6 +191,7 @@ + diff --git a/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs b/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs index 723bb7d7f3..eb98548c19 100644 --- a/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs +++ b/src/Umbraco.Tests/Persistence/Querying/PetaPocoSqlTests.cs @@ -16,7 +16,7 @@ namespace Umbraco.Tests.Persistence.Querying public void Generate_Replace_Entity_Permissions_Test() { // Act - var sql = PermissionRepository.GenerateReplaceEntityPermissionsSql(123, new[]{"A"}, new object[] {10, 11, 12}); + var sql = PermissionRepository.GenerateReplaceEntityPermissionsSql(123, "A", new object[] {10, 11, 12}); // Assert Assert.AreEqual(@"SET [permission]='A' WHERE (([nodeId]=123) AND ([userId]=10 OR [userId]=11 OR [userId]=12))", sql); @@ -26,7 +26,7 @@ namespace Umbraco.Tests.Persistence.Querying public void Generate_Replace_Entity_Permissions_With_Descendants_Test() { // Act - var sql = PermissionRepository.GenerateReplaceEntityPermissionsSql(new[] { 123, 456 }, new[] { "A" }, new object[] { 10, 11, 12 }); + var sql = PermissionRepository.GenerateReplaceEntityPermissionsSql(new[] { 123, 456 },"A", new object[] { 10, 11, 12 }); // Assert Assert.AreEqual(@"SET [permission]='A' WHERE (([nodeId]=123 OR [nodeId]=456) AND ([userId]=10 OR [userId]=11 OR [userId]=12))", sql); diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index ff47f5b172..55a978f6b2 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -69,7 +69,7 @@ namespace Umbraco.Tests.Persistence.Repositories unitOfWork.Commit(); // Act - repository.AssignEntityPermissions(parentPage, new[] { "A" }, new object[] { 0 }); + repository.AssignEntityPermissions(parentPage, 'A', new object[] { 0 }); var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage); repository.AddOrUpdate(childPage); unitOfWork.Commit(); @@ -77,7 +77,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert var permissions = repository.GetPermissionsForEntity(childPage.Id); Assert.AreEqual(1, permissions.Count()); - Assert.AreEqual("A", permissions.Single().Permission); + Assert.AreEqual("A", permissions.Single().AssignedPermissions.First()); } } diff --git a/src/Umbraco.Tests/Services/UserServiceTests.cs b/src/Umbraco.Tests/Services/UserServiceTests.cs index 6e50871e46..50229a5440 100644 --- a/src/Umbraco.Tests/Services/UserServiceTests.cs +++ b/src/Umbraco.Tests/Services/UserServiceTests.cs @@ -7,6 +7,7 @@ using Umbraco.Core.Models.Membership; using Umbraco.Core.Persistence.Querying; using Umbraco.Core.Services; using Umbraco.Tests.TestHelpers.Entities; +using umbraco.BusinessLogic.Actions; namespace Umbraco.Tests.Services { @@ -28,6 +29,68 @@ namespace Umbraco.Tests.Services base.TearDown(); } + [Test] + public void UserService_Get_User_Permissions_For_Unassigned_Permission_Nodes() + { + // Arrange + var userService = ServiceContext.UserService; + var userType = userService.GetUserTypeByAlias("admin"); + var user = ServiceContext.UserService.CreateMember("test1", "test1@test.com", "123456", userType); + var contentType = MockedContentTypes.CreateSimpleContentType(); + ServiceContext.ContentTypeService.Save(contentType); + var content = new[] + { + MockedContent.CreateSimpleContent(contentType), + MockedContent.CreateSimpleContent(contentType), + MockedContent.CreateSimpleContent(contentType) + }; + ServiceContext.ContentService.Save(content); + + // Act + var permissions = userService.GetPermissions(user, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id); + + //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()); + } + + [Test] + public void UserService_Get_User_Permissions_For_Assigned_Permission_Nodes() + { + // Arrange + var userService = ServiceContext.UserService; + var userType = userService.GetUserTypeByAlias("admin"); + var user = ServiceContext.UserService.CreateMember("test1", "test1@test.com", "123456", userType); + var contentType = MockedContentTypes.CreateSimpleContentType(); + ServiceContext.ContentTypeService.Save(contentType); + var content = new[] + { + MockedContent.CreateSimpleContent(contentType), + MockedContent.CreateSimpleContent(contentType), + MockedContent.CreateSimpleContent(contentType) + }; + ServiceContext.ContentService.Save(content); + ((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(0), ActionBrowse.Instance.Letter, new object[] { user.Id }); + ((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(0), ActionDelete.Instance.Letter, new object[] { user.Id }); + ((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(0), ActionMove.Instance.Letter, new object[] { user.Id }); + + ((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(1), ActionBrowse.Instance.Letter, new object[] { user.Id }); + ((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(1), ActionDelete.Instance.Letter, new object[] { user.Id }); + + ((ContentService)ServiceContext.ContentService).AssignContentPermissions(content.ElementAt(2), ActionBrowse.Instance.Letter, new object[] { user.Id }); + + // Act + var permissions = userService.GetPermissions(user, 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.Count()); + Assert.AreEqual(2, permissions.ElementAt(1).AssignedPermissions.Count()); + Assert.AreEqual(1, permissions.ElementAt(2).AssignedPermissions.Count()); + } + [Test] public void Can_Delete_User() {