Added email challenge

--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-09-01 14:39:28 -07:00
parent 067c5db740
commit 98d11e81f0
16 changed files with 119 additions and 175 deletions

View File

@@ -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();
}
}
}