/*
Kooboo is a content management system based on ASP.NET MVC framework. Copyright 2009 Yardi Technology Limited.
This program is free software: you can redistribute it and/or modify it under the terms of the
GNU General Public License version 3 as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License along with this program.
If not, see http://www.kooboo.com/gpl3/.
*/
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Security.Principal;
using System.Web;
using System.Web.Mvc;
using System.Web.Security;
using System.Web.UI;
using Everest.Library.Mvc;
using Everest.Library.ExtensionMethod;
namespace Everest.CmsServices.Controllers{
[HandleError]
[OutputCache(Location = OutputCacheLocation.None)]
public class AccountController : EverestControllerBase
{
public AccountController()
: this(null, null)
{
}
public AccountController(IFormsAuthentication formsAuth, MembershipProvider provider)
{
FormsAuth = formsAuth ?? new FormsAuthenticationWrapper();
Provider = provider ?? Membership.Provider;
}
public IFormsAuthentication FormsAuth
{
get;
private set;
}
public MembershipProvider Provider
{
get;
private set;
}
[Authorize]
public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword)
{
ViewData["Title"] = Resources.Account_ChangePassoword;
ViewData["PasswordLength"] = Provider.MinRequiredPasswordLength;
// Non-POST requests should just display the ChangePassword form
if (Request.HttpMethod != "POST")
{
return View();
}
// Basic parameter validation
List<string> errors = new List<string>();
if (StringExtensions.IsNullOrEmptyTrim(currentPassword))
{
errors.Add(Resources.Account_ChangePassoword);
}
if (newPassword == null || newPassword.Length < Provider.MinRequiredPasswordLength)
{
errors.Add(String.Format(CultureInfo.InvariantCulture,
Resources.Account_SpecifyNewPassword,
Provider.MinRequiredPasswordLength));
}
if (!String.Equals(newPassword, confirmPassword, StringComparison.Ordinal))
{
errors.Add(Resources.Account_PasswordDotMatch);
}
if (errors.Count == 0)
{
// Attempt to change password
MembershipUser currentUser = Provider.GetUser(User.Identity.Name, true /* userIsOnline */);
bool changeSuccessful = false;
try
{
changeSuccessful = currentUser.ChangePassword(currentPassword, newPassword);
}
catch
{
// An exception is thrown if the new password does not meet the provider's requirements
}
if (changeSuccessful)
{
return RedirectToAction("ChangePasswordSuccess");
}
else
{
errors.Add(Resources.Account_CurrentPasswordIsIncorrect);
}
}
// If we got this far, something failed, redisplay form
ViewData["errors"] = errors;
return View();
}
public ActionResult ChangePasswordSuccess()
{
return View();
}
[AcceptVerbs(HttpVerbs.Get)]
public ActionResult Login()
{
Response.AddHeader("RedirectToLogin", "1");
return View();
}
[AcceptVerbs(HttpVerbs.Post)]
public ActionResult Login(string username, string password, bool? rememberMe)
{
ViewData["Title"] = Resources.Account_Login;
// Basic parameter validation
List<string> errors = new List<string>();
if (StringExtensions.IsNullOrEmptyTrim(username))
{
errors.Add(Resources.Account_SpecifyUserName);
}
if (errors.Count == 0)
{
// Attempt to login
bool loginSuccessful = Provider.ValidateUser(username, password);
if (loginSuccessful)
{
return Redirect(FormsAuth.SetAuthCookie(username, rememberMe ?? false));
}
else
{
errors.Add(Resources.Account_UserNameOrPasswordIncorrect);
}
}
// If we got this far, something failed, redisplay form
ViewData["errors"] = errors;
ViewData["username"] = username;
return View();
}
public ActionResult Logout()
{
FormsAuth.SignOut();
return RedirectToAction("Login");
}
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
if (filterContext.HttpContext.User.Identity is WindowsIdentity)
{
throw new InvalidOperationException("Windows authentication is not supported.");
}
}
public static string ErrorCodeToString(MembershipCreateStatus createStatus)
{
// See http://msdn.microsoft.com/en-us/library/system.web.security.membershipcreatestatus.aspx for
// a full list of status codes.
switch (createStatus)
{
case MembershipCreateStatus.DuplicateUserName:
return Resources.Account_DuplicateUserName;
case MembershipCreateStatus.DuplicateEmail:
return Resources.Account_DuplicateEmail;
case MembershipCreateStatus.InvalidPassword:
return Resources.Account_InvalidPassword;
case MembershipCreateStatus.InvalidEmail:
return Resources.Account_InvalidEmail;
case MembershipCreateStatus.InvalidAnswer:
return Resources.Account_InvalidAnswer;
case MembershipCreateStatus.InvalidQuestion:
return Resources.Account_InvalidQuestion;
case MembershipCreateStatus.InvalidUserName:
return Resources.Account_InvalidUserName;
case MembershipCreateStatus.ProviderError:
return Resources.Account_ProviderError;
case MembershipCreateStatus.UserRejected:
return Resources.Account_UserRejected;
default:
return Resources.Account_UnknownError;
}
}
}
// The FormsAuthentication type is sealed and contains static members, so it is difficult to
// unit test code that calls its members. The interface and helper class below demonstrate
// how to create an abstract wrapper around such a type in order to make the AccountController
// code unit testable.
public interface IFormsAuthentication
{
string SetAuthCookie(string userName, bool createPersistentCookie);
void SignOut();
}
public class FormsAuthenticationWrapper : IFormsAuthentication
{
public string SetAuthCookie(string userName, bool createPersistentCookie)
{
FormsAuthentication.SetAuthCookie(userName, createPersistentCookie);
string url = FormsAuthentication.GetRedirectUrl(userName, createPersistentCookie);
return url;
}
public void SignOut()
{
FormsAuthentication.SignOut();
}
}
}
|