Ensures admin can access anything
This commit is contained in:
114
src/Umbraco.Web/Editors/UserEditorAuthorizationHelper.cs
Normal file
114
src/Umbraco.Web/Editors/UserEditorAuthorizationHelper.cs
Normal file
@@ -0,0 +1,114 @@
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
using Umbraco.Core.Services;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
{
|
||||
internal class UserEditorAuthorizationHelper
|
||||
{
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IEntityService _entityService;
|
||||
|
||||
public UserEditorAuthorizationHelper(IContentService contentService, IMediaService mediaService, IUserService userService, IEntityService entityService)
|
||||
{
|
||||
_contentService = contentService;
|
||||
_mediaService = mediaService;
|
||||
_userService = userService;
|
||||
_entityService = entityService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current user has access to save the user data
|
||||
/// </summary>
|
||||
/// <param name="currentUser">The current user trying to save user data</param>
|
||||
/// <param name="savingUser">The user instance being saved (can be null if it's a new user)</param>
|
||||
/// <param name="startContentIds">The start content ids of the user being saved (can be null or empty)</param>
|
||||
/// <param name="startMediaIds">The start media ids of the user being saved (can be null or empty)</param>
|
||||
/// <param name="userGroupAliases">The user aliases of the user being saved (can be null or empty)</param>
|
||||
/// <returns></returns>
|
||||
public Attempt<string> AuthorizeActions(IUser currentUser,
|
||||
IUser savingUser,
|
||||
IEnumerable<int> startContentIds, IEnumerable<int> startMediaIds,
|
||||
IEnumerable<string> userGroupAliases)
|
||||
{
|
||||
var currentIsAdmin = currentUser.IsAdmin();
|
||||
|
||||
// a1) An admin can edit anything
|
||||
if (currentIsAdmin)
|
||||
return Attempt<string>.Succeed();
|
||||
|
||||
// a2) A non-admin cannot save an admin
|
||||
|
||||
if (savingUser != null)
|
||||
{
|
||||
if (savingUser.IsAdmin())
|
||||
return Attempt.Fail("The current user is not an administrator");
|
||||
}
|
||||
|
||||
// b0) A user cannot set a start node on another user that they don't have access to
|
||||
|
||||
var pathResult = AuthorizePath(currentUser, startContentIds, startMediaIds);
|
||||
if (pathResult == false)
|
||||
return pathResult;
|
||||
|
||||
if (userGroupAliases != null)
|
||||
{
|
||||
var userGroups = _userService.GetUserGroupsByAlias(userGroupAliases.ToArray()).ToArray();
|
||||
|
||||
// b1) A user cannot assign a group to another user that grants them access to a start node they don't have access to
|
||||
foreach (var group in userGroups)
|
||||
{
|
||||
pathResult = AuthorizePath(currentUser,
|
||||
group.StartContentId.HasValue ? new[] { group.StartContentId.Value } : null,
|
||||
group.StartMediaId.HasValue ? new[] { group.StartMediaId.Value } : null);
|
||||
if (pathResult == false)
|
||||
return pathResult;
|
||||
}
|
||||
|
||||
// c) A user cannot set a section on another user that they don't have access to
|
||||
var allGroupSections = userGroups.SelectMany(x => x.AllowedSections).Distinct();
|
||||
var missingSectionAccess = allGroupSections.Except(currentUser.AllowedSections).ToArray();
|
||||
if (missingSectionAccess.Length > 0)
|
||||
{
|
||||
return Attempt.Fail("The current user does not have access to sections " + string.Join(",", missingSectionAccess));
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<string>.Succeed();
|
||||
}
|
||||
|
||||
private Attempt<string> AuthorizePath(IUser currentUser, IEnumerable<int> startContentIds, IEnumerable<int> startMediaIds)
|
||||
{
|
||||
if (startContentIds != null)
|
||||
{
|
||||
foreach (var contentId in startContentIds)
|
||||
{
|
||||
var content = _contentService.GetById(contentId);
|
||||
if (content == null) continue;
|
||||
var hasAccess = currentUser.HasPathAccess(content, _entityService);
|
||||
if (hasAccess == false)
|
||||
return Attempt.Fail("The current user does not have access to the content path " + content.Path);
|
||||
}
|
||||
}
|
||||
|
||||
if (startMediaIds != null)
|
||||
{
|
||||
foreach (var mediaId in startMediaIds)
|
||||
{
|
||||
var media = _mediaService.GetById(mediaId);
|
||||
if (media == null) continue;
|
||||
var hasAccess = currentUser.HasPathAccess(media, _entityService);
|
||||
if (hasAccess == false)
|
||||
return Attempt.Fail("The current user does not have access to the media path " + media.Path);
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<string>.Succeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -4,6 +4,7 @@ using System.Net.Http;
|
||||
using System.Web.Http;
|
||||
using System.Web.Http.Controllers;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
namespace Umbraco.Web.Editors
|
||||
@@ -41,6 +42,11 @@ namespace Umbraco.Web.Editors
|
||||
protected override bool IsAuthorized(HttpActionContext actionContext)
|
||||
{
|
||||
var currentUser = GetUmbracoContext().Security.CurrentUser;
|
||||
|
||||
//admins can access any group
|
||||
if (currentUser.IsAdmin())
|
||||
return base.IsAuthorized(actionContext);
|
||||
|
||||
var queryString = actionContext.Request
|
||||
.GetQueryNameValuePairs();
|
||||
|
||||
|
||||
@@ -672,105 +672,4 @@ namespace Umbraco.Web.Editors
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
internal class UserEditorAuthorizationHelper
|
||||
{
|
||||
private readonly IContentService _contentService;
|
||||
private readonly IMediaService _mediaService;
|
||||
private readonly IUserService _userService;
|
||||
private readonly IEntityService _entityService;
|
||||
|
||||
public UserEditorAuthorizationHelper(IContentService contentService, IMediaService mediaService, IUserService userService, IEntityService entityService)
|
||||
{
|
||||
_contentService = contentService;
|
||||
_mediaService = mediaService;
|
||||
_userService = userService;
|
||||
_entityService = entityService;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current user has access to save the user data
|
||||
/// </summary>
|
||||
/// <param name="currentUser">The current user trying to save user data</param>
|
||||
/// <param name="savingUser">The user instance being saved (can be null if it's a new user)</param>
|
||||
/// <param name="startContentIds">The start content ids of the user being saved (can be null or empty)</param>
|
||||
/// <param name="startMediaIds">The start media ids of the user being saved (can be null or empty)</param>
|
||||
/// <param name="userGroupAliases">The user aliases of the user being saved (can be null or empty)</param>
|
||||
/// <returns></returns>
|
||||
public Attempt<string> AuthorizeActions(IUser currentUser,
|
||||
IUser savingUser,
|
||||
IEnumerable<int> startContentIds, IEnumerable<int> startMediaIds,
|
||||
IEnumerable<string> userGroupAliases)
|
||||
{
|
||||
// a) A non-admin cannot save an admin
|
||||
|
||||
if (savingUser != null)
|
||||
{
|
||||
var currentIsAdmin = currentUser.IsAdmin();
|
||||
var savingIsAdmin = savingUser.IsAdmin();
|
||||
if (currentIsAdmin == false && savingIsAdmin)
|
||||
return Attempt.Fail("The current user is not an administrator");
|
||||
}
|
||||
|
||||
// b0) A user cannot set a start node on another user that they don't have access to
|
||||
|
||||
var pathResult = AuthorizePath(currentUser, startContentIds, startMediaIds);
|
||||
if (pathResult == false)
|
||||
return pathResult;
|
||||
|
||||
if (userGroupAliases != null)
|
||||
{
|
||||
var userGroups = _userService.GetUserGroupsByAlias(userGroupAliases.ToArray()).ToArray();
|
||||
|
||||
// b1) A user cannot assign a group to another user that grants them access to a start node they don't have access to
|
||||
foreach (var group in userGroups)
|
||||
{
|
||||
pathResult = AuthorizePath(currentUser,
|
||||
group.StartContentId.HasValue ? new[] { group.StartContentId.Value } : null,
|
||||
group.StartMediaId.HasValue ? new[] { group.StartMediaId.Value } : null);
|
||||
if (pathResult == false)
|
||||
return pathResult;
|
||||
}
|
||||
|
||||
// c) A user cannot set a section on another user that they don't have access to
|
||||
var allGroupSections = userGroups.SelectMany(x => x.AllowedSections).Distinct();
|
||||
var missingSectionAccess = allGroupSections.Except(currentUser.AllowedSections).ToArray();
|
||||
if (missingSectionAccess.Length > 0)
|
||||
{
|
||||
return Attempt.Fail("The current user does not have access to sections " + string.Join(",", missingSectionAccess));
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<string>.Succeed();
|
||||
}
|
||||
|
||||
private Attempt<string> AuthorizePath(IUser currentUser, IEnumerable<int> startContentIds, IEnumerable<int> startMediaIds)
|
||||
{
|
||||
if (startContentIds != null)
|
||||
{
|
||||
foreach (var contentId in startContentIds)
|
||||
{
|
||||
var content = _contentService.GetById(contentId);
|
||||
if (content == null) continue;
|
||||
var hasAccess = currentUser.HasPathAccess(content, _entityService);
|
||||
if (hasAccess == false)
|
||||
return Attempt.Fail("The current user does not have access to the content path " + content.Path);
|
||||
}
|
||||
}
|
||||
|
||||
if (startMediaIds != null)
|
||||
{
|
||||
foreach (var mediaId in startMediaIds)
|
||||
{
|
||||
var media = _mediaService.GetById(mediaId);
|
||||
if (media == null) continue;
|
||||
var hasAccess = currentUser.HasPathAccess(media, _entityService);
|
||||
if (hasAccess == false)
|
||||
return Attempt.Fail("The current user does not have access to the media path " + media.Path);
|
||||
}
|
||||
}
|
||||
|
||||
return Attempt<string>.Succeed();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -328,6 +328,7 @@
|
||||
<Compile Include="Editors\TemplateController.cs" />
|
||||
<Compile Include="Editors\ParameterSwapControllerActionSelector.cs" />
|
||||
<Compile Include="Editors\CodeFileController.cs" />
|
||||
<Compile Include="Editors\UserEditorAuthorizationHelper.cs" />
|
||||
<Compile Include="Editors\UserGroupAuthorizationAttribute.cs" />
|
||||
<Compile Include="Editors\UserGroupsController.cs" />
|
||||
<Compile Include="Editors\UserGroupValidateAttribute.cs" />
|
||||
|
||||
Reference in New Issue
Block a user