Files
Orchard/src/Orchard.Web/Modules/Orchard.Users/Controllers/AccountController.cs
Alessandro Agostini c515ce1917 Added Username policies (#8638)
* Added Username policies

* Added newline at the end of files

# Conflicts:
#	src/Orchard.Web/Modules/Orchard.Users/Services/AccountValidationService.cs

* Added check for username length that must be under 255 characters (even if username policies are disabled).
If username isn't modified, policies are not enforced when saving the user inside backoffice.
Default length limits are 1 and 255.

* Added UsernameValidationError.cs
Added a setting to bypass non fatal errors and show them as warning when creating/editing users from the backoffice
Added the relative checkbox in RegistrationSettings.cshtml
Modified the UsernameMeetsPolicies method to use the new class
Modified AdminController (CreatePOST, EditPOST) and AccountController (Register)

* If username is an email check that it matches the specified email

* Added hints to UserRegistrationSettings view
Changed the severity of some custom policies errors

* Removed UsernameValidLengthAttribute.cs, if MinimumUsernameLength and MaximumUsernameLength settings don't make sense these settings are ignored

* bugfix. The admin could change the a username setting an already existing username.

Co-authored-by: Andrea Piovanelli <andrea.piovanelli@laser-group.com>
2023-01-27 11:23:22 +01:00

665 lines
30 KiB
C#

using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Text.RegularExpressions;
using System.Web.Mvc;
using System.Web.Security;
using Orchard.ContentManagement;
using Orchard.Localization;
using Orchard.Logging;
using Orchard.Mvc;
using Orchard.Mvc.Extensions;
using Orchard.Security;
using Orchard.Services;
using Orchard.Themes;
using Orchard.UI.Notify;
using Orchard.Users.Events;
using Orchard.Users.Models;
using Orchard.Users.Services;
using Orchard.Utility.Extensions;
namespace Orchard.Users.Controllers {
[HandleError, Themed]
public class AccountController : Controller {
private readonly IAuthenticationService _authenticationService;
private readonly IMembershipService _membershipService;
private readonly IUserService _userService;
private readonly IOrchardServices _orchardServices;
private readonly IUserEventHandler _userEventHandler;
private readonly IClock _clock;
private readonly IAccountValidationService _accountValidationService;
public AccountController(
IAuthenticationService authenticationService,
IMembershipService membershipService,
IUserService userService,
IOrchardServices orchardServices,
IUserEventHandler userEventHandler,
IClock clock,
IAccountValidationService accountValidationService) {
_authenticationService = authenticationService;
_membershipService = membershipService;
_userService = userService;
_orchardServices = orchardServices;
_userEventHandler = userEventHandler;
_clock = clock;
_accountValidationService = accountValidationService;
Logger = NullLogger.Instance;
T = NullLocalizer.Instance;
}
public ILogger Logger { get; set; }
public Localizer T { get; set; }
[AlwaysAccessible]
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);
var shape = _orchardServices.New.LogOn().Title(T("Access Denied").Text);
return new ShapeResult(this, shape);
}
Logger.Information("Access denied to user #{0} '{1}' on {2}", currentUser.Id, currentUser.UserName, returnUrl);
_userEventHandler.AccessDenied(currentUser);
return View();
}
[AlwaysAccessible]
public ActionResult LogOn(string returnUrl) {
if (_authenticationService.GetAuthenticatedUser() != null)
return this.RedirectLocal(returnUrl);
var shape = _orchardServices.New.LogOn().Title(T("Log On").Text);
return new ShapeResult(this, shape);
}
[HttpPost]
[AlwaysAccessible]
[ValidateInput(false)]
[SuppressMessage("Microsoft.Design", "CA1054:UriParametersShouldNotBeStrings",
Justification = "Needs to take same parameter type as Controller.Redirect()")]
public ActionResult LogOn(string userNameOrEmail, string password, string returnUrl, bool rememberMe = false) {
_userEventHandler.LoggingIn(userNameOrEmail, password);
var user = ValidateLogOn(userNameOrEmail, password);
if (!ModelState.IsValid) {
var shape = _orchardServices.New.LogOn().Title(T("Log On").Text);
return new ShapeResult(this, shape);
}
var membershipSettings = _membershipService.GetSettings();
if (user != null &&
membershipSettings.EnableCustomPasswordPolicy &&
membershipSettings.EnablePasswordExpiration &&
_membershipService.PasswordIsExpired(user, membershipSettings.PasswordExpirationTimeInDays)) {
return RedirectToAction("ChangeExpiredPassword", new { username = user.UserName });
}
if (user != null && user.As<UserPart>().ForcePasswordChange) {
return RedirectToAction("ChangeExpiredPassword", new { username = user.UserName });
}
_authenticationService.SignIn(user, rememberMe);
_userEventHandler.LoggedIn(user);
return this.RedirectLocal(returnUrl);
}
public ActionResult LogOff(string returnUrl) {
_authenticationService.SignOut();
var loggedUser = _authenticationService.GetAuthenticatedUser();
if (loggedUser != null) {
_userEventHandler.LoggedOut(loggedUser);
}
return this.RedirectLocal(returnUrl);
}
[AlwaysAccessible]
public ActionResult Register() {
// ensure users can register
var membershipSettings = _membershipService.GetSettings();
if (!membershipSettings.UsersCanRegister) {
return HttpNotFound();
}
ViewData["PasswordLength"] = membershipSettings.GetMinimumPasswordLength();
ViewData["LowercaseRequirement"] = membershipSettings.GetPasswordLowercaseRequirement();
ViewData["UppercaseRequirement"] = membershipSettings.GetPasswordUppercaseRequirement();
ViewData["SpecialCharacterRequirement"] = membershipSettings.GetPasswordSpecialRequirement();
ViewData["NumberRequirement"] = membershipSettings.GetPasswordNumberRequirement();
var shape = _orchardServices.New.Register();
return new ShapeResult(this, shape);
}
[HttpPost]
[AlwaysAccessible]
[ValidateInput(false)]
public ActionResult Register(string userName, string email, string password, string confirmPassword, string returnUrl = null) {
// ensure users can register
var membershipSettings = _membershipService.GetSettings();
if (!membershipSettings.UsersCanRegister) {
return HttpNotFound();
}
ViewData["PasswordLength"] = membershipSettings.GetMinimumPasswordLength();
ViewData["LowercaseRequirement"] = membershipSettings.GetPasswordLowercaseRequirement();
ViewData["UppercaseRequirement"] = membershipSettings.GetPasswordUppercaseRequirement();
ViewData["SpecialCharacterRequirement"] = membershipSettings.GetPasswordSpecialRequirement();
ViewData["NumberRequirement"] = membershipSettings.GetPasswordNumberRequirement();
if (ValidateRegistration(userName, email, password, confirmPassword)) {
// Attempt to register the user
// No need to report this to IUserEventHandler because _membershipService does that for us
var user = _membershipService.CreateUser(new CreateUserParams(userName, password, email, null, null, false, false));
if (user != null) {
if (user.As<UserPart>().EmailStatus == UserStatus.Pending) {
var siteUrl = _orchardServices.WorkContext.CurrentSite.BaseUrl;
if (String.IsNullOrWhiteSpace(siteUrl)) {
siteUrl = HttpContext.Request.ToRootUrlString();
}
_userService.SendChallengeEmail(user.As<UserPart>(), nonce => Url.MakeAbsolute(Url.Action("ChallengeEmail", "Account", new { Area = "Orchard.Users", nonce = nonce }), siteUrl));
_userEventHandler.SentChallengeEmail(user);
return RedirectToAction("ChallengeEmailSent", new { ReturnUrl = returnUrl });
}
if (user.As<UserPart>().RegistrationStatus == UserStatus.Pending) {
return RedirectToAction("RegistrationPending", new { ReturnUrl = returnUrl });
}
_userEventHandler.LoggingIn(userName, password);
_authenticationService.SignIn(user, false /* createPersistentCookie */);
_userEventHandler.LoggedIn(user);
return this.RedirectLocal(returnUrl);
}
ModelState.AddModelError("_FORM", T(ErrorCodeToString(/*createStatus*/MembershipCreateStatus.ProviderError)));
}
// If we got this far, something failed, redisplay form
var shape = _orchardServices.New.Register();
return new ShapeResult(this, shape);
}
[AlwaysAccessible]
public ActionResult RequestLostPassword() {
// ensure users can request lost password
var membershipSettings = _membershipService.GetSettings();
if (!membershipSettings.EnableLostPassword) {
return HttpNotFound();
}
return View();
}
[HttpPost]
[AlwaysAccessible]
public ActionResult RequestLostPassword(string username) {
// ensure users can request lost password
var membershipSettings = _membershipService.GetSettings();
if (!membershipSettings.EnableLostPassword) {
return HttpNotFound();
}
if (string.IsNullOrWhiteSpace(username)) {
ModelState.AddModelError("username", T("You must specify a username or e-mail."));
return View();
}
var siteUrl = _orchardServices.WorkContext.CurrentSite.BaseUrl;
if (string.IsNullOrWhiteSpace(siteUrl)) {
siteUrl = HttpContext.Request.ToRootUrlString();
}
_userService.SendLostPasswordEmail(username, nonce =>
Url.MakeAbsolute(Url.Action("LostPassword", "Account", new { Area = "Orchard.Users", nonce }), siteUrl));
_orchardServices.Notifier.Information(T("If your username or email is correct, we will send you an email with a link to reset your password."));
return RedirectToAction("LogOn");
}
[AlwaysAccessible]
public ActionResult RequestChallengeEmail(string email = null) {
// ensure users can request lost password
var membershipSettings = _membershipService.GetSettings();
if (!membershipSettings.UsersMustValidateEmail) {
return HttpNotFound();
}
return View(model: email);
}
[HttpPost, ActionName("RequestChallengeEmail")]
[AlwaysAccessible]
public ActionResult RequestChallengeEmailPOST(string username) {
// ensure users can request lost password
var membershipSettings = _membershipService.GetSettings();
if (!membershipSettings.UsersMustValidateEmail) {
return HttpNotFound();
}
if (string.IsNullOrWhiteSpace(username)) {
ModelState.AddModelError("username", T("You must specify a username or e-mail."));
return View();
}
// Get the user
var user = _userService.GetUserByNameOrEmail(username);
if (user != null && user.EmailStatus == UserStatus.Pending) {
var siteUrl = _orchardServices.WorkContext.CurrentSite.BaseUrl;
if (string.IsNullOrWhiteSpace(siteUrl)) {
siteUrl = HttpContext.Request.ToRootUrlString();
}
_userService.SendChallengeEmail(user.As<UserPart>(), nonce => Url.MakeAbsolute(Url.Action("ChallengeEmail", "Account", new { Area = "Orchard.Users", nonce = nonce }), siteUrl));
_userEventHandler.SentChallengeEmail(user);
}
return RedirectToAction("ChallengeEmailSent");
}
[Authorize]
[AlwaysAccessible]
public ActionResult ChangePassword() {
var membershipSettings = _membershipService.GetSettings();
ViewData["PasswordLength"] = membershipSettings.GetMinimumPasswordLength();
ViewData["LowercaseRequirement"] = membershipSettings.GetPasswordLowercaseRequirement();
ViewData["UppercaseRequirement"] = membershipSettings.GetPasswordUppercaseRequirement();
ViewData["SpecialCharacterRequirement"] = membershipSettings.GetPasswordSpecialRequirement();
ViewData["NumberRequirement"] = membershipSettings.GetPasswordNumberRequirement();
ViewData["InvalidateOnPasswordChange"] = _orchardServices.WorkContext
.CurrentSite.As<SecuritySettingsPart>()
.ShouldInvalidateAuthOnPasswordChanged;
return View();
}
[Authorize]
[HttpPost]
[AlwaysAccessible]
[ValidateInput(false)]
[SuppressMessage("Microsoft.Design", "CA1031:DoNotCatchGeneralExceptionTypes",
Justification = "Exceptions result in password not being changed.")]
public ActionResult ChangePassword(string currentPassword, string newPassword, string confirmPassword) {
var membershipSettings = _membershipService.GetSettings();
ViewData["PasswordLength"] = membershipSettings.GetMinimumPasswordLength();
ViewData["LowercaseRequirement"] = membershipSettings.GetPasswordLowercaseRequirement();
ViewData["UppercaseRequirement"] = membershipSettings.GetPasswordUppercaseRequirement();
ViewData["SpecialCharacterRequirement"] = membershipSettings.GetPasswordSpecialRequirement();
ViewData["NumberRequirement"] = membershipSettings.GetPasswordNumberRequirement();
var shouldSignout = _orchardServices.WorkContext
.CurrentSite.As<SecuritySettingsPart>()
.ShouldInvalidateAuthOnPasswordChanged;
ViewData["InvalidateOnPasswordChange"] = shouldSignout;
if (!ValidateChangePassword(currentPassword, newPassword, confirmPassword, _orchardServices.WorkContext.CurrentUser)) {
return View();
}
if (PasswordChangeIsSuccess(currentPassword, newPassword, _orchardServices.WorkContext.CurrentUser.UserName)) {
if (shouldSignout) {
_authenticationService.SignOut();
var loggedUser = _authenticationService.GetAuthenticatedUser();
if (loggedUser != null) {
_userEventHandler.LoggedOut(loggedUser);
}
}
return RedirectToAction("ChangePasswordSuccess");
} else {
return ChangePassword();
}
}
[AlwaysAccessible]
public ActionResult ChangeExpiredPassword(string username) {
if (string.IsNullOrWhiteSpace(username)) {
return RedirectToAction("LogOn");
}
var userPart = _membershipService.GetUser(username)?.As<UserPart>();
if (userPart == null) {
// user not valid / doesn't exist
return RedirectToAction("LogOn");
}
var membershipSettings = _membershipService.GetSettings();
// if the password hasn't actually expired for the user, redirect to logon
var passwordIsActuallyExpired = membershipSettings.EnableCustomPasswordPolicy
&& membershipSettings.EnablePasswordExpiration
&& _membershipService.PasswordIsExpired(userPart, membershipSettings.PasswordExpirationTimeInDays);
if (!passwordIsActuallyExpired && !userPart.ForcePasswordChange) {
return RedirectToAction("LogOn");
}
var viewModel = _orchardServices.New.ViewModel(
Username: username,
PasswordLength: membershipSettings.GetMinimumPasswordLength(),
LowercaseRequirement: membershipSettings.GetPasswordLowercaseRequirement(),
UppercaseRequirement: membershipSettings.GetPasswordUppercaseRequirement(),
SpecialCharacterRequirement: membershipSettings.GetPasswordSpecialRequirement(),
NumberRequirement: membershipSettings.GetPasswordNumberRequirement());
return View(viewModel);
}
[HttpPost, AlwaysAccessible, ValidateInput(false)]
public ActionResult ChangeExpiredPassword(string currentPassword, string newPassword, string confirmPassword, string username) {
var membershipSettings = _membershipService.GetSettings();
var viewModel = _orchardServices.New.ViewModel(
Username: username,
PasswordLength: membershipSettings.GetMinimumPasswordLength(),
LowercaseRequirement: membershipSettings.GetPasswordLowercaseRequirement(),
UppercaseRequirement: membershipSettings.GetPasswordUppercaseRequirement(),
SpecialCharacterRequirement: membershipSettings.GetPasswordSpecialRequirement(),
NumberRequirement: membershipSettings.GetPasswordNumberRequirement());
if (!ValidateChangePassword(currentPassword, newPassword, confirmPassword, _membershipService.GetUser(username))) {
return View(viewModel);
}
if (PasswordChangeIsSuccess(currentPassword, newPassword, username)) {
return RedirectToAction("ChangePasswordSuccess");
} else {
return View(viewModel);
}
}
private bool PasswordChangeIsSuccess(string currentPassword, string newPassword, string username) {
try {
var validated = _membershipService.ValidateUser(username, currentPassword, out List<LocalizedString> validationErrors);
if (validated != null) {
_userEventHandler.ChangingPassword(validated, newPassword);
_membershipService.SetPassword(validated, newPassword);
_userEventHandler.ChangedPassword(validated, newPassword);
// if security settings tell to invalidate on password change fire the LoggedOut event
if (_orchardServices.WorkContext
.CurrentSite.As<SecuritySettingsPart>()
.ShouldInvalidateAuthOnPasswordChanged) {
_userEventHandler.LoggedOut(validated);
}
return true;
}
} catch {
ModelState.AddModelError("_FORM", T("The current password is incorrect or the new password is invalid."));
return false;
}
// unknown error
ModelState.AddModelError("_FORM", T("The current password is incorrect or the new password is invalid."));
return false;
}
[AlwaysAccessible]
public ActionResult LostPassword(string nonce) {
if (_userService.ValidateLostPassword(nonce) == null) {
return RedirectToAction("LogOn");
}
var membershipSettings = _membershipService.GetSettings();
ViewData["PasswordLength"] = membershipSettings.GetMinimumPasswordLength();
ViewData["LowercaseRequirement"] = membershipSettings.GetPasswordLowercaseRequirement();
ViewData["UppercaseRequirement"] = membershipSettings.GetPasswordUppercaseRequirement();
ViewData["SpecialCharacterRequirement"] = membershipSettings.GetPasswordSpecialRequirement();
ViewData["NumberRequirement"] = membershipSettings.GetPasswordNumberRequirement();
return View();
}
[HttpPost]
[AlwaysAccessible]
[ValidateInput(false)]
public ActionResult LostPassword(string nonce, string newPassword, string confirmPassword) {
IUser user;
if ((user = _userService.ValidateLostPassword(nonce)) == null) {
return Redirect("~/");
}
var membershipSettings = _membershipService.GetSettings();
ViewData["PasswordLength"] = membershipSettings.GetMinimumPasswordLength();
ViewData["LowercaseRequirement"] = membershipSettings.GetPasswordLowercaseRequirement();
ViewData["UppercaseRequirement"] = membershipSettings.GetPasswordUppercaseRequirement();
ViewData["SpecialCharacterRequirement"] = membershipSettings.GetPasswordSpecialRequirement();
ViewData["NumberRequirement"] = membershipSettings.GetPasswordNumberRequirement();
if (!ValidatePassword(newPassword, confirmPassword, user)) {
return View();
}
_userEventHandler.ChangingPassword(user, newPassword);
_membershipService.SetPassword(user, newPassword);
_userEventHandler.ChangedPassword(user, newPassword);
return RedirectToAction("ChangePasswordSuccess");
}
[AlwaysAccessible]
public ActionResult ChangePasswordSuccess() {
ViewData["InvalidateOnPasswordChange"] = _orchardServices.WorkContext
.CurrentSite.As<SecuritySettingsPart>()
.ShouldInvalidateAuthOnPasswordChanged;
return View();
}
[AlwaysAccessible]
public ActionResult RegistrationPending() {
return View();
}
[AlwaysAccessible]
public ActionResult ChallengeEmailSent() {
return View();
}
[AlwaysAccessible]
public ActionResult ChallengeEmailSuccess() {
return View();
}
[AlwaysAccessible]
public ActionResult ChallengeEmailFail() {
return View();
}
[AlwaysAccessible]
public ActionResult ChallengeEmail(string nonce) {
var user = _userService.ValidateChallenge(nonce);
if (user != null) {
_userEventHandler.ConfirmedEmail(user);
return RedirectToAction("ChallengeEmailSuccess");
}
return RedirectToAction("ChallengeEmailFail");
}
#region Validation Methods
private bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword, IUser user) {
if (string.IsNullOrEmpty(currentPassword)) {
ModelState.AddModelError("currentPassword", T("You must specify a current password."));
}
if (string.Equals(currentPassword, newPassword, StringComparison.Ordinal)) {
ModelState.AddModelError("newPassword", T("The new password must be different from the current password."));
}
if (!ModelState.IsValid) {
return false;
}
return ValidatePassword(newPassword, confirmPassword, user);
}
private IUser ValidateLogOn(string userNameOrEmail, string password) {
bool validate = true;
if (string.IsNullOrEmpty(userNameOrEmail)) {
ModelState.AddModelError("userNameOrEmail", T("You must specify a username or e-mail."));
validate = false;
}
// Here we don't do the "full" validation of the password, because policies may have
// changed since its creation and that should not prevent a user from logging in.
if (string.IsNullOrEmpty(password)) {
ModelState.AddModelError("password", T("You must specify a password."));
validate = false;
}
if (!validate)
return null;
var validationResult = _membershipService.ValidateUser(userNameOrEmail, password, out List<LocalizedString> validationErrors);
if (validationResult == null) {
_userEventHandler.LogInFailed(userNameOrEmail, password);
}
foreach (var error in validationErrors) {
ModelState.AddModelError("_FORM", error);
}
return validationResult;
}
private bool ValidateRegistration(string userName, string email, string password, string confirmPassword) {
var context = new AccountValidationContext {
UserName = userName,
Email = email,
Password = password
};
_accountValidationService.ValidateUserName(context);
_accountValidationService.ValidateEmail(context);
// Don't do the other validations if we already know we failed
if (!context.ValidationSuccessful) {
foreach (var error in context.ValidationErrors) {
ModelState.AddModelError(error.Key, error.Value);
}
return false;
}
if (!_userService.VerifyUserUnicity(userName, email)) {
// Not a new registration, but perhaps we already have that user and they
// haven't validated their email address. This doesn't care whether there
// were other issues with the registration attempt that caused its validation
// to fail: if the user exists and still has to confirm their email, we show
// a link to the action from which the challenge email is sent again.
var membershipSettings = _membershipService.GetSettings();
if (membershipSettings.UsersMustValidateEmail) {
var user = _userService.GetUserByNameOrEmail(email);
if (user == null) {
user = _userService.GetUserByNameOrEmail(userName);
}
if (user != null && user.EmailStatus == UserStatus.Pending) {
// We can't have links in the "text" of a ModelState Error. We are using a notifier
// to provide the user with an option to ask for a new challenge email.
_orchardServices.Notifier.Warning(
T("User with that username and/or email already exists. Follow <a href=\"{0}\">this link</a> if you want to receive a new email to validate your address.",
Url.Action(actionName: "RequestChallengeEmail", routeValues: new { email = email })));
// In creating the link above we use the email that was written in the form
// rather than the actual user's email address to prevent exploiting this
// for information discovery.
}
}
// We should add the error to the ModelState anyway.
context.ValidationErrors.Add("userExists", T("User with that username and/or email already exists."));
}
_accountValidationService.ValidatePassword(context);
if (!string.Equals(password, confirmPassword, StringComparison.Ordinal)) {
context.ValidationErrors.Add("_FORM", T("The new password and confirmation password do not match."));
}
if (!context.ValidationSuccessful) {
foreach (var error in context.ValidationErrors) {
ModelState.AddModelError(error.Key, error.Value);
}
}
return ModelState.IsValid;
}
private bool ValidatePassword(string password, IUser user) {
var context = new AccountValidationContext {
Password = password,
User = user
};
var result = _accountValidationService.ValidatePassword(context);
if (!result) {
foreach (var error in context.ValidationErrors) {
ModelState.AddModelError(error.Key, error.Value);
}
}
return result;
}
private bool ValidatePassword(string password, string confirmPassword, IUser user) {
if (!string.Equals(password, confirmPassword, StringComparison.Ordinal)) {
ModelState.AddModelError("_FORM", T("The new password and confirmation password do not match."));
return false;
}
return ValidatePassword(password, user);
}
private 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 "Username already exists. Please enter a different user name.";
case MembershipCreateStatus.DuplicateEmail:
return "A username for that e-mail address already exists. Please enter a different e-mail address.";
case MembershipCreateStatus.InvalidPassword:
return "The password provided is invalid. Please enter a valid password value.";
case MembershipCreateStatus.InvalidEmail:
return "The e-mail address provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidAnswer:
return "The password retrieval answer provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidQuestion:
return "The password retrieval question provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.InvalidUserName:
return "The user name provided is invalid. Please check the value and try again.";
case MembershipCreateStatus.ProviderError:
return
"The authentication provider returned an error. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
case MembershipCreateStatus.UserRejected:
return
"The user creation request has been canceled. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
default:
return
"An unknown error occurred. Please verify your entry and try again. If the problem persists, please contact your system administrator.";
}
}
#endregion
}
}