mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-02-09 09:16:41 +08:00
Added admin search permissions (#8346)
This commit is contained in:
committed by
GitHub
parent
21cb531949
commit
b523b342d6
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user