Display custom login errors (#7734)

Fixes #7588
This commit is contained in:
Julián Alazorza
2017-09-14 21:26:55 +02:00
committed by Sébastien Ros
parent 70adb1833f
commit 8036e539b6
12 changed files with 98 additions and 70 deletions

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.Web.Security; using System.Web.Security;
using Autofac; using Autofac;
using Moq; using Moq;
@@ -21,6 +22,7 @@ using Orchard.DisplayManagement.Implementation;
using Orchard.Environment; using Orchard.Environment;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;
using Orchard.Environment.Extensions; using Orchard.Environment.Extensions;
using Orchard.Localization;
using Orchard.Security; using Orchard.Security;
using Orchard.Services; using Orchard.Services;
using Orchard.Settings; using Orchard.Settings;
@@ -32,7 +34,7 @@ using Orchard.Users.Handlers;
using Orchard.Users.Models; using Orchard.Users.Models;
using Orchard.Users.Services; using Orchard.Users.Services;
namespace Orchard.Tests.Modules.Users.Services namespace Orchard.Tests.Modules.Users.Services
{ {
[TestFixture] [TestFixture]
public class MembershipServiceTests { public class MembershipServiceTests {
@@ -146,8 +148,9 @@ namespace Orchard.Tests.Modules.Users.Services
Assert.That(user1Record.PasswordSalt, Is.Not.EqualTo(user2Record.PasswordSalt)); Assert.That(user1Record.PasswordSalt, Is.Not.EqualTo(user2Record.PasswordSalt));
Assert.That(user1Record.Password, Is.Not.EqualTo(user2Record.Password)); Assert.That(user1Record.Password, Is.Not.EqualTo(user2Record.Password));
Assert.That(_membershipService.ValidateUser("a", "b"), Is.Not.Null); List<LocalizedString> validationErrors;
Assert.That(_membershipService.ValidateUser("d", "b"), Is.Not.Null); Assert.That(_membershipService.ValidateUser("a", "b", out validationErrors), Is.Not.Null);
Assert.That(_membershipService.ValidateUser("d", "b", out validationErrors), Is.Not.Null);
} }
[Test] [Test]
@@ -156,9 +159,10 @@ namespace Orchard.Tests.Modules.Users.Services
_session.Flush(); _session.Flush();
_session.Clear(); _session.Clear();
var validate1 = _membershipService.ValidateUser("test-user", "bad-password"); List<LocalizedString> validationErrors;
var validate2 = _membershipService.ValidateUser("bad-user", "test-password"); var validate1 = _membershipService.ValidateUser("test-user", "bad-password", out validationErrors);
var validate3 = _membershipService.ValidateUser("test-user", "test-password"); var validate2 = _membershipService.ValidateUser("bad-user", "test-password", out validationErrors);
var validate3 = _membershipService.ValidateUser("test-user", "test-password", out validationErrors);
Assert.That(validate1, Is.Null); Assert.That(validate1, Is.Null);
Assert.That(validate2, Is.Null); Assert.That(validate2, Is.Null);
@@ -168,7 +172,7 @@ namespace Orchard.Tests.Modules.Users.Services
[Test] [Test]
public void UsersWhoHaveNeverLoggedInCanBeAuthenticated() { public void UsersWhoHaveNeverLoggedInCanBeAuthenticated() {
var user = (UserPart)_membershipService.CreateUser(new CreateUserParams("a", "b", "c", null, null, true)); var user = (UserPart)_membershipService.CreateUser(new CreateUserParams("a", "b", "c", null, null, true));
Assert.That(_membershipValidationService.CanAuthenticateWithCookie(user), Is.True); Assert.That(_membershipValidationService.CanAuthenticateWithCookie(user), Is.True);
} }

View File

@@ -18,6 +18,7 @@ using Orchard.Security;
using Orchard.Blogs.Extensions; using Orchard.Blogs.Extensions;
using Orchard.Mvc.Html; using Orchard.Mvc.Html;
using Orchard.Core.Title.Models; using Orchard.Core.Title.Models;
using System.Linq;
namespace Orchard.Blogs.Services { namespace Orchard.Blogs.Services {
[OrchardFeature("Orchard.Blogs.RemotePublishing")] [OrchardFeature("Orchard.Blogs.RemotePublishing")]
@@ -30,7 +31,7 @@ namespace Orchard.Blogs.Services {
private readonly RouteCollection _routeCollection; private readonly RouteCollection _routeCollection;
public XmlRpcHandler(IBlogService blogService, IBlogPostService blogPostService, IContentManager contentManager, public XmlRpcHandler(IBlogService blogService, IBlogPostService blogPostService, IContentManager contentManager,
IAuthorizationService authorizationService, IMembershipService membershipService, IAuthorizationService authorizationService, IMembershipService membershipService,
RouteCollection routeCollection) { RouteCollection routeCollection) {
_blogService = blogService; _blogService = blogService;
_blogPostService = blogPostService; _blogPostService = blogPostService;
@@ -205,10 +206,10 @@ namespace Orchard.Blogs.Services {
if (blogPost.Is<TitlePart>()) { if (blogPost.Is<TitlePart>()) {
blogPost.As<TitlePart>().Title = HttpUtility.HtmlDecode(title); blogPost.As<TitlePart>().Title = HttpUtility.HtmlDecode(title);
} }
//AutoroutePart //AutoroutePart
dynamic dBlogPost = blogPost; dynamic dBlogPost = blogPost;
if (dBlogPost.AutoroutePart!=null){ if (dBlogPost.AutoroutePart!=null) {
dBlogPost.AutoroutePart.DisplayAlias = slug; dBlogPost.AutoroutePart.DisplayAlias = slug;
} }
@@ -340,11 +341,11 @@ namespace Orchard.Blogs.Services {
} }
private IUser ValidateUser(string userName, string password) { private IUser ValidateUser(string userName, string password) {
IUser user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
if (user == null) { IUser user = _membershipService.ValidateUser(userName, password,out validationErrors);
throw new OrchardCoreException(T("The username or e-mail or password provided is incorrect.")); if (validationErrors.Any()) {
throw new OrchardCoreException(validationErrors.FirstOrDefault());
} }
return user; return user;
} }
@@ -361,13 +362,13 @@ namespace Orchard.Blogs.Services {
var blogStruct = new XRpcStruct() var blogStruct = new XRpcStruct()
.Set("postid", blogPostPart.Id) .Set("postid", blogPostPart.Id)
.Set("title", HttpUtility.HtmlEncode(blogPostPart.Title)) .Set("title", HttpUtility.HtmlEncode(blogPostPart.Title))
.Set("description", blogPostPart.Text) .Set("description", blogPostPart.Text)
.Set("link", url) .Set("link", url)
.Set("permaLink", url); .Set("permaLink", url);
blogStruct.Set("wp_slug", blogPostPart.As<IAliasAspect>().Path); blogStruct.Set("wp_slug", blogPostPart.As<IAliasAspect>().Path);
if (blogPostPart.PublishedUtc != null) { if (blogPostPart.PublishedUtc != null) {
blogStruct.Set("dateCreated", blogPostPart.PublishedUtc); blogStruct.Set("dateCreated", blogPostPart.PublishedUtc);

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
@@ -55,7 +56,8 @@ namespace Orchard.Media.Services {
XRpcStruct file, XRpcStruct file,
UrlHelper url) { UrlHelper url) {
var user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
var user = _membershipService.ValidateUser(userName, password, out validationErrors);
if (!_authorizationService.TryCheckAccess(Permissions.ManageMedia, user, null)) { if (!_authorizationService.TryCheckAccess(Permissions.ManageMedia, user, null)) {
throw new OrchardCoreException(T("Access denied")); throw new OrchardCoreException(T("Access denied"));
} }

View File

@@ -1,4 +1,5 @@
using System; using System;
using System.Collections.Generic;
using System.IO; using System.IO;
using System.Web.Mvc; using System.Web.Mvc;
using System.Web.Routing; using System.Web.Routing;
@@ -59,7 +60,8 @@ namespace Orchard.MediaLibrary.Services {
XRpcStruct file, XRpcStruct file,
UrlHelper url) { UrlHelper url) {
var user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
var user = _membershipService.ValidateUser(userName, password, out validationErrors);
if (!_authorizationService.TryCheckAccess(Permissions.ManageOwnMedia, user, null)) { if (!_authorizationService.TryCheckAccess(Permissions.ManageOwnMedia, user, null)) {
throw new OrchardCoreException(T("Access denied")); throw new OrchardCoreException(T("Access denied"));
} }

View File

@@ -162,7 +162,8 @@ namespace Orchard.OpenId.Controllers
if (!validate) if (!validate)
return null; return null;
var user = _membershipService.ValidateUser(userNameOrEmail, password); List<LocalizedString> validationErrors;
var user = _membershipService.ValidateUser(userNameOrEmail, password, out validationErrors);
if (user == null) { if (user == null) {
ModelState.AddModelError("password", T("The username or e-mail or password provided is incorrect.")); ModelState.AddModelError("password", T("The username or e-mail or password provided is incorrect."));
} }
@@ -170,8 +171,8 @@ namespace Orchard.OpenId.Controllers
return user; return user;
} }
private string GetCallbackPath(WorkContext workContext) private string GetCallbackPath(WorkContext workContext)
{ {
var shellSettings = workContext.Resolve<ShellSettings>(); var shellSettings = workContext.Resolve<ShellSettings>();
var tenantPrefix = shellSettings.RequestUrlPrefix; var tenantPrefix = shellSettings.RequestUrlPrefix;

View File

@@ -1,5 +1,6 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
using System.Xml.Linq; using System.Xml.Linq;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Core.Contents; using Orchard.Core.Contents;
@@ -147,9 +148,10 @@ namespace Orchard.PublishLater.Services {
} }
private IUser ValidateUser(string userName, string password) { private IUser ValidateUser(string userName, string password) {
IUser user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
if (user == null) { IUser user = _membershipService.ValidateUser(userName, password, out validationErrors);
throw new OrchardCoreException(T("The username or e-mail or password provided is incorrect.")); if (validationErrors.Any()) {
throw new OrchardCoreException(validationErrors.FirstOrDefault());
} }
return user; return user;

View File

@@ -4,6 +4,7 @@ using System.Xml.Linq;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Core.XmlRpc; using Orchard.Core.XmlRpc;
using Orchard.Core.XmlRpc.Models; using Orchard.Core.XmlRpc.Models;
using Orchard.Localization;
using Orchard.Security; using Orchard.Security;
using Orchard.Tags.Helpers; using Orchard.Tags.Helpers;
using Orchard.Tags.Models; using Orchard.Tags.Models;
@@ -88,7 +89,8 @@ namespace Orchard.Tags.Services {
if (postId < 1) if (postId < 1)
return; return;
var user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
var user = _membershipService.ValidateUser(userName, password, out validationErrors);
_authorizationService.CheckAccess(StandardPermissions.AccessAdminPanel, user, null); _authorizationService.CheckAccess(StandardPermissions.AccessAdminPanel, user, null);
var driver = new XmlRpcDriver(item => { var driver = new XmlRpcDriver(item => {
@@ -117,7 +119,8 @@ namespace Orchard.Tags.Services {
} }
private XRpcArray MetaWeblogGetTags(string appKey, string userName, string password) { private XRpcArray MetaWeblogGetTags(string appKey, string userName, string password) {
var user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
var user = _membershipService.ValidateUser(userName, password, out validationErrors);
_authorizationService.CheckAccess(StandardPermissions.AccessAdminPanel, user, null); _authorizationService.CheckAccess(StandardPermissions.AccessAdminPanel, user, null);
var array = new XRpcArray(); var array = new XRpcArray();
@@ -127,17 +130,18 @@ namespace Orchard.Tags.Services {
.Set("tag_id", thisTag.TagName) .Set("tag_id", thisTag.TagName)
.Set("name", thisTag.TagName)); .Set("name", thisTag.TagName));
// nyi - not yet implemented // nyi - not yet implemented
//.Set("count", "") //.Set("count", "")
//.Set("slug", "") //.Set("slug", "")
//.Set("html_url", "") //.Set("html_url", "")
//.Set("rss_url", "")); //.Set("rss_url", ""));
} }
return array; return array;
} }
private void MetaWeblogUpdateTags(int contentItemId, string userName, string password, XRpcStruct content, bool publish, ICollection<IXmlRpcDriver> drivers) { private void MetaWeblogUpdateTags(int contentItemId, string userName, string password, XRpcStruct content, bool publish, ICollection<IXmlRpcDriver> drivers) {
var user = _membershipService.ValidateUser(userName, password); List<LocalizedString> validationErrors;
var user = _membershipService.ValidateUser(userName, password, out validationErrors);
var rawTags = content.Optional<string>("mt_keywords"); var rawTags = content.Optional<string>("mt_keywords");
if (string.IsNullOrWhiteSpace(rawTags)) if (string.IsNullOrWhiteSpace(rawTags))

View File

@@ -60,8 +60,8 @@ namespace Orchard.Users.Activities {
yield return T("IncorrectUserNameOrPassword"); yield return T("IncorrectUserNameOrPassword");
yield break; yield break;
} }
List<LocalizedString> validationErrors;
user = _membershipService.ValidateUser(userNameOrEmail, password); user = _membershipService.ValidateUser(userNameOrEmail, password, out validationErrors);
} }
if (user == null) { if (user == null) {
@@ -71,7 +71,7 @@ namespace Orchard.Users.Activities {
_userEventHandler.LoggingIn(userNameOrEmail, password); _userEventHandler.LoggingIn(userNameOrEmail, password);
_authenticationService.SignIn(user, createPersistentCookie); _authenticationService.SignIn(user, createPersistentCookie);
_userEventHandler.LoggedIn(user); _userEventHandler.LoggedIn(user);
yield return T("Done"); yield return T("Done");
} }
@@ -80,7 +80,7 @@ namespace Orchard.Users.Activities {
if (String.IsNullOrWhiteSpace(value)) if (String.IsNullOrWhiteSpace(value))
return false; return false;
var falseValues = new[] {"false", "off", "no"}; var falseValues = new[] { "false", "off", "no" };
return falseValues.All(x => !String.Equals(x, value, StringComparison.OrdinalIgnoreCase)); return falseValues.All(x => !String.Equals(x, value, StringComparison.OrdinalIgnoreCase));
} }
} }

View File

@@ -17,6 +17,7 @@ using System.Web.Mvc;
using System.Web.Security; using System.Web.Security;
using Orchard.Services; using Orchard.Services;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq;
namespace Orchard.Users.Controllers { namespace Orchard.Users.Controllers {
[HandleError, Themed] [HandleError, Themed]
@@ -289,7 +290,8 @@ namespace Orchard.Users.Controllers {
private bool PasswordChangeIsSuccess(string currentPassword, string newPassword, string username) { private bool PasswordChangeIsSuccess(string currentPassword, string newPassword, string username) {
try { try {
var validated = _membershipService.ValidateUser(username, currentPassword); List<LocalizedString> validationErrors;
var validated = _membershipService.ValidateUser(username, currentPassword, out validationErrors);
if (validated != null) { if (validated != null) {
_membershipService.SetPassword(validated, newPassword); _membershipService.SetPassword(validated, newPassword);
@@ -311,7 +313,7 @@ namespace Orchard.Users.Controllers {
[AlwaysAccessible] [AlwaysAccessible]
public ActionResult LostPassword(string nonce) { public ActionResult LostPassword(string nonce) {
if ( _userService.ValidateLostPassword(nonce) == null ) { if ( _userService.ValidateLostPassword(nonce) == null) {
return RedirectToAction("LogOn"); return RedirectToAction("LogOn");
} }
@@ -326,7 +328,7 @@ namespace Orchard.Users.Controllers {
[ValidateInput(false)] [ValidateInput(false)]
public ActionResult LostPassword(string nonce, string newPassword, string confirmPassword) { public ActionResult LostPassword(string nonce, string newPassword, string confirmPassword) {
IUser user; IUser user;
if ( (user = _userService.ValidateLostPassword(nonce)) == null ) { if ( (user = _userService.ValidateLostPassword(nonce)) == null) {
return Redirect("~/"); return Redirect("~/");
} }
@@ -374,7 +376,7 @@ namespace Orchard.Users.Controllers {
public ActionResult ChallengeEmail(string nonce) { public ActionResult ChallengeEmail(string nonce) {
var user = _userService.ValidateChallenge(nonce); var user = _userService.ValidateChallenge(nonce);
if ( user != null ) { if ( user != null) {
_userEventHandler.ConfirmedEmail(user); _userEventHandler.ConfirmedEmail(user);
return RedirectToAction("ChallengeEmailSuccess"); return RedirectToAction("ChallengeEmailSuccess");
@@ -385,7 +387,7 @@ namespace Orchard.Users.Controllers {
#region Validation Methods #region Validation Methods
private bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword) { private bool ValidateChangePassword(string currentPassword, string newPassword, string confirmPassword) {
if ( String.IsNullOrEmpty(currentPassword) ) { if ( String.IsNullOrEmpty(currentPassword)) {
ModelState.AddModelError("currentPassword", T("You must specify a current password.")); ModelState.AddModelError("currentPassword", T("You must specify a current password."));
} }
@@ -395,7 +397,7 @@ namespace Orchard.Users.Controllers {
ValidatePassword(newPassword); ValidatePassword(newPassword);
if ( !String.Equals(newPassword, confirmPassword, StringComparison.Ordinal) ) { if ( !String.Equals(newPassword, confirmPassword, StringComparison.Ordinal)) {
ModelState.AddModelError("_FORM", T("The new password and confirmation password do not match.")); ModelState.AddModelError("_FORM", T("The new password and confirmation password do not match."));
} }
@@ -418,13 +420,17 @@ namespace Orchard.Users.Controllers {
if (!validate) if (!validate)
return null; return null;
var user = _membershipService.ValidateUser(userNameOrEmail, password); List<LocalizedString> validationErrors;
if (user == null) { var validationResult = _membershipService.ValidateUser(userNameOrEmail, password, out validationErrors);
if (validationResult == null) {
_userEventHandler.LogInFailed(userNameOrEmail, password); _userEventHandler.LogInFailed(userNameOrEmail, password);
ModelState.AddModelError("_FORM", T("The username or e-mail or password provided is incorrect."));
} }
return user; foreach (var error in validationErrors) {
ModelState.AddModelError("_FORM", error);
}
return validationResult;
} }
private bool ValidateRegistration(string userName, string email, string password, string confirmPassword) { private bool ValidateRegistration(string userName, string email, string password, string confirmPassword) {

View File

@@ -33,10 +33,10 @@ namespace Orchard.Users.Services {
private readonly IClock _clock; private readonly IClock _clock;
public MembershipService( public MembershipService(
IOrchardServices orchardServices, IOrchardServices orchardServices,
IMessageService messageService, IMessageService messageService,
IUserEventHandler userEventHandlers, IUserEventHandler userEventHandlers,
IClock clock, IClock clock,
IEncryptionService encryptionService, IEncryptionService encryptionService,
IShapeFactory shapeFactory, IShapeFactory shapeFactory,
IShapeDisplay shapeDisplay, IShapeDisplay shapeDisplay,
@@ -74,7 +74,7 @@ namespace Orchard.Users.Services {
user.CreatedUtc = _clock.UtcNow; user.CreatedUtc = _clock.UtcNow;
SetPassword(user, createUserParams.Password); SetPassword(user, createUserParams.Password);
if ( registrationSettings != null ) { if ( registrationSettings != null) {
user.RegistrationStatus = registrationSettings.UsersAreModerated ? UserStatus.Pending : UserStatus.Approved; user.RegistrationStatus = registrationSettings.UsersAreModerated ? UserStatus.Pending : UserStatus.Approved;
user.EmailStatus = registrationSettings.UsersMustValidateEmail ? UserStatus.Pending : UserStatus.Approved; user.EmailStatus = registrationSettings.UsersMustValidateEmail ? UserStatus.Pending : UserStatus.Approved;
} }
@@ -84,7 +84,7 @@ namespace Orchard.Users.Services {
user.EmailStatus = UserStatus.Approved; user.EmailStatus = UserStatus.Approved;
} }
var userContext = new UserContext {User = user, Cancel = false, UserParameters = createUserParams}; var userContext = new UserContext { User = user, Cancel = false, UserParameters = createUserParams };
_userEventHandlers.Creating(userContext); _userEventHandlers.Creating(userContext);
if(userContext.Cancel) { if(userContext.Cancel) {
@@ -98,10 +98,10 @@ namespace Orchard.Users.Services {
_userEventHandlers.Approved(user); _userEventHandlers.Approved(user);
} }
if ( registrationSettings != null if ( registrationSettings != null
&& registrationSettings.UsersAreModerated && registrationSettings.UsersAreModerated
&& registrationSettings.NotifyModeration && registrationSettings.NotifyModeration
&& !createUserParams.IsApproved ) { && !createUserParams.IsApproved) {
var usernames = String.IsNullOrWhiteSpace(registrationSettings.NotificationsRecipients) var usernames = String.IsNullOrWhiteSpace(registrationSettings.NotificationsRecipients)
? new string[0] ? new string[0]
: registrationSettings.NotificationsRecipients.Split(new[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries); : registrationSettings.NotificationsRecipients.Split(new[] {',', ' '}, StringSplitOptions.RemoveEmptyEntries);
@@ -135,27 +135,28 @@ namespace Orchard.Users.Services {
return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault(); return _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
} }
public IUser ValidateUser(string userNameOrEmail, string password) { public IUser ValidateUser(string userNameOrEmail, string password, out List<LocalizedString> validationErrors) {
var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLowerInvariant(); var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLowerInvariant();
validationErrors = new List<LocalizedString>();
var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault(); var user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.NormalizedUserName == lowerName).List().FirstOrDefault();
if (user == null) if (user == null)
user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.Email == lowerName).List().FirstOrDefault(); user = _orchardServices.ContentManager.Query<UserPart, UserPartRecord>().Where(u => u.Email == lowerName).List().FirstOrDefault();
if ( user == null || ValidatePassword(user.As<UserPart>(), password) == false ) if (user == null || ValidatePassword(user.As<UserPart>(), password) == false) {
validationErrors.Add(T("The username or e-mail or password provided is incorrect."));
return null; return null;
}
if ( user.EmailStatus != UserStatus.Approved ) if (user.EmailStatus != UserStatus.Approved)
return null; validationErrors.Add(T("You must verify your email"));
if ( user.RegistrationStatus != UserStatus.Approved ) if (user.RegistrationStatus != UserStatus.Approved)
return null; validationErrors.Add(T("You must be approved before being able to login"));
return user; return user;
} }
public bool PasswordIsExpired(IUser user, int days){ public bool PasswordIsExpired(IUser user, int days) {
return user.As<UserPart>().LastPasswordChangeUtc.Value.AddDays(days) < _clock.UtcNow; return user.As<UserPart>().LastPasswordChangeUtc.Value.AddDays(days) < _clock.UtcNow;
} }
@@ -227,7 +228,7 @@ namespace Orchard.Users.Services {
isValid = Crypto.VerifyHashedPassword(userPart.Password, Encoding.Unicode.GetString(CombineSaltAndPassword(saltBytes, password))); isValid = Crypto.VerifyHashedPassword(userPart.Password, Encoding.Unicode.GetString(CombineSaltAndPassword(saltBytes, password)));
} }
else { else {
isValid = SecureStringEquality(userPart.Password, ComputeHashBase64(userPart.HashAlgorithm, saltBytes, password)); isValid = SecureStringEquality(userPart.Password, ComputeHashBase64(userPart.HashAlgorithm, saltBytes, password));
} }
// Migrating older password hashes to Default algorithm if necessary and enabled. // Migrating older password hashes to Default algorithm if necessary and enabled.
@@ -235,7 +236,7 @@ namespace Orchard.Users.Services {
var keepOldConfiguration = _appConfigurationAccessor.GetConfiguration("Orchard.Users.KeepOldPasswordHash"); var keepOldConfiguration = _appConfigurationAccessor.GetConfiguration("Orchard.Users.KeepOldPasswordHash");
if (String.IsNullOrEmpty(keepOldConfiguration) || keepOldConfiguration.Equals("false", StringComparison.OrdinalIgnoreCase)) { if (String.IsNullOrEmpty(keepOldConfiguration) || keepOldConfiguration.Equals("false", StringComparison.OrdinalIgnoreCase)) {
userPart.HashAlgorithm = DefaultHashAlgorithm; userPart.HashAlgorithm = DefaultHashAlgorithm;
userPart.Password = ComputeHashBase64(userPart.HashAlgorithm, saltBytes, password); userPart.Password = ComputeHashBase64(userPart.HashAlgorithm, saltBytes, password);
} }
} }

View File

@@ -1,10 +1,13 @@
namespace Orchard.Security { using System.Collections.Generic;
using Orchard.Localization;
namespace Orchard.Security {
public interface IMembershipService : IDependency { public interface IMembershipService : IDependency {
IMembershipSettings GetSettings(); IMembershipSettings GetSettings();
IUser CreateUser(CreateUserParams createUserParams); IUser CreateUser(CreateUserParams createUserParams);
IUser GetUser(string username); IUser GetUser(string username);
IUser ValidateUser(string userNameOrEmail, string password); IUser ValidateUser(string userNameOrEmail, string password, out List<LocalizedString> validationErrors);
void SetPassword(IUser user, string password); void SetPassword(IUser user, string password);
bool PasswordIsExpired(IUser user, int days); bool PasswordIsExpired(IUser user, int days);

View File

@@ -1,4 +1,6 @@
using System; using System;
using System.Collections.Generic;
using Orchard.Localization;
namespace Orchard.Security { namespace Orchard.Security {
/// <summary> /// <summary>
@@ -23,7 +25,7 @@ namespace Orchard.Security {
throw new NotImplementedException(); throw new NotImplementedException();
} }
public IUser ValidateUser(string userNameOrEmail, string password) { public IUser ValidateUser(string userNameOrEmail, string password, out List<LocalizedString> validationErrors) {
throw new NotImplementedException(); throw new NotImplementedException();
} }