#17021 Redirects in actions using returnUrl need to only redirect to the returnUrl if Url.IsLocalUrl

We did this in a lot of places. Adds a controller extension method that makes this easier.

--HG--
branch : dev
This commit is contained in:
Dave Reed
2010-12-10 14:20:08 -08:00
parent 919a57c1bf
commit 629a48958f
11 changed files with 59 additions and 98 deletions

View File

@@ -15,6 +15,7 @@ using Orchard.Data;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Mvc.Extensions;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
using Orchard.Settings;
@@ -173,10 +174,7 @@ namespace Orchard.Core.Contents.Controllers {
}
}
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("List");
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}
ActionResult CreatableTypeList() {
@@ -300,10 +298,7 @@ namespace Orchard.Core.Contents.Controllers {
? T("Your content has been saved.")
: T("Your {0} has been saved.", contentItem.TypeDefinition.DisplayName));
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } });
return this.RedirectLocal(returnUrl, () => RedirectToAction("Edit", new RouteValueDictionary { { "Id", contentItem.Id } }));
}
public ActionResult Remove(int id, string returnUrl) {
@@ -319,10 +314,7 @@ namespace Orchard.Core.Contents.Controllers {
: T("That {0} has been removed.", contentItem.TypeDefinition.DisplayName));
}
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("List");
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}
[HttpPost]
@@ -338,10 +330,7 @@ namespace Orchard.Core.Contents.Controllers {
Services.ContentManager.Flush();
Services.Notifier.Information(string.IsNullOrWhiteSpace(contentItem.TypeDefinition.DisplayName) ? T("That content has been published.") : T("That {0} has been published.", contentItem.TypeDefinition.DisplayName));
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("List");
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}
[HttpPost]
@@ -357,10 +346,7 @@ namespace Orchard.Core.Contents.Controllers {
Services.ContentManager.Flush();
Services.Notifier.Information(string.IsNullOrWhiteSpace(contentItem.TypeDefinition.DisplayName) ? T("That content has been unpublished.") : T("That {0} has been unpublished.", contentItem.TypeDefinition.DisplayName));
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("List");
return this.RedirectLocal(returnUrl, () => RedirectToAction("List"));
}
bool IUpdateModel.TryUpdateModel<TModel>(TModel model, string prefix, string[] includeProperties, string[] excludeProperties) {

View File

@@ -9,6 +9,7 @@ using Orchard.ContentManagement.Aspects;
using Orchard.Core.Contents.Settings;
using Orchard.Localization;
using Orchard.Mvc.AntiForgery;
using Orchard.Mvc.Extensions;
using Orchard.Security;
using Orchard.Security.Permissions;
using Orchard.UI.Admin;
@@ -153,10 +154,7 @@ namespace Orchard.Blogs.Controllers {
Services.Notifier.Information(T("Your {0} has been saved.", blogPost.TypeDefinition.DisplayName));
if (!String.IsNullOrEmpty(returnUrl))
return Redirect(returnUrl);
return Redirect(Url.BlogPostEdit(blogPost));
return this.RedirectLocal(returnUrl, Url.BlogPostEdit(blogPost));
}
[ValidateAntiForgeryTokenOrchard]

View File

@@ -8,6 +8,7 @@ using Orchard.ContentManagement;
using Orchard.DisplayManagement;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Mvc.Extensions;
using Orchard.UI.Navigation;
using Orchard.UI.Notify;
using Orchard.Comments.ViewModels;
@@ -244,18 +245,11 @@ namespace Orchard.Comments.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't close comments")))
return new HttpUnauthorizedResult();
_commentService.CloseCommentsForCommentedContent(commentedItemId);
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
}
catch (Exception exception) {
Services.Notifier.Error(T("Closing Comments failed: " + exception.Message));
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
}
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
[HttpPost]
@@ -264,18 +258,11 @@ namespace Orchard.Comments.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ManageComments, T("Couldn't enable comments")))
return new HttpUnauthorizedResult();
_commentService.EnableCommentsForCommentedContent(commentedItemId);
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
}
catch (Exception exception) {
Services.Notifier.Error(T("Enabling Comments failed: " + exception.Message));
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
}
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
public ActionResult Edit(int id) {
@@ -324,17 +311,12 @@ namespace Orchard.Comments.Controllers {
int commentedOn = _commentService.GetComment(id).Record.CommentedOn;
_commentService.ApproveComment(id);
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Details", new { id = commentedOn });
return this.RedirectLocal(returnUrl, () => RedirectToAction("Details", new { id = commentedOn }));
}
catch (Exception exception) {
Services.Notifier.Error(T("Approving comment failed: " + exception.Message));
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
}
@@ -347,17 +329,11 @@ namespace Orchard.Comments.Controllers {
int commentedOn = _commentService.GetComment(id).Record.CommentedOn;
_commentService.UnapproveComment(id);
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Details", new { id = commentedOn });
return this.RedirectLocal(returnUrl, () => RedirectToAction("Details", new { id = commentedOn }));
}
catch (Exception exception) {
Services.Notifier.Error(T("Unapproving comment failed: " + exception.Message));
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
}
@@ -370,17 +346,11 @@ namespace Orchard.Comments.Controllers {
int commentedOn = _commentService.GetComment(id).Record.CommentedOn;
_commentService.MarkCommentAsSpam(id);
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Details", new { id = commentedOn });
return this.RedirectLocal(returnUrl, () => RedirectToAction("Details", new { id = commentedOn }));
}
catch (Exception exception) {
Services.Notifier.Error(T("Marking comment as spam failed: " + exception.Message));
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
}
@@ -393,17 +363,11 @@ namespace Orchard.Comments.Controllers {
int commentedOn = _commentService.GetComment(id).Record.CommentedOn;
_commentService.DeleteComment(id);
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Details", new { id = commentedOn });
return this.RedirectLocal(returnUrl, () => RedirectToAction("Details", new { id = commentedOn }));
}
catch (Exception exception) {
Services.Notifier.Error(T("Deleting comment failed: " + exception.Message));
if (!String.IsNullOrEmpty(returnUrl)) {
return Redirect(returnUrl);
}
return RedirectToAction("Index");
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
}

View File

@@ -6,6 +6,7 @@ using Orchard.Comments.Services;
using Orchard.Comments.ViewModels;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Mvc.Extensions;
using Orchard.UI.Notify;
namespace Orchard.Comments.Controllers {
@@ -26,9 +27,7 @@ namespace Orchard.Comments.Controllers {
[HttpPost, ValidateInput(false)]
public ActionResult Create(string returnUrl) {
if (!Services.Authorizer.Authorize(Permissions.AddComment, T("Couldn't add comment")))
return !String.IsNullOrEmpty(returnUrl)
? Redirect(returnUrl)
: Redirect("~/");
return this.RedirectLocal(returnUrl, "~/");
var viewModel = new CommentsCreateViewModel();
@@ -73,10 +72,7 @@ namespace Orchard.Comments.Controllers {
TempData["CreateCommentContext.SiteName"] = context.SiteName;
}
return !String.IsNullOrEmpty(returnUrl)
? Redirect(returnUrl)
: Redirect("~/");
return this.RedirectLocal(returnUrl, "~/");
}
}
}

View File

@@ -7,6 +7,7 @@ using NuGet;
using Orchard.Environment.Extensions;
using Orchard.FileSystems.AppData;
using Orchard.Localization;
using Orchard.Mvc.Extensions;
using Orchard.Packaging.Services;
using Orchard.Security;
using Orchard.Themes;
@@ -101,7 +102,7 @@ namespace Orchard.Packaging.Controllers {
}
}
return Redirect(returnUrl);
return this.RedirectLocal(returnUrl, "~/");
} catch (Exception exception) {
for (Exception scan = exception; scan != null; scan = scan.InnerException) {
_notifier.Error(T("Uploading module package failed: {0}", exception.Message));
@@ -120,7 +121,7 @@ namespace Orchard.Packaging.Controllers {
_notifier.Information(T("Uninstalled package \"{0}\"", id));
return Redirect(returnUrl);
return this.RedirectLocal(returnUrl, "~/");
} catch (Exception exception) {
for (Exception scan = exception; scan != null; scan = scan.InnerException) {
_notifier.Error(T("Uninstall failed: {0}", exception.Message));

View File

@@ -4,6 +4,7 @@ using System.Linq;
using System.Web.Mvc;
using Orchard.Core.Contents.Controllers;
using Orchard.Localization;
using Orchard.Mvc.Extensions;
using Orchard.Roles.Models;
using Orchard.Roles.Services;
using Orchard.Roles.ViewModels;
@@ -160,10 +161,7 @@ namespace Orchard.Roles.Controllers {
Services.Notifier.Information(T("Role was successfully deleted."));
if (!string.IsNullOrWhiteSpace(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("Index");
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
} catch (Exception exception) {
Services.Notifier.Error(T("Editing Role failed: {0}", exception.Message));
return RedirectToAction("Edit", id);

View File

@@ -5,6 +5,7 @@ using System.Reflection;
using System.Web.Mvc;
using Orchard.Localization;
using Orchard.ContentManagement;
using Orchard.Mvc.Extensions;
using Orchard.Tags.Models;
using Orchard.Tags.ViewModels;
using Orchard.Tags.Services;
@@ -120,10 +121,7 @@ namespace Orchard.Tags.Controllers {
_tagService.DeleteTag(id);
if (!string.IsNullOrWhiteSpace(returnUrl))
return Redirect(returnUrl);
return RedirectToAction("Index");
return this.RedirectLocal(returnUrl, () => RedirectToAction("Index"));
}
private static TagEntry CreateTagEntry(TagRecord tagRecord) {

View File

@@ -8,6 +8,7 @@ using Orchard.Environment.Extensions;
using Orchard.Environment.Extensions.Models;
using Orchard.Environment.Features;
using Orchard.Localization;
using Orchard.Mvc.Extensions;
using Orchard.Reports.Services;
using Orchard.Security;
using Orchard.Themes.Preview;
@@ -85,7 +86,7 @@ namespace Orchard.Themes.Controllers {
if (!Services.Authorizer.Authorize(Permissions.ApplyTheme, T("Couldn't preview the current theme")))
return new HttpUnauthorizedResult();
_previewTheme.SetPreviewTheme(themeName);
return Redirect(returnUrl ?? "~/");
return this.RedirectLocal(returnUrl, "~/");
}
catch (Exception exception) {
Services.Notifier.Error(T("Previewing theme failed: " + exception.Message));

View File

@@ -71,19 +71,13 @@ namespace Orchard.Users.Controllers {
_authenticationService.SignIn(user, false);
if (string.IsNullOrEmpty(returnUrl))
return new RedirectResult("~/");
return new RedirectResult(returnUrl);
return this.RedirectLocal(returnUrl);
}
public ActionResult LogOff(string returnUrl) {
_authenticationService.SignOut();
if (string.IsNullOrEmpty(returnUrl))
return new RedirectResult("~/");
return new RedirectResult(returnUrl);
return this.RedirectLocal(returnUrl);
}
int MinPasswordLength {

View File

@@ -0,0 +1,24 @@
using System;
using System.Web.Mvc;
namespace Orchard.Mvc.Extensions {
public static class ControllerExtensions {
public static ActionResult RedirectLocal(this Controller controller, string redirectUrl, Func<ActionResult> invalidUrlBehavior) {
if (!string.IsNullOrWhiteSpace(redirectUrl) && controller.Url.IsLocalUrl(redirectUrl)) {
return new RedirectResult(redirectUrl);
}
return invalidUrlBehavior != null ? invalidUrlBehavior() : null;
}
public static ActionResult RedirectLocal(this Controller controller, string redirectUrl) {
return RedirectLocal(controller, redirectUrl, (string)null);
}
public static ActionResult RedirectLocal(this Controller controller, string redirectUrl, string defaultUrl) {
if (!string.IsNullOrWhiteSpace(redirectUrl) && controller.Url.IsLocalUrl(redirectUrl)) {
return new RedirectResult(redirectUrl);
}
return new RedirectResult(defaultUrl ?? "~/");
}
}
}

View File

@@ -177,6 +177,7 @@
<Compile Include="Localization\Services\DefaultLocalizedStringManager.cs" />
<Compile Include="Localization\Services\ILocalizedStringManager.cs" />
<Compile Include="Messaging\Services\DefaultMessageManager.cs" />
<Compile Include="Mvc\Extensions\ControllerExtensions.cs" />
<Compile Include="Mvc\IOrchardViewPage.cs" />
<Compile Include="Mvc\Spooling\HtmlStringWriter.cs" />
<Compile Include="Mvc\ViewEngines\Razor\IRazorCompilationEvents.cs" />