diff --git a/src/Umbraco.Core/EmailSender.cs b/src/Umbraco.Abstractions/EmailSender.cs
similarity index 78%
rename from src/Umbraco.Core/EmailSender.cs
rename to src/Umbraco.Abstractions/EmailSender.cs
index 698034a7e9..5cfdd765bc 100644
--- a/src/Umbraco.Core/EmailSender.cs
+++ b/src/Umbraco.Abstractions/EmailSender.cs
@@ -2,6 +2,7 @@
using System.Net.Mail;
using System.Threading.Tasks;
using Umbraco.Core.Composing;
+using Umbraco.Core.Configuration;
using Umbraco.Core.Events;
namespace Umbraco.Core
@@ -13,21 +14,22 @@ namespace Umbraco.Core
{
// TODO: This should encapsulate a BackgroundTaskRunner with a queue to send these emails!
+ private readonly IGlobalSettings _globalSettings;
private readonly bool _enableEvents;
- ///
- /// Default constructor
- ///
- public EmailSender() : this(false)
+ public EmailSender(IGlobalSettings globalSettings) : this(globalSettings, false)
{
}
- internal EmailSender(bool enableEvents)
+ internal EmailSender(IGlobalSettings globalSettings, bool enableEvents)
{
+ _globalSettings = globalSettings;
_enableEvents = enableEvents;
+
+ _smtpConfigured = new Lazy(() => _globalSettings.IsSmtpServerConfigured);
}
- private static readonly Lazy SmtpConfigured = new Lazy(() => Current.Configs.Global().IsSmtpServerConfigured);
+ private readonly Lazy _smtpConfigured;
///
/// Sends the message non-async
@@ -35,7 +37,7 @@ namespace Umbraco.Core
///
public void Send(MailMessage message)
{
- if (SmtpConfigured.Value == false && _enableEvents)
+ if (_smtpConfigured.Value == false && _enableEvents)
{
OnSendEmail(new SendEmailEventArgs(message));
}
@@ -55,7 +57,7 @@ namespace Umbraco.Core
///
public async Task SendAsync(MailMessage message)
{
- if (SmtpConfigured.Value == false && _enableEvents)
+ if (_smtpConfigured.Value == false && _enableEvents)
{
OnSendEmail(new SendEmailEventArgs(message));
}
@@ -81,10 +83,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
- {
- get { return EventHandlerRegistered || SmtpConfigured.Value; }
- }
+ internal static bool CanSendRequiredEmail(IGlobalSettings globalSettings) => EventHandlerRegistered || globalSettings.IsSmtpServerConfigured;
///
/// returns true if an event handler has been registered
diff --git a/src/Umbraco.Core/ReflectionUtilities.cs b/src/Umbraco.Abstractions/ReflectionUtilities.cs
similarity index 99%
rename from src/Umbraco.Core/ReflectionUtilities.cs
rename to src/Umbraco.Abstractions/ReflectionUtilities.cs
index a8e6836ca1..b3fd8c1b59 100644
--- a/src/Umbraco.Core/ReflectionUtilities.cs
+++ b/src/Umbraco.Abstractions/ReflectionUtilities.cs
@@ -18,7 +18,7 @@ namespace Umbraco.Core
/// Supports emitting constructors, instance and static methods, instance property getters and
/// setters. Does not support static properties yet.
///
- public static partial class ReflectionUtilities
+ public static class ReflectionUtilities
{
#region Fields
diff --git a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj
index 7e00359c37..a4d379d2bf 100644
--- a/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj
+++ b/src/Umbraco.Abstractions/Umbraco.Abstractions.csproj
@@ -12,6 +12,7 @@
+
diff --git a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs
index 40dd4575dc..1432e6b7f2 100644
--- a/src/Umbraco.Core/Runtime/CoreInitialComponent.cs
+++ b/src/Umbraco.Core/Runtime/CoreInitialComponent.cs
@@ -1,4 +1,5 @@
using Umbraco.Core.Composing;
+using Umbraco.Core.Configuration;
using Umbraco.Core.IO;
namespace Umbraco.Core.Runtime
@@ -6,10 +7,12 @@ namespace Umbraco.Core.Runtime
public class CoreInitialComponent : IComponent
{
private readonly IIOHelper _ioHelper;
+ private readonly IGlobalSettings _globalSettings;
- public CoreInitialComponent(IIOHelper ioHelper)
+ public CoreInitialComponent(IIOHelper ioHelper, IGlobalSettings globalSettings)
{
_ioHelper = ioHelper;
+ _globalSettings = globalSettings;
}
public void Initialize()
@@ -17,7 +20,7 @@ namespace Umbraco.Core.Runtime
// ensure we have some essential directories
// every other component can then initialize safely
_ioHelper.EnsurePathExists(Constants.SystemDirectories.Data);
- _ioHelper.EnsurePathExists(Current.Configs.Global().UmbracoMediaPath);
+ _ioHelper.EnsurePathExists(_globalSettings.UmbracoMediaPath);
_ioHelper.EnsurePathExists(Constants.SystemDirectories.MvcViews);
_ioHelper.EnsurePathExists(Constants.SystemDirectories.PartialViews);
_ioHelper.EnsurePathExists(Constants.SystemDirectories.MacroPartials);
diff --git a/src/Umbraco.Core/Umbraco.Core.csproj b/src/Umbraco.Core/Umbraco.Core.csproj
index 5f6a877415..5bbd3942a4 100755
--- a/src/Umbraco.Core/Umbraco.Core.csproj
+++ b/src/Umbraco.Core/Umbraco.Core.csproj
@@ -314,7 +314,6 @@
-
@@ -325,7 +324,6 @@
-
@@ -701,7 +699,6 @@
-
diff --git a/src/Umbraco.Tests.Benchmarks/CtorInvokeBenchmarks.cs b/src/Umbraco.Tests.Benchmarks/CtorInvokeBenchmarks.cs
index 8d15613791..0ce1b3eac3 100644
--- a/src/Umbraco.Tests.Benchmarks/CtorInvokeBenchmarks.cs
+++ b/src/Umbraco.Tests.Benchmarks/CtorInvokeBenchmarks.cs
@@ -145,8 +145,8 @@ namespace Umbraco.Tests.Benchmarks
//_expressionMethod3 = (Func) Delegate.CreateDelegate(typeof (Func), _expressionMethod.Method);
// but, our utilities know how to do it!
- _expressionMethod3 = ReflectionUtilities.CompileToDelegate(expr);
- _expressionMethod4 = ReflectionUtilities.GetCtor();
+ _expressionMethod3 = ReflectionUtilitiesForTest.CompileToDelegate(expr);
+ _expressionMethod4 = ReflectionUtilitiesForTest.GetCtor();
// however, unfortunately, the generated "compiled to delegate" code cannot access private stuff :(
diff --git a/src/Umbraco.Core/ReflectionUtilities-Unused.cs b/src/Umbraco.Tests.Benchmarks/ReflectionUtilities-Unused.cs
similarity index 99%
rename from src/Umbraco.Core/ReflectionUtilities-Unused.cs
rename to src/Umbraco.Tests.Benchmarks/ReflectionUtilities-Unused.cs
index 53317f7101..1182891477 100644
--- a/src/Umbraco.Core/ReflectionUtilities-Unused.cs
+++ b/src/Umbraco.Tests.Benchmarks/ReflectionUtilities-Unused.cs
@@ -5,12 +5,12 @@ using System.Linq.Expressions;
using System.Reflection;
using System.Reflection.Emit;
-namespace Umbraco.Core
+namespace Umbraco.Tests.Benchmarks
{
///
/// Provides utilities to simplify reflection.
///
- public static partial class ReflectionUtilities
+ public static class ReflectionUtilitiesForTest
{
// the code below should NOT be used
//
@@ -363,4 +363,4 @@ namespace Umbraco.Core
return module.DefineType("Class", TypeAttributes.Public | TypeAttributes.Abstract);
}
}
-}
\ No newline at end of file
+}
diff --git a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
index b6858bd5cb..8ccb49b67c 100644
--- a/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
+++ b/src/Umbraco.Tests.Benchmarks/Umbraco.Tests.Benchmarks.csproj
@@ -57,6 +57,7 @@
+
diff --git a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs
index a15b5bf63b..010487b4c0 100644
--- a/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs
+++ b/src/Umbraco.Web/Editors/BackOfficeServerVariables.cs
@@ -101,6 +101,7 @@ namespace Umbraco.Web.Editors
///
internal Dictionary GetServerVariables()
{
+ var globalSettings = Current.Configs.Global();
var defaultVals = new Dictionary
{
{
@@ -319,7 +320,7 @@ namespace Umbraco.Web.Editors
"umbracoSettings", new Dictionary
{
{"umbracoPath", _globalSettings.Path},
- {"mediaPath", Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoMediaPath).TrimEnd('/')},
+ {"mediaPath", Current.IOHelper.ResolveUrl(globalSettings.UmbracoMediaPath).TrimEnd('/')},
{"appPluginsPath", Current.IOHelper.ResolveUrl(Constants.SystemDirectories.AppPlugins).TrimEnd('/')},
{
"imageFileTypes",
@@ -339,11 +340,11 @@ namespace Umbraco.Web.Editors
},
{"keepUserLoggedIn", Current.Configs.Settings().Security.KeepUserLoggedIn},
{"usernameIsEmail", Current.Configs.Settings().Security.UsernameIsEmail},
- {"cssPath", Current.IOHelper.ResolveUrl(Current.Configs.Global().UmbracoCssPath).TrimEnd('/')},
+ {"cssPath", Current.IOHelper.ResolveUrl(globalSettings.UmbracoCssPath).TrimEnd('/')},
{"allowPasswordReset", Current.Configs.Settings().Security.AllowPasswordReset},
{"loginBackgroundImage", Current.Configs.Settings().Content.LoginBackgroundImage},
- {"showUserInvite", EmailSender.CanSendRequiredEmail},
- {"canSendRequiredEmail", EmailSender.CanSendRequiredEmail},
+ {"showUserInvite", EmailSender.CanSendRequiredEmail(globalSettings)},
+ {"canSendRequiredEmail", EmailSender.CanSendRequiredEmail(globalSettings)},
}
},
{
diff --git a/src/Umbraco.Web/Editors/UsersController.cs b/src/Umbraco.Web/Editors/UsersController.cs
index 2211813f63..1e751d2383 100644
--- a/src/Umbraco.Web/Editors/UsersController.cs
+++ b/src/Umbraco.Web/Editors/UsersController.cs
@@ -40,9 +40,12 @@ namespace Umbraco.Web.Editors
[IsCurrentUserModelFilter]
public class UsersController : UmbracoAuthorizedJsonController
{
+ private readonly IGlobalSettings _globalSettings;
+
public UsersController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ISqlContext sqlContext, ServiceContext services, AppCaches appCaches, IProfilingLogger logger, IRuntimeState runtimeState, UmbracoHelper umbracoHelper)
: base(globalSettings, umbracoContextAccessor, sqlContext, services, appCaches, logger, runtimeState, umbracoHelper)
{
+ _globalSettings = globalSettings;
}
///
@@ -343,7 +346,7 @@ namespace Umbraco.Web.Editors
throw new HttpResponseException(Request.CreateErrorResponse(HttpStatusCode.BadRequest, ModelState));
}
- if (EmailSender.CanSendRequiredEmail == false)
+ if (EmailSender.CanSendRequiredEmail(_globalSettings) == false)
{
throw new HttpResponseException(
Request.CreateNotificationValidationErrorResponse("No Email server is configured"));
@@ -473,7 +476,7 @@ namespace Umbraco.Web.Editors
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(true))
+ new UmbracoEmailMessage(new EmailSender(_globalSettings, true))
{
Body = emailBody,
Destination = userDisplay.Email,
diff --git a/src/Umbraco.Web/HealthCheck/NotificationMethods/EmailNotificationMethod.cs b/src/Umbraco.Web/HealthCheck/NotificationMethods/EmailNotificationMethod.cs
index 87c0e4f46d..ddde3f7b98 100644
--- a/src/Umbraco.Web/HealthCheck/NotificationMethods/EmailNotificationMethod.cs
+++ b/src/Umbraco.Web/HealthCheck/NotificationMethods/EmailNotificationMethod.cs
@@ -17,8 +17,9 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods
private readonly ILocalizedTextService _textService;
private readonly IRuntimeState _runtimeState;
private readonly ILogger _logger;
+ private readonly IGlobalSettings _globalSettings;
- public EmailNotificationMethod(ILocalizedTextService textService, IRuntimeState runtimeState, ILogger logger)
+ public EmailNotificationMethod(ILocalizedTextService textService, IRuntimeState runtimeState, ILogger logger, IGlobalSettings globalSettings)
{
var recipientEmail = Settings["recipientEmail"]?.Value;
if (string.IsNullOrWhiteSpace(recipientEmail))
@@ -32,6 +33,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods
_textService = textService ?? throw new ArgumentNullException(nameof(textService));
_runtimeState = runtimeState;
_logger = logger;
+ _globalSettings = globalSettings;
}
public string RecipientEmail { get; }
@@ -61,7 +63,7 @@ namespace Umbraco.Web.HealthCheck.NotificationMethods
var subject = _textService.Localize("healthcheck/scheduledHealthCheckEmailSubject", new[] { host.ToString() });
- var mailSender = new EmailSender();
+ var mailSender = new EmailSender(_globalSettings);
using (var mailMessage = CreateMailMessage(subject, message))
{
await mailSender.SendAsync(mailMessage);
diff --git a/src/Umbraco.Web/Security/AppBuilderExtensions.cs b/src/Umbraco.Web/Security/AppBuilderExtensions.cs
index ede574671f..3f459cf734 100644
--- a/src/Umbraco.Web/Security/AppBuilderExtensions.cs
+++ b/src/Umbraco.Web/Security/AppBuilderExtensions.cs
@@ -96,7 +96,8 @@ namespace Umbraco.Web.Security
customUserStore,
contentSettings,
passwordConfiguration,
- ipResolver));
+ ipResolver,
+ globalSettings));
app.SetBackOfficeUserManagerType();
diff --git a/src/Umbraco.Web/Security/BackOfficeUserManager.cs b/src/Umbraco.Web/Security/BackOfficeUserManager.cs
index 52bf901bfa..c644f5e428 100644
--- a/src/Umbraco.Web/Security/BackOfficeUserManager.cs
+++ b/src/Umbraco.Web/Security/BackOfficeUserManager.cs
@@ -28,11 +28,12 @@ namespace Umbraco.Web.Security
IdentityFactoryOptions options,
IContentSection contentSectionConfig,
IPasswordConfiguration passwordConfiguration,
- IIpResolver ipResolver)
+ IIpResolver ipResolver,
+ IGlobalSettings globalSettings)
: base(store, passwordConfiguration, ipResolver)
{
if (options == null) throw new ArgumentNullException("options");
- InitUserManager(this, passwordConfiguration, options.DataProtectionProvider, contentSectionConfig);
+ InitUserManager(this, passwordConfiguration, options.DataProtectionProvider, contentSectionConfig, globalSettings);
}
#region Static Create methods
@@ -64,7 +65,7 @@ namespace Umbraco.Web.Security
if (externalLoginService == null) throw new ArgumentNullException("externalLoginService");
var store = new BackOfficeUserStore(userService, entityService, externalLoginService, globalSettings, mapper);
- var manager = new BackOfficeUserManager(store, options, contentSectionConfig, passwordConfiguration, ipResolver);
+ var manager = new BackOfficeUserManager(store, options, contentSectionConfig, passwordConfiguration, ipResolver, globalSettings);
return manager;
}
@@ -81,9 +82,10 @@ namespace Umbraco.Web.Security
BackOfficeUserStore customUserStore,
IContentSection contentSectionConfig,
IPasswordConfiguration passwordConfiguration,
- IIpResolver ipResolver)
+ IIpResolver ipResolver,
+ IGlobalSettings globalSettings)
{
- var manager = new BackOfficeUserManager(customUserStore, options, contentSectionConfig, passwordConfiguration, ipResolver);
+ var manager = new BackOfficeUserManager(customUserStore, options, contentSectionConfig, passwordConfiguration, ipResolver, globalSettings);
return manager;
}
#endregion
@@ -157,7 +159,8 @@ namespace Umbraco.Web.Security
BackOfficeUserManager manager,
IPasswordConfiguration passwordConfig,
IDataProtectionProvider dataProtectionProvider,
- IContentSection contentSectionConfig)
+ IContentSection contentSectionConfig,
+ IGlobalSettings globalSettings)
{
// Configure validation logic for usernames
manager.UserValidator = new BackOfficeUserValidator(manager)
@@ -192,7 +195,7 @@ namespace Umbraco.Web.Security
manager.EmailService = new EmailService(
contentSectionConfig.NotificationEmailAddress,
- new EmailSender());
+ new EmailSender(globalSettings));
//NOTE: Not implementing these, if people need custom 2 factor auth, they'll need to implement their own UserStore to support it
diff --git a/src/Umbraco.Web/Trees/ContentTreeController.cs b/src/Umbraco.Web/Trees/ContentTreeController.cs
index 1ef0683916..1a56642a74 100644
--- a/src/Umbraco.Web/Trees/ContentTreeController.cs
+++ b/src/Umbraco.Web/Trees/ContentTreeController.cs
@@ -39,6 +39,7 @@ namespace Umbraco.Web.Trees
{
private readonly UmbracoTreeSearcher _treeSearcher;
private readonly ActionCollection _actions;
+ private readonly IGlobalSettings _globalSettings;
protected override int RecycleBinId => Constants.System.RecycleBinContent;
@@ -53,6 +54,7 @@ namespace Umbraco.Web.Trees
{
_treeSearcher = treeSearcher;
_actions = actions;
+ _globalSettings = globalSettings;
}
///
@@ -240,7 +242,7 @@ namespace Umbraco.Web.Trees
AddActionNode(item, menu, opensDialog: true);
AddActionNode(item, menu, true, opensDialog: true);
- if (EmailSender.CanSendRequiredEmail)
+ if (EmailSender.CanSendRequiredEmail(_globalSettings))
{
menu.Items.Add(new MenuItem("notify", Services.TextService)
{