diff --git a/src/Umbraco.Core/Models/Membership/EntityPermission.cs b/src/Umbraco.Core/Models/Membership/EntityPermission.cs index 8a72eb69ba..c417a4985c 100644 --- a/src/Umbraco.Core/Models/Membership/EntityPermission.cs +++ b/src/Umbraco.Core/Models/Membership/EntityPermission.cs @@ -12,12 +12,13 @@ AssignedPermissions = assignedPermissions; } - public object UserId { get; set; } - public int EntityId { get; set; } + public object UserId { get; private set; } + public int EntityId { get; private set; } /// /// The assigned permissions for the user/entity combo /// - public string[] AssignedPermissions { get; set; } + public string[] AssignedPermissions { get; private set; } } + } \ No newline at end of file diff --git a/src/Umbraco.Core/Models/Membership/IUser.cs b/src/Umbraco.Core/Models/Membership/IUser.cs index 268ed04219..264ccbf1a7 100644 --- a/src/Umbraco.Core/Models/Membership/IUser.cs +++ b/src/Umbraco.Core/Models/Membership/IUser.cs @@ -19,7 +19,14 @@ namespace Umbraco.Core.Models.Membership bool NoConsole { get; set; } IUserType UserType { get; } - string DefaultPermissions { get; set; } + + /// + /// The default permissions for the user + /// + /// + /// The default permissions are assigned to the user object based on the user type's default permissions + /// + string DefaultPermissions { get; } } internal interface IUserProfile : IProfile diff --git a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs index 0a046ca7a0..c1be1d360b 100644 --- a/src/Umbraco.Core/Persistence/Factories/UserFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/UserFactory.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using System.Globalization; using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; @@ -32,7 +33,9 @@ namespace Umbraco.Core.Persistence.Factories Language = dto.UserLanguage, DefaultToLiveEditing = dto.DefaultToLiveEditing, NoConsole = dto.NoConsole, - DefaultPermissions = dto.DefaultPermissions + + //NOTE: The umbracoUser.DefaultPermissions column is never used, the default permission come from the user type's default permissions + DefaultPermissions = _userType.Permissions }; foreach (var app in dto.User2AppDtos) @@ -61,8 +64,9 @@ namespace Umbraco.Core.Persistence.Factories Password = entity.Password, UserLanguage = entity.Language, UserName = entity.Name, - Type = short.Parse(entity.UserType.Id.ToString()), - DefaultPermissions = entity.DefaultPermissions, + Type = short.Parse(entity.UserType.Id.ToString(CultureInfo.InvariantCulture)), + //NOTE: This column in the db is *not* used so we'll just let it remain null + DefaultPermissions = null, User2AppDtos = new List() }; diff --git a/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs b/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs index 5e2947c3a7..68bf091fc5 100644 --- a/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs +++ b/src/Umbraco.Core/Persistence/Mappers/UserMapper.cs @@ -33,7 +33,8 @@ namespace Umbraco.Core.Persistence.Mappers CacheMap(src => src.Username, dto => dto.Login); CacheMap(src => src.Password, dto => dto.Password); CacheMap(src => src.Name, dto => dto.UserName); - CacheMap(src => src.DefaultPermissions, dto => dto.DefaultPermissions); + //NOTE: This column in the db is *not* used! + //CacheMap(src => src.DefaultPermissions, dto => dto.DefaultPermissions); CacheMap(src => src.StartMediaId, dto => dto.MediaStartId); CacheMap(src => src.StartContentId, dto => dto.ContentStartId); CacheMap(src => src.DefaultToLiveEditing, dto => dto.DefaultToLiveEditing); diff --git a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs index a4351ef99f..da34715234 100644 --- a/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/ContentRepository.cs @@ -251,7 +251,7 @@ namespace Umbraco.Core.Persistence.Repositories var userPermissions = ( from perm in parentPermissions from p in perm.AssignedPermissions - select new KeyValuePair(perm.UserId, p)).ToList(); + select new Tuple(perm.UserId, p)).ToList(); permissionsRepo.AssignEntityPermissions(entity, userPermissions); //flag the entity's permissions changed flag so we can track those changes. @@ -505,7 +505,7 @@ namespace Umbraco.Core.Persistence.Repositories return GetByVersion(dto.ContentVersionDto.VersionId); } - public void AssignEntityPermissions(IContent entity, string permission, IEnumerable userIds) + public void AssignEntityPermissions(IContent entity, char permission, IEnumerable userIds) { var repo = new PermissionRepository(UnitOfWork); repo.AssignEntityPermissions(entity, permission, userIds); diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs index 92748f1029..06beebda9e 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IContentRepository.cs @@ -23,7 +23,7 @@ namespace Umbraco.Core.Persistence.Repositories /// An enumerable list of IEnumerable GetByPublishedVersion(IQuery query); - void AssignEntityPermissions(IContent entity, string permission, IEnumerable userIds); + void AssignEntityPermissions(IContent entity, char permission, IEnumerable userIds); IEnumerable GetPermissionsForEntity(int entityId); } diff --git a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs index f61f4f0d33..d04a3fc9bf 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; @@ -32,7 +33,7 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - /// + /// internal IEnumerable GetUserPermissionsForEntities(object userId, params int[] entityIds) { var whereBuilder = new StringBuilder(); @@ -108,12 +109,12 @@ namespace Umbraco.Core.Persistence.Repositories /// /// /// - internal void AssignEntityPermissions(TEntity entity, string permission, IEnumerable userIds) + internal void AssignEntityPermissions(TEntity entity, char permission, IEnumerable userIds) { var actions = userIds.Select(id => new User2NodePermissionDto { NodeId = entity.Id, - Permission = permission, + Permission = permission.ToString(CultureInfo.InvariantCulture), UserId = (int)id }); @@ -127,13 +128,13 @@ namespace Umbraco.Core.Persistence.Repositories /// /// A key/value pair list containing a userId and a permission to assign /// - 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 = p.Value, - UserId = (int)p.Key + Permission = p.Item2, + UserId = (int)p.Item1 }); _unitOfWork.Database.BulkInsertRecords(actions); diff --git a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs index 00438bb935..144e2a9d8f 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs @@ -223,6 +223,12 @@ namespace Umbraco.Core.Persistence.Repositories return ConvertFromDtos(Database.Fetch(new UserSectionRelator().Map, sql)); } + /// + /// Returns permissions for a given user for any number of nodes + /// + /// + /// + /// public IEnumerable GetUserPermissionsForEntities(object userId, params int[] entityIds) { var repo = new PermissionRepository(UnitOfWork); diff --git a/src/Umbraco.Core/Services/ContentService.cs b/src/Umbraco.Core/Services/ContentService.cs index 6d0e002eea..225e523493 100644 --- a/src/Umbraco.Core/Services/ContentService.cs +++ b/src/Umbraco.Core/Services/ContentService.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Events; using Umbraco.Core.IO; using Umbraco.Core.Logging; using Umbraco.Core.Models; +using Umbraco.Core.Models.Membership; using Umbraco.Core.Models.Rdbms; using Umbraco.Core.Persistence; using Umbraco.Core.Persistence.Caching; @@ -57,6 +58,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/IContentService.cs b/src/Umbraco.Core/Services/IContentService.cs index 6525a9d825..2d5a44e0ff 100644 --- a/src/Umbraco.Core/Services/IContentService.cs +++ b/src/Umbraco.Core/Services/IContentService.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using Umbraco.Core.Models; +using Umbraco.Core.Models.Membership; namespace Umbraco.Core.Services { @@ -9,6 +10,7 @@ namespace Umbraco.Core.Services /// public interface IContentService : IService { + /// /// Creates an object using the alias of the /// that this Content should based on. diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 7118e5cc1e..421283e3e1 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -168,12 +168,35 @@ namespace Umbraco.Core.Services 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)) { - return repository.GetUserPermissionsForEntities(user.Id, nodeIds); + 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.ToCharArray().Select(c => c.ToString(CultureInfo.InvariantCulture)).ToArray())); + } + + return result; } } diff --git a/src/Umbraco.Tests/Controllers/WebApiEditors/FilterAllowedOutgoingContentAttributeTests.cs b/src/Umbraco.Tests/Controllers/WebApiEditors/FilterAllowedOutgoingContentAttributeTests.cs new file mode 100644 index 0000000000..510941ed0c --- /dev/null +++ b/src/Umbraco.Tests/Controllers/WebApiEditors/FilterAllowedOutgoingContentAttributeTests.cs @@ -0,0 +1,130 @@ +using System.Collections.Generic; +using System.Linq; +using System.Net.Http; +using System.Net.Http.Formatting; +using System.Net.Http.Headers; +using NUnit.Framework; +using Rhino.Mocks; +using Umbraco.Core; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; +using Umbraco.Web.Models.ContentEditing; +using Umbraco.Web.WebApi.Filters; + +namespace Umbraco.Tests.Controllers.WebApiEditors +{ + [TestFixture] + public class FilterAllowedOutgoingContentAttributeTests + { + [Test] + public void GetValueFromResponse_Already_EnumerableContent() + { + var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable)); + var val = new List() {new ContentItemBasic()}; + var result = att.GetValueFromResponse( + new ObjectContent(typeof (IEnumerable), + val, + new JsonMediaTypeFormatter(), + new MediaTypeHeaderValue("html/text"))); + + Assert.AreEqual(val, result); + Assert.AreEqual(1, ((IEnumerable)result).Count()); + } + + [Test] + public void GetValueFromResponse_From_Property() + { + var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "MyList"); + var val = new List() { new ContentItemBasic() }; + var container = new MyTestClass() {MyList = val}; + + var result = att.GetValueFromResponse( + new ObjectContent(typeof(MyTestClass), + container, + new JsonMediaTypeFormatter(), + new MediaTypeHeaderValue("html/text"))); + + Assert.AreEqual(val, result); + Assert.AreEqual(1, ((IEnumerable)result).Count()); + } + + [Test] + public void GetValueFromResponse_Returns_Null_Not_Found_Property() + { + var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "DontFind"); + var val = new List() { new ContentItemBasic() }; + var container = new MyTestClass() { MyList = val }; + + var result = att.GetValueFromResponse( + new ObjectContent(typeof(MyTestClass), + container, + new JsonMediaTypeFormatter(), + new MediaTypeHeaderValue("html/text"))); + + Assert.AreEqual(null, result); + + } + + [Test] + public void Filter_On_Start_Node() + { + var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable)); + var list = new List(); + var path = ""; + for (var i = 0; i < 10; i++) + { + if (i > 0 && path.EndsWith(",") == false) + { + path += ","; + } + path += i.ToInvariantString(); + list.Add(new ContentItemBasic { Id = i, Name = "Test" + i, ParentId = i, Path = path }); + } + var user = MockRepository.GenerateStub(); + user.Id = 9; + user.StartContentId = 5; + + att.FilterBasedOnStartNode(list, user); + + Assert.AreEqual(5, list.Count); + + } + + [Test] + public void Filter_On_Permissions() + { + var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable)); + var list = new List(); + for (var i = 0; i < 10; i++) + { + list.Add(new ContentItemBasic{Id = i, Name = "Test" + i, ParentId = -1}); + } + var ids = list.Select(x => (int)x.Id).ToArray(); + var user = MockRepository.GenerateStub(); + user.Id = 9; + user.StartContentId = -1; + var userService = MockRepository.GenerateStub(); + //we're only assigning 3 nodes browse permissions so that is what we expect as a result + var permissions = new List + { + new EntityPermission(9, 1, new string[]{ "F" }), + new EntityPermission(9, 2, new string[]{ "F" }), + new EntityPermission(9, 3, new string[]{ "F" }), + new EntityPermission(9, 4, new string[]{ "A" }) + }; + userService.Stub(x => x.GetPermissions(user, ids)).Return(permissions); + + att.FilterBasedOnPermissions(list, user, userService); + + Assert.AreEqual(3, list.Count); + Assert.AreEqual(1, list.ElementAt(0).Id); + Assert.AreEqual(2, list.ElementAt(1).Id); + Assert.AreEqual(3, list.ElementAt(2).Id); + } + + private class MyTestClass + { + public IEnumerable MyList { get; set; } + } + } +} \ No newline at end of file diff --git a/src/Umbraco.Tests/Controllers/WebApiEditors/MediaControllerUnitTests.cs b/src/Umbraco.Tests/Controllers/WebApiEditors/MediaControllerUnitTests.cs index c9704a8cf5..9a04aab6cd 100644 --- a/src/Umbraco.Tests/Controllers/WebApiEditors/MediaControllerUnitTests.cs +++ b/src/Umbraco.Tests/Controllers/WebApiEditors/MediaControllerUnitTests.cs @@ -1,136 +1,14 @@ using System.Collections.Generic; -using System.Linq; -using System.Net.Http; -using System.Net.Http.Formatting; -using System.Net.Http.Headers; using System.Web.Http; using NUnit.Framework; using Rhino.Mocks; -using Umbraco.Core; using Umbraco.Core.Models; using Umbraco.Core.Models.Membership; using Umbraco.Core.Services; using Umbraco.Web.Editors; -using Umbraco.Web.Models.ContentEditing; -using Umbraco.Web.WebApi.Filters; namespace Umbraco.Tests.Controllers.WebApiEditors { - [TestFixture] - public class FilterAllowedOutgoingContentAttributeTests - { - [Test] - public void GetValueFromResponse_Already_EnumerableContent() - { - var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable)); - var val = new List() {new ContentItemBasic()}; - var result = att.GetValueFromResponse( - new ObjectContent(typeof (IEnumerable), - val, - new JsonMediaTypeFormatter(), - new MediaTypeHeaderValue("html/text"))); - - Assert.AreEqual(val, result); - Assert.AreEqual(1, ((IEnumerable)result).Count()); - } - - [Test] - public void GetValueFromResponse_From_Property() - { - var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "MyList"); - var val = new List() { new ContentItemBasic() }; - var container = new MyTestClass() {MyList = val}; - - var result = att.GetValueFromResponse( - new ObjectContent(typeof(MyTestClass), - container, - new JsonMediaTypeFormatter(), - new MediaTypeHeaderValue("html/text"))); - - Assert.AreEqual(val, result); - Assert.AreEqual(1, ((IEnumerable)result).Count()); - } - - [Test] - public void GetValueFromResponse_Returns_Null_Not_Found_Property() - { - var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable), "DontFind"); - var val = new List() { new ContentItemBasic() }; - var container = new MyTestClass() { MyList = val }; - - var result = att.GetValueFromResponse( - new ObjectContent(typeof(MyTestClass), - container, - new JsonMediaTypeFormatter(), - new MediaTypeHeaderValue("html/text"))); - - Assert.AreEqual(null, result); - - } - - [Test] - public void Filter_On_Start_Node() - { - var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable)); - var list = new List(); - var path = ""; - for (var i = 0; i < 10; i++) - { - if (i > 0 && path.EndsWith(",") == false) - { - path += ","; - } - path += i.ToInvariantString(); - list.Add(new ContentItemBasic { Id = i, Name = "Test" + i, ParentId = i, Path = path }); - } - var user = MockRepository.GenerateStub(); - user.Id = 9; - user.StartContentId = 5; - - att.FilterBasedOnStartNode(list, user); - - Assert.AreEqual(5, list.Count); - - } - - [Test] - public void Filter_On_Permissions() - { - var att = new FilterAllowedOutgoingContentAttribute(typeof(IEnumerable)); - var list = new List(); - for (var i = 0; i < 10; i++) - { - list.Add(new ContentItemBasic{Id = i, Name = "Test" + i, ParentId = -1}); - } - var ids = list.Select(x => (int)x.Id).ToArray(); - var user = MockRepository.GenerateStub(); - user.Id = 9; - user.StartContentId = -1; - var userService = MockRepository.GenerateStub(); - //we're only assigning 3 nodes browse permissions so that is what we expect as a result - var permissions = new List - { - new EntityPermission(9, 1, new string[]{ "F" }), - new EntityPermission(9, 2, new string[]{ "F" }), - new EntityPermission(9, 3, new string[]{ "F" }), - new EntityPermission(9, 4, new string[]{ "A" }) - }; - userService.Stub(x => x.GetPermissions(user, ids)).Return(permissions); - - att.FilterBasedOnPermissions(list, user, userService); - - Assert.AreEqual(3, list.Count); - Assert.AreEqual(1, list.ElementAt(0).Id); - Assert.AreEqual(2, list.ElementAt(1).Id); - Assert.AreEqual(3, list.ElementAt(2).Id); - } - - private class MyTestClass - { - public IEnumerable MyList { get; set; } - } - } - [TestFixture] public class MediaControllerUnitTests { diff --git a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs index 301b844be4..388c390234 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/ContentRepositoryTest.cs @@ -59,7 +59,7 @@ namespace Umbraco.Tests.Persistence.Repositories unitOfWork.Commit(); // Act - repository.AssignEntityPermissions(parentPage, "A", new object[] {0}); + repository.AssignEntityPermissions(parentPage, 'A', new object[] {0}); var childPage = MockedContent.CreateSimpleContent(contentType, "child", parentPage); repository.AddOrUpdate(childPage); unitOfWork.Commit(); diff --git a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs index 4c3026e27b..011cf2e2b1 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/UserRepositoryTest.cs @@ -115,7 +115,8 @@ namespace Umbraco.Tests.Persistence.Repositories var resolved = repository.Get((int)user.Id); resolved.Name = "New Name"; - resolved.DefaultPermissions = "ZYX"; + //the db column is not used, default permissions are taken from the user type's permissions, this is a getter only + //resolved.DefaultPermissions = "ZYX"; resolved.Language = "fr"; resolved.IsApproved = false; resolved.Password = "new"; @@ -134,7 +135,7 @@ namespace Umbraco.Tests.Persistence.Repositories // Assert Assert.That(updatedItem.Id, Is.EqualTo(resolved.Id)); Assert.That(updatedItem.Name, Is.EqualTo(resolved.Name)); - Assert.That(updatedItem.DefaultPermissions, Is.EqualTo(resolved.DefaultPermissions)); + //Assert.That(updatedItem.DefaultPermissions, Is.EqualTo(resolved.DefaultPermissions)); Assert.That(updatedItem.Language, Is.EqualTo(resolved.Language)); Assert.That(updatedItem.IsApproved, Is.EqualTo(resolved.IsApproved)); Assert.That(updatedItem.Password, Is.EqualTo(resolved.Password)); @@ -427,6 +428,24 @@ namespace Umbraco.Tests.Persistence.Repositories Assert.IsTrue(names.Contains("TestUser3")); } + [Test] + public void Default_User_Permissions_Based_On_User_Type() + { + // Arrange + var provider = new PetaPocoUnitOfWorkProvider(); + var unitOfWork = provider.GetUnitOfWork(); + var repository = RepositoryResolver.Current.ResolveByType(unitOfWork); + + + // Act + var user1 = MockedUser.CreateUser(CreateAndCommitUserType(), "1", "test", "media"); + repository.AddOrUpdate(user1); + unitOfWork.Commit(); + + // Assert + Assert.AreEqual("ABC", user1.DefaultPermissions); + } + private void AssertPropertyValues(IUser updatedItem, IUser originalUser) { Assert.That(updatedItem.Id, Is.EqualTo(originalUser.Id)); diff --git a/src/Umbraco.Tests/Services/UserServiceTests.cs b/src/Umbraco.Tests/Services/UserServiceTests.cs index b8cc7f6225..b36520d927 100644 --- a/src/Umbraco.Tests/Services/UserServiceTests.cs +++ b/src/Umbraco.Tests/Services/UserServiceTests.cs @@ -4,6 +4,9 @@ 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; namespace Umbraco.Tests.Services { @@ -25,6 +28,70 @@ 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"); + //we know this actually is an IUser so we'll just cast + var user = (IUser)ServiceContext.UserService.CreateMembershipUser("test1", "test1", "test1", userType, "test1@test.com"); + 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"); + //we know this actually is an IUser so we'll just cast + var user = (IUser)ServiceContext.UserService.CreateMembershipUser("test1", "test1", "test1", userType, "test1@test.com"); + 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 UserService_Can_Persist_New_User() { diff --git a/src/Umbraco.Tests/Umbraco.Tests.csproj b/src/Umbraco.Tests/Umbraco.Tests.csproj index b1840c6915..92720fe76c 100644 --- a/src/Umbraco.Tests/Umbraco.Tests.csproj +++ b/src/Umbraco.Tests/Umbraco.Tests.csproj @@ -234,6 +234,7 @@ + diff --git a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs index dda78dc4d2..8193b528f6 100644 --- a/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs +++ b/src/Umbraco.Web/WebApi/Filters/FilterAllowedOutgoingContentAttribute.cs @@ -34,6 +34,7 @@ namespace Umbraco.Web.WebApi.Filters public FilterAllowedOutgoingContentAttribute(Type outgoingType, string propertyName) : base(outgoingType, propertyName) { + _permissionToCheck = ActionBrowse.Instance.Letter; } protected override void FilterItems(IUser user, IList items) @@ -57,9 +58,12 @@ namespace Umbraco.Web.WebApi.Filters foreach(dynamic item in items) { var nodePermission = permissions.Where(x => x.EntityId == item.Id).ToArray(); - //if there are no permissions for this id, then remove the item + //if there are no permissions for this id then we need to check what the user's default + // permissions are. if (nodePermission.Any() == false) { + //var defaultP = user.DefaultPermissions + toRemove.Add(item); } else