Registration settings

--HG--
branch : dev
This commit is contained in:
Sebastien Ros
2010-08-31 12:57:15 -07:00
parent e81ec58497
commit 6264af8888
24 changed files with 266 additions and 77 deletions

View File

@@ -5,7 +5,6 @@ using System.Data;
using System.IO; using System.IO;
using System.Linq; using System.Linq;
using System.Reflection; using System.Reflection;
using System.Web;
using Autofac; using Autofac;
using Autofac.Features.Metadata; using Autofac.Features.Metadata;
using NHibernate; using NHibernate;
@@ -14,10 +13,8 @@ using Orchard.Caching;
using Orchard.ContentManagement.Records; using Orchard.ContentManagement.Records;
using Orchard.Data; using Orchard.Data;
using Orchard.Data.Conventions; using Orchard.Data.Conventions;
using Orchard.Data.Migration;
using Orchard.Data.Migration.Generator; using Orchard.Data.Migration.Generator;
using Orchard.Data.Migration.Interpreters; using Orchard.Data.Migration.Interpreters;
using Orchard.Data.Migration.Records;
using Orchard.Data.Migration.Schema; using Orchard.Data.Migration.Schema;
using Orchard.DevTools.Services; using Orchard.DevTools.Services;
using Orchard.Environment.Configuration; using Orchard.Environment.Configuration;

View File

