diff --git a/src/Umbraco.Core/Models/EntityBase/Entity.cs b/src/Umbraco.Core/Models/EntityBase/Entity.cs index d4da2676c1..3e7770088b 100644 --- a/src/Umbraco.Core/Models/EntityBase/Entity.cs +++ b/src/Umbraco.Core/Models/EntityBase/Entity.cs @@ -119,7 +119,7 @@ namespace Umbraco.Core.Models.EntityBase if (IsPropertyDirty("CreateDate") == false || _createDate == default(DateTime)) CreateDate = DateTime.Now; if (IsPropertyDirty("UpdateDate") == false || _updateDate == default(DateTime)) - UpdateDate = CreateDate; + UpdateDate = DateTime.Now; } /// @@ -129,6 +129,10 @@ namespace Umbraco.Core.Models.EntityBase { if (IsPropertyDirty("UpdateDate") == false || _updateDate == default(DateTime)) UpdateDate = DateTime.Now; + + //this is just in case + if (_createDate == default(DateTime)) + CreateDate = DateTime.Now; } /// diff --git a/src/Umbraco.Core/Models/Membership/IUserGroup.cs b/src/Umbraco.Core/Models/Membership/IUserGroup.cs index 336caa4c47..d2c58883a2 100644 --- a/src/Umbraco.Core/Models/Membership/IUserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/IUserGroup.cs @@ -5,6 +5,14 @@ namespace Umbraco.Core.Models.Membership { public interface IUserGroup : IAggregateRoot { + int StartContentId { get; set; } + int StartMediaId { get; set; } + + /// + /// The icon + /// + string Icon { get; set; } + /// /// The alias /// diff --git a/src/Umbraco.Core/Models/Membership/UserGroup.cs b/src/Umbraco.Core/Models/Membership/UserGroup.cs index 885a7cbe55..b008f4652f 100644 --- a/src/Umbraco.Core/Models/Membership/UserGroup.cs +++ b/src/Umbraco.Core/Models/Membership/UserGroup.cs @@ -14,7 +14,10 @@ namespace Umbraco.Core.Models.Membership [DataContract(IsReference = true)] internal class UserGroup : Entity, IUserGroup { + private int _startContentId; + private int _startMediaId; private string _alias; + private string _icon; private string _name; private IEnumerable _permissions; private readonly List _sectionCollection; @@ -26,6 +29,9 @@ namespace Umbraco.Core.Models.Membership public readonly PropertyInfo NameSelector = ExpressionHelper.GetPropertyInfo(x => x.Name); public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo(x => x.Alias); public readonly PropertyInfo PermissionsSelector = ExpressionHelper.GetPropertyInfo>(x => x.Permissions); + public readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo(x => x.Icon); + public readonly PropertyInfo StartContentIdSelector = ExpressionHelper.GetPropertyInfo(x => x.StartContentId); + public readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo(x => x.StartMediaId); } public UserGroup() @@ -33,6 +39,27 @@ namespace Umbraco.Core.Models.Membership _sectionCollection = new List(); } + [DataMember] + public int StartMediaId + { + get { return _startMediaId; } + set { SetPropertyValueAndDetectChanges(value, ref _startMediaId, Ps.Value.StartMediaIdSelector); } + } + + [DataMember] + public int StartContentId + { + get { return _startContentId; } + set { SetPropertyValueAndDetectChanges(value, ref _startContentId, Ps.Value.StartContentIdSelector); } + } + + [DataMember] + public string Icon + { + get { return _icon; } + set { SetPropertyValueAndDetectChanges(value, ref _icon, Ps.Value.IconSelector); } + } + [DataMember] public string Alias { diff --git a/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs b/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs index cd700dee68..77f1fed7f1 100644 --- a/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs +++ b/src/Umbraco.Core/Models/Rdbms/UserGroupDto.cs @@ -45,6 +45,10 @@ namespace Umbraco.Core.Models.Rdbms [Constraint(Default = SystemMethods.CurrentDateTime)] public DateTime UpdateDate { get; set; } + [Column("icon")] + [NullSetting(NullSetting = NullSettings.Null)] + public string Icon { get; set; } + [ResultColumn] public List UserGroup2AppDtos { get; set; } } diff --git a/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs b/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs index cdbc153814..a9cbf95c77 100644 --- a/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs +++ b/src/Umbraco.Core/Persistence/Factories/UserGroupFactory.cs @@ -24,6 +24,7 @@ namespace Umbraco.Core.Persistence.Factories : dto.DefaultPermissions.ToCharArray().Select(x => x.ToString(CultureInfo.InvariantCulture)); userGroup.CreateDate = dto.CreateDate; userGroup.UpdateDate = dto.UpdateDate; + userGroup.Icon = dto.Icon; if (dto.UserGroup2AppDtos != null) { @@ -51,7 +52,8 @@ namespace Umbraco.Core.Persistence.Factories Name = entity.Name, UserGroup2AppDtos = new List(), CreateDate = entity.CreateDate, - UpdateDate = entity.UpdateDate + UpdateDate = entity.UpdateDate, + Icon = entity.Icon }; foreach (var app in entity.AllowedSections) diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs index 878fef654d..6b798862b0 100644 --- a/src/Umbraco.Core/Services/IUserService.cs +++ b/src/Umbraco.Core/Services/IUserService.cs @@ -65,14 +65,6 @@ namespace Umbraco.Core.Services /// This is useful when an entire section is removed from config /// Alias of the section to remove void DeleteSectionFromAllUserGroups(string sectionAlias); - - /// - /// Add a specific section to all user groups or those specified as parameters - /// - /// This is useful when a new section is created to allow specific user groups to access it - /// Alias of the section to add - /// Specifiying nothing will add the section to all user - void AddSectionToAllUserGroups(string sectionAlias, params int[] groupIds); /// /// Get permissions set for a user and optional node ids diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 9bba28ee62..8072ecb94d 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -807,39 +807,7 @@ namespace Umbraco.Core.Services uow.Commit(); //TODO: Events? } - } - - /// - /// Add a specific section to all user groups or those specified as parameters - /// - /// This is useful when a new section is created to allow specific user groups to access it - /// Alias of the section to add - /// Specifiying nothing will add the section to all user - public void AddSectionToAllUserGroups(string sectionAlias, params int[] groupIds) - { - using (var uow = UowProvider.GetUnitOfWork()) - { - var repository = RepositoryFactory.CreateUserGroupRepository(uow); - IEnumerable groups; - if (groupIds.Any()) - { - groups = repository.GetAll(groupIds); - } - else - { - groups = repository.GetAll(); - } - foreach (var group in groups.Where(g => g.AllowedSections.InvariantContains(sectionAlias) == false)) - { - //now add the section for each group and commit - group.AddAllowedSection(sectionAlias); - repository.AddOrUpdate(group); - } - - uow.Commit(); - //TODO: Events? - } - } + } /// /// Get permissions set for a user and node Id diff --git a/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs b/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs index 79340d71b3..e9d9163b12 100644 --- a/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs +++ b/src/Umbraco.Tests/Persistence/Repositories/NotificationsRepositoryTest.cs @@ -45,7 +45,7 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); using (var repo = new NotificationsRepository(unitOfWork)) { - var userDto = new UserDto { ContentStartId = -1, Email = "test" , Login = "test" , MediaStartId = -1, Password = "test" , UserName = "test" , UserLanguage = "en" }; + var userDto = new UserDto {ContentStartId = -1, Email = "test", Login = "test", MediaStartId = -1, Password = "test", UserName = "test", UserLanguage = "en", CreateDate = DateTime.Now, UpdateDate = DateTime.Now }; unitOfWork.Database.Insert(userDto); var userNew = Mock.Of(e => e.Id == userDto.Id); @@ -81,7 +81,7 @@ namespace Umbraco.Tests.Persistence.Repositories for (var i = 0; i < 10; i++) { - var userDto = new UserDto { ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", UserName = "test" + i, UserLanguage = "en" }; + var userDto = new UserDto {ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", UserName = "test" + i, UserLanguage = "en", CreateDate = DateTime.Now, UpdateDate = DateTime.Now}; unitOfWork.Database.Insert(userDto); var userNew = Mock.Of(e => e.Id == userDto.Id); var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture)); @@ -109,7 +109,7 @@ namespace Umbraco.Tests.Persistence.Repositories for (var i = 0; i < 10; i++) { - var userDto = new UserDto { ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", UserName = "test" + i, UserLanguage = "en" }; + var userDto = new UserDto {ContentStartId = -1, Email = "test" + i, Login = "test" + i, MediaStartId = -1, Password = "test", UserName = "test" + i, UserLanguage = "en", CreateDate = DateTime.Now, UpdateDate = DateTime.Now}; unitOfWork.Database.Insert(userDto); var userNew = Mock.Of(e => e.Id == userDto.Id); var notification = repo.CreateNotification(userNew, (i % 2 == 0) ? entity1 : entity2, i.ToString(CultureInfo.InvariantCulture)); @@ -128,7 +128,7 @@ namespace Umbraco.Tests.Persistence.Repositories var unitOfWork = provider.GetUnitOfWork(); using (var repo = new NotificationsRepository(unitOfWork)) { - var userDto = new UserDto { ContentStartId = -1, Email = "test", Login = "test", MediaStartId = -1, Password = "test", UserName = "test", UserLanguage = "en" }; + var userDto = new UserDto {ContentStartId = -1, Email = "test", Login = "test", MediaStartId = -1, Password = "test", UserName = "test", UserLanguage = "en", CreateDate = DateTime.Now, UpdateDate = DateTime.Now }; unitOfWork.Database.Insert(userDto); var userNew = Mock.Of(e => e.Id == userDto.Id); diff --git a/src/Umbraco.Tests/Services/UserServiceTests.cs b/src/Umbraco.Tests/Services/UserServiceTests.cs index 682b3695d7..d99f6e70d2 100644 --- a/src/Umbraco.Tests/Services/UserServiceTests.cs +++ b/src/Umbraco.Tests/Services/UserServiceTests.cs @@ -40,7 +40,8 @@ namespace Umbraco.Tests.Services { // Arrange var userService = ServiceContext.UserService; - var user = CreateTestUser(); + IUserGroup userGroup; + var user = CreateTestUser(out userGroup); var contentType = MockedContentTypes.CreateSimpleContentType(); ServiceContext.ContentTypeService.Save(contentType); @@ -67,7 +68,8 @@ namespace Umbraco.Tests.Services { // Arrange var userService = ServiceContext.UserService; - var user = CreateTestUser(); + IUserGroup userGroup; + var user = CreateTestUser(out userGroup); var contentType = MockedContentTypes.CreateSimpleContentType(); ServiceContext.ContentTypeService.Save(contentType); @@ -78,12 +80,12 @@ namespace Umbraco.Tests.Services MockedContent.CreateSimpleContent(contentType) }; ServiceContext.ContentService.Save(content); - ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionBrowse.Instance.Letter, new int[] { 1 }); - ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionDelete.Instance.Letter, new int[] { 1 }); - ServiceContext.ContentService.AssignContentPermission(content.ElementAt(0), ActionMove.Instance.Letter, new int[] { 1 }); - ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionBrowse.Instance.Letter, new int[] { 1 }); - ServiceContext.ContentService.AssignContentPermission(content.ElementAt(1), ActionDelete.Instance.Letter, new int[] { 1 }); - ServiceContext.ContentService.AssignContentPermission(content.ElementAt(2), ActionBrowse.Instance.Letter, new int[] { 1 }); + 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 }); + ServiceContext.ContentService.AssignContentPermission(content.ElementAt(2), ActionBrowse.Instance.Letter, new int[] { userGroup.Id }); // Act var permissions = userService.GetPermissions(user, content.ElementAt(0).Id, content.ElementAt(1).Id, content.ElementAt(2).Id); @@ -476,7 +478,6 @@ namespace Umbraco.Tests.Services { var userGroup = new UserGroup { - Id = 1, Alias = "Group1", Name = "Group 1" }; @@ -521,13 +522,11 @@ namespace Umbraco.Tests.Services { var userGroup1 = new UserGroup { - Id = 1, Alias = "Group1", Name = "Group 1" }; var userGroup2 = new UserGroup { - Id = 2, Alias = "Group2", Name = "Group 2" }; @@ -555,29 +554,27 @@ namespace Umbraco.Tests.Services { var userGroup1 = new UserGroup { - Id = 1, Alias = "Group1", Name = "Group 1" }; + userGroup1.AddAllowedSection("test"); + var userGroup2 = new UserGroup { - Id = 2, Alias = "Group2", Name = "Group 2" }; + userGroup2.AddAllowedSection("test"); + var userGroup3 = new UserGroup - { - Id = 3, + { Alias = "Group3", Name = "Group 3" }; ServiceContext.UserService.Save(userGroup1); ServiceContext.UserService.Save(userGroup2); ServiceContext.UserService.Save(userGroup3); - - //now add the section to specific groups - ServiceContext.UserService.AddSectionToAllUserGroups("test", userGroup1.Id, userGroup2.Id); - + //assert var result1 = ServiceContext.UserService.GetUserGroupById(userGroup1.Id); var result2 = ServiceContext.UserService.GetUserGroupById(userGroup2.Id); @@ -587,7 +584,11 @@ namespace Umbraco.Tests.Services Assert.IsFalse(result3.AllowedSections.Contains("test")); //now add the section to all groups - ServiceContext.UserService.AddSectionToAllUserGroups("test"); + foreach (var userGroup in new[]{userGroup1, userGroup2, userGroup3}) + { + userGroup.AddAllowedSection("test"); + ServiceContext.UserService.Save(userGroup); + } //assert result1 = ServiceContext.UserService.GetUserGroupById(userGroup1.Id); @@ -668,7 +669,8 @@ namespace Umbraco.Tests.Services public void Get_User_By_Username() { // Arrange - var originalUser = CreateTestUser(); + IUserGroup userGroup; + var originalUser = CreateTestUser(out userGroup); // Act @@ -689,9 +691,9 @@ namespace Umbraco.Tests.Services Assert.That(updatedItem.AllowedSections.Count(), Is.EqualTo(2)); } - private IUser CreateTestUser() + private IUser CreateTestUser(out IUserGroup userGroup) { - var userGroup = CreateTestUserGroup(); + userGroup = CreateTestUserGroup(); var user = ServiceContext.UserService.CreateUserWithIdentity("test1", "test1@test.com"); user.AddGroup(userGroup.Alias); @@ -703,14 +705,16 @@ namespace Umbraco.Tests.Services { var userGroup = new UserGroup { - Id = 1, Alias = "testGroup", Name = "Test Group", Permissions = "ABCDEFGHIJ1234567".ToCharArray().Select(x => x.ToString()) }; - ServiceContext.UserService.Save(userGroup); - ServiceContext.UserService.AddSectionToAllUserGroups("content", 1); - ServiceContext.UserService.AddSectionToAllUserGroups("media", 1); + + userGroup.AddAllowedSection("content"); + userGroup.AddAllowedSection("media"); + + ServiceContext.UserService.Save(userGroup); + return userGroup; } } diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 575e354876..24d1c50a65 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -53,6 +53,15 @@ namespace Umbraco.Web.Editors return Mapper.Map(user); } + /// + /// Returns all user groups + /// + /// + public IEnumerable GetUserGroups() + { + return Mapper.Map< IEnumerable, IEnumerable>(Services.UserService.GetAllUserGroups()); + } + /// /// Returns a paged users collection /// @@ -118,12 +127,13 @@ namespace Umbraco.Web.Editors /// public bool PostDisableUsers([FromUri]int[] userIds) { - var users = Services.UserService.GetUsersById(userIds); + var users = Services.UserService.GetUsersById(userIds).ToArray(); foreach (var u in users) { - //without the permanent flag, this will just disable - Services.UserService.Delete(u); + u.IsApproved = false; } + Services.UserService.Save(users); + return true; } diff --git a/src/Umbraco.Web/Models/ContentEditing/UserDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/UserDisplay.cs index fe1933669b..a0c2a8ef33 100644 --- a/src/Umbraco.Web/Models/ContentEditing/UserDisplay.cs +++ b/src/Umbraco.Web/Models/ContentEditing/UserDisplay.cs @@ -39,7 +39,7 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "email", IsRequired = true)] public string Email { get; set; } - + /// /// The list of group aliases assigned to the user /// @@ -60,9 +60,11 @@ namespace Umbraco.Web.Models.ContentEditing [DataMember(Name = "availableCultures")] public IDictionary AvailableCultures { get; set; } + //TODO: This will become StartContentIds as an array! [DataMember(Name = "startContentId")] public int StartContentId { get; set; } + //TODO: This will become StartMediaIds as an array! [DataMember(Name = "startMediaId")] public int StartMediaId { get; set; } diff --git a/src/Umbraco.Web/Models/ContentEditing/UserGroupDisplay.cs b/src/Umbraco.Web/Models/ContentEditing/UserGroupDisplay.cs new file mode 100644 index 0000000000..06e24b7d38 --- /dev/null +++ b/src/Umbraco.Web/Models/ContentEditing/UserGroupDisplay.cs @@ -0,0 +1,29 @@ +using System.Collections.Generic; +using System.Runtime.Serialization; + +namespace Umbraco.Web.Models.ContentEditing +{ + [DataContract(Name = "userGroup", Namespace = "")] + public class UserGroupDisplay : EntityBasic, INotificationModel + { + public UserGroupDisplay() + { + Notifications = new List(); + } + + /// + /// This is used to add custom localized messages/strings to the response for the app to use for localized UI purposes. + /// + [DataMember(Name = "notifications")] + public List Notifications { get; private set; } + + [DataMember(Name = "sections")] + public IEnumerable Sections { get; set; } + + [DataMember(Name = "startNodeContent")] + public int StartContentId { get; set; } + + [DataMember(Name = "startNodeMedia")] + public int StartMediaId { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs index 00e8e9a230..885d61bccb 100644 --- a/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs +++ b/src/Umbraco.Web/Models/Mapping/UserModelMapper.cs @@ -16,8 +16,9 @@ namespace Umbraco.Web.Models.Mapping { public override void ConfigureMappings(IConfiguration config, ApplicationContext applicationContext) { - config.CreateMap() - .ForMember(detail => detail.Id, opt => opt.MapFrom(user => user.Id)) + config.CreateMap(); + + config.CreateMap() .ForMember(detail => detail.UserGroups, opt => opt.MapFrom(user => user.Groups)) .ForMember(detail => detail.StartContentId, opt => opt.MapFrom(user => user.StartContentId)) .ForMember(detail => detail.StartMediaId, opt => opt.MapFrom(user => user.StartMediaId)) diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index 43b85365d7..6666189113 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -368,6 +368,7 @@ +