From ea380985dbb3274c50fa6f428c3503bac3d74a49 Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Wed, 20 May 2020 00:19:43 +0200 Subject: [PATCH 1/6] Moving files using MailKit nuget package (Smtp successor) as SmtpClient has been marked as obsolete by Microsoft --- .../Events/SendEmailEventArgs.cs | 0 .../Users}/EmailSender.cs | 50 ++++++++++++++++--- .../Users}/IEmailSender.cs | 0 3 files changed, 43 insertions(+), 7 deletions(-) rename src/{Umbraco.Core => Umbraco.Infrastructure}/Events/SendEmailEventArgs.cs (100%) rename src/{Umbraco.Core => Umbraco.Infrastructure/Users}/EmailSender.cs (58%) rename src/{Umbraco.Core => Umbraco.Infrastructure/Users}/IEmailSender.cs (100%) diff --git a/src/Umbraco.Core/Events/SendEmailEventArgs.cs b/src/Umbraco.Infrastructure/Events/SendEmailEventArgs.cs similarity index 100% rename from src/Umbraco.Core/Events/SendEmailEventArgs.cs rename to src/Umbraco.Infrastructure/Events/SendEmailEventArgs.cs diff --git a/src/Umbraco.Core/EmailSender.cs b/src/Umbraco.Infrastructure/Users/EmailSender.cs similarity index 58% rename from src/Umbraco.Core/EmailSender.cs rename to src/Umbraco.Infrastructure/Users/EmailSender.cs index 5cfdd765bc..62c45b8f78 100644 --- a/src/Umbraco.Core/EmailSender.cs +++ b/src/Umbraco.Infrastructure/Users/EmailSender.cs @@ -1,9 +1,12 @@ using System; using System.Net.Mail; using System.Threading.Tasks; -using Umbraco.Core.Composing; +using MailKit.Security; +using MimeKit; +using MimeKit.Text; using Umbraco.Core.Configuration; using Umbraco.Core.Events; +using SmtpClient = MailKit.Net.Smtp.SmtpClient; namespace Umbraco.Core { @@ -21,7 +24,7 @@ namespace Umbraco.Core { } - internal EmailSender(IGlobalSettings globalSettings, bool enableEvents) + public EmailSender(IGlobalSettings globalSettings, bool enableEvents) { _globalSettings = globalSettings; _enableEvents = enableEvents; @@ -45,7 +48,9 @@ namespace Umbraco.Core { using (var client = new SmtpClient()) { - client.Send(message); + client.Connect(_globalSettings.SmtpSettings.Host, _globalSettings.SmtpSettings.Port); + client.Send(ConstructEmailMessage(message)); + client.Disconnect(true); } } } @@ -65,14 +70,21 @@ namespace Umbraco.Core { using (var client = new SmtpClient()) { - if (client.DeliveryMethod == SmtpDeliveryMethod.Network) + var appSettingsDeliveryMethod = _globalSettings.SmtpSettings.DeliveryMethod; + var deliveryMethod = (SmtpDeliveryMethod)Enum.Parse(typeof(SmtpDeliveryMethod), appSettingsDeliveryMethod, true); + + await client.ConnectAsync(_globalSettings.SmtpSettings.Host, _globalSettings.SmtpSettings.Port); + + if (deliveryMethod == SmtpDeliveryMethod.Network) { - await client.SendMailAsync(message); + await client.SendAsync(ConstructEmailMessage(message)); } else { - client.Send(message); + client.Send(ConstructEmailMessage(message)); } + + await client.DisconnectAsync(true); } } } @@ -83,7 +95,7 @@ namespace Umbraco.Core /// /// We assume this is possible if either an event handler is registered or an smtp server is configured /// - internal static bool CanSendRequiredEmail(IGlobalSettings globalSettings) => EventHandlerRegistered || globalSettings.IsSmtpServerConfigured; + public static bool CanSendRequiredEmail(IGlobalSettings globalSettings) => EventHandlerRegistered || globalSettings.IsSmtpServerConfigured; /// /// returns true if an event handler has been registered @@ -103,5 +115,29 @@ namespace Umbraco.Core var handler = SendEmail; if (handler != null) handler(null, e); } + + private MimeMessage ConstructEmailMessage(MailMessage mailMessage) + { + var messageToSend = new MimeMessage + { + Subject = mailMessage.Subject + }; + + var fromEmail = mailMessage.From?.Address; + if(string.IsNullOrEmpty(fromEmail)) + fromEmail = _globalSettings.SmtpSettings.From; + + messageToSend.From.Add(new MailboxAddress(fromEmail)); + + foreach (var mailAddress in mailMessage.To) + messageToSend.To.Add(new MailboxAddress(mailAddress.Address)); + + if (mailMessage.IsBodyHtml) + messageToSend.Body = new TextPart(TextFormat.Html) { Text = mailMessage.Body }; + else + messageToSend.Body = new TextPart(TextFormat.Plain) { Text = mailMessage.Body }; + + return messageToSend; + } } } diff --git a/src/Umbraco.Core/IEmailSender.cs b/src/Umbraco.Infrastructure/Users/IEmailSender.cs similarity index 100% rename from src/Umbraco.Core/IEmailSender.cs rename to src/Umbraco.Infrastructure/Users/IEmailSender.cs From e85ccb0dabd0b488292f566afcbb1640980f5cb6 Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Wed, 20 May 2020 00:20:25 +0200 Subject: [PATCH 2/6] Removing TODOs with the actual implementation --- .../Editors/AuthenticationController.cs | 21 +++++++++++++------ src/Umbraco.Web/Editors/UsersController.cs | 20 +++++++++--------- 2 files changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index fc34a35566..50e9921154 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -3,6 +3,7 @@ using System.Linq; using System.Net; using System.Net.Http; using System.Collections.Generic; +using System.Net.Mail; using System.Security.Principal; using System.Threading.Tasks; using System.Web; @@ -328,12 +329,20 @@ namespace Umbraco.Web.Editors UmbracoUserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings), new[] { identityUser.UserName, callbackUrl }); - // TODO: Port email service to ASP.NET Core - /*await UserManager.SendEmailAsync(identityUser.Id, - Services.TextService.Localize("login/resetPasswordEmailCopySubject", - // Ensure the culture of the found user is used for the email! - UmbracoUserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings)), - message);*/ + var subject = Services.TextService.Localize("login/resetPasswordEmailCopySubject", + // Ensure the culture of the found user is used for the email! + UmbracoUserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings)); + + var emailSender = new EmailSender(GlobalSettings, true); + var mailMessage = new MailMessage() + { + Subject = subject, + Body = message, + IsBodyHtml = true + }; + mailMessage.To.Add(user.Email); + + await emailSender.SendAsync(mailMessage); UserManager.RaiseForgotPasswordRequestedEvent(user.Id); } diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 7aa71b6e2e..029612dc90 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -4,6 +4,7 @@ using System.IO; using System.Linq; using System.Net; using System.Net.Http; +using System.Net.Mail; using System.Runtime.Serialization; using System.Security.Cryptography; using System.Threading.Tasks; @@ -500,17 +501,16 @@ namespace Umbraco.Web.Editors UmbracoUserExtensions.GetUserCulture(to.Language, Services.TextService, GlobalSettings), new[] { userDisplay.Name, from, message, inviteUri.ToString(), fromEmail }); - // TODO: Port email service to ASP.NET Core - /*await UserManager.EmailService.SendAsync( - //send the special UmbracoEmailMessage which configures it's own sender - //to allow for events to handle sending the message if no smtp is configured - new UmbracoEmailMessage(new EmailSender(GlobalSettings, true)) - { - Body = emailBody, - Destination = userDisplay.Email, - Subject = emailSubject - });*/ + var emailSender = new EmailSender(GlobalSettings, true); + var mailMessage = new MailMessage() + { + Subject = emailSubject, + Body = emailBody, + IsBodyHtml = true + }; + mailMessage.To.Add(to.Email); + await emailSender.SendAsync(mailMessage); } /// From ad31db9f4afa888a88e5617d25f94d43d856336b Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Wed, 20 May 2020 00:21:45 +0200 Subject: [PATCH 3/6] Adding DeliveryMethod option which we make use of in EmailSender.cs --- src/Umbraco.Configuration/Legacy/SmtpSettings.cs | 1 + src/Umbraco.Configuration/Models/GlobalSettings.cs | 5 +++-- src/Umbraco.Core/Configuration/ISmtpSettings.cs | 1 + .../Builders/SmtpSettingsBuilder.cs | 10 ++++++++++ 4 files changed, 15 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Configuration/Legacy/SmtpSettings.cs b/src/Umbraco.Configuration/Legacy/SmtpSettings.cs index 7e3ff80690..beb6eb9691 100644 --- a/src/Umbraco.Configuration/Legacy/SmtpSettings.cs +++ b/src/Umbraco.Configuration/Legacy/SmtpSettings.cs @@ -8,5 +8,6 @@ namespace Umbraco.Configuration public string Host { get; set; } public int Port { get; set; } public string PickupDirectoryLocation { get; set; } + public string DeliveryMethod { get; set; } } } diff --git a/src/Umbraco.Configuration/Models/GlobalSettings.cs b/src/Umbraco.Configuration/Models/GlobalSettings.cs index 4b30813bd5..646bca0f13 100644 --- a/src/Umbraco.Configuration/Models/GlobalSettings.cs +++ b/src/Umbraco.Configuration/Models/GlobalSettings.cs @@ -72,10 +72,10 @@ namespace Umbraco.Configuration.Models _configuration.GetValue(Prefix + "NoNodesViewPath", "~/config/splashes/NoNodes.cshtml"); public bool IsSmtpServerConfigured => - _configuration.GetSection(Constants.Configuration.ConfigPrefix + "Smtp")?.GetChildren().Any() ?? false; + _configuration.GetSection(Constants.Configuration.ConfigGlobalPrefix + "Smtp")?.GetChildren().Any() ?? false; public ISmtpSettings SmtpSettings => - new SmtpSettingsImpl(_configuration.GetSection(Constants.Configuration.ConfigPrefix + "Smtp")); + new SmtpSettingsImpl(_configuration.GetSection(Constants.Configuration.ConfigGlobalPrefix + "Smtp")); private class SmtpSettingsImpl : ISmtpSettings { @@ -90,6 +90,7 @@ namespace Umbraco.Configuration.Models public string Host => _configurationSection.GetValue("Host"); public int Port => _configurationSection.GetValue("Port"); public string PickupDirectoryLocation => _configurationSection.GetValue("PickupDirectoryLocation"); + public string DeliveryMethod => _configurationSection.GetValue("DeliveryMethod"); } } } diff --git a/src/Umbraco.Core/Configuration/ISmtpSettings.cs b/src/Umbraco.Core/Configuration/ISmtpSettings.cs index c2fb4b2dbe..217e83455b 100644 --- a/src/Umbraco.Core/Configuration/ISmtpSettings.cs +++ b/src/Umbraco.Core/Configuration/ISmtpSettings.cs @@ -6,5 +6,6 @@ namespace Umbraco.Core.Configuration string Host { get; } int Port{ get; } string PickupDirectoryLocation { get; } + string DeliveryMethod { get; } } } diff --git a/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs b/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs index 344d7bcf87..140af5f723 100644 --- a/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs +++ b/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs @@ -16,6 +16,7 @@ namespace Umbraco.Tests.Common.Builders private string _host; private int? _port; private string _pickupDirectoryLocation; + private string _deliveryMethod; public SmtpSettingsBuilder(TParent parentBuilder) : base(parentBuilder) { @@ -45,12 +46,19 @@ namespace Umbraco.Tests.Common.Builders return this; } + public SmtpSettingsBuilder WithDeliveryMethod(string deliveryMethod) + { + _deliveryMethod = deliveryMethod; + return this; + } + public override ISmtpSettings Build() { var from = _from ?? null; var host = _host ?? null; var port = _port ?? 25; var pickupDirectoryLocation = _pickupDirectoryLocation ?? null; + var deliveryMethod = _deliveryMethod ?? null; return new TestSmtpSettings() { @@ -58,6 +66,7 @@ namespace Umbraco.Tests.Common.Builders Host = host, Port = port, PickupDirectoryLocation = pickupDirectoryLocation, + DeliveryMethod = deliveryMethod }; } @@ -67,6 +76,7 @@ namespace Umbraco.Tests.Common.Builders public string Host { get; set; } public int Port { get; set; } public string PickupDirectoryLocation { get; set; } + public string DeliveryMethod { get; set; } } } } From 16d805e6f5b7750b5acb52fdd43d8380aae020c6 Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Wed, 20 May 2020 00:24:55 +0200 Subject: [PATCH 4/6] Adding Smtp section in appsettings, registering IEmailSender as an email service and ofc the MailKit nuget in Infrastructure proj --- .../Runtime/CoreInitialComposer.cs | 1 + .../Umbraco.Infrastructure.csproj | 1 + src/Umbraco.Web.UI.NetCore/appsettings.json | 10 ++++++++++ 3 files changed, 12 insertions(+) diff --git a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs index 19d3716e1c..34d69c2cd5 100644 --- a/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs +++ b/src/Umbraco.Infrastructure/Runtime/CoreInitialComposer.cs @@ -320,6 +320,7 @@ namespace Umbraco.Core.Runtime composition.RegisterUnique(); composition.RegisterUnique(); composition.RegisterUnique(); + composition.RegisterUnique(); composition.RegisterUnique(); diff --git a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj index db3ae1bc25..8da86df6e8 100644 --- a/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj +++ b/src/Umbraco.Infrastructure/Umbraco.Infrastructure.csproj @@ -11,6 +11,7 @@ + diff --git a/src/Umbraco.Web.UI.NetCore/appsettings.json b/src/Umbraco.Web.UI.NetCore/appsettings.json index 46dc20034b..95fdaeec67 100644 --- a/src/Umbraco.Web.UI.NetCore/appsettings.json +++ b/src/Umbraco.Web.UI.NetCore/appsettings.json @@ -116,6 +116,16 @@ "Replacement": "" } ] + }, + "Global": { + "Smtp": { + "From": "noreply@example.com", + "Host": "127.0.0.1", + "Port": 25, + "UserName": "username", + "Password": "password", + "DeliveryMethod": "network" + } } } } From 65fa1efc9c7f3dd4fddc3775810a224e35651659 Mon Sep 17 00:00:00 2001 From: Elitsa Marinovska Date: Wed, 20 May 2020 00:54:28 +0200 Subject: [PATCH 5/6] Changing a var name for better reflection on the origin of its value --- src/Umbraco.Infrastructure/Users/EmailSender.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Umbraco.Infrastructure/Users/EmailSender.cs b/src/Umbraco.Infrastructure/Users/EmailSender.cs index 62c45b8f78..87f27e5097 100644 --- a/src/Umbraco.Infrastructure/Users/EmailSender.cs +++ b/src/Umbraco.Infrastructure/Users/EmailSender.cs @@ -70,8 +70,8 @@ namespace Umbraco.Core { using (var client = new SmtpClient()) { - var appSettingsDeliveryMethod = _globalSettings.SmtpSettings.DeliveryMethod; - var deliveryMethod = (SmtpDeliveryMethod)Enum.Parse(typeof(SmtpDeliveryMethod), appSettingsDeliveryMethod, true); + var smtpSettingsDeliveryMethod = _globalSettings.SmtpSettings.DeliveryMethod; + var deliveryMethod = (SmtpDeliveryMethod)Enum.Parse(typeof(SmtpDeliveryMethod), smtpSettingsDeliveryMethod, true); await client.ConnectAsync(_globalSettings.SmtpSettings.Host, _globalSettings.SmtpSettings.Port); From 2b4dfbca9d44b7415bae5d6582bec35fde37a3b5 Mon Sep 17 00:00:00 2001 From: Bjarke Berg Date: Wed, 20 May 2020 11:42:23 +0200 Subject: [PATCH 6/6] #8142 - Small cleanup, and bugfix --- .../Legacy/SmtpSettings.cs | 7 +++- .../Models/GlobalSettings.cs | 7 +++- .../Configuration/ISmtpSettings.cs | 6 +++- .../Events/SendEmailEventArgs.cs | 0 .../Users => Umbraco.Core}/IEmailSender.cs | 0 .../Users/EmailSender.cs | 35 +++++++------------ .../Builders/SmtpSettingsBuilder.cs | 34 ++++++++++++++---- src/Umbraco.Tests/Testing/UmbracoTestBase.cs | 1 + .../AuthenticationControllerTests.cs | 3 +- .../Web/Controllers/UsersControllerTests.cs | 15 +++++--- .../Editors/AuthenticationController.cs | 12 ++++--- src/Umbraco.Web/Editors/UsersController.cs | 12 ++++--- 12 files changed, 85 insertions(+), 47 deletions(-) rename src/{Umbraco.Infrastructure => Umbraco.Core}/Events/SendEmailEventArgs.cs (100%) rename src/{Umbraco.Infrastructure/Users => Umbraco.Core}/IEmailSender.cs (100%) diff --git a/src/Umbraco.Configuration/Legacy/SmtpSettings.cs b/src/Umbraco.Configuration/Legacy/SmtpSettings.cs index beb6eb9691..dce3d85840 100644 --- a/src/Umbraco.Configuration/Legacy/SmtpSettings.cs +++ b/src/Umbraco.Configuration/Legacy/SmtpSettings.cs @@ -1,3 +1,4 @@ +using System.Net.Mail; using Umbraco.Core.Configuration; namespace Umbraco.Configuration @@ -8,6 +9,10 @@ namespace Umbraco.Configuration public string Host { get; set; } public int Port { get; set; } public string PickupDirectoryLocation { get; set; } - public string DeliveryMethod { get; set; } + public SmtpDeliveryMethod DeliveryMethod { get; set; } + + public string Username { get; set; } + + public string Password { get; set; } } } diff --git a/src/Umbraco.Configuration/Models/GlobalSettings.cs b/src/Umbraco.Configuration/Models/GlobalSettings.cs index 646bca0f13..e4995cfb0b 100644 --- a/src/Umbraco.Configuration/Models/GlobalSettings.cs +++ b/src/Umbraco.Configuration/Models/GlobalSettings.cs @@ -1,5 +1,6 @@ using System; using System.Linq; +using System.Net.Mail; using Microsoft.Extensions.Configuration; using Umbraco.Core; using Umbraco.Core.Configuration; @@ -90,7 +91,11 @@ namespace Umbraco.Configuration.Models public string Host => _configurationSection.GetValue("Host"); public int Port => _configurationSection.GetValue("Port"); public string PickupDirectoryLocation => _configurationSection.GetValue("PickupDirectoryLocation"); - public string DeliveryMethod => _configurationSection.GetValue("DeliveryMethod"); + public SmtpDeliveryMethod DeliveryMethod => _configurationSection.GetValue("DeliveryMethod"); + + public string Username => _configurationSection.GetValue("Username"); + + public string Password => _configurationSection.GetValue("Password"); } } } diff --git a/src/Umbraco.Core/Configuration/ISmtpSettings.cs b/src/Umbraco.Core/Configuration/ISmtpSettings.cs index 217e83455b..ea42ae5567 100644 --- a/src/Umbraco.Core/Configuration/ISmtpSettings.cs +++ b/src/Umbraco.Core/Configuration/ISmtpSettings.cs @@ -1,3 +1,5 @@ +using System.Net.Mail; + namespace Umbraco.Core.Configuration { public interface ISmtpSettings @@ -6,6 +8,8 @@ namespace Umbraco.Core.Configuration string Host { get; } int Port{ get; } string PickupDirectoryLocation { get; } - string DeliveryMethod { get; } + SmtpDeliveryMethod DeliveryMethod { get; } + string Username { get; } + string Password { get; } } } diff --git a/src/Umbraco.Infrastructure/Events/SendEmailEventArgs.cs b/src/Umbraco.Core/Events/SendEmailEventArgs.cs similarity index 100% rename from src/Umbraco.Infrastructure/Events/SendEmailEventArgs.cs rename to src/Umbraco.Core/Events/SendEmailEventArgs.cs diff --git a/src/Umbraco.Infrastructure/Users/IEmailSender.cs b/src/Umbraco.Core/IEmailSender.cs similarity index 100% rename from src/Umbraco.Infrastructure/Users/IEmailSender.cs rename to src/Umbraco.Core/IEmailSender.cs diff --git a/src/Umbraco.Infrastructure/Users/EmailSender.cs b/src/Umbraco.Infrastructure/Users/EmailSender.cs index 87f27e5097..315a1748c3 100644 --- a/src/Umbraco.Infrastructure/Users/EmailSender.cs +++ b/src/Umbraco.Infrastructure/Users/EmailSender.cs @@ -1,7 +1,7 @@ using System; +using System.Linq; using System.Net.Mail; using System.Threading.Tasks; -using MailKit.Security; using MimeKit; using MimeKit.Text; using Umbraco.Core.Configuration; @@ -70,20 +70,18 @@ namespace Umbraco.Core { using (var client = new SmtpClient()) { - var smtpSettingsDeliveryMethod = _globalSettings.SmtpSettings.DeliveryMethod; - var deliveryMethod = (SmtpDeliveryMethod)Enum.Parse(typeof(SmtpDeliveryMethod), smtpSettingsDeliveryMethod, true); - await client.ConnectAsync(_globalSettings.SmtpSettings.Host, _globalSettings.SmtpSettings.Port); - if (deliveryMethod == SmtpDeliveryMethod.Network) + var mailMessage = ConstructEmailMessage(message); + if (_globalSettings.SmtpSettings.DeliveryMethod == SmtpDeliveryMethod.Network) { - await client.SendAsync(ConstructEmailMessage(message)); + await client.SendAsync(mailMessage); } else { - client.Send(ConstructEmailMessage(message)); + client.Send(mailMessage); } - + await client.DisconnectAsync(true); } } @@ -118,24 +116,17 @@ namespace Umbraco.Core private MimeMessage ConstructEmailMessage(MailMessage mailMessage) { - var messageToSend = new MimeMessage - { - Subject = mailMessage.Subject - }; - var fromEmail = mailMessage.From?.Address; if(string.IsNullOrEmpty(fromEmail)) fromEmail = _globalSettings.SmtpSettings.From; - - messageToSend.From.Add(new MailboxAddress(fromEmail)); - foreach (var mailAddress in mailMessage.To) - messageToSend.To.Add(new MailboxAddress(mailAddress.Address)); - - if (mailMessage.IsBodyHtml) - messageToSend.Body = new TextPart(TextFormat.Html) { Text = mailMessage.Body }; - else - messageToSend.Body = new TextPart(TextFormat.Plain) { Text = mailMessage.Body }; + var messageToSend = new MimeMessage + { + Subject = mailMessage.Subject, + From = { new MailboxAddress(fromEmail)}, + Body = new TextPart(mailMessage.IsBodyHtml ? TextFormat.Html : TextFormat.Plain) { Text = mailMessage.Body } + }; + messageToSend.To.AddRange(mailMessage.To.Select(x=>new MailboxAddress(x.Address))); return messageToSend; } diff --git a/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs b/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs index 140af5f723..bd85807203 100644 --- a/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs +++ b/src/Umbraco.Tests.Common/Builders/SmtpSettingsBuilder.cs @@ -1,4 +1,6 @@ -using Umbraco.Core.Configuration; +using System.Net.Mail; +using Umbraco.Core.Configuration; +using Umbraco.Core.Models.Membership; namespace Umbraco.Tests.Common.Builders { @@ -16,7 +18,9 @@ namespace Umbraco.Tests.Common.Builders private string _host; private int? _port; private string _pickupDirectoryLocation; - private string _deliveryMethod; + private SmtpDeliveryMethod? _deliveryMethod; + private string _username; + private string _password; public SmtpSettingsBuilder(TParent parentBuilder) : base(parentBuilder) { @@ -34,19 +38,31 @@ namespace Umbraco.Tests.Common.Builders return this; } + public SmtpSettingsBuilder WithUsername(string username) + { + _username = username; + return this; + } + public SmtpSettingsBuilder WithPost(int port) { _port = port; return this; } + public SmtpSettingsBuilder WithPassword(string password) + { + _password = password; + return this; + } + public SmtpSettingsBuilder WithPickupDirectoryLocation(string pickupDirectoryLocation) { _pickupDirectoryLocation = pickupDirectoryLocation; return this; } - public SmtpSettingsBuilder WithDeliveryMethod(string deliveryMethod) + public SmtpSettingsBuilder WithDeliveryMethod(SmtpDeliveryMethod deliveryMethod) { _deliveryMethod = deliveryMethod; return this; @@ -58,7 +74,9 @@ namespace Umbraco.Tests.Common.Builders var host = _host ?? null; var port = _port ?? 25; var pickupDirectoryLocation = _pickupDirectoryLocation ?? null; - var deliveryMethod = _deliveryMethod ?? null; + var deliveryMethod = _deliveryMethod ?? SmtpDeliveryMethod.Network; + var username = _username ?? null; + var password = _password ?? null; return new TestSmtpSettings() { @@ -66,7 +84,9 @@ namespace Umbraco.Tests.Common.Builders Host = host, Port = port, PickupDirectoryLocation = pickupDirectoryLocation, - DeliveryMethod = deliveryMethod + DeliveryMethod = deliveryMethod, + Username = username, + Password = password, }; } @@ -76,7 +96,9 @@ namespace Umbraco.Tests.Common.Builders public string Host { get; set; } public int Port { get; set; } public string PickupDirectoryLocation { get; set; } - public string DeliveryMethod { get; set; } + public SmtpDeliveryMethod DeliveryMethod { get; set; } + public string Username { get; set; } + public string Password { get; set; } } } } diff --git a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs index 80f6ab9c9e..bbc869fc65 100644 --- a/src/Umbraco.Tests/Testing/UmbracoTestBase.cs +++ b/src/Umbraco.Tests/Testing/UmbracoTestBase.cs @@ -313,6 +313,7 @@ namespace Umbraco.Tests.Testing Composition.RegisterUnique(); Composition.RegisterUnique(); + Composition.RegisterUnique(); Composition.RegisterUnique(); Composition.RegisterUnique(); Composition.RegisterUnique(); diff --git a/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs index a162b0cd48..f8f02560c4 100644 --- a/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/AuthenticationControllerTests.cs @@ -91,7 +91,8 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), - Factory.GetInstance() + Factory.GetInstance(), + Factory.GetInstance() ); return usersController; } diff --git a/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs b/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs index 4c373b2bc8..ce355180f6 100644 --- a/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs +++ b/src/Umbraco.Tests/Web/Controllers/UsersControllerTests.cs @@ -103,7 +103,8 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), - Factory.GetInstance() + Factory.GetInstance(), + Factory.GetInstance() ); return usersController; @@ -176,7 +177,8 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), - Factory.GetInstance() + Factory.GetInstance(), + Factory.GetInstance() ); return usersController; } @@ -219,7 +221,8 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), - Factory.GetInstance() + Factory.GetInstance(), + Factory.GetInstance() ); return usersController; } @@ -297,7 +300,8 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), - Factory.GetInstance() + Factory.GetInstance(), + Factory.GetInstance() ); return usersController; } @@ -487,7 +491,8 @@ namespace Umbraco.Tests.Web.Controllers Factory.GetInstance(), Factory.GetInstance(), Factory.GetInstance(), - Factory.GetInstance()); + Factory.GetInstance(), + Factory.GetInstance()); var mockOwinContext = new Mock(); var mockUserManagerMarker = new Mock(); diff --git a/src/Umbraco.Web/Editors/AuthenticationController.cs b/src/Umbraco.Web/Editors/AuthenticationController.cs index 50e9921154..01e13ff051 100644 --- a/src/Umbraco.Web/Editors/AuthenticationController.cs +++ b/src/Umbraco.Web/Editors/AuthenticationController.cs @@ -48,6 +48,7 @@ namespace Umbraco.Web.Editors private readonly IHostingEnvironment _hostingEnvironment; private readonly IRuntimeState _runtimeState; private readonly ISecuritySettings _securitySettings; + private readonly IEmailSender _emailSender; public AuthenticationController( IUserPasswordConfiguration passwordConfiguration, @@ -61,13 +62,15 @@ namespace Umbraco.Web.Editors IRuntimeState runtimeState, UmbracoMapper umbracoMapper, ISecuritySettings securitySettings, - IPublishedUrlProvider publishedUrlProvider) + IPublishedUrlProvider publishedUrlProvider, + IEmailSender emailSender) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoMapper, publishedUrlProvider) { _passwordConfiguration = passwordConfiguration ?? throw new ArgumentNullException(nameof(passwordConfiguration)); _hostingEnvironment = hostingEnvironment ?? throw new ArgumentNullException(nameof(hostingEnvironment)); _runtimeState = runtimeState ?? throw new ArgumentNullException(nameof(runtimeState)); _securitySettings = securitySettings ?? throw new ArgumentNullException(nameof(securitySettings)); + _emailSender = emailSender; } protected BackOfficeUserManager UserManager => _userManager @@ -333,16 +336,15 @@ namespace Umbraco.Web.Editors // Ensure the culture of the found user is used for the email! UmbracoUserExtensions.GetUserCulture(identityUser.Culture, Services.TextService, GlobalSettings)); - var emailSender = new EmailSender(GlobalSettings, true); var mailMessage = new MailMessage() { Subject = subject, Body = message, - IsBodyHtml = true + IsBodyHtml = true, + To = { user.Email} }; - mailMessage.To.Add(user.Email); - await emailSender.SendAsync(mailMessage); + await _emailSender.SendAsync(mailMessage); UserManager.RaiseForgotPasswordRequestedEvent(user.Id); } diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs index 029612dc90..3c71245a0a 100644 --- a/src/Umbraco.Web/Editors/UsersController.cs +++ b/src/Umbraco.Web/Editors/UsersController.cs @@ -53,6 +53,7 @@ namespace Umbraco.Web.Editors private readonly ISqlContext _sqlContext; private readonly IImageUrlGenerator _imageUrlGenerator; private readonly ISecuritySettings _securitySettings; + private readonly IEmailSender _emailSender; public UsersController( IGlobalSettings globalSettings, @@ -69,7 +70,8 @@ namespace Umbraco.Web.Editors IHostingEnvironment hostingEnvironment, IImageUrlGenerator imageUrlGenerator, IPublishedUrlProvider publishedUrlProvider, - ISecuritySettings securitySettings) + ISecuritySettings securitySettings, + IEmailSender emailSender) : base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, shortStringHelper, umbracoMapper, publishedUrlProvider) { _mediaFileSystem = mediaFileSystem; @@ -78,6 +80,7 @@ namespace Umbraco.Web.Editors _sqlContext = sqlContext; _imageUrlGenerator = imageUrlGenerator; _securitySettings = securitySettings; + _emailSender = emailSender; } /// @@ -501,16 +504,15 @@ namespace Umbraco.Web.Editors UmbracoUserExtensions.GetUserCulture(to.Language, Services.TextService, GlobalSettings), new[] { userDisplay.Name, from, message, inviteUri.ToString(), fromEmail }); - var emailSender = new EmailSender(GlobalSettings, true); var mailMessage = new MailMessage() { Subject = emailSubject, Body = emailBody, - IsBodyHtml = true + IsBodyHtml = true, + To = { to.Email} }; - mailMessage.To.Add(to.Email); - await emailSender.SendAsync(mailMessage); + await _emailSender.SendAsync(mailMessage); } ///