@@ -4,32 +4,29 @@ using System.Linq;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Core.Messaging.Models; using Orchard.Core.Messaging.Models;
using Orchard.Data;
using Orchard.Logging; using Orchard.Logging;
using Orchard.Messaging.Events; using Orchard.Messaging.Events;
using Orchard.Messaging.Models; using Orchard.Messaging.Models;
using Orchard.Messaging.Services; using Orchard.Messaging.Services;
using Orchard.Settings; using Orchard.Settings;
using Orchard.ContentManagement.Records;
namespace Orchard.Core.Messaging.Services { namespace Orchard.Core.Messaging.Services {
public class DefaultMessageManager : IMessageManager { public class DefaultMessageManager : IMessageManager {
private readonly IMessageEventHandler _messageEventHandler; private readonly IMessageEventHandler _messageEventHandler;
private readonly IEnumerable<IMessagingChannel> _channels; private readonly IEnumerable<IMessagingChannel> _channels;
private readonly IRepository<Message> _messageRepository;
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; } protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public DefaultMessageManager( public DefaultMessageManager(
IMessageEventHandler messageEventHandler, IMessageEventHandler messageEventHandler,
IEnumerable<IMessagingChannel> channels, IEnumerable<IMessagingChannel> channels) {
IRepository<Message> messageRepository) {
_messageEventHandler = messageEventHandler; _messageEventHandler = messageEventHandler;
_channels = channels; _channels = channels;
_messageRepository = messageRepository;
} }
public void Send(Message message) { public void Send(ContentItemRecord recipient, string type, string service = null) {
if ( !HasChannels() ) if ( !HasChannels() )
return; return;
@@ -39,15 +36,19 @@ namespace Orchard.Core.Messaging.Services {
return; return;
} }
Logger.Information("Sending message {0}", message.Type); Logger.Information("Sending message {0}", type);
try { try {
// if the service is not explicit, use the default one, as per settings configuration // if the service is not explicit, use the default one, as per settings configuration
if ( String.IsNullOrWhiteSpace(message.Service) ) { if ( String.IsNullOrWhiteSpace(service) ) {
message.Service = messageSettings.DefaultChannelService; service = messageSettings.DefaultChannelService;
} }
var context = new MessageContext(message); var context = new MessageContext {
Recipient = recipient,
Type = type,
Service = service
};
_messageEventHandler.Sending(context); _messageEventHandler.Sending(context);
@@ -57,10 +58,10 @@ namespace Orchard.Core.Messaging.Services {
_messageEventHandler.Sent(context); _messageEventHandler.Sent(context);
Logger.Information("Message {0} sent", message.Type); Logger.Information("Message {0} sent", type);
} }
catch ( Exception e ) { catch ( Exception e ) {
Logger.Error(e, "An error occured while sending the message {0}", message.Type); Logger.Error(e, "An error occured while sending the message {0}", type);
} }
} }

View File

@@ -1,5 +1,4 @@
using Orchard.Messaging.Events; using Orchard.Messaging.Events;
using Orchard.Core.Messaging.Models;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Users.Models; using Orchard.Users.Models;
using Orchard.Messaging.Models; using Orchard.Messaging.Models;
@@ -13,7 +12,7 @@ namespace Orchard.Email.Services {
} }
public void Sending(MessageContext context) { public void Sending(MessageContext context) {
var contentItem = _contentManager.Get(context.Message.Recipient.Id); var contentItem = _contentManager.Get(context.Recipient.Id);
if ( contentItem == null ) if ( contentItem == null )
return; return;
@@ -21,7 +20,7 @@ namespace Orchard.Email.Services {
if ( recipient == null ) if ( recipient == null )
return; return;
context.Properties.Add(EmailMessagingChannel.EmailAddress, recipient.Email); context.MailMessage.To.Add(recipient.Email);
} }
public void Sent(MessageContext context) { public void Sent(MessageContext context) {

View File

@@ -2,14 +2,10 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net; using System.Net;
using System.Net.Mail; using System.Net.Mail;
using System.Web;
using System.Web.Hosting;
using JetBrains.Annotations; using JetBrains.Annotations;
using Orchard.ContentManagement; using Orchard.ContentManagement;
using Orchard.Localization; using Orchard.Localization;
using Orchard.Logging; using Orchard.Logging;
using Orchard.Core.Messaging.Models;
using Orchard.Core.Messaging.Services;
using Orchard.Email.Models; using Orchard.Email.Models;
using Orchard.Settings; using Orchard.Settings;
using Orchard.Messaging.Services; using Orchard.Messaging.Services;
@@ -19,7 +15,6 @@ namespace Orchard.Email.Services {
public class EmailMessagingChannel : IMessagingChannel { public class EmailMessagingChannel : IMessagingChannel {
public const string EmailService = "Email"; public const string EmailService = "Email";
public const string EmailAddress = "EmailAddress";
public EmailMessagingChannel() { public EmailMessagingChannel() {
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
@@ -30,7 +25,7 @@ namespace Orchard.Email.Services {
public Localizer T { get; set; } public Localizer T { get; set; }
public void SendMessage(MessageContext context) { public void SendMessage(MessageContext context) {
if ( context.Message.Service.ToLower() != EmailService ) if ( !context.Service.Equals(EmailService, StringComparison.InvariantCultureIgnoreCase) )
return; return;
var smtpSettings = CurrentSite.As<SmtpSettingsPart>(); var smtpSettings = CurrentSite.As<SmtpSettingsPart>();
@@ -45,9 +40,7 @@ namespace Orchard.Email.Services {
smtpClient.Credentials = new NetworkCredential(smtpSettings.UserName, smtpSettings.Password); smtpClient.Credentials = new NetworkCredential(smtpSettings.UserName, smtpSettings.Password);
} }
var emailAddress = context.Properties[EmailAddress]; if(context.MailMessage.To.Count == 0) {
if(String.IsNullOrWhiteSpace(emailAddress)) {
Logger.Error("Recipient is missing an email address"); Logger.Error("Recipient is missing an email address");
return; return;
} }
@@ -59,33 +52,18 @@ namespace Orchard.Email.Services {
smtpClient.EnableSsl = smtpSettings.EnableSsl; smtpClient.EnableSsl = smtpSettings.EnableSsl;
smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network; smtpClient.DeliveryMethod = SmtpDeliveryMethod.Network;
var message = new MailMessage { context.MailMessage.From = new MailAddress(smtpSettings.Address);
From = new MailAddress(smtpSettings.Address), context.MailMessage.IsBodyHtml = context.MailMessage.Body != null && context.MailMessage.Body.Contains("<") && context.MailMessage.Body.Contains(">");
Subject = context.Message.Subject ?? "",
Body = context.Message.Body ?? "",
IsBodyHtml = context.Message.Body != null && context.Message.Body.Contains("<") && context.Message.Body.Contains(">")
};
message.To.Add(emailAddress);
try { try {
smtpClient.Send(message); smtpClient.Send(context.MailMessage);
Logger.Debug("Message sent to {0}: {1}", emailAddress, context.Message.Subject); Logger.Debug("Message sent to {0}: {1}", context.MailMessage.To[0].Address, context.Type);
} }
catch(Exception e) { catch(Exception e) {
Logger.Error(e, "An unexpected error while sending a message to {0}: {1}", emailAddress, context.Message.Subject); Logger.Error(e, "An unexpected error while sending a message to {0}: {1}", context.MailMessage.To[0].Address, context.Type);
} }
} }
public bool IsRecipientValidated(ContentItem contentItem) {
return false;
}
public void ValidateRecipient(ContentItem contentItem) {
var context = new MessageContext(new Message { Recipient = contentItem.Record, Body = "Please validate your account", Service = "email", Subject = "Validate your account" } );
SendMessage(context);
}
public IEnumerable<string> GetAvailableServices() { public IEnumerable<string> GetAvailableServices() {
return new[] {EmailService}; return new[] {EmailService};
} }

View File

@@ -10,6 +10,11 @@ using Orchard.Mvc.ViewModels;
using Orchard.Security; using Orchard.Security;
using Orchard.Users.Services; using Orchard.Users.Services;
using Orchard.Users.ViewModels; using Orchard.Users.ViewModels;
using Orchard.Settings;
using JetBrains.Annotations;
using Orchard.ContentManagement;
using Orchard.Users.Models;
using Orchard.Mvc.Results;
namespace Orchard.Users.Controllers { namespace Orchard.Users.Controllers {
[HandleError] [HandleError]
@@ -31,6 +36,7 @@ namespace Orchard.Users.Controllers {
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
public Localizer T { get; set; } public Localizer T { get; set; }
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
public ActionResult AccessDenied() { public ActionResult AccessDenied() {
var returnUrl = Request.QueryString["ReturnUrl"]; var returnUrl = Request.QueryString["ReturnUrl"];
@@ -87,6 +93,12 @@ namespace Orchard.Users.Controllers {
} }
public ActionResult Register() { public ActionResult Register() {
// ensure users can register
var registrationSettings = CurrentSite.As<RegistrationSettingsPart>();
if ( !registrationSettings.UsersCanRegister ) {
return new NotFoundResult();
}
ViewData["PasswordLength"] = MinPasswordLength; ViewData["PasswordLength"] = MinPasswordLength;
return View(new BaseViewModel()); return View(new BaseViewModel());
@@ -94,6 +106,12 @@ namespace Orchard.Users.Controllers {
[HttpPost] [HttpPost]
public ActionResult Register(string userName, string email, string password, string confirmPassword) { public ActionResult Register(string userName, string email, string password, string confirmPassword) {
// ensure users can register
var registrationSettings = CurrentSite.As<RegistrationSettingsPart>();
if ( !registrationSettings.UsersCanRegister ) {
return new NotFoundResult();
}
ViewData["PasswordLength"] = MinPasswordLength; ViewData["PasswordLength"] = MinPasswordLength;
if (ValidateRegistration(userName, email, password, confirmPassword)) { if (ValidateRegistration(userName, email, password, confirmPassword)) {

View File

@@ -18,5 +18,24 @@ namespace Orchard.Users.DataMigrations {
return 1; return 1;
} }
public int UpdateFrom1() {
// Adds registration fields to previous versions
SchemaBuilder
.AlterTable("UserPartRecord", table => table.AddColumn<string>("RegistrationStatus", c => c.WithDefault("'Approved'")))
.AlterTable("UserPartRecord", table => table.AddColumn<string>("EmailStatus", c => c.WithDefault("'Approved'")));
// Site Settings record
SchemaBuilder.CreateTable("RegistrationSettingsPartRecord", table => table
.ContentPartRecord()
.Column<bool>("UsersCanRegister", c => c.WithDefault("'0'"))
.Column<bool>("UsersMustValidateEmail", c => c.WithDefault("'0'"))
.Column<bool>("UsersAreModerated", c => c.WithDefault("'0'"))
.Column<bool>("NotifyModeration", c => c.WithDefault("'0'"))
);
return 2;
}
} }
} }

View File

@@ -0,0 +1,38 @@
using Orchard.Messaging.Events;
using Orchard.Messaging.Models;
using Orchard.ContentManagement;
using Orchard.Users.Models;
namespace Orchard.Users.Handlers {
public class ModerationMessageAlteration : IMessageEventHandler {
private readonly IContentManager _contentManager;
public ModerationMessageAlteration(IContentManager contentManager) {
_contentManager = contentManager;
}
public void Sending(MessageContext context) {
var contentItem = _contentManager.Get(context.Recipient.Id);
if ( contentItem == null )
return;
var recipient = contentItem.As<UserPart>();
if ( recipient == null )
return;
if ( context.Type == MessageTypes.Moderation ) {
context.MailMessage.Subject = "User needs moderation";
context.MailMessage.Body = string.Format("The following user account needs to be moderated: {0}", recipient.UserName);
}
if ( context.Type == MessageTypes.Validation ) {
context.MailMessage.Subject = "User account validation";
context.MailMessage.Body = string.Format("Dear {0}, please click on the folowwing link to validate you email address: {1}", recipient.UserName, "http://foo");
}
}
public void Sent(MessageContext context) {
}
}
}

View File

@@ -0,0 +1,15 @@
using JetBrains.Annotations;
using Orchard.Data;
using Orchard.ContentManagement.Handlers;
using Orchard.Users.Models;
namespace Orchard.Users.Handlers {
[UsedImplicitly]
public class RegistrationSettingsPartHandler : ContentHandler {
public RegistrationSettingsPartHandler(IRepository<RegistrationSettingsPartRecord> repository) {
Filters.Add(new ActivatingFilter<RegistrationSettingsPart>("Site"));
Filters.Add(StorageFilter.For(repository));
Filters.Add(new TemplateFilterForRecord<RegistrationSettingsPartRecord>("RegistrationSettings", "Parts/Users.RegistrationSettings"));
}
}
}

View File

@@ -0,0 +1,12 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
namespace Orchard.Users.Models {
public static class MessageTypes {
public const string Moderation = "ORCHARD_USERS_MODERATION";
public const string Validation = "ORCHARD_USERS_VALIDATION";
}
}

View File

@@ -0,0 +1,27 @@
using Orchard.ContentManagement;
using System;
namespace Orchard.Users.Models {
public class RegistrationSettingsPart : ContentPart<RegistrationSettingsPartRecord> {
public bool UsersCanRegister {
get { return Record.UsersCanRegister; }
set { Record.UsersCanRegister = value; }
}
public bool UsersMustValidateEmail {
get { return Record.UsersMustValidateEmail; }
set { Record.UsersMustValidateEmail = value; }
}
public bool UsersAreModerated {
get { return Record.UsersAreModerated; }
set { Record.UsersAreModerated = value; }
}
public bool NotifyModeration {
get { return Record.NotifyModeration; }
set { Record.NotifyModeration = value; }
}
}
}

View File

@@ -0,0 +1,12 @@
using System.Net.Mail;
using Orchard.ContentManagement.Records;
using System.ComponentModel.DataAnnotations;
namespace Orchard.Users.Models {
public class RegistrationSettingsPartRecord : ContentPartRecord {
public virtual bool UsersCanRegister { get; set; }
public virtual bool UsersMustValidateEmail { get; set; }
public virtual bool UsersAreModerated { get; set; }
public virtual bool NotifyModeration { get; set; }
}
}

View File

@@ -21,5 +21,15 @@ namespace Orchard.Users.Models {
get { return Record.NormalizedUserName; } get { return Record.NormalizedUserName; }
set { Record.NormalizedUserName = value; } set { Record.NormalizedUserName = value; }
} }
public UserStatus RegistrationStatus {
get { return Record.RegistrationStatus; }
set { Record.RegistrationStatus = value; }
}
public UserStatus EmailStatus {
get { return Record.EmailStatus; }
set { Record.EmailStatus = value; }
}
} }
} }

View File

@@ -11,5 +11,8 @@ namespace Orchard.Users.Models {
public virtual MembershipPasswordFormat PasswordFormat { get; set; } public virtual MembershipPasswordFormat PasswordFormat { get; set; }
public virtual string HashAlgorithm { get; set; } public virtual string HashAlgorithm { get; set; }
public virtual string PasswordSalt { get; set; } public virtual string PasswordSalt { get; set; }
public virtual UserStatus RegistrationStatus { get; set; }
public virtual UserStatus EmailStatus { get; set; }
} }
} }

View File

@@ -0,0 +1,6 @@
namespace Orchard.Users.Models {
public enum UserStatus {
Pending,
Approved
}
}

View File

@@ -69,9 +69,15 @@
<Compile Include="Controllers\AdminController.cs" /> <Compile Include="Controllers\AdminController.cs" />
<Compile Include="DataMigrations\UsersDataMigration.cs" /> <Compile Include="DataMigrations\UsersDataMigration.cs" />
<Compile Include="Drivers\UserPartDriver.cs" /> <Compile Include="Drivers\UserPartDriver.cs" />
<Compile Include="Handlers\ModerationMessageAlteration.cs" />
<Compile Include="Handlers\RegistrationSettingsPartHandler.cs" />
<Compile Include="Models\MessageTypes.cs" />
<Compile Include="Models\RegistrationSettingsPart.cs" />
<Compile Include="Models\RegistrationSettingsPartRecord.cs" />
<Compile Include="Models\UserPart.cs" /> <Compile Include="Models\UserPart.cs" />
<Compile Include="Handlers\UserPartHandler.cs" /> <Compile Include="Handlers\UserPartHandler.cs" />
<Compile Include="Models\UserPartRecord.cs" /> <Compile Include="Models\UserPartRecord.cs" />
<Compile Include="Models\UserStatus.cs" />
<Compile Include="Permissions.cs" /> <Compile Include="Permissions.cs" />
<Compile Include="Properties\AssemblyInfo.cs" /> <Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="Services\IUserService.cs" /> <Compile Include="Services\IUserService.cs" />
@@ -95,6 +101,7 @@
<Content Include="Views\Admin\EditorTemplates\inputPasswordLarge.ascx" /> <Content Include="Views\Admin\EditorTemplates\inputPasswordLarge.ascx" />
<Content Include="Views\Admin\EditorTemplates\inputTextLarge.ascx" /> <Content Include="Views\Admin\EditorTemplates\inputTextLarge.ascx" />
<Content Include="Views\Admin\Index.aspx" /> <Content Include="Views\Admin\Index.aspx" />
<Content Include="Views\EditorTemplates\Parts\Users.RegistrationSettings.ascx" />
<Content Include="Web.config" /> <Content Include="Web.config" />
<Content Include="Views\Web.config" /> <Content Include="Views\Web.config" />
</ItemGroup> </ItemGroup>

View File

@@ -10,20 +10,25 @@ using Orchard.ContentManagement;
using Orchard.Security; using Orchard.Security;
using Orchard.Users.Drivers; using Orchard.Users.Drivers;
using Orchard.Users.Models; using Orchard.Users.Models;
using Orchard.Settings;
using Orchard.Messaging.Services;
namespace Orchard.Users.Services { namespace Orchard.Users.Services {
[UsedImplicitly] [UsedImplicitly]
public class MembershipService : IMembershipService { public class MembershipService : IMembershipService {
private readonly IContentManager _contentManager; private readonly IContentManager _contentManager;
private readonly IMessageManager _messageManager;
private readonly IRepository<UserPartRecord> _userRepository; private readonly IRepository<UserPartRecord> _userRepository;
public MembershipService(IContentManager contentManager, IRepository<UserPartRecord> userRepository) { public MembershipService(IContentManager contentManager, IRepository<UserPartRecord> userRepository, IMessageManager messageManager ) {
_contentManager = contentManager; _contentManager = contentManager;
_userRepository = userRepository; _userRepository = userRepository;
_messageManager = messageManager;
Logger = NullLogger.Instance; Logger = NullLogger.Instance;
} }
public ILogger Logger { get; set; } public ILogger Logger { get; set; }
protected virtual ISite CurrentSite { get; [UsedImplicitly] private set; }
public MembershipSettings GetSettings() { public MembershipSettings GetSettings() {
var settings = new MembershipSettings(); var settings = new MembershipSettings();
@@ -34,14 +39,35 @@ namespace Orchard.Users.Services {
public IUser CreateUser(CreateUserParams createUserParams) { public IUser CreateUser(CreateUserParams createUserParams) {
Logger.Information("CreateUser {0} {1}", createUserParams.Username, createUserParams.Email); Logger.Information("CreateUser {0} {1}", createUserParams.Username, createUserParams.Email);
return _contentManager.Create<UserPart>(UserPartDriver.ContentType.Name, init => var registrationSettings = CurrentSite.As<RegistrationSettingsPart>();
var user = _contentManager.Create<UserPart>(UserPartDriver.ContentType.Name, init =>
{ {
init.Record.UserName = createUserParams.Username; init.Record.UserName = createUserParams.Username;
init.Record.Email = createUserParams.Email; init.Record.Email = createUserParams.Email;
init.Record.NormalizedUserName = createUserParams.Username.ToLower(); init.Record.NormalizedUserName = createUserParams.Username.ToLower();
init.Record.HashAlgorithm = "SHA1"; init.Record.HashAlgorithm = "SHA1";
SetPassword(init.Record, createUserParams.Password); SetPassword(init.Record, createUserParams.Password);
init.Record.RegistrationStatus = registrationSettings.UsersAreModerated ? UserStatus.Pending : UserStatus.Approved;
init.Record.EmailStatus = registrationSettings.UsersMustValidateEmail ? UserStatus.Pending : UserStatus.Approved;
}); });
if ( registrationSettings.UsersMustValidateEmail ) {
SendEmailValidationMessage(user);
}
if ( registrationSettings.UsersAreModerated && registrationSettings.NotifyModeration ) {
var superUser = GetUser(CurrentSite.SuperUser);
if(superUser != null)
_messageManager.Send(superUser.ContentItem.Record, MessageTypes.Moderation);
}
return user;
}
public void SendEmailValidationMessage(IUser user) {
_messageManager.Send(user.ContentItem.Record, MessageTypes.Validation);
} }
public IUser GetUser(string username) { public IUser GetUser(string username) {
@@ -58,16 +84,22 @@ namespace Orchard.Users.Services {
var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLower(); var lowerName = userNameOrEmail == null ? "" : userNameOrEmail.ToLower();
var userRecord = _userRepository.Get(x => x.NormalizedUserName == lowerName); var userRecord = _userRepository.Get(x => x.NormalizedUserName == lowerName);
if(userRecord == null) if(userRecord == null)
userRecord = _userRepository.Get(x => x.Email == lowerName); userRecord = _userRepository.Get(x => x.Email == lowerName);
if (userRecord == null || ValidatePassword(userRecord, password) == false) if (userRecord == null || ValidatePassword(userRecord, password) == false)
return null; return null;
if ( userRecord.EmailStatus != UserStatus.Approved )
return null;
if ( userRecord.RegistrationStatus != UserStatus.Approved )
return null;
return _contentManager.Get<IUser>(userRecord.Id); return _contentManager.Get<IUser>(userRecord.Id);
} }
public void SetPassword(IUser user, string password) { public void SetPassword(IUser user, string password) {
if (!user.Is<UserPart>()) if (!user.Is<UserPart>())
throw new InvalidCastException(); throw new InvalidCastException();

View File

@@ -0,0 +1,25 @@
<%@ Control Language="C#" Inherits="Orchard.Mvc.ViewUserControl<RegistrationSettingsPartRecord>" %>
<%@ Import Namespace="Orchard.Users.Models"%>
<fieldset>
<legend><%: T("Users registration")%></legend>
<div>
<%: Html.EditorFor(m => m.UsersCanRegister) %>
<label class="forcheckbox" for="<%: Html.FieldIdFor( m => m.UsersCanRegister) %>"><%: T("Users can create new accounts on the site")%></label>
<%: Html.ValidationMessage("UsersCanRegister", "*")%>
</div>
<div>
<%: Html.EditorFor(m => m.UsersMustValidateEmail)%>
<label class="forcheckbox" for="<%: Html.FieldIdFor( m => m.UsersMustValidateEmail) %>"><%: T("Users must justify their email address")%></label>
<%: Html.ValidationMessage("UsersMustValidateEmail", "*")%>
</div>
<div>
<%: Html.EditorFor(m => m.UsersAreModerated)%>
<label class="forcheckbox" for="<%: Html.FieldIdFor( m => m.UsersAreModerated) %>"><%: T("Users must be approved before they can log in")%></label>
<%: Html.ValidationMessage("UsersAreModerated", "*")%>
</div>
<div data-controllerid="<%:Html.FieldIdFor(m => m.UsersAreModerated) %>">
<%: Html.EditorFor(m => m.NotifyModeration)%>
<label class="forcheckbox" for="<%: Html.FieldIdFor( m => m.NotifyModeration) %>"><%: T("Send a notification when a user needs moderation")%></label>
<%: Html.ValidationMessage("NotifyModeration", "*")%>
</div>
</fieldset>

View File

@@ -18,6 +18,11 @@ namespace Orchard.Data.Migration.Schema {
TableCommands.Add(command); TableCommands.Add(command);
} }
public void AddColumn<T>(string columnName, Action<AddColumnCommand> column = null) {
var dbType = SchemaUtils.ToDbType(typeof(T));
AddColumn(columnName, dbType, column);
}
public void DropColumn(string columnName) { public void DropColumn(string columnName) {
var command = new DropColumnCommand(Name, columnName); var command = new DropColumnCommand(Name, columnName);
TableCommands.Add(command); TableCommands.Add(command);

View File

@@ -1,11 +0,0 @@
using Orchard.ContentManagement.Records;
namespace Orchard.Messaging.Models {
public class Message {
public string Service { get; set; }
public string Subject { get; set; }
public string Body { get; set; }
public string Type { get; set; }
public ContentItemRecord Recipient { get; set; }
}
}

View File

@@ -1,16 +1,18 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Net.Mail; using System.Net.Mail;
using Orchard.ContentManagement.Records;
namespace Orchard.Messaging.Models { namespace Orchard.Messaging.Models {
public class MessageContext { public class MessageContext {
public Dictionary<string, string> Properties { get; private set; }
public Message Message { get; private set; }
public MailMessage MailMessage { get; private set; } public MailMessage MailMessage { get; private set; }
public string Type { get; set; }
public string Service { get; set; }
public ContentItemRecord Recipient { get; set; }
public Dictionary<string, string> Properties { get; private set; }
public MessageContext(Message message) { public MessageContext() {
Properties = new Dictionary<string, string>(); Properties = new Dictionary<string, string>();
Message = message; MailMessage = new MailMessage();
MailMessage = new MailMessage {Body = message.Body, Subject = message.Subject};
} }
} }
} }

View File

@@ -1,12 +1,12 @@
using System.Collections.Generic; using System.Collections.Generic;
using Orchard.Messaging.Models; using Orchard.ContentManagement.Records;
namespace Orchard.Messaging.Services { namespace Orchard.Messaging.Services {
public interface IMessageManager : IDependency { public interface IMessageManager : IDependency {
/// <summary> /// <summary>
/// Sends a message without using the queue /// Sends a message to a channel
/// </summary> /// </summary>
void Send(Message message); void Send(ContentItemRecord recipient, string type, string service = null);
/// <summary> /// <summary>
/// Wether at least one channel is active on the current site /// Wether at least one channel is active on the current site

View File

@@ -9,11 +9,6 @@ namespace Orchard.Messaging.Services {
/// </summary> /// </summary>
void SendMessage(MessageContext message); void SendMessage(MessageContext message);
/// <summary>
/// Sends a message to the recipient to validate his account
/// </summary>
void ValidateRecipient(ContentItem recipient);
/// <summary> /// <summary>
/// Provides all the handled services, the user can choose from when receving messages /// Provides all the handled services, the user can choose from when receving messages
/// </summary> /// </summary>

View File

@@ -372,7 +372,6 @@
<Compile Include="Environment\IShellContainerRegistrations.cs" /> <Compile Include="Environment\IShellContainerRegistrations.cs" />
<Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" /> <Compile Include="FileSystems\Dependencies\DynamicModuleVirtualPathProvider.cs" />
<Compile Include="Messaging\Events\IMessageEventHandler.cs" /> <Compile Include="Messaging\Events\IMessageEventHandler.cs" />
<Compile Include="Messaging\Models\Message.cs" />
<Compile Include="Messaging\Models\MessageContext.cs" /> <Compile Include="Messaging\Models\MessageContext.cs" />
<Compile Include="Messaging\Services\IMessageManager.cs" /> <Compile Include="Messaging\Services\IMessageManager.cs" />
<Compile Include="Messaging\Services\IMessagingChannel.cs" /> <Compile Include="Messaging\Services\IMessagingChannel.cs" />