Skip to content

Commit

Permalink
AdminMenu to check ListContent permission instead od IsListable (#13725)
Browse files Browse the repository at this point in the history
  • Loading branch information
MikeAlhayek authored May 25, 2023
1 parent 3fca36c commit 3bdf765
Show file tree
Hide file tree
Showing 2 changed files with 70 additions and 25 deletions.
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using OrchardCore.ContentManagement.Metadata;
using OrchardCore.ContentManagement.Metadata.Models;
using OrchardCore.DisplayManagement.Handlers;
Expand All @@ -13,11 +16,20 @@ namespace OrchardCore.Contents.AdminNodes
public class ContentTypesAdminNodeDriver : DisplayDriver<MenuItem, ContentTypesAdminNode>
{
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IAuthorizationService _authorizationService;

public ContentTypesAdminNodeDriver(IContentDefinitionManager contentDefinitionManager)
public ContentTypesAdminNodeDriver(
IContentDefinitionManager contentDefinitionManager,
IHttpContextAccessor httpContextAccessor,
IAuthorizationService authorizationService
)
{
_contentDefinitionManager = contentDefinitionManager;
_httpContextAccessor = httpContextAccessor;
_authorizationService = authorizationService;
}

public override IDisplayResult Display(ContentTypesAdminNode treeNode)
{
return Combine(
Expand All @@ -28,22 +40,18 @@ public override IDisplayResult Display(ContentTypesAdminNode treeNode)

public override IDisplayResult Edit(ContentTypesAdminNode treeNode)
{
var listable = _contentDefinitionManager.ListTypeDefinitions()
.Where(ctd => ctd.IsListable())
.OrderBy(ctd => ctd.DisplayName).ToList();

var entries = listable.Select(x => new ContentTypeEntryViewModel
return Initialize<ContentTypesAdminNodeViewModel>("ContentTypesAdminNode_Fields_TreeEdit", async model =>
{
ContentTypeId = x.Name,
IsChecked = treeNode.ContentTypes.Any(selected => String.Equals(selected.ContentTypeId, x.Name, StringComparison.OrdinalIgnoreCase)),
IconClass = treeNode.ContentTypes.Where(selected => selected.ContentTypeId == x.Name).FirstOrDefault()?.IconClass ?? String.Empty
}).ToArray();
var listable = await GetListableContentTypeDefinitionsAsync();
return Initialize<ContentTypesAdminNodeViewModel>("ContentTypesAdminNode_Fields_TreeEdit", model =>
{
model.ShowAll = treeNode.ShowAll;
model.IconClass = treeNode.IconClass;
model.ContentTypes = entries;
model.ContentTypes = listable.Select(x => new ContentTypeEntryViewModel
{
ContentTypeId = x.Name,
IsChecked = treeNode.ContentTypes.Any(selected => String.Equals(selected.ContentTypeId, x.Name, StringComparison.OrdinalIgnoreCase)),
IconClass = treeNode.ContentTypes.FirstOrDefault(selected => selected.ContentTypeId == x.Name)?.IconClass ?? String.Empty
}).ToArray();
}).Location("Content");
}

Expand All @@ -60,11 +68,35 @@ public override async Task<IDisplayResult> UpdateAsync(ContentTypesAdminNode tre
treeNode.IconClass = model.IconClass;
treeNode.ContentTypes = model.ContentTypes
.Where(x => x.IsChecked == true)
.Select(x => new ContentTypeEntry { ContentTypeId = x.ContentTypeId, IconClass = x.IconClass })
.Select(x =>
new ContentTypeEntry
{
ContentTypeId = x.ContentTypeId,
IconClass = x.IconClass
})
.ToArray();
};

return Edit(treeNode);
}

private async Task<IEnumerable<ContentTypeDefinition>> GetListableContentTypeDefinitionsAsync()
{
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions();

var listableContentTypeDefinitions = new List<ContentTypeDefinition>();

foreach (var contentTypeDefinition in contentTypeDefinitions)
{
if (!await _authorizationService.AuthorizeContentTypeAsync(_httpContextAccessor.HttpContext.User, CommonPermissions.ListContent, contentTypeDefinition))
{
continue;
}

listableContentTypeDefinitions.Add(contentTypeDefinition);
}

return listableContentTypeDefinitions.OrderBy(t => t.DisplayName);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Localization;
Expand All @@ -18,18 +19,21 @@ public class ContentTypesAdminNodeNavigationBuilder : IAdminNodeNavigationBuilde
{
private readonly LinkGenerator _linkGenerator;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IAuthorizationService _authorizationService;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ILogger _logger;

public ContentTypesAdminNodeNavigationBuilder(
IContentDefinitionManager contentDefinitionManager,
LinkGenerator linkGenerator,
IHttpContextAccessor httpContextAccessor,
IAuthorizationService authorizationService,
ILogger<ContentTypesAdminNodeNavigationBuilder> logger)
{
_contentDefinitionManager = contentDefinitionManager;
_linkGenerator = linkGenerator;
_httpContextAccessor = httpContextAccessor;
_authorizationService = authorizationService;
_logger = logger;
}

Expand All @@ -39,18 +43,18 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil
{
var node = menuItem as ContentTypesAdminNode;

if ((node == null) || (!node.Enabled))
if (node == null || !node.Enabled)
{
return;
}

// Add ContentTypes specific children
var typesToShow = GetContentTypesToShow(node);
var typesToShow = await GetListableContentTypeDefinitionsAsync(node);
foreach (var ctd in typesToShow)
{
builder.Add(new LocalizedString(ctd.DisplayName, ctd.DisplayName), cTypeMenu =>
{
cTypeMenu.Url(_linkGenerator.GetPathByRouteValues(_httpContextAccessor.HttpContext, "", new
cTypeMenu.Url(_linkGenerator.GetPathByRouteValues(_httpContextAccessor.HttpContext, String.Empty, new
{
area = "OrchardCore.Contents",
controller = "Admin",
Expand Down Expand Up @@ -82,19 +86,28 @@ public async Task BuildNavigationAsync(MenuItem menuItem, NavigationBuilder buil
}
}

private IEnumerable<ContentTypeDefinition> GetContentTypesToShow(ContentTypesAdminNode node)
private async Task<IEnumerable<ContentTypeDefinition>> GetListableContentTypeDefinitionsAsync(ContentTypesAdminNode node)
{
var typesToShow = _contentDefinitionManager.ListTypeDefinitions()
.Where(ctd => ctd.IsListable());
var contentTypeDefinitions = _contentDefinitionManager.ListTypeDefinitions();

if (!node.ShowAll)
var listableContentTypeDefinitions = new List<ContentTypeDefinition>();

foreach (var contentTypeDefinition in contentTypeDefinitions)
{
typesToShow = typesToShow
.Where(ctd => node.ContentTypes.ToList()
.Any(s => String.Equals(ctd.Name, s.ContentTypeId, StringComparison.OrdinalIgnoreCase)));
if (!node.ShowAll && !node.ContentTypes.Any(entry => String.Equals(contentTypeDefinition.Name, entry.ContentTypeId, StringComparison.OrdinalIgnoreCase)))
{
continue;
}

if (!await _authorizationService.AuthorizeContentTypeAsync(_httpContextAccessor.HttpContext.User, CommonPermissions.ListContent, contentTypeDefinition))
{
continue;
}

listableContentTypeDefinitions.Add(contentTypeDefinition);
}

return typesToShow.OrderBy(t => t.DisplayName);
return listableContentTypeDefinitions.OrderBy(t => t.DisplayName);
}

private static List<string> GetIconClasses(ContentTypeDefinition contentType, ContentTypesAdminNode node)
Expand Down

0 comments on commit 3bdf765

Please sign in to comment.