diff --git a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/LoginStatus.cshtml b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/LoginStatus.cshtml index 25b5e7eadd..0623bbeb2f 100644 --- a/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/LoginStatus.cshtml +++ b/src/Umbraco.Web.UI/Umbraco/PartialViewMacros/Templates/LoginStatus.cshtml @@ -1,4 +1,5 @@ @inherits Umbraco.Web.Macros.PartialViewMacroPage +@using System.Web.Mvc.Html @using ClientDependency.Core.Mvc @using Umbraco.Web @using Umbraco.Web.Models @@ -12,6 +13,16 @@ Html.RequiresJs("/umbraco_client/ui/jquery.js"); Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.min.js"); Html.RequiresJs("/umbraco_client/Application/JQuery/jquery.validate.unobtrusive.min.js"); + + var logoutModel = new PostRedirectModel(); + + /* + * Here you can specify a redirect URL for after logging out, by default umbraco will simply + * redirect to the current page. Example to redirect to the home page: + * + * logoutModel.RedirectUrl = "/"; + * + */ } @*NOTE: This RenderJsHere code should be put on your main template page where the rest of your script tags are placed*@ @@ -27,5 +38,7 @@ Logout + + @Html.HiddenFor(m => logoutModel.RedirectUrl) } } \ No newline at end of file diff --git a/src/Umbraco.Web/Controllers/UmbLoginController.cs b/src/Umbraco.Web/Controllers/UmbLoginController.cs index 3ae41835bc..33d657cc3f 100644 --- a/src/Umbraco.Web/Controllers/UmbLoginController.cs +++ b/src/Umbraco.Web/Controllers/UmbLoginController.cs @@ -4,6 +4,7 @@ using System.Web.Security; using umbraco.cms.businesslogic.member; using Umbraco.Web.Models; using Umbraco.Web.Mvc; +using Umbraco.Core; namespace Umbraco.Web.Controllers { @@ -24,7 +25,16 @@ namespace Umbraco.Web.Controllers return CurrentUmbracoPage(); } - return Redirect("/"); + //if there is a specified path to redirect to then use it + if (model.RedirectUrl.IsNullOrWhiteSpace() == false) + { + return Redirect(model.RedirectUrl); + } + + //redirect to current page by default + TempData.Add("LoginSuccess", true); + //return RedirectToCurrentUmbracoPage(); + return RedirectToCurrentUmbracoUrl(); } } } diff --git a/src/Umbraco.Web/Controllers/UmbLoginStatusController.cs b/src/Umbraco.Web/Controllers/UmbLoginStatusController.cs index 19a7ef2b00..a4081413c3 100644 --- a/src/Umbraco.Web/Controllers/UmbLoginStatusController.cs +++ b/src/Umbraco.Web/Controllers/UmbLoginStatusController.cs @@ -4,13 +4,14 @@ using System.Web.Security; using umbraco.cms.businesslogic.member; using Umbraco.Web.Models; using Umbraco.Web.Mvc; +using Umbraco.Core; namespace Umbraco.Web.Controllers { public class UmbLoginStatusController : SurfaceController { [HttpPost] - public ActionResult HandleLogout([Bind(Prefix = "loginStatusModel")]LoginStatusModel model) + public ActionResult HandleLogout([Bind(Prefix = "logoutModel")]PostRedirectModel model) { if (ModelState.IsValid == false) { @@ -22,9 +23,15 @@ namespace Umbraco.Web.Controllers FormsAuthentication.SignOut(); } - //TODO: Shouldn't we be redirecting to the current page or integrating this with the - // normal Umbraco protection stuff? - return Redirect("/"); + //if there is a specified path to redirect to then use it + if (model.RedirectUrl.IsNullOrWhiteSpace() == false) + { + return Redirect(model.RedirectUrl); + } + + //redirect to current page by default + TempData.Add("LogoutSuccess", true); + return RedirectToCurrentUmbracoPage(); } } } diff --git a/src/Umbraco.Web/Models/LoginModel.cs b/src/Umbraco.Web/Models/LoginModel.cs index f0cea26b0e..dd4d57d08d 100644 --- a/src/Umbraco.Web/Models/LoginModel.cs +++ b/src/Umbraco.Web/Models/LoginModel.cs @@ -2,12 +2,13 @@ namespace Umbraco.Web.Models { - public class LoginModel + public class LoginModel : PostRedirectModel { [Required] public string Username { get; set; } [Required] public string Password { get; set; } + } } diff --git a/src/Umbraco.Web/Models/LoginStatusModel.cs b/src/Umbraco.Web/Models/LoginStatusModel.cs index bc36a42202..e832af7245 100644 --- a/src/Umbraco.Web/Models/LoginStatusModel.cs +++ b/src/Umbraco.Web/Models/LoginStatusModel.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel.DataAnnotations; using System.Web; using Umbraco.Core; using Umbraco.Web.Security; @@ -49,6 +50,7 @@ namespace Umbraco.Web.Models /// /// The name of the member /// + [Required] public string Name { get; set; } /// @@ -59,6 +61,7 @@ namespace Umbraco.Web.Models /// /// The email of the member /// + [Required] public string Email { get; set; } /// diff --git a/src/Umbraco.Web/Models/PostRedirectModel.cs b/src/Umbraco.Web/Models/PostRedirectModel.cs new file mode 100644 index 0000000000..ed8176cc5f --- /dev/null +++ b/src/Umbraco.Web/Models/PostRedirectModel.cs @@ -0,0 +1,15 @@ +namespace Umbraco.Web.Models +{ + /// + /// A base model containing a value to indicate to Umbraco where to redirect to after Posting if + /// a developer doesn't want the controller to redirect to the current Umbraco page - which is the default. + /// + public class PostRedirectModel + { + /// + /// The path to redirect to when update is successful, if not specified then the user will be + /// redirected to the current Umbraco page + /// + public string RedirectUrl { get; set; } + } +} \ No newline at end of file diff --git a/src/Umbraco.Web/Models/ProfileModel.cs b/src/Umbraco.Web/Models/ProfileModel.cs index 5aa014510c..7d47b24919 100644 --- a/src/Umbraco.Web/Models/ProfileModel.cs +++ b/src/Umbraco.Web/Models/ProfileModel.cs @@ -10,7 +10,7 @@ using Umbraco.Web.Security; namespace Umbraco.Web.Models { - public class ProfileModel + public class ProfileModel : PostRedirectModel { public static ProfileModel CreateModel() { @@ -60,10 +60,5 @@ namespace Umbraco.Web.Models /// public List MemberProperties { get; set; } - /// - /// The path to redirect to when update is successful, if not specified then the user will be - /// redirected to the current Umbraco page - /// - public string RedirectUrl { get; set; } } } diff --git a/src/Umbraco.Web/Models/RegisterModel.cs b/src/Umbraco.Web/Models/RegisterModel.cs index ac89609347..a65e7a990b 100644 --- a/src/Umbraco.Web/Models/RegisterModel.cs +++ b/src/Umbraco.Web/Models/RegisterModel.cs @@ -10,7 +10,7 @@ using Umbraco.Web.Security; namespace Umbraco.Web.Models { - public class RegisterModel + public class RegisterModel : PostRedirectModel { /// /// Creates a new empty RegisterModel @@ -74,13 +74,7 @@ namespace Umbraco.Web.Models [ReadOnly(true)] [Obsolete("This is no longer used and will be removed from the codebase in future versions")] public bool RedirectOnSucces { get; set; } - - /// - /// The path to redirect to when registration is successful, if not specified then the user will be - /// redirected to the current Umbraco page - /// - public string RedirectUrl { get; set; } - + /// /// The username of the model, if UsernameIsEmail is true then this is ignored. /// diff --git a/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs b/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs index 917191f03f..6fb3610411 100644 --- a/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs +++ b/src/Umbraco.Web/Mvc/RedirectToUmbracoPageResult.cs @@ -7,6 +7,43 @@ using Umbraco.Web.Routing; namespace Umbraco.Web.Mvc { + /// + /// Redirects to the current URL rendering an Umbraco page + /// + /// + /// this is useful if you need to redirect + /// to the current page but the current page is actually a rewritten URL normally done with something like + /// Server.Transfer. + /// + public class RedirectToUmbracoUrlResult : ActionResult + { + private readonly UmbracoContext _umbracoContext; + + /// + /// Creates a new RedirectToUmbracoResult + /// + /// + public RedirectToUmbracoUrlResult(UmbracoContext umbracoContext) + { + _umbracoContext = umbracoContext; + } + + public override void ExecuteResult(ControllerContext context) + { + if (context == null) throw new ArgumentNullException("context"); + + if (context.IsChildAction) + { + throw new InvalidOperationException("Cannot redirect from a Child Action"); + } + + var destinationUrl = _umbracoContext.OriginalRequestUrl.PathAndQuery; + context.Controller.TempData.Keep(); + + context.HttpContext.Response.Redirect(destinationUrl, endResponse: false); + } + } + /// /// Redirects to an Umbraco page by Id or Entity /// diff --git a/src/Umbraco.Web/Mvc/SurfaceController.cs b/src/Umbraco.Web/Mvc/SurfaceController.cs index aa98d190bf..1010db48df 100644 --- a/src/Umbraco.Web/Mvc/SurfaceController.cs +++ b/src/Umbraco.Web/Mvc/SurfaceController.cs @@ -75,6 +75,20 @@ namespace Umbraco.Web.Mvc return new RedirectToUmbracoPageResult(CurrentPage, UmbracoContext); } + /// + /// Redirects to the currently rendered Umbraco URL + /// + /// + /// + /// this is useful if you need to redirect + /// to the current page but the current page is actually a rewritten URL normally done with something like + /// Server.Transfer. + /// + protected RedirectToUmbracoUrlResult RedirectToCurrentUmbracoUrl() + { + return new RedirectToUmbracoUrlResult(UmbracoContext); + } + /// /// Returns the currently rendered Umbraco page /// diff --git a/src/Umbraco.Web/Umbraco.Web.csproj b/src/Umbraco.Web/Umbraco.Web.csproj index e343d61cd1..97ece6e73a 100644 --- a/src/Umbraco.Web/Umbraco.Web.csproj +++ b/src/Umbraco.Web/Umbraco.Web.csproj @@ -297,6 +297,7 @@ +