diff --git a/src/Umbraco.Core/Mail/IEmailSender.cs b/src/Umbraco.Core/Mail/IEmailSender.cs index b5b353455d..0b4b135d03 100644 --- a/src/Umbraco.Core/Mail/IEmailSender.cs +++ b/src/Umbraco.Core/Mail/IEmailSender.cs @@ -9,5 +9,7 @@ namespace Umbraco.Cms.Core.Mail public interface IEmailSender { Task SendAsync(EmailMessage message); + + bool CanSendRequiredEmail(); } } diff --git a/src/Umbraco.Core/Mail/NotImplementedEmailSender.cs b/src/Umbraco.Core/Mail/NotImplementedEmailSender.cs index 45e7925764..b7c7d43fb6 100644 --- a/src/Umbraco.Core/Mail/NotImplementedEmailSender.cs +++ b/src/Umbraco.Core/Mail/NotImplementedEmailSender.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Threading.Tasks; using Umbraco.Cms.Core.Models; @@ -8,5 +8,8 @@ namespace Umbraco.Cms.Core.Mail { public Task SendAsync(EmailMessage message) => throw new NotImplementedException("To send an Email ensure IEmailSender is implemented with a custom implementation"); + + public bool CanSendRequiredEmail() + => throw new NotImplementedException("To send an Email ensure IEmailSender is implemented with a custom implementation"); } } diff --git a/src/Umbraco.Infrastructure/EmailSender.cs b/src/Umbraco.Infrastructure/EmailSender.cs index fe18301295..75f4a61f4d 100644 --- a/src/Umbraco.Infrastructure/EmailSender.cs +++ b/src/Umbraco.Infrastructure/EmailSender.cs @@ -1,14 +1,12 @@ -// Copyright (c) Umbraco. +// Copyright (c) Umbraco. // See LICENSE for more details. -using System; using System.Net.Mail; using System.Threading.Tasks; using Microsoft.Extensions.Options; using MimeKit; using MimeKit.Text; using Umbraco.Cms.Core.Configuration.Models; -using Umbraco.Cms.Core.Events; using Umbraco.Cms.Core.Mail; using Umbraco.Cms.Core.Models; using SmtpClient = MailKit.Net.Smtp.SmtpClient; @@ -23,50 +21,8 @@ namespace Umbraco.Cms.Infrastructure // TODO: This should encapsulate a BackgroundTaskRunner with a queue to send these emails! private readonly GlobalSettings _globalSettings; - private readonly bool _enableEvents; - public EmailSender(IOptions globalSettings) : this(globalSettings, false) - { - } - - public EmailSender(IOptions globalSettings, bool enableEvents) - { - _globalSettings = globalSettings.Value; - _enableEvents = enableEvents; - - _smtpConfigured = new Lazy(() => _globalSettings.IsSmtpServerConfigured); - } - - private readonly Lazy _smtpConfigured; - - /// - /// Sends the message non-async - /// - /// - public void Send(EmailMessage message) - { - if (_smtpConfigured.Value == false && _enableEvents) - { - OnSendEmail(new SendEmailEventArgs(message)); - } - else if (_smtpConfigured.Value == true) - { - using (var client = new SmtpClient()) - { - client.Connect(_globalSettings.Smtp.Host, - _globalSettings.Smtp.Port, - (MailKit.Security.SecureSocketOptions)(int)_globalSettings.Smtp.SecureSocketOptions); - - if (!(_globalSettings.Smtp.Username is null && _globalSettings.Smtp.Password is null)) - { - client.Authenticate(_globalSettings.Smtp.Username, _globalSettings.Smtp.Password); - } - - client.Send(ConstructEmailMessage(message)); - client.Disconnect(true); - } - } - } + public EmailSender(IOptions globalSettings) => _globalSettings = globalSettings.Value; /// /// Sends the message async @@ -75,35 +31,33 @@ namespace Umbraco.Cms.Infrastructure /// public async Task SendAsync(EmailMessage message) { - if (_smtpConfigured.Value == false && _enableEvents) + if (_globalSettings.IsSmtpServerConfigured == false) { - OnSendEmail(new SendEmailEventArgs(message)); + return; } - else if (_smtpConfigured.Value == true) + + using (var client = new SmtpClient()) { - using (var client = new SmtpClient()) + await client.ConnectAsync(_globalSettings.Smtp.Host, + _globalSettings.Smtp.Port, + (MailKit.Security.SecureSocketOptions)(int)_globalSettings.Smtp.SecureSocketOptions); + + if (!(_globalSettings.Smtp.Username is null && _globalSettings.Smtp.Password is null)) { - await client.ConnectAsync(_globalSettings.Smtp.Host, - _globalSettings.Smtp.Port, - (MailKit.Security.SecureSocketOptions)(int)_globalSettings.Smtp.SecureSocketOptions); - - if (!(_globalSettings.Smtp.Username is null && _globalSettings.Smtp.Password is null)) - { - await client.AuthenticateAsync(_globalSettings.Smtp.Username, _globalSettings.Smtp.Password); - } - - var mailMessage = ConstructEmailMessage(message); - if (_globalSettings.Smtp.DeliveryMethod == SmtpDeliveryMethod.Network) - { - await client.SendAsync(mailMessage); - } - else - { - client.Send(mailMessage); - } - - await client.DisconnectAsync(true); + await client.AuthenticateAsync(_globalSettings.Smtp.Username, _globalSettings.Smtp.Password); } + + var mailMessage = ConstructEmailMessage(message); + if (_globalSettings.Smtp.DeliveryMethod == SmtpDeliveryMethod.Network) + { + await client.SendAsync(mailMessage); + } + else + { + await client.SendAsync(mailMessage); + } + + await client.DisconnectAsync(true); } } @@ -113,25 +67,7 @@ namespace Umbraco.Cms.Infrastructure /// /// We assume this is possible if either an event handler is registered or an smtp server is configured /// - public static bool CanSendRequiredEmail(GlobalSettings globalSettings) => EventHandlerRegistered || globalSettings.IsSmtpServerConfigured; - - /// - /// returns true if an event handler has been registered - /// - internal static bool EventHandlerRegistered - { - get { return SendEmail != null; } - } - - /// - /// An event that is raised when no smtp server is configured if events are enabled - /// - internal static event EventHandler SendEmail; - - private static void OnSendEmail(SendEmailEventArgs e) - { - SendEmail?.Invoke(null, e); - } + public bool CanSendRequiredEmail() => _globalSettings.IsSmtpServerConfigured; private MimeMessage ConstructEmailMessage(EmailMessage mailMessage) { diff --git a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs index 14be214c70..789dbfd752 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/BackOfficeServerVariables.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Linq; using System.Runtime.Serialization; @@ -11,6 +11,7 @@ using Umbraco.Cms.Core.Configuration; using Umbraco.Cms.Core.Configuration.Models; using Umbraco.Cms.Core.Features; using Umbraco.Cms.Core.Hosting; +using Umbraco.Cms.Core.Mail; using Umbraco.Cms.Core.Media; using Umbraco.Cms.Core.Models.ContentEditing; using Umbraco.Cms.Core.Services; @@ -49,6 +50,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers private readonly IBackOfficeExternalLoginProviders _externalLogins; private readonly IImageUrlGenerator _imageUrlGenerator; private readonly PreviewRoutes _previewRoutes; + private readonly IEmailSender _emailSender; public BackOfficeServerVariables( LinkGenerator linkGenerator, @@ -65,7 +67,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers IRuntimeMinifier runtimeMinifier, IBackOfficeExternalLoginProviders externalLogins, IImageUrlGenerator imageUrlGenerator, - PreviewRoutes previewRoutes) + PreviewRoutes previewRoutes, + IEmailSender emailSender) { _linkGenerator = linkGenerator; _runtimeState = runtimeState; @@ -82,6 +85,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers _externalLogins = externalLogins; _imageUrlGenerator = imageUrlGenerator; _previewRoutes = previewRoutes; + _emailSender = emailSender; } /// @@ -398,8 +402,8 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers {"allowPasswordReset", _securitySettings.AllowPasswordReset}, {"loginBackgroundImage", _contentSettings.LoginBackgroundImage}, {"loginLogoImage", _contentSettings.LoginLogoImage }, - {"showUserInvite", EmailSender.CanSendRequiredEmail(globalSettings)}, - {"canSendRequiredEmail", EmailSender.CanSendRequiredEmail(globalSettings)}, + {"showUserInvite", _emailSender.CanSendRequiredEmail()}, + {"canSendRequiredEmail", _emailSender.CanSendRequiredEmail()}, {"showAllowSegmentationForDocumentTypes", false}, } }, diff --git a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs index 90b5797804..06c04211d3 100644 --- a/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs +++ b/src/Umbraco.Web.BackOffice/Controllers/UsersController.cs @@ -443,7 +443,7 @@ namespace Umbraco.Cms.Web.BackOffice.Controllers return new ValidationErrorResult(new SimpleValidationModel(ModelState.ToErrorDictionary())); } - if (!EmailSender.CanSendRequiredEmail(_globalSettings) && !_userManager.HasSendingUserInviteEventHandler) + if (!_emailSender.CanSendRequiredEmail() && !_userManager.HasSendingUserInviteEventHandler) { return new ValidationErrorResult("No Email server is configured"); } diff --git a/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs b/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs index 3525c8c48b..89d5dc826c 100644 --- a/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs +++ b/src/Umbraco.Web.BackOffice/Trees/ContentTreeController.cs @@ -5,10 +5,9 @@ using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Http; using Microsoft.AspNetCore.Mvc; using Microsoft.Extensions.Logging; -using Microsoft.Extensions.Options; using Umbraco.Cms.Core; using Umbraco.Cms.Core.Actions; -using Umbraco.Cms.Core.Configuration.Models; +using Umbraco.Cms.Core.Mail; using Umbraco.Cms.Core.Models; using Umbraco.Cms.Core.Models.ContentEditing; using Umbraco.Cms.Core.Models.Entities; @@ -16,7 +15,6 @@ using Umbraco.Cms.Core.Models.Trees; using Umbraco.Cms.Core.Security; using Umbraco.Cms.Core.Services; using Umbraco.Cms.Core.Trees; -using Umbraco.Cms.Infrastructure; using Umbraco.Cms.Infrastructure.Search; using Umbraco.Cms.Web.Common.Attributes; using Umbraco.Cms.Web.Common.Authorization; @@ -34,7 +32,6 @@ namespace Umbraco.Cms.Web.BackOffice.Trees { private readonly UmbracoTreeSearcher _treeSearcher; private readonly ActionCollection _actions; - private readonly GlobalSettings _globalSettings; private readonly IMenuItemCollectionFactory _menuItemCollectionFactory; private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; private readonly IContentService _contentService; @@ -42,6 +39,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees private readonly IPublicAccessService _publicAccessService; private readonly IUserService _userService; private readonly ILocalizationService _localizationService; + private readonly IEmailSender _emailSender; public ContentTreeController( ILocalizedTextService localizedTextService, @@ -55,15 +53,14 @@ namespace Umbraco.Cms.Web.BackOffice.Trees IDataTypeService dataTypeService, UmbracoTreeSearcher treeSearcher, ActionCollection actions, - IOptions globalSettings, IContentService contentService, IPublicAccessService publicAccessService, - ILocalizationService localizationService) + ILocalizationService localizationService, + IEmailSender emailSender) : base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory, entityService, backofficeSecurityAccessor, logger, actionCollection, userService, dataTypeService) { _treeSearcher = treeSearcher; _actions = actions; - _globalSettings = globalSettings.Value; _menuItemCollectionFactory = menuItemCollectionFactory; _backofficeSecurityAccessor = backofficeSecurityAccessor; _contentService = contentService; @@ -71,6 +68,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees _publicAccessService = publicAccessService; _userService = userService; _localizationService = localizationService; + _emailSender = emailSender; } protected override int RecycleBinId => Constants.System.RecycleBinContent; @@ -275,7 +273,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees AddActionNode(item, menu, opensDialog: true); AddActionNode(item, menu, true, opensDialog: true); - if (EmailSender.CanSendRequiredEmail(_globalSettings)) + if (_emailSender.CanSendRequiredEmail()) { menu.Items.Add(new MenuItem("notify", LocalizedTextService) {