Some work on making a blog or (routable) content item inaccessible by its path if it is set as the home page

--HG--
branch : dev
This commit is contained in:
Nathan Heskew
2010-11-30 16:03:01 -08:00
parent dd7b718852
commit 2798850a38
9 changed files with 186 additions and 15 deletions

View File

@@ -1,4 +1,5 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.Mvc;
using Orchard.ContentManagement;
@@ -8,6 +9,7 @@ using Orchard.Core.Routable.Services;
using Orchard.Data;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Services;
using Orchard.Themes;
namespace Orchard.Core.Routable.Controllers {
@@ -16,25 +18,33 @@ namespace Orchard.Core.Routable.Controllers {
private readonly IContentManager _contentManager;
private readonly ITransactionManager _transactionManager;
private readonly IRoutablePathConstraint _routablePathConstraint;
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public ItemController(
IContentManager contentManager,
ITransactionManager transactionManager,
IRoutablePathConstraint routablePathConstraint,
IShapeFactory shapeFactory) {
IRoutablePathConstraint routablePathConstraint,
IShapeFactory shapeFactory,
IWorkContextAccessor workContextAccessor,
IEnumerable<IHomePageProvider> homePageProviders) {
_contentManager = contentManager;
_transactionManager = transactionManager;
_routablePathConstraint = routablePathConstraint;
_workContextAccessor = workContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
Shape = shapeFactory;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
dynamic Shape { get; set; }
[Themed]
public ActionResult Display(string path) {
var matchedPath = _routablePathConstraint.FindPath(path);
if (string.IsNullOrEmpty(matchedPath)) {
throw new ApplicationException("404 - should not have passed path constraint");
if (matchedPath == null) {
throw new ApplicationException(T("404 - should not have passed path constraint").Text);
}
var hits = _contentManager
@@ -42,13 +52,20 @@ namespace Orchard.Core.Routable.Controllers {
.Where(r => r.Path == matchedPath)
.Slice(0, 2);
if (hits.Count() == 0) {
throw new ApplicationException("404 - should not have passed path constraint");
throw new ApplicationException(T("404 - should not have passed path constraint").Text);
}
if (hits.Count() != 1) {
throw new ApplicationException("Ambiguous content");
throw new ApplicationException(T("Ambiguous content").Text);
}
dynamic model = _contentManager.BuildDisplay(hits.Single());
var item = hits.Single();
// primary action run for a home paged item shall not pass
if (!RouteData.DataTokens.ContainsKey("ParentActionViewContext")
&& item.Id == _routableHomePageProvider.GetHomePageId(_workContextAccessor.GetContext().CurrentSite.HomePage)) {
return HttpNotFound();
}
dynamic model = _contentManager.BuildDisplay(item);
// Casting to avoid invalid (under medium trust) reflection over the protected View method and force a static invocation.
return View((object)model);
}

View File

@@ -23,6 +23,7 @@ namespace Orchard.Core.Routable.Handlers {
IRepository<RoutePartRecord> repository,
IRoutablePathConstraint routablePathConstraint,
IRoutableService routableService,
IWorkContextAccessor workContextAccessor,
IEnumerable<IHomePageProvider> homePageProviders) {
_services = services;
_routablePathConstraint = routablePathConstraint;
@@ -46,8 +47,10 @@ namespace Orchard.Core.Routable.Handlers {
OnPublished<RoutePart>((context, route) => {
FinalizePath(route, context, processSlug);
if (route.ContentItem.Id != 0 && route.PromoteToHomePage && _routableHomePageProvider != null)
if (route.ContentItem.Id != 0 && route.PromoteToHomePage && _routableHomePageProvider != null) {
_services.WorkContext.CurrentSite.HomePage = _routableHomePageProvider.GetSettingValue(route.ContentItem.Id);
_routablePathConstraint.AddPath("");
}
});
OnRemoved<RoutePart>((context, route) => {
@@ -87,6 +90,14 @@ namespace Orchard.Core.Routable.Handlers {
}
public class RoutePartHandlerBase : ContentHandlerBase {
private readonly IWorkContextAccessor _workContextAccessor;
private readonly IHomePageProvider _routableHomePageProvider;
public RoutePartHandlerBase(IWorkContextAccessor workContextAccessor, IEnumerable<IHomePageProvider> homePageProviders) {
_workContextAccessor = workContextAccessor;
_routableHomePageProvider = homePageProviders.SingleOrDefault(p => p.GetProviderName() == RoutableHomePageProvider.Name);
}
public override void GetContentItemMetadata(GetContentItemMetadataContext context) {
var routable = context.ContentItem.As<RoutePart>();
@@ -98,11 +109,15 @@ namespace Orchard.Core.Routable.Handlers {
// set the display route values if it hasn't been set or only has been set by the Contents module.
// allows other modules to set their own display. probably not common enough to warrant some priority implemntation
if (context.Metadata.DisplayRouteValues == null || context.Metadata.DisplayRouteValues["Area"] as string == "Contents") {
var itemPath = routable.Id == _routableHomePageProvider.GetHomePageId(_workContextAccessor.GetContext().CurrentSite.HomePage)
? ""
: routable.Path;
context.Metadata.DisplayRouteValues = new RouteValueDictionary {
{"Area", "Routable"},
{"Controller", "Item"},
{"Action", "Display"},
{"path", routable.Path}
{"path", itemPath}
};
}
}

View File

@@ -1,7 +1,9 @@
using System.Web.Mvc;
using System;
using System.Web.Mvc;
using JetBrains.Annotations;
using Orchard.Core.Routable.Models;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Services;
using Orchard.ContentManagement;
@@ -16,8 +18,10 @@ namespace Orchard.Core.Routable.Services {
IShapeFactory shapeFactory) {
_contentManager = contentManager;
Shape = shapeFactory;
T = NullLocalizer.Instance;
}
public Localizer T { get; set; }
dynamic Shape { get; set; }
public string GetProviderName() {
@@ -28,6 +32,15 @@ namespace Orchard.Core.Routable.Services {
return GetProviderName() + ";" + id;
}
public int GetHomePageId(string value) {
int id;
if (string.IsNullOrWhiteSpace(value) || !int.TryParse(value.Substring(Name.Length + 1), out id))
throw new ApplicationException(T("Invalid home page setting value for {0}: {1}", Name, value).Text);
return id;
}
public ActionResult GetHomePage(int id) {
var contentItem = _contentManager.Get(id, VersionOptions.Published);
if (contentItem == null || !contentItem.Is<RoutePart>())