mirror of
https://github.com/OrchardCMS/Orchard.git
synced 2026-01-24 13:52:21 +08:00
Added email challenge
--HG-- branch : dev
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
using System;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Security.Cryptography;
|
||||
using System.Text;
|
||||
using System.Web.Security;
|
||||
using System.Xml.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using Orchard.Data;
|
||||
using Orchard.Logging;
|
||||
@@ -13,12 +15,13 @@ using Orchard.Users.Events;
|
||||
using Orchard.Users.Models;
|
||||
using Orchard.Settings;
|
||||
using Orchard.Messaging.Services;
|
||||
using System.Collections;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Mvc;
|
||||
|
||||
namespace Orchard.Users.Services {
|
||||
[UsedImplicitly]
|
||||
public class MembershipService : IMembershipService {
|
||||
private static readonly TimeSpan DelayToValidate = new TimeSpan(7, 0, 0, 0); // one week to validate email
|
||||
private readonly IContentManager _contentManager;
|
||||
private readonly IMessageManager _messageManager;
|
||||
private readonly IEnumerable<IUserEventHandler> _userEventHandlers;
|
||||
@@ -53,8 +56,8 @@ namespace Orchard.Users.Services {
|
||||
user.Record.NormalizedUserName = createUserParams.Username.ToLower();
|
||||
user.Record.HashAlgorithm = "SHA1";
|
||||
SetPassword(user.Record, createUserParams.Password);
|
||||
user.Record.RegistrationStatus = registrationSettings.UsersAreModerated ? UserStatus.Pending : UserStatus.Approved;
|
||||
user.Record.EmailStatus = registrationSettings.UsersMustValidateEmail ? UserStatus.Pending : UserStatus.Approved;
|
||||
user.Record.RegistrationStatus = registrationSettings.UsersAreModerated && !createUserParams.IsApproved ? UserStatus.Pending : UserStatus.Approved;
|
||||
user.Record.EmailStatus = registrationSettings.UsersMustValidateEmail && !createUserParams.IsApproved ? UserStatus.Pending : UserStatus.Approved;
|
||||
|
||||
var userContext = new UserContext {User = user, Cancel = false};
|
||||
foreach(var userEventHandler in _userEventHandlers) {
|
||||
@@ -71,11 +74,7 @@ namespace Orchard.Users.Services {
|
||||
userEventHandler.Created(userContext);
|
||||
}
|
||||
|
||||
if ( registrationSettings.UsersMustValidateEmail ) {
|
||||
SendEmailValidationMessage(user);
|
||||
}
|
||||
|
||||
if ( registrationSettings.UsersAreModerated && registrationSettings.NotifyModeration ) {
|
||||
if ( registrationSettings.UsersAreModerated && registrationSettings.NotifyModeration && !createUserParams.IsApproved ) {
|
||||
var superUser = GetUser(CurrentSite.SuperUser);
|
||||
if(superUser != null)
|
||||
_messageManager.Send(superUser.ContentItem.Record, MessageTypes.Moderation);
|
||||
@@ -84,8 +83,52 @@ namespace Orchard.Users.Services {
|
||||
return user;
|
||||
}
|
||||
|
||||
public void SendEmailValidationMessage(IUser user) {
|
||||
_messageManager.Send(user.ContentItem.Record, MessageTypes.Validation);
|
||||
public void SendChallengeEmail(UserPart user, string url) {
|
||||
_messageManager.Send(user.ContentItem.Record, MessageTypes.Validation, "Email", new Dictionary<string, string> { { "ChallengeUrl", url } });
|
||||
}
|
||||
|
||||
public IUser ValidateChallengeToken(string challengeToken) {
|
||||
string username;
|
||||
DateTime validateByUtc;
|
||||
|
||||
if(!DecryptChallengeToken(challengeToken, out username, out validateByUtc)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( validateByUtc < DateTime.UtcNow )
|
||||
return null;
|
||||
|
||||
var user = GetUser(username);
|
||||
if ( user == null )
|
||||
return null;
|
||||
|
||||
user.As<UserPart>().EmailStatus = UserStatus.Approved;
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
public string GetEncryptedChallengeToken(UserPart user) {
|
||||
var challengeToken = new XElement("Token", new XAttribute("username", user.UserName), new XAttribute("validate-by-utc", DateTime.UtcNow.Add(DelayToValidate).ToString(CultureInfo.InvariantCulture))).ToString();
|
||||
var data = Encoding.UTF8.GetBytes(challengeToken);
|
||||
return MachineKey.Encode(data, MachineKeyProtection.All);
|
||||
}
|
||||
|
||||
private static bool DecryptChallengeToken(string challengeToken, out string username, out DateTime validateByUtc) {
|
||||
username = null;
|
||||
validateByUtc = DateTime.UtcNow;
|
||||
|
||||
try {
|
||||
var data = MachineKey.Decode(challengeToken, MachineKeyProtection.All);
|
||||
var xml = Encoding.UTF8.GetString(data);
|
||||
var element = XElement.Parse(xml);
|
||||
username = element.Attribute("username").Value;
|
||||
validateByUtc = DateTime.Parse(element.Attribute("validate-by-utc").Value, CultureInfo.InvariantCulture);
|
||||
return true;
|
||||
}
|
||||
catch {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public IUser GetUser(string username) {
|
||||
@@ -143,7 +186,7 @@ namespace Orchard.Users.Services {
|
||||
}
|
||||
}
|
||||
|
||||
private bool ValidatePassword(UserPartRecord partRecord, string password) {
|
||||
private static bool ValidatePassword(UserPartRecord partRecord, string password) {
|
||||
// Note - the password format stored with the record is used
|
||||
// otherwise changing the password format on the site would invalidate
|
||||
// all logins
|
||||
@@ -197,7 +240,7 @@ namespace Orchard.Users.Services {
|
||||
|
||||
var hashAlgorithm = HashAlgorithm.Create(partRecord.HashAlgorithm);
|
||||
var hashBytes = hashAlgorithm.ComputeHash(combinedBytes);
|
||||
|
||||
|
||||
return partRecord.Password == Convert.ToBase64String(hashBytes);
|
||||
}
|
||||
|
||||
@@ -208,5 +251,6 @@ namespace Orchard.Users.Services {
|
||||
private static bool ValidatePasswordEncrypted(UserPartRecord partRecord, string password) {
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user