diff --git a/src/Umbraco.Web/Editors/ContentController.cs b/src/Umbraco.Web/Editors/ContentController.cs index c8e598016a..a0dfe0f454 100644 --- a/src/Umbraco.Web/Editors/ContentController.cs +++ b/src/Umbraco.Web/Editors/ContentController.cs @@ -9,6 +9,7 @@ using System.Web.Http; using System.Web.Http.Controllers; using System.Web.Http.ModelBinding; using AutoMapper; +using umbraco.BusinessLogic.Actions; using Umbraco.Core; using Umbraco.Core.Logging; using Umbraco.Core.Models; @@ -94,6 +95,8 @@ namespace Umbraco.Web.Editors public IEnumerable PostSaveUserGroupPermissions(UserGroupPermissionsSave saveModel) { if (saveModel.ContentId <= 0) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); + + //TODO: Should non-admins be alowed to set granular permissions? var content = Services.ContentService.GetById(saveModel.ContentId); if (content == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); @@ -156,7 +159,9 @@ namespace Umbraco.Web.Editors if (contentId <= 0) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); var content = Services.ContentService.GetById(contentId); if (content == null) throw new HttpResponseException(Request.CreateResponse(HttpStatusCode.NotFound)); - + + //TODO: Should non-admins be able to see detailed permissions? + var allUserGroups = Services.UserService.GetAllUserGroups(); return GetDetailedPermissions(content, allUserGroups); diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index eabc2bd248..e82cecdbaa 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -9,6 +9,7 @@ using System.Runtime.Serialization; using System.Threading.Tasks; using System.Web; using System.Web.Http; +using System.Web.Http.Controllers; using System.Web.Mvc; using System.Web.Routing; using System.Web.Security; @@ -30,6 +31,7 @@ using Umbraco.Web.Models.ContentEditing; using Umbraco.Web.Mvc; using Umbraco.Web.WebApi; using Umbraco.Web.WebApi.Filters; +using ActionFilterAttribute = System.Web.Http.Filters.ActionFilterAttribute; using Constants = Umbraco.Core.Constants; using IUser = Umbraco.Core.Models.Membership.IUser; using Task = System.Threading.Tasks.Task; @@ -63,8 +65,7 @@ namespace Umbraco.Web.Editors : base(umbracoContext, umbracoHelper, backOfficeUserManager) { } - - + /// /// Returns a list of the sizes of gravatar urls for the user or null if the gravatar server cannot be reached /// @@ -190,8 +191,6 @@ namespace Umbraco.Web.Editors return Mapper.Map(user); } - - /// /// Returns a paged users collection /// @@ -212,6 +211,30 @@ namespace Umbraco.Web.Editors [FromUri]UserState[] userStates = null, string filter = "") { + //following the same principle we had in previous versions, we would only show admins to admins, see + // https://github.com/umbraco/Umbraco-CMS/blob/dev-v7/src/Umbraco.Web/umbraco.presentation/umbraco/Trees/loadUsers.cs#L91 + // so to do that here, we'll need to check if this current user is an admin and if not we should exclude all user who are + // also admins + + var isAdmin = Security.CurrentUser.IsAdmin(); + if (isAdmin == false) + { + //this user is not an admin so in that case we need to either: + //A) remove the admin group from the userGroup filter if one is supplied + //B) if no filter is applied, create a filter based on all of the groups except for admin + if (userGroups != null && userGroups.Length > 0) + { + userGroups = userGroups.Except(new[] { Constants.Security.AdminGroupAlias }).ToArray(); + } + else + { + userGroups = Services.UserService.GetAllUserGroups() + .Where(x => x.Alias != Constants.Security.AdminGroupAlias) + .Select(x => x.Alias) + .ToArray(); + } + } + long pageIndex = pageNumber - 1; long total; var result = Services.UserService.GetAll(pageIndex, pageSize, out total, orderBy, orderDirection, userStates, userGroups, filter); @@ -359,9 +382,7 @@ namespace Umbraco.Web.Editors return display; } - - private HttpContextBase EnsureHttpContext() { var attempt = this.TryGetHttpContext(); @@ -432,6 +453,11 @@ namespace Umbraco.Web.Editors if (found == null) throw new HttpResponseException(HttpStatusCode.NotFound); + //TODO: + // a) A non-admin cannot save an admin + // b) A user cannot set a start node on another user that they don't have access to + // c) A user cannot set a section on another user that they don't have access to + var hasErrors = false; var existing = Services.UserService.GetByEmail(userSave.Email); @@ -557,8 +583,8 @@ namespace Umbraco.Web.Editors return Request.CreateNotificationSuccessResponse( Services.TextService.Localize("speechBubbles/enableUserSuccess", new[] { users[0].Name })); - } - + } + /// /// Unlocks the users with the given user ids /// @@ -592,7 +618,7 @@ namespace Umbraco.Web.Editors } return Request.CreateNotificationSuccessResponse( - Services.TextService.Localize("speechBubbles/unlockUsersSuccess", new[] { userIds.Length.ToString() })); + Services.TextService.Localize("speechBubbles/unlockUsersSuccess", new[] { userIds.Length.ToString() })); } public HttpResponseMessage PostSetUserGroupsOnUsers([FromUri]string[] userGroupAliases, [FromUri]int[] userIds) @@ -625,5 +651,48 @@ namespace Umbraco.Web.Editors [DataMember(Name = "userStates")] public IDictionary UserStates { get; set; } } + + //internal class NonAdminAuthorizationFilterAttribute : ActionFilterAttribute + //{ + // public override void OnActionExecuting(HttpActionContext actionContext) + // { + // var contentItem = (ContentItemSave)actionContext.ActionArguments["userSave"]; + + + // } + //} + } + + internal class UserEditorAuthorizationHelper + { + private readonly IContentService _contentService; + private readonly IMediaService _mediaService; + private readonly IEntityService _entityService; + + public UserEditorAuthorizationHelper(IContentService contentService, IMediaService mediaService, IEntityService entityService) + { + _contentService = contentService; + _mediaService = mediaService; + _entityService = entityService; + } + + public bool AuthorizeActions(IUser currentUser, IUser savingUser) + { + // a) A non-admin cannot save an admin + + var currentIsAdmin = currentUser.IsAdmin(); + var savingIsAdmin = savingUser.IsAdmin(); + if (currentIsAdmin == false && savingIsAdmin) + return false; + + // b) A user cannot set a start node on another user that they don't have access to + + //var startContent = _contentService. + //var currentHasContentAccess = currentUser.HasPathAccess() + + // c) A user cannot set a section on another user that they don't have access to + + return true; + } } } \ No newline at end of file