U4-10813 - fix error with groups having a large number of permissions

This commit is contained in:
Stephan
2018-01-17 13:07:03 +01:00
parent 7f12cff3bd
commit 2a982f21a7

View File

@@ -201,10 +201,24 @@ namespace Umbraco.Web.Models.Mapping
var allContentPermissions = applicationContext.Services.UserService.GetPermissions(@group, true)
.ToDictionary(x => x.EntityId, x => x);
var contentEntities = allContentPermissions.Keys.Count == 0
? new IUmbracoEntity[0]
: applicationContext.Services.EntityService.GetAll(UmbracoObjectTypes.Document, allContentPermissions.Keys.ToArray());
IEnumerable<IUmbracoEntity> contentEntities;
if (allContentPermissions.Keys.Count == 0)
{
contentEntities = new IUmbracoEntity[0];
}
else
{
// a group can end up with way more than 2000 assigned permissions,
// so we need to break them into groups in order to avoid breaking
// the entity service due to too many Sql parameters.
var list = new List<IUmbracoEntity>();
contentEntities = list;
var entityService = applicationContext.Services.EntityService;
foreach (var idGroup in allContentPermissions.Keys.InGroupsOf(2000))
list.AddRange(entityService.GetAll(UmbracoObjectTypes.Document, idGroup.ToArray()));
}
var allAssignedPermissions = new List<AssignedContentPermissions>();
foreach (var entity in contentEntities)
@@ -229,7 +243,7 @@ namespace Umbraco.Web.Models.Mapping
});
//Important! Currently we are never mapping to multiple UserDisplay objects but if we start doing that
// this will cause an N+1 and we'll need to change how this works.
// this will cause an N+1 and we'll need to change how this works.
config.CreateMap<IUser, UserDisplay>()
.ForMember(detail => detail.Avatars, opt => opt.MapFrom(user => user.GetCurrentUserAvatarUrls(applicationContext.Services.UserService, applicationContext.ApplicationCache.RuntimeCache)))
.ForMember(detail => detail.Username, opt => opt.MapFrom(user => user.Username))
@@ -253,7 +267,7 @@ namespace Umbraco.Web.Models.Mapping
"media/mediaRoot")))
.ForMember(
detail => detail.StartContentIds,
opt => opt.MapFrom(user => GetStartNodeValues(
opt => opt.MapFrom(user => GetStartNodeValues(
user.StartContentIds.ToArray(),
applicationContext.Services.TextService,
applicationContext.Services.EntityService,
@@ -261,7 +275,7 @@ namespace Umbraco.Web.Models.Mapping
"content/contentRoot")))
.ForMember(
detail => detail.StartMediaIds,
opt => opt.MapFrom(user => GetStartNodeValues(
opt => opt.MapFrom(user => GetStartNodeValues(
user.StartMediaIds.ToArray(),
applicationContext.Services.TextService,
applicationContext.Services.EntityService,
@@ -328,7 +342,7 @@ namespace Umbraco.Web.Models.Mapping
//the best we can do here is to return the user's first user group as a IUserType object
//but we should attempt to return any group that is the built in ones first
var groups = user.Groups.ToArray();
detail.UserGroups = user.Groups.Select(x => x.Alias).ToArray();
detail.UserGroups = user.Groups.Select(x => x.Alias).ToArray();
if (groups.Length == 0)
{
@@ -369,8 +383,8 @@ namespace Umbraco.Web.Models.Mapping
}
private IEnumerable<EntityBasic> GetStartNodeValues(int[] startNodeIds,
ILocalizedTextService textService, IEntityService entityService, UmbracoObjectTypes objectType,
private IEnumerable<EntityBasic> GetStartNodeValues(int[] startNodeIds,
ILocalizedTextService textService, IEntityService entityService, UmbracoObjectTypes objectType,
string localizedKey)
{
if (startNodeIds.Length > 0)
@@ -385,7 +399,7 @@ namespace Umbraco.Web.Models.Mapping
return startNodes;
}
return Enumerable.Empty<EntityBasic>();
}
}
private void MapUserGroupBasic(ServiceContext services, dynamic group, UserGroupBasic display)
{