From 81b1a375efb7744382871d34c2c5b9ed64fe78cf Mon Sep 17 00:00:00 2001 From: Sebastien Ros Date: Thu, 14 Oct 2010 16:33:12 -0700 Subject: [PATCH] Fixing dots on routes - http://orchard.codeplex.com/workitem/16533 --HG-- branch : dev --- .../Core/Routable/Drivers/RoutePartDriver.cs | 9 +++++++-- .../Core/Routable/Services/RoutableService.cs | 11 +++++++++-- .../Orchard.Blogs/Controllers/BlogAdminController.cs | 5 ----- .../Orchard.Blogs/Handlers/BlogPartArchiveHandler.cs | 8 ++++---- .../Modules/Orchard.Blogs/Models/BlogPart.cs | 1 - src/Orchard/Mvc/Html/HtmlHelperExtensions.cs | 1 - 6 files changed, 20 insertions(+), 15 deletions(-) diff --git a/src/Orchard.Web/Core/Routable/Drivers/RoutePartDriver.cs b/src/Orchard.Web/Core/Routable/Drivers/RoutePartDriver.cs index 5a0b308cc..4356be02a 100644 --- a/src/Orchard.Web/Core/Routable/Drivers/RoutePartDriver.cs +++ b/src/Orchard.Web/Core/Routable/Drivers/RoutePartDriver.cs @@ -82,8 +82,13 @@ namespace Orchard.Core.Routable.Drivers { part.Title = model.Title; part.Slug = model.Slug; - if (!_routableService.IsSlugValid(part.Slug)) { - updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead).")); + if ( !_routableService.IsSlugValid(part.Slug) ) { + if ( ( part.Slug ?? String.Empty ).Trim().EndsWith(".") ) { + updater.AddModelError("Routable.Slug", T("The \".\" can't be used around routes.")); + } + else { + updater.AddModelError("Routable.Slug", T("Please do not use any of the following characters in your slugs: \":\", \"?\", \"#\", \"[\", \"]\", \"@\", \"!\", \"$\", \"&\", \"'\", \"(\", \")\", \"*\", \"+\", \",\", \";\", \"=\". No spaces are allowed (please use dashes or underscores instead).")); + } } string originalSlug = part.Slug; diff --git a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs index 7d29d7397..0c013e1c1 100644 --- a/src/Orchard.Web/Core/Routable/Services/RoutableService.cs +++ b/src/Orchard.Web/Core/Routable/Services/RoutableService.cs @@ -26,6 +26,9 @@ namespace Orchard.Core.Routable.Services { if (slug.Length > 1000) slug = slug.Substring(0, 1000); + // dots are not allowed at the begin and the end of routes + slug = slug.Trim('.'); + model.Slug = slug.ToLowerInvariant(); } @@ -63,8 +66,13 @@ namespace Orchard.Core.Routable.Services { } public bool IsSlugValid(string slug) { + slug = (slug ?? String.Empty).Trim(); + return !( SlugHasProhibitedChard(slug) || slug.StartsWith(".") || slug.EndsWith(".") ); + } + + public bool SlugHasProhibitedChard(string slug) { // see http://tools.ietf.org/html/rfc3987 for prohibited chars - return slug == null || String.IsNullOrEmpty(slug.Trim()) || Regex.IsMatch(slug, @"^[^:?#\[\]@!$&'()*+,;=\s]+$"); + return Regex.IsMatch(slug, @"^[^:?#\[\]@!$&'()*+,;=\s]+$"); } public bool ProcessSlug(RoutePart part) { @@ -80,7 +88,6 @@ namespace Orchard.Core.Routable.Services { // of slugs to consider for conflict detection pathsLikeThis = pathsLikeThis.Where(p => p.ContentItem.Id != part.ContentItem.Id); - //todo: (heskew) need better messages if (pathsLikeThis.Count() > 0) { var originalSlug = part.Slug; //todo: (heskew) make auto-uniqueness optional diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs index 069495e45..bd5bc5990 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Controllers/BlogAdminController.cs @@ -43,7 +43,6 @@ namespace Orchard.Blogs.Controllers { public IOrchardServices Services { get; set; } public ActionResult Create() { - //TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to create blogs"))) return new HttpUnauthorizedResult(); @@ -57,7 +56,6 @@ namespace Orchard.Blogs.Controllers { [HttpPost, ActionName("Create")] public ActionResult CreatePOST() { - //TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't create blog"))) return new HttpUnauthorizedResult(); @@ -79,7 +77,6 @@ namespace Orchard.Blogs.Controllers { } public ActionResult Edit(string blogSlug) { - //TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Not allowed to edit blog"))) return new HttpUnauthorizedResult(); @@ -93,7 +90,6 @@ namespace Orchard.Blogs.Controllers { [HttpPost, ActionName("Edit")] public ActionResult EditPOST(string blogSlug) { - //TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't edit blog"))) return new HttpUnauthorizedResult(); @@ -112,7 +108,6 @@ namespace Orchard.Blogs.Controllers { [HttpPost] public ActionResult Remove(string blogSlug) { - //TODO: (erikpo) Might think about moving this to an ActionFilter/Attribute if (!Services.Authorizer.Authorize(Permissions.ManageBlogs, T("Couldn't delete blog"))) return new HttpUnauthorizedResult(); diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPartArchiveHandler.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPartArchiveHandler.cs index 1574775b3..bad560846 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPartArchiveHandler.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Handlers/BlogPartArchiveHandler.cs @@ -18,21 +18,21 @@ namespace Orchard.Blogs.Handlers { private static void RecalculateBlogArchive(IRepository blogArchiveRepository, IRepository commonRepository, BlogPostPart blogPostPart) { blogArchiveRepository.Flush(); - //INFO: (erikpo) Remove all current blog archive records + // remove all current blog archive records var blogArchiveRecords = from bar in blogArchiveRepository.Table where bar.BlogPart == blogPostPart.BlogPart.Record select bar; blogArchiveRecords.ToList().ForEach(blogArchiveRepository.Delete); - //INFO: (erikpo) Get all blog posts for the current blog + // get all blog posts for the current blog var postsQuery = from bpr in commonRepository.Table where bpr.ContentItemRecord.ContentType.Name == "BlogPost" && bpr.Container.Id == blogPostPart.BlogPart.Record.Id orderby bpr.PublishedUtc select bpr; - //INFO: (erikpo) Create a dictionary of all the year/month combinations and their count of posts that are published in this blog + // create a dictionary of all the year/month combinations and their count of posts that are published in this blog var inMemoryBlogArchives = new Dictionary(postsQuery.Count()); foreach (var post in postsQuery) { if (!post.PublishedUtc.HasValue) @@ -46,7 +46,7 @@ namespace Orchard.Blogs.Handlers { inMemoryBlogArchives[key] = 1; } - //INFO: (erikpo) Create the new blog archive records based on the in memory values + // create the new blog archive records based on the in memory values foreach (KeyValuePair item in inMemoryBlogArchives) { blogArchiveRepository.Create(new BlogPartArchiveRecord {BlogPart = blogPostPart.BlogPart.Record, Year = item.Key.Year, Month = item.Key.Month, PostCount = item.Value}); } diff --git a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPart.cs b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPart.cs index 09bffdedc..7aec67522 100644 --- a/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPart.cs +++ b/src/Orchard.Web/Modules/Orchard.Blogs/Models/BlogPart.cs @@ -9,7 +9,6 @@ namespace Orchard.Blogs.Models { set { this.As().Title = value; } } - //TODO: (erikpo) Need a data type for slug public string Slug { get { return this.As().Slug; } set { this.As().Slug = value; } diff --git a/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs b/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs index 8af130861..d4bf700da 100644 --- a/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs +++ b/src/Orchard/Mvc/Html/HtmlHelperExtensions.cs @@ -195,7 +195,6 @@ namespace Orchard.Mvc.Html { return value.HasValue ? htmlHelper.DateTimeRelative(value.Value, T) : defaultIfNull; } - //TODO: (erikpo) This method needs localized public static LocalizedString DateTimeRelative(this HtmlHelper htmlHelper, DateTime value, Localizer T) { var time = htmlHelper.Resolve().UtcNow - value;