Merge pull request #9900 from kjac/netcore/feature/emailsender-without-statics

Remove static methods and events from EmailSender
This commit is contained in:
Bjarke Berg
2021-03-01 14:15:09 +01:00
committed by GitHub
6 changed files with 46 additions and 103 deletions

View File

@@ -9,5 +9,7 @@ namespace Umbraco.Cms.Core.Mail
public interface IEmailSender
{
Task SendAsync(EmailMessage message);
bool CanSendRequiredEmail();
}
}

View File

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

View File

@@ -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> globalSettings) : this(globalSettings, false)
{
}
public EmailSender(IOptions<GlobalSettings> globalSettings, bool enableEvents)
{
_globalSettings = globalSettings.Value;
_enableEvents = enableEvents;
_smtpConfigured = new Lazy<bool>(() => _globalSettings.IsSmtpServerConfigured);
}
private readonly Lazy<bool> _smtpConfigured;
/// <summary>
/// Sends the message non-async
/// </summary>
/// <param name="message"></param>
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 = globalSettings.Value;
/// <summary>
/// Sends the message async
@@ -75,35 +31,33 @@ namespace Umbraco.Cms.Infrastructure
/// <returns></returns>
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
{
client.Send(mailMessage);
}
await client.DisconnectAsync(true);
}
}
@@ -113,25 +67,7 @@ namespace Umbraco.Cms.Infrastructure
/// <remarks>
/// We assume this is possible if either an event handler is registered or an smtp server is configured
/// </remarks>
public static bool CanSendRequiredEmail(GlobalSettings globalSettings) => EventHandlerRegistered || globalSettings.IsSmtpServerConfigured;
/// <summary>
/// returns true if an event handler has been registered
/// </summary>
internal static bool EventHandlerRegistered
{
get { return SendEmail != null; }
}
/// <summary>
/// An event that is raised when no smtp server is configured if events are enabled
/// </summary>
internal static event EventHandler<SendEmailEventArgs> SendEmail;
private static void OnSendEmail(SendEmailEventArgs e)
{
SendEmail?.Invoke(null, e);
}
public bool CanSendRequiredEmail() => _globalSettings.IsSmtpServerConfigured;
private MimeMessage ConstructEmailMessage(EmailMessage mailMessage)
{

View File

@@ -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;
}
/// <summary>
@@ -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},
}
},

View File

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

View File

@@ -5,11 +5,10 @@ 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.Events;
using Umbraco.Cms.Core.Mail;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Core.Models.ContentEditing;
using Umbraco.Cms.Core.Models.Entities;
@@ -17,7 +16,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;
@@ -35,7 +33,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;
@@ -43,6 +40,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,
@@ -56,16 +54,15 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
IDataTypeService dataTypeService,
UmbracoTreeSearcher treeSearcher,
ActionCollection actions,
IOptions<GlobalSettings> globalSettings,
IContentService contentService,
IPublicAccessService publicAccessService,
ILocalizationService localizationService,
IEventAggregator eventAggregator)
IEventAggregator eventAggregator,
IEmailSender emailSender)
: base(localizedTextService, umbracoApiControllerTypeCollection, menuItemCollectionFactory, entityService, backofficeSecurityAccessor, logger, actionCollection, userService, dataTypeService, eventAggregator)
{
_treeSearcher = treeSearcher;
_actions = actions;
_globalSettings = globalSettings.Value;
_menuItemCollectionFactory = menuItemCollectionFactory;
_backofficeSecurityAccessor = backofficeSecurityAccessor;
_contentService = contentService;
@@ -73,6 +70,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
_publicAccessService = publicAccessService;
_userService = userService;
_localizationService = localizationService;
_emailSender = emailSender;
}
protected override int RecycleBinId => Constants.System.RecycleBinContent;
@@ -277,7 +275,7 @@ namespace Umbraco.Cms.Web.BackOffice.Trees
AddActionNode<ActionRights>(item, menu, opensDialog: true);
AddActionNode<ActionProtect>(item, menu, true, opensDialog: true);
if (EmailSender.CanSendRequiredEmail(_globalSettings))
if (_emailSender.CanSendRequiredEmail())
{
menu.Items.Add(new MenuItem("notify", LocalizedTextService)
{