Contents: Adding redirects to overridden routes in AdminController and ItemController (#8224)

This commit is contained in:
Hermes Sbicego 2019-07-11 21:08:39 +02:00 committed by Sébastien Ros
parent 02ff859cf4
commit bb87e47bc3
8 changed files with 125 additions and 54 deletions

View File

@ -13,20 +13,19 @@ using Orchard.Core.Containers.Models;
using Orchard.Core.Contents.Settings; using Orchard.Core.Contents.Settings;
using Orchard.Core.Contents.ViewModels; using Orchard.Core.Contents.ViewModels;
using Orchard.Data; using Orchard.Data;
using Orchard.DisplayManagement;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Logging; using Orchard.Logging;
using Orchard.Mvc.Extensions; using Orchard.Mvc.Extensions;
using Orchard.Mvc.Html; using Orchard.Mvc.Html;
using Orchard.Settings;
using Orchard.UI.Navigation; using Orchard.UI.Navigation;
using Orchard.UI.Notify; using Orchard.UI.Notify;
using Orchard.Settings;
using Orchard.Utility.Extensions; using Orchard.Utility.Extensions;
using Orchard.Localization.Services;
namespace Orchard.Core.Contents.Controllers { namespace Orchard.Core.Contents.Controllers {
[ValidateInput(false)] [ValidateInput(false)]
public class AdminController : Controller, IUpdateModel { public class AdminController : ContentControllerBase, IUpdateModel {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IContentDefinitionManager _contentDefinitionManager; private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ITransactionManager _transactionManager; private readonly ITransactionManager _transactionManager;
@ -36,24 +35,21 @@ namespace Orchard.Core.Contents.Controllers {
public AdminController( public AdminController(
IOrchardServices orchardServices, IOrchardServices orchardServices,
IContentManager contentManager,
IContentDefinitionManager contentDefinitionManager, IContentDefinitionManager contentDefinitionManager,
ITransactionManager transactionManager,
ISiteService siteService, ISiteService siteService,
IShapeFactory shapeFactory,
ICultureManager cultureManager, ICultureManager cultureManager,
ICultureFilter cultureFilter) { ICultureFilter cultureFilter) : base(orchardServices.ContentManager) {
Services = orchardServices; Services = orchardServices;
_contentManager = contentManager; _contentManager = orchardServices.ContentManager;
_transactionManager = orchardServices.TransactionManager;
_contentDefinitionManager = contentDefinitionManager; _contentDefinitionManager = contentDefinitionManager;
_transactionManager = transactionManager;
_siteService = siteService; _siteService = siteService;
_cultureManager = cultureManager; _cultureManager = cultureManager;
_cultureFilter = cultureFilter; _cultureFilter = cultureFilter;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
Shape = shapeFactory; Shape = orchardServices.New;
} }
dynamic Shape { get; set; } dynamic Shape { get; set; }
@ -247,6 +243,11 @@ namespace Orchard.Core.Contents.Controllers {
var contentItem = _contentManager.New(id); var contentItem = _contentManager.New(id);
var customRouteRedirection = GetCustomContentItemRouteRedirection(contentItem, ContentItemRoute.Create);
if (customRouteRedirection != null) {
return customRouteRedirection;
}
if (!Services.Authorizer.Authorize(Permissions.CreateContent, contentItem, T("Cannot create content"))) if (!Services.Authorizer.Authorize(Permissions.CreateContent, contentItem, T("Cannot create content")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
@ -313,6 +314,11 @@ namespace Orchard.Core.Contents.Controllers {
public ActionResult Edit(int id) { public ActionResult Edit(int id) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest); var contentItem = _contentManager.Get(id, VersionOptions.Latest);
var customRouteRedirection = GetCustomContentItemRouteRedirection(contentItem, ContentItemRoute.Editor);
if (customRouteRedirection != null) {
return customRouteRedirection;
}
if (contentItem == null) if (contentItem == null)
return HttpNotFound(); return HttpNotFound();
@ -396,6 +402,12 @@ namespace Orchard.Core.Contents.Controllers {
if (!Services.Authorizer.Authorize(Permissions.CreateContent, contentItem, T("Couldn't clone content"))) if (!Services.Authorizer.Authorize(Permissions.CreateContent, contentItem, T("Couldn't clone content")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
// pass a dummy content to the authorization check to check for "own" variations
var dummyContent = _contentManager.New(contentItem.ContentType);
if (!Services.Authorizer.Authorize(Permissions.EditContent, dummyContent, T("You do not have permission to edit (or create) content.")))
return new HttpUnauthorizedResult();
try { try {
Services.ContentManager.Clone(contentItem); Services.ContentManager.Clone(contentItem);
} }
@ -413,7 +425,7 @@ namespace Orchard.Core.Contents.Controllers {
public ActionResult Remove(int id, string returnUrl) { public ActionResult Remove(int id, string returnUrl) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest); var contentItem = _contentManager.Get(id, VersionOptions.Latest);
if (!Services.Authorizer.Authorize(Permissions.DeleteContent, contentItem, T("Couldn't remove content"))) if (!Services.Authorizer.Authorize(Permissions.DeleteContent, contentItem, T("You do not have permission to delete content.")))
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
if (contentItem != null) { if (contentItem != null) {

View File

@ -0,0 +1,52 @@
using System;
using System.Web.Mvc;
using System.Web.Routing;
using Orchard.ContentManagement;
using Orchard.Mvc.Extensions;
namespace Orchard.Core.Contents.Controllers {
public abstract class ContentControllerBase : Controller {
private readonly IContentManager _contentManager;
public ContentControllerBase(IContentManager contentManager) {
_contentManager = contentManager;
}
public RedirectToRouteResult GetCustomContentItemRouteRedirection(IContent content, ContentItemRoute contentItemRoute) {
if (content == null) return null;
var itemMetadata = _contentManager.GetItemMetadata(content);
var currentRoute = RouteData.Values;
bool isCustomRoute(RouteValueDictionary routeValues) =>
!currentRoute.ToRouteString().Equals(routeValues.ToRouteString(), StringComparison.InvariantCultureIgnoreCase);
switch (contentItemRoute) {
case ContentItemRoute.Admin:
if (isCustomRoute(itemMetadata.AdminRouteValues))
return RedirectToRoute(itemMetadata.AdminRouteValues);
break;
case ContentItemRoute.Editor:
if (isCustomRoute(itemMetadata.EditorRouteValues))
return RedirectToRoute(itemMetadata.EditorRouteValues);
break;
case ContentItemRoute.Create:
if (isCustomRoute(itemMetadata.CreateRouteValues))
return RedirectToRoute(itemMetadata.CreateRouteValues);
break;
case ContentItemRoute.Display:
if (isCustomRoute(itemMetadata.DisplayRouteValues))
return RedirectToRoute(itemMetadata.DisplayRouteValues);
break;
}
return null;
}
}
}

View File

@ -1,28 +1,25 @@
using System.Web.Mvc; using System.Web.Mvc;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Mvc; using Orchard.Mvc;
using Orchard.Themes; using Orchard.Themes;
namespace Orchard.Core.Contents.Controllers { namespace Orchard.Core.Contents.Controllers {
[Themed] [Themed]
public class ItemController : Controller { public class ItemController : ContentControllerBase {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IHttpContextAccessor _hca; private readonly IHttpContextAccessor _hca;
public ItemController(IContentManager contentManager, public ItemController(
IShapeFactory shapeFactory, IOrchardServices orchardServices,
IOrchardServices services, IHttpContextAccessor hca) : base(orchardServices.ContentManager) {
IHttpContextAccessor hca) { _contentManager = orchardServices.ContentManager;
_contentManager = contentManager;
_hca = hca; _hca = hca;
Shape = shapeFactory; Services = orchardServices;
Services = services;
T = NullLocalizer.Instance; T = NullLocalizer.Instance;
} }
dynamic Shape { get; set; }
public IOrchardServices Services { get; private set; } public IOrchardServices Services { get; private set; }
public Localizer T { get; set; } public Localizer T { get; set; }
@ -36,16 +33,21 @@ namespace Orchard.Core.Contents.Controllers {
var contentItem = _contentManager.Get(id.Value, VersionOptions.Published); var contentItem = _contentManager.Get(id.Value, VersionOptions.Published);
var customRouteRedirection = GetCustomContentItemRouteRedirection(contentItem, ContentItemRoute.Display);
if (customRouteRedirection != null) {
return customRouteRedirection;
}
if (contentItem == null) if (contentItem == null)
return HttpNotFound(); return HttpNotFound();
if (!Services.Authorizer.Authorize(Permissions.ViewContent, contentItem, T("Cannot view content"))) { if (!Services.Authorizer.Authorize(Permissions.ViewContent, contentItem, T("Cannot view content"))) {
return new HttpUnauthorizedResult(); return new HttpUnauthorizedResult();
} }
var model = _contentManager.BuildDisplay(contentItem); var model = _contentManager.BuildDisplay(contentItem);
if (_hca.Current().Request.IsAjaxRequest()) { if (_hca.Current().Request.IsAjaxRequest()) {
return new ShapePartialResult(this,model); return new ShapePartialResult(this, model);
} }
return View(model); return View(model);

View File

@ -158,6 +158,7 @@
<Compile Include="Containers\ViewModels\ContainerViewModel.cs" /> <Compile Include="Containers\ViewModels\ContainerViewModel.cs" />
<Compile Include="Containers\ViewModels\ContainerTypePartSettingsViewModel.cs" /> <Compile Include="Containers\ViewModels\ContainerTypePartSettingsViewModel.cs" />
<Compile Include="Containers\ViewModels\ContainerWidgetViewModel.cs" /> <Compile Include="Containers\ViewModels\ContainerWidgetViewModel.cs" />
<Compile Include="Contents\Controllers\ContentControllerBase.cs" />
<Compile Include="Contents\ControlWrapper.cs" /> <Compile Include="Contents\ControlWrapper.cs" />
<Compile Include="Contents\Security\AuthorizationEventHandler.cs" /> <Compile Include="Contents\Security\AuthorizationEventHandler.cs" />
<Compile Include="Common\Services\BbcodeFilter.cs" /> <Compile Include="Common\Services\BbcodeFilter.cs" />

View File

@ -24,4 +24,12 @@ namespace Orchard.ContentManagement {
public readonly IList<GroupInfo> DisplayGroupInfo = new List<GroupInfo>(); public readonly IList<GroupInfo> DisplayGroupInfo = new List<GroupInfo>();
public readonly IList<GroupInfo> EditorGroupInfo = new List<GroupInfo>(); public readonly IList<GroupInfo> EditorGroupInfo = new List<GroupInfo>();
} }
public enum ContentItemRoute {
Admin,
Create,
Editor,
Remove,
Display
}
} }

View File

@ -1,29 +0,0 @@
using System.Web.Routing;
using System.Web.Mvc;
namespace Orchard.Mvc.Extensions {
public static class RouteExtension{
public static string GetAreaName(this RouteBase route){
var routeWithArea = route as IRouteWithArea;
if (routeWithArea != null) {
return routeWithArea.Area;
}
var castRoute = route as Route;
if (castRoute != null && castRoute.DataTokens != null) {
return castRoute.DataTokens["area"] as string;
}
return null;
}
public static string GetAreaName(this RouteData routeData){
object area;
if (routeData.DataTokens.TryGetValue("area", out area)) {
return area as string;
}
return GetAreaName(routeData.Route);
}
}
}

View File

@ -0,0 +1,25 @@
using System.Web.Mvc;
using System.Web.Routing;
namespace Orchard.Mvc.Extensions {
public static class RouteExtensions {
public static string GetAreaName(this RouteBase route) {
if (route is IRouteWithArea routeWithArea) {
return routeWithArea.Area;
}
if (route is Route castRoute && castRoute.DataTokens != null) {
return castRoute.DataTokens["area"] as string;
}
return null;
}
public static string GetAreaName(this RouteData routeData) =>
routeData.DataTokens.TryGetValue("area", out object area) ?
area as string : GetAreaName(routeData.Route);
public static string ToRouteString(this RouteValueDictionary route) =>
string.Join("/", route["Area"], route["Controller"], route["Action"]);
}
}

View File

@ -391,7 +391,7 @@
<Compile Include="Mvc\DataAnnotations\LocalizedRangeAttribute.cs" /> <Compile Include="Mvc\DataAnnotations\LocalizedRangeAttribute.cs" />
<Compile Include="Mvc\DataAnnotations\LocalizedModelValidatorProvider.cs" /> <Compile Include="Mvc\DataAnnotations\LocalizedModelValidatorProvider.cs" />
<Compile Include="Mvc\DataAnnotations\LocalizedRequiredAttribute.cs" /> <Compile Include="Mvc\DataAnnotations\LocalizedRequiredAttribute.cs" />
<Compile Include="Mvc\Extensions\RouteExtension.cs" /> <Compile Include="Mvc\Extensions\RouteExtensions.cs" />
<Compile Include="Mvc\Extensions\HttpContextBaseExtensions.cs" /> <Compile Include="Mvc\Extensions\HttpContextBaseExtensions.cs" />
<Compile Include="Mvc\FormValueRequiredAttribute.cs" /> <Compile Include="Mvc\FormValueRequiredAttribute.cs" />
<Compile Include="Mvc\HttpContextAccessor.cs" /> <Compile Include="Mvc\HttpContextAccessor.cs" />