diff --git a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs index e40d996637..542cceac40 100644 --- a/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/Interfaces/IUserRepository.cs @@ -55,5 +55,13 @@ namespace Umbraco.Core.Persistence.Repositories /// /// void ReplaceUserPermissions(int userId, IEnumerable permissions, params int[] entityIds); + + /// + /// Assigns the same permission set for a single user to any number of entities + /// + /// + /// + /// + void AssignUserPermission(int userId, char permission, 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 8a2cd21acd..10c20663e4 100644 --- a/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/PermissionRepository.cs @@ -152,6 +152,42 @@ namespace Umbraco.Core.Persistence.Repositories AssignedPermissions.RaiseEvent( new SaveEventArgs(ConvertToPermissionList(toInsert), false), this); } + } + + /// + /// Assigns one permission for a user to many entities + /// + /// + /// + /// + public void AssignUserPermission(int userId, char permission, params int[] entityIds) + { + var db = _unitOfWork.Database; + using (var trans = db.GetTransaction()) + { + db.Execute("DELETE FROM umbracoUser2NodePermission WHERE userId=@userId AND permission=@permission AND nodeId in (@entityIds)", + new + { + userId = userId, + permission = permission.ToString(CultureInfo.InvariantCulture), + entityIds = entityIds + }); + + var actions = entityIds.Select(id => new User2NodePermissionDto + { + NodeId = id, + Permission = permission.ToString(CultureInfo.InvariantCulture), + UserId = userId + }).ToArray(); + + _unitOfWork.Database.BulkInsertRecords(actions, trans); + + trans.Complete(); + + //Raise the event + AssignedPermissions.RaiseEvent( + new SaveEventArgs(ConvertToPermissionList(actions), false), this); + } } /// diff --git a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs index 670cb89c5d..86eb2964fc 100644 --- a/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs +++ b/src/Umbraco.Core/Persistence/Repositories/UserRepository.cs @@ -389,6 +389,18 @@ namespace Umbraco.Core.Persistence.Repositories repo.ReplaceUserPermissions(userId, permissions, entityIds); } + /// + /// Assigns the same permission set for a single user to any number of entities + /// + /// + /// + /// + public void AssignUserPermission(int userId, char permission, params int[] entityIds) + { + var repo = new PermissionRepository(UnitOfWork, _cacheHelper, SqlSyntax); + repo.AssignUserPermission(userId, permission, entityIds); + } + #endregion private IEnumerable ConvertFromDtos(IEnumerable dtos) diff --git a/src/Umbraco.Core/Services/ContentServiceExtensions.cs b/src/Umbraco.Core/Services/ContentServiceExtensions.cs index 5180955542..4919a81217 100644 --- a/src/Umbraco.Core/Services/ContentServiceExtensions.cs +++ b/src/Umbraco.Core/Services/ContentServiceExtensions.cs @@ -1,9 +1,20 @@ using System.Linq; +using Umbraco.Core.Models.Membership; namespace Umbraco.Core.Services { public static class ContentServiceExtensions { + /// + /// Remove all permissions for this user for all nodes + /// + /// + /// + public static void RemoveContentPermissions(this IContentService contentService, int contentId) + { + contentService.ReplaceContentPermissions(new EntityPermissionSet(contentId, Enumerable.Empty())); + } + /// /// Returns true if there is any content in the recycle bin /// diff --git a/src/Umbraco.Core/Services/IUserService.cs b/src/Umbraco.Core/Services/IUserService.cs index aa8250cf59..7353f44cb8 100644 --- a/src/Umbraco.Core/Services/IUserService.cs +++ b/src/Umbraco.Core/Services/IUserService.cs @@ -73,13 +73,24 @@ namespace Umbraco.Core.Services /// /// Replaces the same permission set for a single user to any number of entities - /// - /// If no 'entityIds' are specified all permissions will be removed for the specified user. + /// /// Id of the user - /// Permissions as enumerable list of + /// + /// Permissions as enumerable list of , + /// if no permissions are specified then all permissions for this node are removed for this user + /// /// Specify the nodes to replace permissions for. If nothing is specified all permissions are removed. + /// If no 'entityIds' are specified all permissions will be removed for the specified user. void ReplaceUserPermissions(int userId, IEnumerable permissions, params int[] entityIds); + /// + /// Assigns the same permission set for a single user to any number of entities + /// + /// Id of the user + /// + /// Specify the nodes to replace permissions for + void AssignUserPermission(int userId, char permission, params int[] entityIds); + #region User types /// diff --git a/src/Umbraco.Core/Services/UserService.cs b/src/Umbraco.Core/Services/UserService.cs index 6ba20cd4fa..961175f455 100644 --- a/src/Umbraco.Core/Services/UserService.cs +++ b/src/Umbraco.Core/Services/UserService.cs @@ -559,6 +559,21 @@ namespace Umbraco.Core.Services } } + /// + /// Assigns the same permission set for a single user to any number of entities + /// + /// Id of the user + /// + /// Specify the nodes to replace permissions for + public void AssignUserPermission(int userId, char permission, params int[] entityIds) + { + var uow = UowProvider.GetUnitOfWork(); + using (var repository = RepositoryFactory.CreateUserRepository(uow)) + { + repository.AssignUserPermission(userId, permission, entityIds); + } + } + /// /// Gets all UserTypes or thosed specified as parameters /// diff --git a/src/Umbraco.Core/Services/UserServiceExtensions.cs b/src/Umbraco.Core/Services/UserServiceExtensions.cs index b97a40ace8..afb679afa1 100644 --- a/src/Umbraco.Core/Services/UserServiceExtensions.cs +++ b/src/Umbraco.Core/Services/UserServiceExtensions.cs @@ -6,6 +6,27 @@ namespace Umbraco.Core.Services { internal static class UserServiceExtensions { + /// + /// Remove all permissions for this user for all nodes specified + /// + /// + /// + /// + public static void RemoveUserPermissions(this IUserService userService, int userId, params int[] entityIds) + { + userService.ReplaceUserPermissions(userId, new char[] {}, entityIds); + } + + /// + /// Remove all permissions for this user for all nodes + /// + /// + /// + public static void RemoveUserPermissions(this IUserService userService, int userId) + { + userService.ReplaceUserPermissions(userId, new char[] { }); + } + /// /// Maps a custom provider's information to an umbraco user account /// diff --git a/src/umbraco.businesslogic/Properties/AssemblyInfo.cs b/src/umbraco.businesslogic/Properties/AssemblyInfo.cs index 73bfa02ee2..ca3992844b 100644 --- a/src/umbraco.businesslogic/Properties/AssemblyInfo.cs +++ b/src/umbraco.businesslogic/Properties/AssemblyInfo.cs @@ -18,4 +18,5 @@ using System.Runtime.CompilerServices; [assembly: InternalsVisibleTo("Umbraco.Tests")] [assembly: InternalsVisibleTo("umbraco")] +[assembly: InternalsVisibleTo("cms")] [assembly: InternalsVisibleTo("Umbraco.LegacyTests")] \ No newline at end of file diff --git a/src/umbraco.businesslogic/User.cs b/src/umbraco.businesslogic/User.cs index e3349f6af6..475a2614dd 100644 --- a/src/umbraco.businesslogic/User.cs +++ b/src/umbraco.businesslogic/User.cs @@ -23,7 +23,7 @@ namespace umbraco.BusinessLogic [Obsolete("Use the UserService instead")] public class User { - private IUser _user; + internal IUser UserEntity; private int? _lazyId; private bool? _defaultToLiveEditing; @@ -38,7 +38,7 @@ namespace umbraco.BusinessLogic internal User(IUser user) { - _user = user; + UserEntity = user; } /// @@ -81,8 +81,8 @@ namespace umbraco.BusinessLogic private void SetupUser(int ID) { - _user = ApplicationContext.Current.Services.UserService.GetUserById(ID); - if (_user == null) + UserEntity = ApplicationContext.Current.Services.UserService.GetUserById(ID); + if (UserEntity == null) { throw new ArgumentException("No User exists with ID " + ID); } @@ -95,7 +95,7 @@ namespace umbraco.BusinessLogic { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - ApplicationContext.Current.Services.UserService.Save(_user); + ApplicationContext.Current.Services.UserService.Save(UserEntity); OnSaving(EventArgs.Empty); } @@ -109,11 +109,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.Name; + return UserEntity.Name; } set { - _user.Name = value; + UserEntity.Name = value; } } @@ -127,11 +127,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.Email; + return UserEntity.Email; } set { - _user.Email = value; + UserEntity.Email = value; } } @@ -144,11 +144,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.Language; + return UserEntity.Language; } set { - _user.Language = value; + UserEntity.Language = value; } } @@ -164,7 +164,7 @@ namespace umbraco.BusinessLogic } set { - _user.RawPasswordValue = value; + UserEntity.RawPasswordValue = value; } } @@ -175,7 +175,7 @@ namespace umbraco.BusinessLogic public string GetPassword() { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.RawPasswordValue; + return UserEntity.RawPasswordValue; } /// @@ -233,7 +233,7 @@ namespace umbraco.BusinessLogic var allApps = Application.getAll(); var apps = new List(); - var sections = _user.AllowedSections; + var sections = UserEntity.AllowedSections; foreach (var s in sections) { @@ -254,14 +254,14 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.Username; + return UserEntity.Username; } set { if (EnsureUniqueLoginName(value, this) == false) throw new Exception(String.Format("A user with the login '{0}' already exists", value)); - _user.Username = value; + UserEntity.Username = value; } } @@ -327,11 +327,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return new UserType(_user.UserType); + return new UserType(UserEntity.UserType); } set { - _user.UserType = value.UserTypeItem; + UserEntity.UserType = value.UserTypeItem; } } @@ -576,7 +576,7 @@ namespace umbraco.BusinessLogic OnDeleting(EventArgs.Empty); - ApplicationContext.Current.Services.UserService.Delete(_user, true); + ApplicationContext.Current.Services.UserService.Delete(UserEntity, true); FlushFromCache(); } @@ -589,7 +589,7 @@ namespace umbraco.BusinessLogic OnDisabling(EventArgs.Empty); //delete without the true overload will perform the disable operation - ApplicationContext.Current.Services.UserService.Delete(_user); + ApplicationContext.Current.Services.UserService.Delete(UserEntity); } /// @@ -603,7 +603,7 @@ namespace umbraco.BusinessLogic var defaultPermissions = UserType.DefaultPermissions; - var cachedPermissions = ApplicationContext.Current.Services.UserService.GetPermissions(_user) + var cachedPermissions = ApplicationContext.Current.Services.UserService.GetPermissions(UserEntity) .ToArray(); // NH 4.7.1 changing default permission behavior to default to User Type permissions IF no specific permissions has been @@ -668,7 +668,7 @@ namespace umbraco.BusinessLogic { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - var notifications = ApplicationContext.Current.Services.NotificationService.GetUserNotifications(_user); + var notifications = ApplicationContext.Current.Services.NotificationService.GetUserNotifications(UserEntity); foreach (var n in notifications.OrderBy(x => x.EntityId)) { int nodeId = n.EntityId; @@ -688,7 +688,7 @@ namespace umbraco.BusinessLogic /// The id. public int Id { - get { return _user.Id; } + get { return UserEntity.Id; } } /// @@ -697,9 +697,9 @@ namespace umbraco.BusinessLogic public void ClearApplications() { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - foreach (var s in _user.AllowedSections.ToArray()) + foreach (var s in UserEntity.AllowedSections.ToArray()) { - _user.RemoveAllowedSection(s); + UserEntity.RemoveAllowedSection(s); } } @@ -711,13 +711,13 @@ namespace umbraco.BusinessLogic { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - foreach (var s in _user.AllowedSections.ToArray()) + foreach (var s in UserEntity.AllowedSections.ToArray()) { - _user.RemoveAllowedSection(s); + UserEntity.RemoveAllowedSection(s); } //For backwards compatibility this requires an implicit save - ApplicationContext.Current.Services.UserService.Save(_user); + ApplicationContext.Current.Services.UserService.Save(UserEntity); } /// @@ -727,7 +727,7 @@ namespace umbraco.BusinessLogic public void AddApplication(string appAlias) { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - _user.AddAllowedSection(appAlias); + UserEntity.AddAllowedSection(appAlias); } /// @@ -739,10 +739,10 @@ namespace umbraco.BusinessLogic { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - _user.AddAllowedSection(AppAlias); + UserEntity.AddAllowedSection(AppAlias); //For backwards compatibility this requires an implicit save - ApplicationContext.Current.Services.UserService.Save(_user); + ApplicationContext.Current.Services.UserService.Save(UserEntity); } /// @@ -754,11 +754,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.IsLockedOut; + return UserEntity.IsLockedOut; } set { - _user.IsLockedOut = value; + UserEntity.IsLockedOut = value; } } @@ -771,11 +771,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.IsApproved == false; + return UserEntity.IsApproved == false; } set { - _user.IsApproved = value == false; + UserEntity.IsApproved = value == false; } } @@ -789,11 +789,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.StartContentId; + return UserEntity.StartContentId; } set { - _user.StartContentId = value; + UserEntity.StartContentId = value; } } @@ -806,11 +806,11 @@ namespace umbraco.BusinessLogic get { if (_lazyId.HasValue) SetupUser(_lazyId.Value); - return _user.StartMediaId; + return UserEntity.StartMediaId; } set { - _user.StartMediaId = value; + UserEntity.StartMediaId = value; } } diff --git a/src/umbraco.cms/businesslogic/Permission.cs b/src/umbraco.cms/businesslogic/Permission.cs index ba0ad56b14..1a598452fe 100644 --- a/src/umbraco.cms/businesslogic/Permission.cs +++ b/src/umbraco.cms/businesslogic/Permission.cs @@ -2,7 +2,6 @@ using System; using System.Collections; using System.Collections.Specialized; using System.Data; -using System.Globalization; using System.Linq; using System.Runtime.CompilerServices; using Umbraco.Core; @@ -10,13 +9,12 @@ using Umbraco.Core.Events; using umbraco.DataLayer; using umbraco.cms.businesslogic; using System.Collections.Generic; +using Umbraco.Core.Models.Membership; +using Umbraco.Core.Services; using DeleteEventArgs = umbraco.cms.businesslogic.DeleteEventArgs; namespace umbraco.BusinessLogic { - - //TODO: Wrap this in the new services/repo layer! - /// /// Summary description for Permission. /// @@ -31,39 +29,17 @@ namespace umbraco.BusinessLogic /// Private constructor, this class cannot be directly instantiated /// private Permission() { } - - private static ISqlHelper SqlHelper - { - get { return Application.SqlHelper; } - } - - + public static void MakeNew(User User, CMSNode Node, char PermissionKey) { MakeNew(User, Node, PermissionKey, true); } - [MethodImpl(MethodImplOptions.Synchronized)] - internal static void MakeNew(User user, IEnumerable nodes, char permissionKey, bool raiseEvents) + private static void MakeNew(User user, IEnumerable nodes, char permissionKey, bool raiseEvents) { var asArray = nodes.ToArray(); - foreach (var node in asArray) - { - var parameters = new[] { SqlHelper.CreateParameter("@userId", user.Id), - SqlHelper.CreateParameter("@nodeId", node.Id), - SqlHelper.CreateParameter("@permission", permissionKey.ToString()) }; - // Method is synchronized so exists remains consistent (avoiding race condition) - var exists = SqlHelper.ExecuteScalar( - "SELECT COUNT(userId) FROM umbracoUser2nodePermission WHERE userId = @userId AND nodeId = @nodeId AND permission = @permission", - parameters) > 0; - - if (exists) return; - - SqlHelper.ExecuteNonQuery( - "INSERT INTO umbracoUser2nodePermission (userId, nodeId, permission) VALUES (@userId, @nodeId, @permission)", - parameters); - } + ApplicationContext.Current.Services.UserService.AssignUserPermission(user.Id, permissionKey, asArray.Select(x => x.Id).ToArray()); if (raiseEvents) { @@ -83,20 +59,17 @@ namespace umbraco.BusinessLogic /// public static IEnumerable GetUserPermissions(User user) { - var items = new List(); - using (IRecordsReader dr = SqlHelper.ExecuteReader("select * from umbracoUser2NodePermission where userId = @userId order by nodeId", SqlHelper.CreateParameter("@userId", user.Id))) - { - while (dr.Read()) + var permissions = ApplicationContext.Current.Services.UserService.GetPermissions(user.UserEntity); + + return permissions.SelectMany( + entityPermission => entityPermission.AssignedPermissions, + (entityPermission, assignedPermission) => new Permission { - items.Add(new Permission() - { - NodeId = dr.GetInt("nodeId"), - PermissionId = Convert.ToChar(dr.GetString("permission")), - UserId = dr.GetInt("userId") - }); - } - } - return items; + NodeId = entityPermission.EntityId, + PermissionId = assignedPermission[0], + UserId = entityPermission.UserId + }); + } /// @@ -106,20 +79,19 @@ namespace umbraco.BusinessLogic /// public static IEnumerable GetNodePermissions(CMSNode node) { - var items = new List(); - using (IRecordsReader dr = SqlHelper.ExecuteReader("select * from umbracoUser2NodePermission where nodeId = @nodeId order by nodeId", SqlHelper.CreateParameter("@nodeId", node.Id))) - { - while (dr.Read()) + var content = ApplicationContext.Current.Services.ContentService.GetById(node.Id); + if (content == null) return Enumerable.Empty(); + + var permissions = ApplicationContext.Current.Services.ContentService.GetPermissionsForEntity(content); + + return permissions.SelectMany( + entityPermission => entityPermission.AssignedPermissions, + (entityPermission, assignedPermission) => new Permission { - items.Add(new Permission() - { - NodeId = dr.GetInt("nodeId"), - PermissionId = Convert.ToChar(dr.GetString("permission")), - UserId = dr.GetInt("userId") - }); - } - } - return items; + NodeId = entityPermission.EntityId, + PermissionId = assignedPermission[0], + UserId = entityPermission.UserId + }); } /// @@ -134,10 +106,7 @@ namespace umbraco.BusinessLogic internal static void DeletePermissions(User user, CMSNode node, bool raiseEvents) { - // delete all settings on the node for this user - SqlHelper.ExecuteNonQuery("delete from umbracoUser2NodePermission where userId = @userId and nodeId = @nodeId", - SqlHelper.CreateParameter("@userId", user.Id), SqlHelper.CreateParameter("@nodeId", node.Id)); - + ApplicationContext.Current.Services.UserService.RemoveUserPermissions(user.Id, node.Id); if (raiseEvents) { OnDeleted(new UserPermission(user, node, null), new DeleteEventArgs()); @@ -150,19 +119,14 @@ namespace umbraco.BusinessLogic /// public static void DeletePermissions(User user) { - // delete all settings on the node for this user - SqlHelper.ExecuteNonQuery("delete from umbracoUser2NodePermission where userId = @userId", - SqlHelper.CreateParameter("@userId", user.Id)); + ApplicationContext.Current.Services.UserService.RemoveUserPermissions(user.Id); OnDeleted(new UserPermission(user, Enumerable.Empty(), null), new DeleteEventArgs()); } public static void DeletePermissions(int iUserID, int[] iNodeIDs) { - var sql = "DELETE FROM umbracoUser2NodePermission WHERE nodeID IN ({0}) AND userID=@userID"; - var nodeIDs = string.Join(",", Array.ConvertAll(iNodeIDs, Converter)); - sql = string.Format(sql, nodeIDs); - SqlHelper.ExecuteNonQuery(sql, new[] { SqlHelper.CreateParameter("@userID", iUserID) }); + ApplicationContext.Current.Services.UserService.RemoveUserPermissions(iUserID, iNodeIDs); OnDeleted(new UserPermission(iUserID, iNodeIDs), new DeleteEventArgs()); } @@ -170,10 +134,6 @@ namespace umbraco.BusinessLogic { DeletePermissions(iUserID, new[] { iNodeID }); } - private static string Converter(int from) - { - return from.ToString(CultureInfo.InvariantCulture); - } /// /// delete all permissions for this node @@ -181,14 +141,11 @@ namespace umbraco.BusinessLogic /// public static void DeletePermissions(CMSNode node) { - SqlHelper.ExecuteNonQuery( - "delete from umbracoUser2NodePermission where nodeId = @nodeId", - SqlHelper.CreateParameter("@nodeId", node.Id)); - + ApplicationContext.Current.Services.ContentService.RemoveContentPermissions(node.Id); + OnDeleted(new UserPermission(null, node, null), new DeleteEventArgs()); } - [MethodImpl(MethodImplOptions.Synchronized)] public static void UpdateCruds(User user, CMSNode node, string permissions) { ApplicationContext.Current.Services.UserService.ReplaceUserPermissions(