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.ViewModels;
using Orchard.Data;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Localization.Services;
using Orchard.Logging;
using Orchard.Mvc.Extensions;
using Orchard.Mvc.Html;
using Orchard.Settings;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
using Orchard.Settings;
using Orchard.Utility.Extensions;
using Orchard.Localization.Services;
namespace Orchard.Core.Contents.Controllers {
[ValidateInput(false)]
public class AdminController : Controller, IUpdateModel {
public class AdminController : ContentControllerBase, IUpdateModel {
private readonly IContentManager _contentManager;
private readonly IContentDefinitionManager _contentDefinitionManager;
private readonly ITransactionManager _transactionManager;
@ -36,24 +35,21 @@ namespace Orchard.Core.Contents.Controllers {
public AdminController(
IOrchardServices orchardServices,
IContentManager contentManager,
IContentDefinitionManager contentDefinitionManager,
ITransactionManager transactionManager,
ISiteService siteService,
IShapeFactory shapeFactory,
ICultureManager cultureManager,
ICultureFilter cultureFilter) {
ICultureFilter cultureFilter) : base(orchardServices.ContentManager) {
Services = orchardServices;
_contentManager = contentManager;
_contentManager = orchardServices.ContentManager;
_transactionManager = orchardServices.TransactionManager;
_contentDefinitionManager = contentDefinitionManager;
_transactionManager = transactionManager;
_siteService = siteService;
_cultureManager = cultureManager;
_cultureFilter = cultureFilter;
T = NullLocalizer.Instance;
Logger = NullLogger.Instance;
Shape = shapeFactory;
Shape = orchardServices.New;
}
dynamic Shape { get; set; }
@ -247,6 +243,11 @@ namespace Orchard.Core.Contents.Controllers {
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")))
return new HttpUnauthorizedResult();
@ -313,6 +314,11 @@ namespace Orchard.Core.Contents.Controllers {
public ActionResult Edit(int id) {
var contentItem = _contentManager.Get(id, VersionOptions.Latest);
var customRouteRedirection = GetCustomContentItemRouteRedirection(contentItem, ContentItemRoute.Editor);
if (customRouteRedirection != null) {
return customRouteRedirection;
}
if (contentItem == null)
return HttpNotFound();
@ -396,6 +402,12 @@ namespace Orchard.Core.Contents.Controllers {
if (!Services.Authorizer.Authorize(Permissions.CreateContent, contentItem, T("Couldn't clone content")))
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 {
Services.ContentManager.Clone(contentItem);
}
@ -413,7 +425,7 @@ namespace Orchard.Core.Contents.Controllers {
public ActionResult Remove(int id, string returnUrl) {
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();
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 Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Mvc;
using Orchard.Themes;
namespace Orchard.Core.Contents.Controllers {
[Themed]
public class ItemController : Controller {
public class ItemController : ContentControllerBase {
private readonly IContentManager _contentManager;
private readonly IHttpContextAccessor _hca;
public ItemController(IContentManager contentManager,
IShapeFactory shapeFactory,
IOrchardServices services,
IHttpContextAccessor hca) {
_contentManager = contentManager;
public ItemController(
IOrchardServices orchardServices,
IHttpContextAccessor hca) : base(orchardServices.ContentManager) {
_contentManager = orchardServices.ContentManager;
_hca = hca;
Shape = shapeFactory;
Services = services;
Services = orchardServices;
T = NullLocalizer.Instance;
}
dynamic Shape { get; set; }
public IOrchardServices Services { get; private set; }
public Localizer T { get; set; }
@ -36,16 +33,21 @@ namespace Orchard.Core.Contents.Controllers {
var contentItem = _contentManager.Get(id.Value, VersionOptions.Published);
var customRouteRedirection = GetCustomContentItemRouteRedirection(contentItem, ContentItemRoute.Display);
if (customRouteRedirection != null) {
return customRouteRedirection;
}
if (contentItem == null)
return HttpNotFound();
if (!Services.Authorizer.Authorize(Permissions.ViewContent, contentItem, T("Cannot view content"))) {
return new HttpUnauthorizedResult();
}
var model = _contentManager.BuildDisplay(contentItem);
if (_hca.Current().Request.IsAjaxRequest()) {
return new ShapePartialResult(this,model);
return new ShapePartialResult(this, model);
}
return View(model);

View File

@ -158,6 +158,7 @@
<Compile Include="Containers\ViewModels\ContainerViewModel.cs" />
<Compile Include="Containers\ViewModels\ContainerTypePartSettingsViewModel.cs" />
<Compile Include="Containers\ViewModels\ContainerWidgetViewModel.cs" />
<Compile Include="Contents\Controllers\ContentControllerBase.cs" />
<Compile Include="Contents\ControlWrapper.cs" />
<Compile Include="Contents\Security\AuthorizationEventHandler.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> 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\LocalizedModelValidatorProvider.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\FormValueRequiredAttribute.cs" />
<Compile Include="Mvc\HttpContextAccessor.cs" />