--HG--
branch : dev
This commit is contained in:
Nathan Heskew
2010-03-09 01:01:54 -08:00
13 changed files with 134 additions and 54 deletions

View File

@@ -1,5 +1,5 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<BodyDisplayViewModel>" %>
<%@ Import Namespace="Orchard.Core.Common.ViewModels"%>
<div class="manage">
<%=Html.ItemEditLink("Edit", Model.BodyAspect.ContentItem) %>
<%=Html.ItemEditLinkWithReturnUrl(_Encoded("Edit").ToString(), Model.BodyAspect.ContentItem) %>
</div>

View File

@@ -3,7 +3,7 @@
<%@ Import Namespace="Orchard.Core.Navigation.ViewModels"%>
<fieldset>
<%=Html.EditorFor(m => m.OnMainMenu) %>
<label for="OnMainMenu" class="forcheckbox"><%=_Encoded("Add to the main menu") %></label>
<label for="OnMainMenu" class="forcheckbox"><%=_Encoded("Show on main menu") %></label>
<div data-controllerid="OnMainMenu" class="">
<label for="MenuText"><%=_Encoded("Menu text") %></label>
<%=Html.TextBoxFor(m => m.MenuText, new { @class = "large text" })%>

View File

@@ -7,6 +7,7 @@ using Orchard.Blogs.ViewModels;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Mvc.AntiForgery;
using Orchard.Mvc.FollowReturnUrl;
using Orchard.Mvc.Results;
using Orchard.UI.Admin;
using Orchard.UI.Notify;
@@ -100,17 +101,17 @@ namespace Orchard.Blogs.Controllers {
return View(model);
}
[HttpPost, ActionName("Edit")]
[HttpPost, ActionName("Edit"), FollowReturnUrl]
public ActionResult EditPOST(string blogSlug, int postId) {
if (!Services.Authorizer.Authorize(Permissions.EditBlogPost, T("Couldn't edit blog post")))
return new HttpUnauthorizedResult();
Blog blog = _blogService.Get(blogSlug);
var blog = _blogService.Get(blogSlug);
if (blog == null)
return new NotFoundResult();
// Get draft (create a new version if needed)
BlogPost post = _blogPostService.Get(postId, VersionOptions.DraftRequired);
var post = _blogPostService.Get(postId, VersionOptions.DraftRequired);
if (post == null)
return new NotFoundResult();

View File

@@ -7,6 +7,7 @@ using JetBrains.Annotations;
using Orchard.Localization;
using Orchard.ContentManagement;
using Orchard.Mvc.AntiForgery;
using Orchard.Mvc.FollowReturnUrl;
using Orchard.Mvc.Results;
using Orchard.Pages.Drivers;
using Orchard.Pages.Models;
@@ -169,9 +170,9 @@ namespace Orchard.Pages.Controllers {
return View(model);
}
[HttpPost, ActionName("Edit")]
[HttpPost, ActionName("Edit"), FollowReturnUrl]
public ActionResult EditPOST(int id) {
Page page = _pageService.GetPageOrDraft(id);
var page = _pageService.GetPageOrDraft(id);
if (page == null)
return new NotFoundResult();
@@ -209,7 +210,7 @@ namespace Orchard.Pages.Controllers {
break;
}
return RedirectToAction("Edit", "Admin", new { id = model.Page.Item.ContentItem.Id });
return RedirectToAction("Edit", "Admin", new {id = model.Page.Item.ContentItem.Id});
}
public ActionResult DiscardDraft(int id) {

View File

@@ -5,6 +5,7 @@ using System.Security.Principal;
using System.Web.Mvc;
using System.Web.Security;
using Orchard.Logging;
using Orchard.Mvc.FollowReturnUrl;
using Orchard.Mvc.ViewModels;
using Orchard.Security;
using Orchard.Users.Services;
@@ -17,7 +18,6 @@ namespace Orchard.Users.Controllers {
private readonly IMembershipService _membershipService;
private readonly IUserService _userService;
public AccountController(
IAuthenticationService authenticationService,
IMembershipService membershipService,
@@ -30,46 +30,47 @@ namespace Orchard.Users.Controllers {
public ILogger Logger { get; set; }
public ActionResult AccessDenied(string returnUrl) {
public ActionResult AccessDenied() {
var returnUrl = Request.QueryString["ReturnUrl"];
var currentUser = _authenticationService.GetAuthenticatedUser();
if (currentUser == null) {
Logger.Information("Access denied to anonymous request on {0}", returnUrl);
return View("LogOn", new LogOnViewModel { Title = "Access Denied", ReturnUrl = returnUrl });
return View("LogOn", new LogOnViewModel {Title = "Access Denied"});
}
//TODO: (erikpo) Add a setting for whether or not to log access denieds since these can fill up a database pretty fast from bots on a high traffic site
Logger.Information("Access denied to user #{0} '{1}' on {2}", currentUser.Id, currentUser.UserName, returnUrl);
return View(new BaseViewModel());
}
public ActionResult LogOn(string returnUrl) {
if(_authenticationService.GetAuthenticatedUser() != null)
public ActionResult LogOn() {
if (_authenticationService.GetAuthenticatedUser() != null)
return Redirect("~/");
return View("LogOn", new LogOnViewModel { Title = "Log On", ReturnUrl = returnUrl });
return View("LogOn", new LogOnViewModel {Title = "Log On"});
}
[HttpPost]
[HttpPost, FollowReturnUrl]
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult LogOn(string userName, string password, bool rememberMe, string returnUrl) {
public ActionResult LogOn(string userName, string password, bool rememberMe) {
var user = ValidateLogOn(userName, password);
if (!ModelState.IsValid) {
return View("LogOn", new LogOnViewModel { Title = "Log On", ReturnUrl = returnUrl });
return View("LogOn", new LogOnViewModel {Title = "Log On"});
}
_authenticationService.SignIn(user, rememberMe);
return !String.IsNullOrEmpty(returnUrl)
? Redirect(returnUrl)
: Redirect("~/");
return Redirect("~/");
}
public ActionResult LogOff(string returnUrl) {
[FollowReturnUrl]
public ActionResult LogOff() {
_authenticationService.SignOut();
return !String.IsNullOrEmpty(returnUrl)
? Redirect(returnUrl)
: Redirect("~/");
return Redirect("~/");
}
int MinPasswordLength {

View File

@@ -1,10 +1,7 @@
using System;
using Orchard.Mvc.ViewModels;
using Orchard.Mvc.ViewModels;
namespace Orchard.Users.ViewModels {
public class LogOnViewModel : BaseViewModel {
public string Title { get; set; }
public string ReturnUrl { get; set; }
}
}

View File

@@ -3,26 +3,24 @@
<h1><%=Html.TitleForPage(Model.Title)%></h1>
<p><%=_Encoded("Please enter your username and password.")%> <%= Html.ActionLink("Register", "Register")%><%=_Encoded(" if you don't have an account.")%></p>
<%= Html.ValidationSummary(T("Login was unsuccessful. Please correct the errors and try again.").ToString())%>
<% using (Html.BeginForm(new { Action = "LogOn" }))
{ %>
<fieldset>
<legend><%=_Encoded("Account Information")%></legend>
<div>
<label for="username"><%=_Encoded("Username:")%></label>
<%= Html.TextBox("username")%>
<%= Html.ValidationMessage("username")%>
</div>
<div>
<label for="password"><%=_Encoded("Password:")%></label>
<%= Html.Password("password")%>
<%= Html.ValidationMessage("password")%>
</div>
<div>
<%= Html.CheckBox("rememberMe")%><label class="forcheckbox" for="rememberMe"><%=_Encoded("Remember me?")%></label>
</div>
<%=Html.HiddenFor(m => m.ReturnUrl)%>
<%=Html.AntiForgeryTokenOrchard()%>
<input type="submit" value="<%=_Encoded("Log On") %>" />
</fieldset>
<% } %><%
<%
using (Html.BeginFormAntiForgeryPost(Url.Action("LogOn", new {ReturnUrl = Request.QueryString["ReturnUrl"]}))) { %>
<fieldset>
<legend><%=_Encoded("Account Information")%></legend>
<div>
<label for="username"><%=_Encoded("Username:")%></label>
<%= Html.TextBox("username")%>
<%= Html.ValidationMessage("username")%>
</div>
<div>
<label for="password"><%=_Encoded("Password:")%></label>
<%= Html.Password("password")%>
<%= Html.ValidationMessage("password")%>
</div>
<div>
<%= Html.CheckBox("rememberMe")%><label class="forcheckbox" for="rememberMe"><%=_Encoded("Remember me?")%></label>
</div>
<input type="submit" value="<%=_Encoded("Log On") %>" />
</fieldset><%
} %><%
using (this.Capture("end-of-page-scripts")) { %><script type="text/javascript">$("#username").closest("form").helpfullyFocus();</script><% } %>

View File

@@ -0,0 +1,21 @@
using System.Web.Routing;
namespace Orchard.Extensions {
public static class RouteValueDictionaryExtensions {
public static RouteValueDictionary Merge(this RouteValueDictionary dictionary, object values) {
return values == null ? dictionary : dictionary.Merge(new RouteValueDictionary(values));
}
public static RouteValueDictionary Merge(this RouteValueDictionary dictionary, RouteValueDictionary dictionaryToMerge) {
if (dictionaryToMerge == null)
return dictionary;
var newDictionary = new RouteValueDictionary(dictionary);
foreach (var valueDictionary in dictionaryToMerge)
newDictionary[valueDictionary.Key] = valueDictionary.Value;
return newDictionary;
}
}
}

View File

@@ -0,0 +1,8 @@
using System;
using System.Web.Mvc;
namespace Orchard.Mvc.FollowReturnUrl {
[AttributeUsage(AttributeTargets.Method)]
public class FollowReturnUrlAttribute : FilterAttribute {
}
}

View File

@@ -0,0 +1,42 @@
using System;
using System.Web.Mvc;
using Orchard.Mvc.Filters;
namespace Orchard.Mvc.FollowReturnUrl {
public class FollowReturnUrlFilter : FilterProvider, IActionFilter {
public void OnActionExecuting(ActionExecutingContext filterContext) {
}
public void OnActionExecuted(ActionExecutedContext filterContext) {
var attributes =
(FollowReturnUrlAttribute[])
filterContext.ActionDescriptor.GetCustomAttributes(typeof (FollowReturnUrlAttribute), false);
if (attributes.Length <= 0) {
return;
}
var request = filterContext.HttpContext.Request;
Uri returnUrl = null;
try {
returnUrl = new Uri(request.QueryString["ReturnUrl"]);
}
catch {
try {
returnUrl =
new Uri(string.Format("{0}://{1}{2}{3}", request.Url.Scheme, request.Url.Host,
request.Url.Port != 80 ? ":" + request.Url.Port : "",
request.QueryString["ReturnUrl"]));
}
catch {}
}
if (returnUrl != null &&
returnUrl.Scheme == request.Url.Scheme &&
returnUrl.Port == request.Url.Port &&
returnUrl.Host == request.Url.Host) {
filterContext.Result = new RedirectResult(returnUrl.ToString());
}
}
}
}

View File

@@ -2,7 +2,7 @@
using System.Web.Mvc;
using System.Web.Mvc.Html;
using Orchard.ContentManagement;
using Orchard.Mvc.ViewModels;
using Orchard.Extensions;
namespace Orchard.Mvc.Html {
public static class ContentItemExtensions {
@@ -29,7 +29,15 @@ namespace Orchard.Mvc.Html {
return ItemDisplayLink(html, null, content);
}
public static MvcHtmlString ItemEditLinkWithReturnUrl(this HtmlHelper html, string linkText, IContent content) {
return html.ItemEditLink(linkText, content, new {ReturnUrl = html.ViewContext.HttpContext.Request.RawUrl});
}
public static MvcHtmlString ItemEditLink(this HtmlHelper html, string linkText, IContent content) {
return html.ItemEditLink(linkText, content, null);
}
public static MvcHtmlString ItemEditLink(this HtmlHelper html, string linkText, IContent content, object additionalRouteValues) {
var metadata = content.ContentItem.ContentManager.GetItemMetadata(content);
if (metadata.EditorRouteValues == null)
return null;
@@ -37,7 +45,7 @@ namespace Orchard.Mvc.Html {
return html.ActionLink(
linkText ?? metadata.DisplayText ?? "edit",
Convert.ToString(metadata.EditorRouteValues["action"]),
metadata.EditorRouteValues);
metadata.EditorRouteValues.Merge(additionalRouteValues));
}
public static MvcHtmlString ItemEditLink(this HtmlHelper html, IContent content) {

View File

@@ -231,7 +231,7 @@ namespace Orchard.Mvc.Html {
#region BeginFormAntiForgeryPost
public static MvcForm BeginFormAntiForgeryPost(this HtmlHelper htmlHelper) {
return htmlHelper.BeginFormAntiForgeryPost(htmlHelper.ViewContext.HttpContext.Request.Url.AbsolutePath, FormMethod.Post, new RouteValueDictionary());
return htmlHelper.BeginFormAntiForgeryPost(htmlHelper.ViewContext.HttpContext.Request.Url.PathAndQuery, FormMethod.Post, new RouteValueDictionary());
}
public static MvcForm BeginFormAntiForgeryPost(this HtmlHelper htmlHelper, string formAction) {
@@ -247,7 +247,7 @@ namespace Orchard.Mvc.Html {
}
public static MvcForm BeginFormAntiForgeryPost(this HtmlHelper htmlHelper, string formAction, FormMethod formMethod, IDictionary<string, object> htmlAttributes) {
TagBuilder tagBuilder = new TagBuilder("form");
var tagBuilder = new TagBuilder("form");
tagBuilder.MergeAttributes(htmlAttributes);
tagBuilder.MergeAttribute("action", formAction);

View File

@@ -151,12 +151,15 @@
<Compile Include="Environment\StandaloneEnvironment.cs" />
<Compile Include="Extensions\AreaFolders.cs" />
<Compile Include="Extensions\ExtensionFolders.cs" />
<Compile Include="Extensions\RouteValueDictionaryExtensions.cs" />
<Compile Include="Extensions\Loaders\AreaExtensionLoader.cs" />
<Compile Include="Extensions\StringExtensions.cs" />
<Compile Include="Extensions\UriExtensions.cs" />
<Compile Include="Mvc\AntiForgery\ValidateAntiForgeryTokenOrchardAttribute.cs" />
<Compile Include="Mvc\FollowReturnUrl\FollowReturnUrlFilter.cs" />
<Compile Include="Mvc\Html\FileRegistrationContextExtensions.cs" />
<Compile Include="Mvc\Extensions\UrlHelperExtensions.cs" />
<Compile Include="Mvc\FollowReturnUrl\FollowReturnUrlAttribute.cs" />
<Compile Include="Mvc\ViewModels\AdaptedViewModel.cs" />
<Compile Include="Mvc\ViewUserControl.cs">
<SubType>ASPXCodeBehind</SubType>