U4-10173 - refactor start nodes
This commit is contained in:
@@ -308,7 +308,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
[IgnoreDataMember]
|
||||
public int[] AllStartContentIds
|
||||
{
|
||||
get { return _allStartContentIds ?? (_allStartContentIds = StartContentIds.Concat(Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value)).Distinct().ToArray()); }
|
||||
get { return this.GetAllContentStartNodes(ApplicationContext.Current.Services.EntityService); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -317,7 +317,7 @@ namespace Umbraco.Core.Models.Membership
|
||||
[IgnoreDataMember]
|
||||
public int[] AllStartMediaIds
|
||||
{
|
||||
get { return _allStartMediaIds ?? (_allStartMediaIds = StartMediaIds.Concat(Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value)).Distinct().ToArray()); }
|
||||
get { return this.GetAllMediaStartNodes(ApplicationContext.Current.Services.EntityService); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -107,17 +107,34 @@ namespace Umbraco.Core.Models
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the user has access to the content item based on their start noe
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="content"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool HasPathAccess(this IUser user, IContent content)
|
||||
internal static bool HasContentRootAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
if (content == null) throw new ArgumentNullException("content");
|
||||
return HasPathAccess(content.Path, user.AllStartContentIds, Constants.System.RecycleBinContent);
|
||||
return HasPathAccess(Constants.System.Root.ToInvariantString(), user.GetAllContentStartNodes(entityService), Constants.System.RecycleBinContent);
|
||||
}
|
||||
|
||||
internal static bool HasContentBinAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return HasPathAccess(Constants.System.RecycleBinContent.ToInvariantString(), user.GetAllContentStartNodes(entityService), Constants.System.RecycleBinContent);
|
||||
}
|
||||
|
||||
internal static bool HasMediaRootAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return HasPathAccess(Constants.System.Root.ToInvariantString(), user.GetAllMediaStartNodes(entityService), Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
internal static bool HasMediaBinAccess(this IUser user, IEntityService entityService)
|
||||
{
|
||||
return HasPathAccess(Constants.System.RecycleBinMedia.ToInvariantString(), user.GetAllMediaStartNodes(entityService), Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
internal static bool HasPathAccess(this IUser user, IContent content, IEntityService entityService)
|
||||
{
|
||||
return HasPathAccess(content.Path, user.GetAllContentStartNodes(entityService), Constants.System.RecycleBinContent);
|
||||
}
|
||||
|
||||
internal static bool HasPathAccess(this IUser user, IMedia media, IEntityService entityService)
|
||||
{
|
||||
return HasPathAccess(media.Path, user.GetAllMediaStartNodes(entityService), Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
internal static bool HasPathAccess(string path, int[] startNodeIds, int recycleBinId)
|
||||
@@ -151,19 +168,6 @@ namespace Umbraco.Core.Models
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the user has access to the media item based on their start noe
|
||||
/// </summary>
|
||||
/// <param name="user"></param>
|
||||
/// <param name="media"></param>
|
||||
/// <returns></returns>
|
||||
internal static bool HasPathAccess(this IUser user, IMedia media)
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
if (media == null) throw new ArgumentNullException("media");
|
||||
return HasPathAccess(media.Path, user.AllStartMediaIds, Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether this user is an admin.
|
||||
/// </summary>
|
||||
@@ -176,5 +180,63 @@ namespace Umbraco.Core.Models
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
return user.Groups != null && user.Groups.Any(x => x.Alias == Constants.Security.AdminGroupAlias);
|
||||
}
|
||||
|
||||
public static int[] GetAllContentStartNodes(this IUser user, IEntityService entityService)
|
||||
{
|
||||
var gsn = user.Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value).Distinct().ToArray();
|
||||
var usn = user.StartContentIds;
|
||||
return CombineStartNodes(gsn, usn, entityService);
|
||||
}
|
||||
|
||||
public static int[] GetAllMediaStartNodes(this IUser user, IEntityService entityService)
|
||||
{
|
||||
var gsn = user.Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value).Distinct().ToArray();
|
||||
var usn = user.StartMediaIds;
|
||||
return CombineStartNodes(gsn, usn, entityService);
|
||||
}
|
||||
|
||||
private static bool StartsWithPath(string test, string path)
|
||||
{
|
||||
return test.StartsWith(path) && test.Length > path.Length && test[path.Length] == ',';
|
||||
}
|
||||
|
||||
private static int[] CombineStartNodes(int[] groupSn, int[] userSn, IEntityService entityService)
|
||||
{
|
||||
// assume groupSn and userSn each don't contain duplicates
|
||||
|
||||
var asn = groupSn.Concat(userSn).Distinct().ToArray();
|
||||
var paths = entityService.GetAll(UmbracoObjectTypes.Document, asn).ToDictionary(x => x.Id, x => x.Path);
|
||||
|
||||
paths[-1] = "-1"; // entityService does not get that one
|
||||
|
||||
var lsn = new List<int>();
|
||||
foreach (var sn in groupSn)
|
||||
{
|
||||
var snp = paths[sn];
|
||||
if (lsn.Any(x => StartsWithPath(snp, paths[x]))) continue; // skip if something above this sn
|
||||
lsn.RemoveAll(x => StartsWithPath(paths[x], snp)); // remove anything below this sn
|
||||
lsn.Add(sn);
|
||||
}
|
||||
|
||||
var usn = new List<int>();
|
||||
foreach (var sn in userSn)
|
||||
{
|
||||
if (groupSn.Contains(sn)) continue;
|
||||
|
||||
var snp = paths[sn];
|
||||
if (usn.Any(x => StartsWithPath(paths[x], snp))) continue; // skip if something below this sn
|
||||
usn.RemoveAll(x => StartsWithPath(snp, paths[x])); // remove anything above this sn
|
||||
usn.Add(sn);
|
||||
}
|
||||
|
||||
foreach (var sn in usn)
|
||||
{
|
||||
var snp = paths[sn];
|
||||
lsn.RemoveAll(x => StartsWithPath(snp, paths[x]) || StartsWithPath(paths[x], snp)); // remove anything above or below this sn
|
||||
lsn.Add(sn);
|
||||
}
|
||||
|
||||
return lsn.ToArray();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,6 @@
|
||||
using Moq;
|
||||
using NUnit.Framework;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Models;
|
||||
using Umbraco.Core.Models.Membership;
|
||||
|
||||
@@ -23,7 +24,7 @@ namespace Umbraco.Tests.Models
|
||||
contentMock.Setup(c => c.Path).Returns(contentPath);
|
||||
var content = contentMock.Object;
|
||||
|
||||
Assert.AreEqual(outcome, user.HasPathAccess(content));
|
||||
Assert.AreEqual(outcome, user.HasPathAccess(content, ApplicationContext.Current.Services.EntityService));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1059,17 +1059,12 @@ namespace Umbraco.Web.Editors
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
var entityService = ApplicationContext.Current.Services.EntityService;
|
||||
var hasPathAccess = (nodeId == Constants.System.Root)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.Root.ToInvariantString(),
|
||||
user.AllStartContentIds,
|
||||
Constants.System.RecycleBinContent)
|
||||
? user.HasContentRootAccess(entityService)
|
||||
: (nodeId == Constants.System.RecycleBinContent)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.RecycleBinContent.ToInvariantString(),
|
||||
user.AllStartContentIds,
|
||||
Constants.System.RecycleBinContent)
|
||||
: user.HasPathAccess(contentItem);
|
||||
? user.HasContentBinAccess(entityService)
|
||||
: user.HasPathAccess(contentItem, entityService);
|
||||
|
||||
if (hasPathAccess == false)
|
||||
{
|
||||
|
||||
@@ -551,10 +551,10 @@ namespace Umbraco.Web.Editors
|
||||
switch (type)
|
||||
{
|
||||
case UmbracoEntityTypes.Document:
|
||||
aids = Security.CurrentUser.AllStartContentIds;
|
||||
aids = Security.CurrentUser.GetAllContentStartNodes(Services.EntityService);
|
||||
break;
|
||||
case UmbracoEntityTypes.Media:
|
||||
aids = Security.CurrentUser.AllStartMediaIds;
|
||||
aids = Security.CurrentUser.GetAllMediaStartNodes(Services.EntityService);
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -695,14 +695,14 @@ namespace Umbraco.Web.Editors
|
||||
type = "media";
|
||||
|
||||
AddExamineSearchFrom(searchFrom, sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.AllStartMediaIds, sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.GetAllMediaStartNodes(Services.EntityService), sb);
|
||||
|
||||
break;
|
||||
case UmbracoEntityTypes.Document:
|
||||
type = "content";
|
||||
|
||||
AddExamineSearchFrom(searchFrom, sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.AllStartContentIds, sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.GetAllContentStartNodes(Services.EntityService), sb);
|
||||
|
||||
break;
|
||||
default:
|
||||
@@ -950,10 +950,10 @@ namespace Umbraco.Web.Editors
|
||||
switch (entityType)
|
||||
{
|
||||
case UmbracoEntityTypes.Document:
|
||||
aids = Security.CurrentUser.AllStartContentIds;
|
||||
aids = Security.CurrentUser.GetAllContentStartNodes(Services.EntityService);
|
||||
break;
|
||||
case UmbracoEntityTypes.Media:
|
||||
aids = Security.CurrentUser.AllStartMediaIds;
|
||||
aids = Security.CurrentUser.GetAllMediaStartNodes(Services.EntityService);
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -254,7 +254,7 @@ namespace Umbraco.Web.Editors
|
||||
private int[] _userStartNodes;
|
||||
protected int[] UserStartNodes
|
||||
{
|
||||
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.AllStartMediaIds); }
|
||||
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.GetAllMediaStartNodes(Services.EntityService)); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
@@ -910,17 +910,12 @@ namespace Umbraco.Web.Editors
|
||||
throw new HttpResponseException(HttpStatusCode.NotFound);
|
||||
}
|
||||
|
||||
var entityService = Core.ApplicationContext.Current.Services.EntityService;
|
||||
var hasPathAccess = (nodeId == Constants.System.Root)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.Root.ToInvariantString(),
|
||||
user.AllStartMediaIds,
|
||||
Constants.System.RecycleBinMedia)
|
||||
? user.HasMediaRootAccess(entityService)
|
||||
: (nodeId == Constants.System.RecycleBinMedia)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.RecycleBinMedia.ToInvariantString(),
|
||||
user.AllStartMediaIds,
|
||||
Constants.System.RecycleBinMedia)
|
||||
: user.HasPathAccess(media);
|
||||
? user.HasMediaBinAccess(entityService)
|
||||
: user.HasPathAccess(media, entityService);
|
||||
|
||||
return hasPathAccess;
|
||||
}
|
||||
|
||||
@@ -215,7 +215,7 @@ namespace Umbraco.Web.Trees
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Security.CurrentUser.HasPathAccess(content);
|
||||
return Security.CurrentUser.HasPathAccess(content, Services.EntityService);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -163,7 +163,7 @@ namespace Umbraco.Web.Trees
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return Security.CurrentUser.HasPathAccess(media);
|
||||
return Security.CurrentUser.HasPathAccess(media, Services.EntityService);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -294,8 +294,8 @@ namespace umbraco.BasePages
|
||||
AllowedApplications = u.GetApplications().Select(x => x.alias).ToArray(),
|
||||
RealName = u.Name,
|
||||
Roles = u.GetGroups(),
|
||||
StartContentNodes = u.UserEntity.AllStartContentIds,
|
||||
StartMediaNodes = u.UserEntity.AllStartMediaIds,
|
||||
StartContentNodes = u.UserEntity.GetAllContentStartNodes(ApplicationContext.Current.Services.EntityService),
|
||||
StartMediaNodes = u.UserEntity.GetAllMediaStartNodes(ApplicationContext.Current.Services.EntityService),
|
||||
Username = u.LoginName,
|
||||
Culture = ui.Culture(u)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user