Added admin search permissions (#8346)

This commit is contained in:
Matteo Piovanelli
2020-04-16 19:22:20 +02:00
committed by GitHub
parent 21cb531949
commit b523b342d6
2 changed files with 135 additions and 14 deletions

View File

@@ -1,11 +1,29 @@
using Orchard.Environment.Extensions;
using System.Linq;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents;
using Orchard.Core.Contents.Settings;
using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Security;
using Orchard.UI.Navigation;
namespace Orchard.Search {
[OrchardFeature("Orchard.Search.Content")]
public class ContentAdminMenu : INavigationProvider {
public ContentAdminMenu() {
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IContentManager _contentManager;
private readonly IAuthorizer _authorizer;
public ContentAdminMenu(
IContentDefinitionManager contentDefinitionManager,
IContentManager contentManager,
IAuthorizer authorizer) {
_contentDefinitionManager = contentDefinitionManager;
_contentManager = contentManager;
_authorizer = authorizer;
T = NullLocalizer.Instance;
}
@@ -16,11 +34,28 @@ namespace Orchard.Search {
}
public void GetNavigation(NavigationBuilder builder) {
builder.Add(T("Content"),
menu => menu
.Add(T("Search"), "1.5", item => item.Action("Index", "Admin", new {area = "Orchard.Search"}).LocalNav())
);
// if the user may edit at least one type of Listable content,
// we add the link to the admin menu for them. This is the same
// logic used for Orcahrd.Core.Contents admin menu
var contentTypeDefinitions = _contentDefinitionManager
.ListTypeDefinitions()
.OrderBy(d => d.Name);
var listableContentTypes = contentTypeDefinitions
.Where(ctd => ctd
.Settings
.GetModel<ContentTypeSettings>()
.Listable);
ContentItem listableCi = null;
foreach (var contentTypeDefinition in listableContentTypes) {
listableCi = _contentManager.New(contentTypeDefinition.Name);
if (_authorizer.Authorize(Permissions.EditContent, listableCi)) {
builder.Add(T("Content"),
menu => menu
.Add(T("Search"), "1.5", item => item.Action("Index", "Admin", new { area = "Orchard.Search" }).LocalNav())
);
break;
}
}
}
}
}

View File

@@ -1,15 +1,22 @@
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Web.Mvc;
using Orchard.Collections;
using Orchard.ContentManagement;
using Orchard.ContentManagement.MetaData;
using Orchard.Core.Contents;
using Orchard.Core.Contents.Settings;
using Orchard.Environment.Extensions;
using Orchard.Indexing;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Logging;
using Orchard.Search.Helpers;
using Orchard.Search.Models;
using Orchard.Search.Services;
using Orchard.Security;
using Orchard.Settings;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
@@ -19,14 +26,31 @@ namespace Orchard.Search.Controllers {
public class AdminController : Controller {
private readonly ISearchService _searchService;
private readonly ISiteService _siteService;
private readonly IIndexManager _indexManager;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly IContentManager _contentManager;
private readonly IAuthorizer _authorizer;
private readonly ICultureManager _cultureManager;
public AdminController(
IOrchardServices orchardServices,
ISearchService searchService,
ISiteService siteService) {
ISiteService siteService,
IIndexManager indexManager,
IContentDefinitionManager contentDefinitionManager,
IContentManager contentManager,
IAuthorizer authorizer,
ICultureManager cultureManager) {
_searchService = searchService;
_siteService = siteService;
Services = orchardServices;
_indexManager = indexManager;
_contentDefinitionManager = contentDefinitionManager;
_contentManager = contentManager;
_authorizer = authorizer;
_cultureManager = cultureManager;
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
}
@@ -42,13 +66,75 @@ namespace Orchard.Search.Controllers {
IPageOfItems<ISearchHit> searchHits = new PageOfItems<ISearchHit>(new ISearchHit[] { });
try {
// replicate a logic similar to ContentPickerController, but here
// we want to filter results based on authorized types. This is also
// partially replicates the logic in SearchService.Search.
if (!string.IsNullOrWhiteSpace(searchText)) {
// select types
var contentTypeDefinitions = _contentDefinitionManager
.ListTypeDefinitions()
.OrderBy(d => d.Name);
var listableContentTypes = contentTypeDefinitions
.Where(ctd => ctd
.Settings
.GetModel<ContentTypeSettings>()
.Listable);
ContentItem listableCi = null;
var searchableTypes = new List<string>();
foreach (var contentTypeDefinition in listableContentTypes) {
listableCi = _contentManager.New(contentTypeDefinition.Name);
if (_authorizer.Authorize(Permissions.EditContent, listableCi)) {
// add the type to the list of types we will filter for
searchableTypes.Add(contentTypeDefinition.Name);
}
}
// we don't even search if no type is allowed
if (searchableTypes.Any()) {
var searchBuilder = _indexManager.HasIndexProvider()
? _indexManager
.GetSearchIndexProvider()
.CreateSearchBuilder(adminSearchSettingsPart.SearchIndex)
: new NullSearchBuilder();
searchHits = _searchService.Query(
searchText, pager.Page, pager.PageSize,
searchSettingsPart.FilterCulture,
adminSearchSettingsPart.SearchIndex,
searchSettingsPart.GetSearchFields(adminSearchSettingsPart.SearchIndex),
searchHit => searchHit);
searchBuilder
.Parse(searchSettingsPart
.GetSearchFields(adminSearchSettingsPart.SearchIndex),
searchText);
foreach (var searchableType in searchableTypes) {
// filter by type
searchBuilder
.WithField("type", searchableType)
.NotAnalyzed()
.AsFilter();
}
// filter by culture?
if (searchSettingsPart.FilterCulture) {
var culture = _cultureManager.GetCurrentCulture(Services.WorkContext.HttpContext);
// use LCID as the text representation gets analyzed by the query parser
searchBuilder
.WithField("culture", CultureInfo.GetCultureInfo(culture).LCID)
.AsFilter();
}
// pagination
var totalCount = searchBuilder.Count();
if (pager != null) {
searchBuilder = searchBuilder
.Slice(
(pager.Page > 0 ? pager.Page - 1 : 0) * pager.PageSize,
pager.PageSize);
}
// search
var searchResults = searchBuilder.Search();
// prepare the shape for the page
searchHits = new PageOfItems<ISearchHit>(searchResults.Select(searchHit => searchHit)) {
PageNumber = pager != null ? pager.Page : 0,
PageSize = pager != null ? (pager.PageSize != 0 ? pager.PageSize : totalCount) : totalCount,
TotalItemCount = totalCount
};
}
}
}
catch (Exception exception) {
Logger.Error(T("Invalid search query: {0}", exception.Message).Text);