Fixes issue with calculating all user start nodes, improves perf too
This commit is contained in:
@@ -2,6 +2,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.Linq;
|
||||
using System.Security.Claims;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNet.Identity;
|
||||
@@ -22,6 +23,9 @@ namespace Umbraco.Core.Models.Identity
|
||||
Culture = Configuration.GlobalSettings.DefaultUILanguage;
|
||||
}
|
||||
|
||||
private int[] _allStartContentIds;
|
||||
private int[] _allStartMediaIds;
|
||||
|
||||
public virtual async Task<ClaimsIdentity> GenerateUserIdentityAsync(BackOfficeUserManager<BackOfficeIdentityUser> manager)
|
||||
{
|
||||
// NOTE the authenticationType must match the umbraco one
|
||||
@@ -112,5 +116,21 @@ namespace Umbraco.Core.Models.Identity
|
||||
if (callback == null) throw new ArgumentNullException("callback");
|
||||
_getLogins = callback;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all start node Ids assigned to the user based on both the explicit start node ids assigned to the user and any start node Ids assigned to it's user groups
|
||||
/// </summary>
|
||||
public int[] AllStartContentIds
|
||||
{
|
||||
get { return _allStartContentIds ?? (_allStartContentIds = StartContentIds.Concat(Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value)).Distinct().ToArray()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all start node Ids assigned to the user based on both the explicit start node ids assigned to the user and any start node Ids assigned to it's user groups
|
||||
/// </summary>
|
||||
public int[] AllStartMediaIds
|
||||
{
|
||||
get { return _allStartMediaIds ?? (_allStartMediaIds = StartMediaIds.Concat(Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value)).Distinct().ToArray()); }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -35,9 +35,9 @@ namespace Umbraco.Core.Models.Identity
|
||||
.ForMember(detail => detail.Roles, opt => opt.MapFrom(user => user.Groups))
|
||||
.ForMember(detail => detail.RealName, opt => opt.MapFrom(user => user.Name))
|
||||
//When mapping to UserData which is used in the authcookie we want ALL start nodes including ones defined on the groups
|
||||
.ForMember(detail => detail.StartContentNodes, opt => opt.MapFrom(user => user.GetCombinedStartContentIds()))
|
||||
.ForMember(detail => detail.StartContentNodes, opt => opt.MapFrom(user => user.AllStartContentIds))
|
||||
//When mapping to UserData which is used in the authcookie we want ALL start nodes including ones defined on the groups
|
||||
.ForMember(detail => detail.StartMediaNodes, opt => opt.MapFrom(user => user.GetCombinedStartMediaIds()))
|
||||
.ForMember(detail => detail.StartMediaNodes, opt => opt.MapFrom(user => user.AllStartMediaIds))
|
||||
.ForMember(detail => detail.Username, opt => opt.MapFrom(user => user.UserName))
|
||||
.ForMember(detail => detail.Culture, opt => opt.MapFrom(user => user.Culture))
|
||||
.ForMember(detail => detail.SessionId, opt => opt.MapFrom(user => user.SecurityStamp.IsNullOrWhiteSpace() ? Guid.NewGuid().ToString("N") : user.SecurityStamp));
|
||||
|
||||
@@ -10,8 +10,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
string Name { get; }
|
||||
string Icon { get; }
|
||||
int Id { get; }
|
||||
int StartContentId { get; }
|
||||
int StartMediaId { get; }
|
||||
int? StartContentId { get; }
|
||||
int? StartMediaId { get; }
|
||||
|
||||
/// <summary>
|
||||
/// The alias
|
||||
|
||||
@@ -45,6 +45,16 @@ namespace Umbraco.Core.Models.Membership
|
||||
/// <summary>
|
||||
/// Will hold the media file system relative path of the users custom avatar if they uploaded one
|
||||
/// </summary>
|
||||
string Avatar { get; set; }
|
||||
string Avatar { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns all start node Ids assigned to the user based on both the explicit start node ids assigned to the user and any start node Ids assigned to it's user groups
|
||||
/// </summary>
|
||||
int[] AllStartContentIds { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Returns all start node Ids assigned to the user based on both the explicit start node ids assigned to the user and any start node Ids assigned to it's user groups
|
||||
/// </summary>
|
||||
int[] AllStartMediaIds { get; }
|
||||
}
|
||||
}
|
||||
@@ -7,8 +7,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
string Alias { get; set; }
|
||||
|
||||
int StartContentId { get; set; }
|
||||
int StartMediaId { get; set; }
|
||||
int? StartContentId { get; set; }
|
||||
int? StartMediaId { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The icon
|
||||
|
||||
@@ -5,22 +5,24 @@ namespace Umbraco.Core.Models.Membership
|
||||
{
|
||||
public class ReadOnlyUserGroup : IReadOnlyUserGroup, IEquatable<ReadOnlyUserGroup>
|
||||
{
|
||||
public ReadOnlyUserGroup(int id, string name, string icon, int startContentId, int startMediaId, string @alias, IEnumerable<string> allowedSections)
|
||||
public ReadOnlyUserGroup(int id, string name, string icon, int? startContentId, int? startMediaId, string @alias, IEnumerable<string> allowedSections)
|
||||
{
|
||||
Name = name;
|
||||
Icon = icon;
|
||||
Id = id;
|
||||
StartContentId = startContentId;
|
||||
StartMediaId = startMediaId;
|
||||
Alias = alias;
|
||||
AllowedSections = allowedSections;
|
||||
|
||||
//Zero is invalid and will be treated as Null
|
||||
StartContentId = startContentId == 0 ? null : startContentId;
|
||||
StartMediaId = startMediaId == 0 ? null : startMediaId;
|
||||
}
|
||||
|
||||
public int Id { get; private set; }
|
||||
public string Name { get; private set; }
|
||||
public string Icon { get; private set; }
|
||||
public int StartContentId { get; private set; }
|
||||
public int StartMediaId { get; private set; }
|
||||
public int? StartContentId { get; private set; }
|
||||
public int? StartMediaId { get; private set; }
|
||||
public string Alias { get; private set; }
|
||||
public IEnumerable<string> AllowedSections { get; private set; }
|
||||
|
||||
|
||||
@@ -117,6 +117,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
private DateTime _lastLockoutDate;
|
||||
|
||||
private bool _defaultToLiveEditing;
|
||||
private int[] _allStartContentIds;
|
||||
private int[] _allStartMediaIds;
|
||||
|
||||
private static readonly Lazy<PropertySelectors> Ps = new Lazy<PropertySelectors>();
|
||||
|
||||
@@ -297,6 +299,24 @@ namespace Umbraco.Core.Models.Membership
|
||||
set { SetPropertyValueAndDetectChanges(value, ref _avatar, Ps.Value.AvatarSelector); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all start node Ids assigned to the user based on both the explicit start node ids assigned to the user and any start node Ids assigned to it's user groups
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
public int[] AllStartContentIds
|
||||
{
|
||||
get { return _allStartContentIds ?? (_allStartContentIds = StartContentIds.Concat(Groups.Where(x => x.StartContentId.HasValue).Select(x => x.StartContentId.Value)).Distinct().ToArray()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all start node Ids assigned to the user based on both the explicit start node ids assigned to the user and any start node Ids assigned to it's user groups
|
||||
/// </summary>
|
||||
[IgnoreDataMember]
|
||||
public int[] AllStartMediaIds
|
||||
{
|
||||
get { return _allStartMediaIds ?? (_allStartMediaIds = StartMediaIds.Concat(Groups.Where(x => x.StartMediaId.HasValue).Select(x => x.StartMediaId.Value)).Distinct().ToArray()); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the session timeout.
|
||||
/// </summary>
|
||||
|
||||
@@ -14,8 +14,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
[DataContract(IsReference = true)]
|
||||
internal class UserGroup : Entity, IUserGroup
|
||||
{
|
||||
private int _startContentId;
|
||||
private int _startMediaId;
|
||||
private int? _startContentId;
|
||||
private int? _startMediaId;
|
||||
private string _alias;
|
||||
private string _icon;
|
||||
private string _name;
|
||||
@@ -30,8 +30,8 @@ namespace Umbraco.Core.Models.Membership
|
||||
public readonly PropertyInfo AliasSelector = ExpressionHelper.GetPropertyInfo<UserGroup, string>(x => x.Alias);
|
||||
public readonly PropertyInfo PermissionsSelector = ExpressionHelper.GetPropertyInfo<UserGroup, IEnumerable<string>>(x => x.Permissions);
|
||||
public readonly PropertyInfo IconSelector = ExpressionHelper.GetPropertyInfo<UserGroup, string>(x => x.Icon);
|
||||
public readonly PropertyInfo StartContentIdSelector = ExpressionHelper.GetPropertyInfo<UserGroup, int>(x => x.StartContentId);
|
||||
public readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo<UserGroup, int>(x => x.StartMediaId);
|
||||
public readonly PropertyInfo StartContentIdSelector = ExpressionHelper.GetPropertyInfo<UserGroup, int?>(x => x.StartContentId);
|
||||
public readonly PropertyInfo StartMediaIdSelector = ExpressionHelper.GetPropertyInfo<UserGroup, int?>(x => x.StartMediaId);
|
||||
|
||||
//Custom comparer for enumerable
|
||||
public readonly DelegateEqualityComparer<IEnumerable<string>> StringEnumerableComparer =
|
||||
@@ -67,14 +67,14 @@ namespace Umbraco.Core.Models.Membership
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int StartMediaId
|
||||
public int? StartMediaId
|
||||
{
|
||||
get { return _startMediaId; }
|
||||
set { SetPropertyValueAndDetectChanges(value, ref _startMediaId, Ps.Value.StartMediaIdSelector); }
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public int StartContentId
|
||||
public int? StartContentId
|
||||
{
|
||||
get { return _startContentId; }
|
||||
set { SetPropertyValueAndDetectChanges(value, ref _startContentId, Ps.Value.StartContentIdSelector); }
|
||||
|
||||
@@ -51,11 +51,11 @@ namespace Umbraco.Core.Models.Rdbms
|
||||
|
||||
[Column("startContentId")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public int StartContentId { get; set; }
|
||||
public int? StartContentId { get; set; }
|
||||
|
||||
[Column("startMediaId")]
|
||||
[NullSetting(NullSetting = NullSettings.Null)]
|
||||
public int StartMediaId { get; set; }
|
||||
public int? StartMediaId { get; set; }
|
||||
|
||||
[ResultColumn]
|
||||
public List<UserGroup2AppDto> UserGroup2AppDtos { get; set; }
|
||||
|
||||
@@ -12,43 +12,7 @@ using Umbraco.Core.Services;
|
||||
namespace Umbraco.Core.Models
|
||||
{
|
||||
public static class UserExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Returns all of the user's assigned start node ids based on ids assigned directly to the IUser object and it's groups
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<int> GetCombinedStartContentIds(this IUser user)
|
||||
{
|
||||
return user.StartContentIds.Concat(user.Groups.Select(x => x.StartContentId)).Distinct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all of the user's assigned start node ids based on ids assigned directly to the BackOfficeIdentityUser object and it's groups
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<int> GetCombinedStartContentIds(this BackOfficeIdentityUser user)
|
||||
{
|
||||
return user.StartContentIds.Concat(user.Groups.Select(x => x.StartContentId)).Distinct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all of the user's assigned start node ids based on ids assigned directly to the IUser object and it's groups
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<int> GetCombinedStartMediaIds(this IUser user)
|
||||
{
|
||||
return user.StartMediaIds.Concat(user.Groups.Select(x => x.StartMediaId)).Distinct();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Returns all of the user's assigned start node ids based on ids assigned directly to the BackOfficeIdentityUser object and it's groups
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
public static IEnumerable<int> GetCombinedStartMediaIds(this BackOfficeIdentityUser user)
|
||||
{
|
||||
return user.StartMediaIds.Concat(user.Groups.Select(x => x.StartMediaId)).Distinct();
|
||||
}
|
||||
|
||||
{
|
||||
/// <summary>
|
||||
/// Tries to lookup the user's gravatar to see if the endpoint can be reached, if so it returns the valid URL
|
||||
/// </summary>
|
||||
@@ -153,7 +117,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
if (content == null) throw new ArgumentNullException("content");
|
||||
return HasPathAccess(content.Path, user.GetCombinedStartContentIds().ToArray(), Constants.System.RecycleBinContent);
|
||||
return HasPathAccess(content.Path, user.AllStartContentIds, Constants.System.RecycleBinContent);
|
||||
}
|
||||
|
||||
internal static bool HasPathAccess(string path, int[] startNodeIds, int recycleBinId)
|
||||
@@ -197,7 +161,7 @@ namespace Umbraco.Core.Models
|
||||
{
|
||||
if (user == null) throw new ArgumentNullException("user");
|
||||
if (media == null) throw new ArgumentNullException("media");
|
||||
return HasPathAccess(media.Path, user.GetCombinedStartMediaIds().ToArray(), Constants.System.RecycleBinMedia);
|
||||
return HasPathAccess(media.Path, user.AllStartMediaIds, Constants.System.RecycleBinMedia);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -802,12 +802,12 @@ namespace Umbraco.Web.Editors
|
||||
var hasPathAccess = (nodeId == Constants.System.Root)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.Root.ToInvariantString(),
|
||||
user.GetCombinedStartContentIds().ToArray(),
|
||||
user.AllStartContentIds,
|
||||
Constants.System.RecycleBinContent)
|
||||
: (nodeId == Constants.System.RecycleBinContent)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.RecycleBinContent.ToInvariantString(),
|
||||
user.GetCombinedStartContentIds().ToArray(),
|
||||
user.AllStartContentIds,
|
||||
Constants.System.RecycleBinContent)
|
||||
: user.HasPathAccess(contentItem);
|
||||
|
||||
|
||||
@@ -667,14 +667,14 @@ namespace Umbraco.Web.Editors
|
||||
type = "media";
|
||||
|
||||
AddExamineSearchFrom(searchFrom, sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.GetCombinedStartMediaIds().ToArray(), sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.AllStartMediaIds, sb);
|
||||
|
||||
break;
|
||||
case UmbracoEntityTypes.Document:
|
||||
type = "content";
|
||||
|
||||
AddExamineSearchFrom(searchFrom, sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.GetCombinedStartContentIds().ToArray(), sb);
|
||||
AddExamineUserStartNode(Security.CurrentUser.AllStartContentIds, sb);
|
||||
|
||||
break;
|
||||
default:
|
||||
|
||||
@@ -887,12 +887,12 @@ namespace Umbraco.Web.Editors
|
||||
var hasPathAccess = (nodeId == Constants.System.Root)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.Root.ToInvariantString(),
|
||||
user.GetCombinedStartMediaIds().ToArray(),
|
||||
user.AllStartMediaIds,
|
||||
Constants.System.RecycleBinMedia)
|
||||
: (nodeId == Constants.System.RecycleBinMedia)
|
||||
? UserExtensions.HasPathAccess(
|
||||
Constants.System.RecycleBinMedia.ToInvariantString(),
|
||||
user.GetCombinedStartMediaIds().ToArray(),
|
||||
user.AllStartMediaIds,
|
||||
Constants.System.RecycleBinMedia)
|
||||
: user.HasPathAccess(media);
|
||||
|
||||
|
||||
@@ -64,7 +64,7 @@ namespace Umbraco.Web.Trees
|
||||
private int[] _userStartNodes;
|
||||
protected override int[] UserStartNodes
|
||||
{
|
||||
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.GetCombinedStartContentIds().ToArray()); }
|
||||
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.AllStartContentIds); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace Umbraco.Web.Trees
|
||||
private int[] _userStartNodes;
|
||||
protected override int[] UserStartNodes
|
||||
{
|
||||
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.GetCombinedStartMediaIds().ToArray()); }
|
||||
get { return _userStartNodes ?? (_userStartNodes = Security.CurrentUser.AllStartMediaIds); }
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -47,7 +47,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
|
||||
protected override int[] GetUserStartNodes(IUser user)
|
||||
{
|
||||
return user.GetCombinedStartContentIds().ToArray();
|
||||
return user.AllStartContentIds;
|
||||
}
|
||||
|
||||
protected override int RecycleBinId
|
||||
|
||||
@@ -41,7 +41,7 @@ namespace Umbraco.Web.WebApi.Filters
|
||||
|
||||
protected virtual int[] GetUserStartNodes(IUser user)
|
||||
{
|
||||
return user.GetCombinedStartMediaIds().ToArray();
|
||||
return user.AllStartMediaIds;
|
||||
}
|
||||
|
||||
protected virtual int RecycleBinId
|
||||
|
||||
@@ -295,8 +295,8 @@ namespace umbraco.BasePages
|
||||
RealName = u.Name,
|
||||
//currently we only have one user type!
|
||||
Roles = u.GetGroups(),
|
||||
StartContentNodes = u.UserEntity.GetCombinedStartContentIds().ToArray(),
|
||||
StartMediaNodes = u.UserEntity.GetCombinedStartMediaIds().ToArray(),
|
||||
StartContentNodes = u.UserEntity.AllStartContentIds,
|
||||
StartMediaNodes = u.UserEntity.AllStartMediaIds,
|
||||
Username = u.LoginName,
|
||||
Culture = ui.Culture(u)
|
||||
|
||||
|
||||
Reference in New Issue
Block a user