Refactored to remove Configs

This commit is contained in:
Bjarke Berg
2020-09-10 13:51:59 +02:00
parent 7f89299150
commit a4e5029912
45 changed files with 334 additions and 554 deletions

View File

@@ -1,48 +0,0 @@
using Microsoft.Extensions.Configuration;
using Umbraco.Configuration.Models;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
using CoreDebugSettings = Umbraco.Configuration.Models.CoreDebugSettings;
namespace Umbraco.Configuration
{
public class AspNetCoreConfigsFactory : IConfigsFactory
{
private readonly IConfiguration _configuration;
public AspNetCoreConfigsFactory(IConfiguration configuration)
{
_configuration = configuration ?? throw new System.ArgumentNullException(nameof(configuration));
}
public Configs Create()
{
var configs = new Configs();
configs.Add<ITourSettings>(() => new TourSettings(_configuration));
configs.Add<ICoreDebugSettings>(() => new CoreDebugSettings(_configuration));
configs.Add<IRequestHandlerSettings>(() => new RequestHandlerSettings(_configuration));
configs.Add<ISecuritySettings>(() => new SecuritySettings(_configuration));
configs.Add<IUserPasswordConfiguration>(() => new UserPasswordConfigurationSettings(_configuration));
configs.Add<IMemberPasswordConfiguration>(() => new MemberPasswordConfigurationSettings(_configuration));
configs.Add<IKeepAliveSettings>(() => new KeepAliveSettings(_configuration));
configs.Add<IContentSettings>(() => new ContentSettings(_configuration));
configs.Add<IHealthChecksSettings>(() => new HealthChecksSettings(_configuration));
configs.Add<ILoggingSettings>(() => new LoggingSettings(_configuration));
configs.Add<IExceptionFilterSettings>(() => new ExceptionFilterSettings(_configuration));
configs.Add<IActiveDirectorySettings>(() => new ActiveDirectorySettings(_configuration));
configs.Add<IRuntimeSettings>(() => new RuntimeSettings(_configuration));
configs.Add<ITypeFinderSettings>(() => new TypeFinderSettings(_configuration));
configs.Add<INuCacheSettings>(() => new NuCacheSettings(_configuration));
configs.Add<IWebRoutingSettings>(() => new WebRoutingSettings(_configuration));
configs.Add<IIndexCreatorSettings>(() => new IndexCreatorSettings(_configuration));
configs.Add<IModelsBuilderConfig>(() => new ModelsBuilderConfig(_configuration));
configs.Add<IHostingSettings>(() => new HostingSettings(_configuration));
configs.Add<IGlobalSettings>(() => new GlobalSettings(_configuration));
configs.Add<IImagingSettings>(() => new ImagingSettings(_configuration));
return configs;
}
}
}

View File

@@ -1,63 +1,63 @@
using Umbraco.Configuration;
using Umbraco.Configuration.Implementations;
using Umbraco.Configuration.Legacy;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.Legacy;
using Umbraco.Core.Configuration.UmbracoSettings;
namespace Umbraco.Core.Configuration
{
public class ConfigsFactory : IConfigsFactory
{
public IHostingSettings HostingSettings { get; } = new HostingSettings();
public ICoreDebugSettings CoreDebugSettings { get; } = new CoreDebugSettings();
public IIndexCreatorSettings IndexCreatorSettings { get; } = new IndexCreatorSettings();
public INuCacheSettings NuCacheSettings { get; } = new NuCacheSettings();
public ITypeFinderSettings TypeFinderSettings { get; } = new TypeFinderSettings();
public IRuntimeSettings RuntimeSettings { get; } = new RuntimeSettings();
public IActiveDirectorySettings ActiveDirectorySettings { get; } = new ActiveDirectorySettings();
public IExceptionFilterSettings ExceptionFilterSettings { get; } = new ExceptionFilterSettings();
public ITourSettings TourSettings { get; } = new TourSettings();
public ILoggingSettings LoggingSettings { get; } = new LoggingSettings();
public IKeepAliveSettings KeepAliveSettings { get; } = new KeepAliveSettings();
public IWebRoutingSettings WebRoutingSettings { get; } = new WebRoutingSettings();
public IRequestHandlerSettings RequestHandlerSettings { get; } = new RequestHandlerSettings();
public ISecuritySettings SecuritySettings { get; } = new SecuritySettings();
public IUserPasswordConfiguration UserPasswordConfigurationSettings { get; } = new UserPasswordConfigurationSettings();
public IMemberPasswordConfiguration MemberPasswordConfigurationSettings { get; } = new MemberPasswordConfigurationSettings();
public IContentSettings ContentSettings { get; } = new ContentSettings();
public IGlobalSettings GlobalSettings { get; } = new GlobalSettings();
public IHealthChecksSettings HealthChecksSettings { get; } = new HealthChecksSettings();
public IConnectionStrings ConnectionStrings { get; } = new ConnectionStrings();
public IModelsBuilderConfig ModelsBuilderConfig { get; } = new ModelsBuilderConfig();
public Configs Create()
{
var configs = new Configs();
configs.Add<IGlobalSettings>(() => GlobalSettings);
configs.Add<IHostingSettings>(() => HostingSettings);
configs.Add<IHealthChecksSettings>(() => HealthChecksSettings);
configs.Add<ICoreDebugSettings>(() => CoreDebugSettings);
configs.Add<IConnectionStrings>(() => ConnectionStrings);
configs.Add<IModelsBuilderConfig>(() => ModelsBuilderConfig);
configs.Add<IIndexCreatorSettings>(() => IndexCreatorSettings);
configs.Add<INuCacheSettings>(() => NuCacheSettings);
configs.Add<ITypeFinderSettings>(() => TypeFinderSettings);
configs.Add<IRuntimeSettings>(() => RuntimeSettings);
configs.Add<IActiveDirectorySettings>(() => ActiveDirectorySettings);
configs.Add<IExceptionFilterSettings>(() => ExceptionFilterSettings);
configs.Add<ITourSettings>(() => TourSettings);
configs.Add<ILoggingSettings>(() => LoggingSettings);
configs.Add<IKeepAliveSettings>(() => KeepAliveSettings);
configs.Add<IWebRoutingSettings>(() => WebRoutingSettings);
configs.Add<IRequestHandlerSettings>(() => RequestHandlerSettings);
configs.Add<ISecuritySettings>(() => SecuritySettings);
configs.Add<IUserPasswordConfiguration>(() => UserPasswordConfigurationSettings);
configs.Add<IMemberPasswordConfiguration>(() => MemberPasswordConfigurationSettings);
configs.Add<IContentSettings>(() => ContentSettings);
return configs;
}
}
}
// using Umbraco.Configuration;
// using Umbraco.Configuration.Implementations;
// using Umbraco.Configuration.Legacy;
// using Umbraco.Core.Configuration.HealthChecks;
// using Umbraco.Core.Configuration.Legacy;
// using Umbraco.Core.Configuration.UmbracoSettings;
//
// namespace Umbraco.Core.Configuration
// {
// public class ConfigsFactory : IConfigsFactory
// {
// public IHostingSettings HostingSettings { get; } = new HostingSettings();
// public ICoreDebugSettings CoreDebugSettings { get; } = new CoreDebugSettings();
// public IIndexCreatorSettings IndexCreatorSettings { get; } = new IndexCreatorSettings();
// public INuCacheSettings NuCacheSettings { get; } = new NuCacheSettings();
// public ITypeFinderSettings TypeFinderSettings { get; } = new TypeFinderSettings();
// public IRuntimeSettings RuntimeSettings { get; } = new RuntimeSettings();
// public IActiveDirectorySettings ActiveDirectorySettings { get; } = new ActiveDirectorySettings();
// public IExceptionFilterSettings ExceptionFilterSettings { get; } = new ExceptionFilterSettings();
// public ITourSettings TourSettings { get; } = new TourSettings();
// public ILoggingSettings LoggingSettings { get; } = new LoggingSettings();
// public IKeepAliveSettings KeepAliveSettings { get; } = new KeepAliveSettings();
// public IWebRoutingSettings WebRoutingSettings { get; } = new WebRoutingSettings();
// public IRequestHandlerSettings RequestHandlerSettings { get; } = new RequestHandlerSettings();
// public ISecuritySettings SecuritySettings { get; } = new SecuritySettings();
// public IUserPasswordConfiguration UserPasswordConfigurationSettings { get; } = new UserPasswordConfigurationSettings();
// public IMemberPasswordConfiguration MemberPasswordConfigurationSettings { get; } = new MemberPasswordConfigurationSettings();
// public IContentSettings ContentSettings { get; } = new ContentSettings();
// public IGlobalSettings GlobalSettings { get; } = new GlobalSettings();
// public IHealthChecksSettings HealthChecksSettings { get; } = new HealthChecksSettings();
// public IConnectionStrings ConnectionStrings { get; } = new ConnectionStrings();
// public IModelsBuilderConfig ModelsBuilderConfig { get; } = new ModelsBuilderConfig();
//
// public Configs Create()
// {
// var configs = new Configs();
//
// configs.Add<IGlobalSettings>(() => GlobalSettings);
// configs.Add<IHostingSettings>(() => HostingSettings);
// configs.Add<IHealthChecksSettings>(() => HealthChecksSettings);
// configs.Add<ICoreDebugSettings>(() => CoreDebugSettings);
// configs.Add<IConnectionStrings>(() => ConnectionStrings);
// configs.Add<IModelsBuilderConfig>(() => ModelsBuilderConfig);
// configs.Add<IIndexCreatorSettings>(() => IndexCreatorSettings);
// configs.Add<INuCacheSettings>(() => NuCacheSettings);
// configs.Add<ITypeFinderSettings>(() => TypeFinderSettings);
// configs.Add<IRuntimeSettings>(() => RuntimeSettings);
// configs.Add<IActiveDirectorySettings>(() => ActiveDirectorySettings);
// configs.Add<IExceptionFilterSettings>(() => ExceptionFilterSettings);
// configs.Add<ITourSettings>(() => TourSettings);
// configs.Add<ILoggingSettings>(() => LoggingSettings);
// configs.Add<IKeepAliveSettings>(() => KeepAliveSettings);
// configs.Add<IWebRoutingSettings>(() => WebRoutingSettings);
// configs.Add<IRequestHandlerSettings>(() => RequestHandlerSettings);
// configs.Add<ISecuritySettings>(() => SecuritySettings);
// configs.Add<IUserPasswordConfiguration>(() => UserPasswordConfigurationSettings);
// configs.Add<IMemberPasswordConfiguration>(() => MemberPasswordConfigurationSettings);
// configs.Add<IContentSettings>(() => ContentSettings);
//
// return configs;
// }
// }
// }

View File

@@ -1,65 +0,0 @@
using System;
using System.Collections.Generic;
using Umbraco.Core.Composing;
namespace Umbraco.Core.Configuration
{
/// <summary>
/// Represents Umbraco configurations.
/// </summary>
/// <remarks>
/// <para>During composition, use composition.Configs. When running, either inject the required configuration,
/// or use Current.Configs.</para>
/// </remarks>
public class Configs
{
private readonly Dictionary<Type, Lazy<object>> _configs = new Dictionary<Type, Lazy<object>>();
private Dictionary<Type, Action<IRegister>> _registerings = new Dictionary<Type, Action<IRegister>>();
/// <summary>
/// Gets a configuration.
/// </summary>
public TConfig GetConfig<TConfig>()
where TConfig : class
{
if (!_configs.TryGetValue(typeof(TConfig), out var configFactory))
throw new InvalidOperationException($"No configuration of type {typeof(TConfig)} has been added.");
return (TConfig) configFactory.Value;
}
/// <summary>
/// Adds a configuration, provided by a factory.
/// </summary>
public void Add<TConfig>(Func<TConfig> configFactory)
where TConfig : class
{
// make sure it is not too late
if (_registerings == null)
throw new InvalidOperationException("Configurations have already been registered.");
var typeOfConfig = typeof(TConfig);
var lazyConfigFactory = _configs[typeOfConfig] = new Lazy<object>(configFactory);
_registerings[typeOfConfig] = register => register.Register(_ => (TConfig) lazyConfigFactory.Value, Lifetime.Singleton);
}
/// <summary>
/// Registers configurations in a register.
/// </summary>
public void RegisterWith(IRegister register)
{
// do it only once
if (_registerings == null)
throw new InvalidOperationException("Configurations have already been registered.");
register.Register(this);
foreach (var registering in _registerings.Values)
registering(register);
// no need to keep them around
_registerings = null;
}
}
}

View File

@@ -1,28 +0,0 @@
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Grid;
using Umbraco.Core.Configuration.HealthChecks;
using Umbraco.Core.Configuration.UmbracoSettings;
namespace Umbraco.Core
{
/// <summary>
/// Provides extension methods for the <see cref="Configs"/> class.
/// </summary>
public static class ConfigsExtensions
{
public static IGlobalSettings Global(this Configs configs)
=> configs.GetConfig<IGlobalSettings>();
public static IConnectionStrings ConnectionStrings(this Configs configs)
=> configs.GetConfig<IConnectionStrings>();
public static ISecuritySettings Security(this Configs configs)
=> configs.GetConfig<ISecuritySettings>();
public static IWebRoutingSettings WebRouting(this Configs configs)
=> configs.GetConfig<IWebRoutingSettings>();
}
}

View File

@@ -1,10 +0,0 @@
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
namespace Umbraco.Core.Configuration
{
public interface IConfigsFactory
{
Configs Create();
}
}

View File

@@ -6,6 +6,8 @@ using Lucene.Net.Store;
using System.IO;
using System;
using Examine.LuceneEngine.Directories;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration.Models;
namespace Umbraco.Examine
{
@@ -14,13 +16,13 @@ namespace Umbraco.Examine
{
private readonly ITypeFinder _typeFinder;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IIndexCreatorSettings _settings;
private readonly IndexCreatorSettings _settings;
public LuceneFileSystemDirectoryFactory(ITypeFinder typeFinder, IHostingEnvironment hostingEnvironment, IIndexCreatorSettings settings)
public LuceneFileSystemDirectoryFactory(ITypeFinder typeFinder, IHostingEnvironment hostingEnvironment, IOptions<IndexCreatorSettings> settings)
{
_typeFinder = typeFinder;
_hostingEnvironment = hostingEnvironment;
_settings = settings;
_settings = settings.Value;
}
public Lucene.Net.Store.Directory CreateDirectory(string indexName) => CreateFileSystemLuceneDirectory(indexName);

View File

@@ -88,8 +88,8 @@ namespace Umbraco.Core.Composing
// after cross wiring, configure "Current"
Current.Initialize(
_container.GetInstance<Umbraco.Core.Logging.ILogger>(),
_container.GetInstance<SecuritySettings>(),
_container.GetInstance<GlobalSettings>(),
_container.GetInstance<IOptions<SecuritySettings>>().Value,
_container.GetInstance<IOptions<GlobalSettings>>().Value,
_container.GetInstance<IIOHelper>(),
_container.GetInstance<Umbraco.Core.Hosting.IHostingEnvironment>(),
_container.GetInstance<IBackOfficeInfo>(),

View File

@@ -1,19 +0,0 @@
using Umbraco.Core.Configuration;
namespace Umbraco.ModelsBuilder.Embedded
{
/// <summary>
/// Provides extension methods for the <see cref="Configs"/> class.
/// </summary>
public static class ConfigsExtensions
{
/// <summary>
/// Gets the models builder configuration.
/// </summary>
/// <remarks>Getting the models builder configuration freezes its state,
/// and any attempt at modifying the configuration using the Setup method
/// will be ignored.</remarks>
public static IModelsBuilderConfig ModelsBuilder(this Configs configs)
=> configs.GetConfig<IModelsBuilderConfig>();
}
}

View File

@@ -58,7 +58,6 @@
<Compile Include="Building\TextHeaderWriter.cs" />
<Compile Include="Building\TypeModel.cs" />
<Compile Include="Compose\DisabledModelsBuilderComponent.cs" />
<Compile Include="ConfigsExtensions.cs" />
<Compile Include="BackOffice\DashboardReport.cs" />
<Compile Include="ImplementPropertyTypeAttribute.cs" />
<Compile Include="ModelsBuilderAssemblyAttribute.cs" />

View File

@@ -46,11 +46,11 @@ namespace Umbraco.Tests.Common
return new TypeLoader(Mock.Of<ITypeFinder>(), Mock.Of<IAppPolicyCache>(), new DirectoryInfo(IOHelper.MapPath("~/App_Data/TEMP")), Mock.Of<IProfilingLogger>());
}
public Configs GetConfigs() => GetConfigsFactory().Create();
// public Configs GetConfigs() => GetConfigsFactory().Create();
public abstract IBackOfficeInfo GetBackOfficeInfo();
public IConfigsFactory GetConfigsFactory() => new ConfigsFactory();
//public IConfigsFactory GetConfigsFactory() => new ConfigsFactory();
/// <summary>
/// Gets the working directory of the test project.

View File

@@ -25,7 +25,6 @@ namespace Umbraco.Tests.Components
private static readonly List<Type> Composed = new List<Type>();
private static readonly List<Type> Initialized = new List<Type>();
private static readonly List<Type> Terminated = new List<Type>();
private static readonly Configs Configs = TestHelper.GetConfigs();
private static IFactory MockFactory(Action<Mock<IFactory>> setup = null)
{

View File

@@ -33,9 +33,9 @@ namespace Umbraco.Tests.Models
Current.Reset();
var configs = TestHelper.GetConfigs();
configs.Add(() => SettingsForTests.DefaultGlobalSettings);
configs.Add(SettingsForTests.GenerateMockContentSettings);
// var configs = TestHelper.GetConfigs();
// configs.Add(() => SettingsForTests.DefaultGlobalSettings);
// configs.Add(SettingsForTests.GenerateMockContentSettings);
_factory = Mock.Of<IFactory>();
@@ -65,7 +65,7 @@ namespace Umbraco.Tests.Models
.Setup(x => x.GetInstance(It.IsAny<Type>()))
.Returns<Type>(x =>
{
if (x == typeof(Configs)) return configs;
//if (x == typeof(Configs)) return configs;
if (x == typeof(PropertyEditorCollection)) return propertyEditors;
if (x == typeof(ServiceContext)) return serviceContext;
if (x == typeof(ILocalizedTextService)) return serviceContext.LocalizationService;

View File

@@ -2,6 +2,7 @@
using System.Linq;
using System.Web.Mvc;
using System.Web.Routing;
using Microsoft.Extensions.Options;
using Moq;
using NUnit.Framework;
using Umbraco.Core;
@@ -153,7 +154,7 @@ namespace Umbraco.Tests.Routing
var handler = new RenderRouteHandler(umbracoContext, new TestControllerFactory(umbracoContextAccessor, Mock.Of<ILogger>(), context =>
{
return new CustomDocumentController(Factory.GetInstance<IGlobalSettings>(),
return new CustomDocumentController(Factory.GetInstance<IOptions<GlobalSettings>>(),
umbracoContextAccessor,
Factory.GetInstance<ServiceContext>(),
Factory.GetInstance<AppCaches>(),
@@ -194,7 +195,7 @@ namespace Umbraco.Tests.Routing
/// </summary>
public class CustomDocumentController : RenderMvcController
{
public CustomDocumentController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
public CustomDocumentController(IOptions<GlobalSettings> globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
: base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger)
{
}

View File

@@ -100,15 +100,6 @@ namespace Umbraco.Tests.Runtimes
private static readonly IContentSettings _contentSettings = SettingsForTests.GenerateMockContentSettings();
private static readonly IWebRoutingSettings _settings = SettingsForTests.GenerateMockWebRoutingSettings();
private static Configs GetConfigs()
{
var configs = new ConfigsFactory().Create();
configs.Add(() => _globalSettings);
configs.Add(() => _contentSettings);
configs.Add(() => _hostingSettings);
return configs;
}
public IRuntime Runtime { get; private set; }
protected override IRuntime GetRuntime(GlobalSettings globalSettings, ConnectionStrings connectionStrings, IUmbracoVersion umbracoVersion, IIOHelper ioHelper, ILogger logger, IProfiler profiler, IHostingEnvironment hostingEnvironment, IBackOfficeInfo backOfficeInfo)

View File

@@ -76,7 +76,6 @@ namespace Umbraco.Tests.Runtimes
var umbracoVersion = TestHelper.GetUmbracoVersion();
var backOfficeInfo = TestHelper.GetBackOfficeInfo();
var runtimeState = new RuntimeState(globalSettings, umbracoVersion, databaseFactory, logger);
var configs = TestHelper.GetConfigs();
var variationContextAccessor = TestHelper.VariationContextAccessor;
// create the register and the composition
@@ -285,7 +284,6 @@ namespace Umbraco.Tests.Runtimes
Mock.Get(runtimeState).Setup(x => x.Level).Returns(RuntimeLevel.Run);
var mainDom = Mock.Of<IMainDom>();
Mock.Get(mainDom).Setup(x => x.IsMainDom).Returns(true);
var configs = TestHelper.GetConfigs();
// create the register and the composition
var register = TestHelper.GetRegister();

View File

@@ -78,11 +78,11 @@ namespace Umbraco.Tests.TestHelpers
public static TypeLoader GetMockedTypeLoader() => _testHelperInternal.GetMockedTypeLoader();
public static Configs GetConfigs() => _testHelperInternal.GetConfigs();
//public static Configs GetConfigs() => _testHelperInternal.GetConfigs();
public static IBackOfficeInfo GetBackOfficeInfo() => _testHelperInternal.GetBackOfficeInfo();
public static IConfigsFactory GetConfigsFactory() => _testHelperInternal.GetConfigsFactory();
// public static IConfigsFactory GetConfigsFactory() => _testHelperInternal.GetConfigsFactory();
/// <summary>
/// Gets the working directory of the test project.

View File

@@ -191,7 +191,7 @@ namespace Umbraco.Tests.Testing
Composition = new Composition(register, typeLoader, proflogger, ComponentTests.MockRuntimeState(RuntimeLevel.Run), TestHelper.IOHelper, AppCaches.NoCache);
TestHelper.GetConfigs().RegisterWith(register);
//TestHelper.GetConfigs().RegisterWith(register);
Composition.RegisterUnique(IOHelper);

View File

@@ -30,7 +30,8 @@ using Constants = Umbraco.Core.Constants;
namespace Umbraco.Web.BackOffice.Controllers
{
//[UmbracoRequireHttps] //TODO Reintroduce
[DisableBrowserCache]
[PluginController(Constants.Web.Mvc.BackOfficeArea)]
public class BackOfficeController : Controller
{
@@ -80,7 +81,7 @@ namespace Umbraco.Web.BackOffice.Controllers
{
var viewPath = Path.Combine(_globalSettings.UmbracoPath , Constants.Web.Mvc.BackOfficeArea, nameof(Default) + ".cshtml")
.Replace("\\", "/"); // convert to forward slashes since it's a virtual path
return await RenderDefaultOrProcessExternalLoginAsync(
() => View(viewPath),
() => View(viewPath));

View File

@@ -18,7 +18,7 @@ namespace Umbraco.Web.BackOffice.Controllers
[UmbracoAuthorize]
[DisableBrowserCache]
[UmbracoWebApiRequireHttps]
//[CheckIfUserTicketDataIsStale] //TODO reintroduce
[CheckIfUserTicketDataIsStale]
//[UnhandedExceptionLoggerConfiguration] //TODO reintroduce
//[EnableDetailedErrors] //TODO reintroduce
public abstract class UmbracoAuthorizedApiController : UmbracoApiController

View File

@@ -0,0 +1,155 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Claims;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Umbraco.Core;
using Umbraco.Core.BackOffice;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Services;
using Umbraco.Extensions;
using Umbraco.Web.BackOffice.Security;
using Umbraco.Web.Common.Security;
namespace Umbraco.Web.BackOffice.Filters
{
internal sealed class CheckIfUserTicketDataIsStaleAttribute : TypeFilterAttribute
{
public CheckIfUserTicketDataIsStaleAttribute() : base(typeof(CheckIfUserTicketDataIsStaleFilter))
{
}
private class CheckIfUserTicketDataIsStaleFilter : IAsyncActionFilter
{
private readonly IRequestCache _requestCache;
private readonly UmbracoMapper _umbracoMapper;
private readonly IUserService _userService;
private readonly IEntityService _entityService;
private readonly ILocalizedTextService _localizedTextService;
private readonly IOptions<GlobalSettings> _globalSettings;
private readonly BackOfficeSignInManager _backOfficeSignInManager;
private readonly IBackOfficeAntiforgery _backOfficeAntiforgery;
public CheckIfUserTicketDataIsStaleFilter(
IRequestCache requestCache,
UmbracoMapper umbracoMapper,
IUserService userService,
IEntityService entityService,
ILocalizedTextService localizedTextService,
IOptions<GlobalSettings> globalSettings,
BackOfficeSignInManager backOfficeSignInManager,
IBackOfficeAntiforgery backOfficeAntiforgery)
{
_requestCache = requestCache;
_umbracoMapper = umbracoMapper;
_userService = userService;
_entityService = entityService;
_localizedTextService = localizedTextService;
_globalSettings = globalSettings;
_backOfficeSignInManager = backOfficeSignInManager;
_backOfficeAntiforgery = backOfficeAntiforgery;
}
public async Task OnActionExecutionAsync(ActionExecutingContext actionContext, ActionExecutionDelegate next)
{
await CheckStaleData(actionContext);
await next();
await CheckStaleData(actionContext);
//we need new tokens and append the custom header if changes have been made
if (!(_requestCache.Get(nameof(CheckIfUserTicketDataIsStaleFilter)) is null))
return;
var tokenFilter =
new SetAngularAntiForgeryTokensAttribute.SetAngularAntiForgeryTokensFilter(_backOfficeAntiforgery,
_globalSettings);
await tokenFilter.OnActionExecutionAsync(actionContext, () => Task.FromResult(new ActionExecutedContext(actionContext, new List<IFilterMetadata>(), null)));
//add the header
AppendUserModifiedHeaderAttribute.AppendHeader(actionContext);
}
private async Task CheckStaleData(ActionExecutingContext actionContext)
{
if (actionContext == null
|| actionContext.HttpContext.Request == null
|| actionContext.HttpContext.User == null
|| actionContext.HttpContext.User.Identity == null)
{
return;
}
//don't execute if it's already been done
if (!(_requestCache.Get(nameof(CheckIfUserTicketDataIsStaleFilter)) is null))
return;
var identity = actionContext.HttpContext.User.Identity as UmbracoBackOfficeIdentity;
if (identity == null) return;
var userId = identity.Id.TryConvertTo<int>();
if (userId == false) return;
var user = _userService.GetUserById(userId.Result);
if (user == null) return;
//a list of checks to execute, if any of them pass then we resync
var checks = new Func<bool>[]
{
() => user.Username != identity.Username,
() =>
{
var culture = user.GetUserCulture(_localizedTextService, _globalSettings.Value);
return culture != null && culture.ToString() != identity.Culture;
},
() => user.AllowedSections.UnsortedSequenceEqual(identity.AllowedApplications) == false,
() => user.Groups.Select(x => x.Alias).UnsortedSequenceEqual(identity.Roles) == false,
() =>
{
var startContentIds = user.CalculateContentStartNodeIds(_entityService);
return startContentIds.UnsortedSequenceEqual(identity.StartContentNodes) == false;
},
() =>
{
var startMediaIds = user.CalculateMediaStartNodeIds(_entityService);
return startMediaIds.UnsortedSequenceEqual(identity.StartMediaNodes) == false;
}
};
if (checks.Any(check => check()))
{
await ReSync(user, actionContext);
}
}
/// <summary>
/// This will update the current request IPrincipal to be correct and re-create the auth ticket
/// </summary>
/// <param name="user"></param>
/// <param name="actionContext"></param>
/// <returns></returns>
private async Task ReSync(IUser user, ActionExecutingContext actionContext)
{
var backOfficeIdentityUser = _umbracoMapper.Map<BackOfficeIdentityUser>(user);
await _backOfficeSignInManager.SignInAsync(backOfficeIdentityUser, isPersistent: true);
//ensure the remainder of the request has the correct principal set
actionContext.HttpContext.SetPrincipalForRequest(ClaimsPrincipal.Current);
//flag that we've made changes
_requestCache.Set(nameof(CheckIfUserTicketDataIsStaleFilter), true);
}
}
}
}

View File

@@ -18,7 +18,7 @@ namespace Umbraco.Extensions
{
}
private class SetAngularAntiForgeryTokensFilter : IAsyncActionFilter
internal class SetAngularAntiForgeryTokensFilter : IAsyncActionFilter
{
private readonly IBackOfficeAntiforgery _antiforgery;
private readonly GlobalSettings _globalSettings;
@@ -55,24 +55,31 @@ namespace Umbraco.Extensions
//We need to set 2 cookies: one is the cookie value that angular will use to set a header value on each request,
// the 2nd is the validation value generated by the anti-forgery helper that we use to validate the header token against.
context.HttpContext.Response.Cookies.Append(
Constants.Web.AngularCookieName, headerToken,
new Microsoft.AspNetCore.Http.CookieOptions
{
Path = "/",
//must be js readable
HttpOnly = false,
Secure = _globalSettings.UseHttps
});
if (!(headerToken is null))
{
context.HttpContext.Response.Cookies.Append(
Constants.Web.AngularCookieName, headerToken,
new Microsoft.AspNetCore.Http.CookieOptions
{
Path = "/",
//must be js readable
HttpOnly = false,
Secure = _globalSettings.UseHttps
});
}
if (!(cookieToken is null))
{
context.HttpContext.Response.Cookies.Append(
Constants.Web.CsrfValidationCookieName, cookieToken,
new Microsoft.AspNetCore.Http.CookieOptions
{
Path = "/",
HttpOnly = true,
Secure = _globalSettings.UseHttps
});
}
context.HttpContext.Response.Cookies.Append(
Constants.Web.CsrfValidationCookieName, cookieToken,
new Microsoft.AspNetCore.Http.CookieOptions
{
Path = "/",
HttpOnly = true,
Secure = _globalSettings.UseHttps
});
}
}

View File

@@ -1,6 +1,5 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Umbraco.Core.Exceptions;
using Umbraco.Web.Common.Exceptions;
namespace Umbraco.Web.Common.Filters

View File

@@ -25,7 +25,7 @@ namespace Umbraco.Web.Common.Filters
public void OnException(ExceptionContext filterContext)
{
if (filterContext.Exception != null)
if (filterContext.Exception != null && !filterContext.ExceptionHandled)
{
filterContext.HttpContext.Response.StatusCode = (int) HttpStatusCode.InternalServerError;

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using Microsoft.Extensions.Options;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Web.Routing;
@@ -8,13 +10,13 @@ namespace Umbraco.Web.AspNet
public class AspNetRequestAccessor : IRequestAccessor
{
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IWebRoutingSettings _webRoutingSettings;
private readonly WebRoutingSettings _webRoutingSettings;
private readonly ISet<string> _applicationUrls = new HashSet<string>();
private Uri _currentApplicationUrl;
public AspNetRequestAccessor(IHttpContextAccessor httpContextAccessor, IWebRoutingSettings webRoutingSettings)
public AspNetRequestAccessor(IHttpContextAccessor httpContextAccessor, IOptions<WebRoutingSettings> webRoutingSettings)
{
_httpContextAccessor = httpContextAccessor;
_webRoutingSettings = webRoutingSettings;
_webRoutingSettings = webRoutingSettings.Value;
UmbracoModule.EndRequest += OnEndRequest;
UmbracoModule.RouteAttempt += OnRouteAttempt;

View File

@@ -213,8 +213,6 @@ namespace Umbraco.Web.Composing
public static TypeLoader TypeLoader => Factory.GetInstance<TypeLoader>();
public static Configs Configs => Factory.GetInstance<Configs>();
public static UrlSegmentProviderCollection UrlSegmentProviders => Factory.GetInstance<UrlSegmentProviderCollection>();
public static CacheRefresherCollection CacheRefreshers => Factory.GetInstance<CacheRefresherCollection>();

View File

@@ -111,7 +111,7 @@ namespace Umbraco.Web.Editors
/// Used to retrieve the 2FA providers for code submission
/// </summary>
/// <returns></returns>
[SetAngularAntiForgeryTokens]
// [SetAngularAntiForgeryTokens] //TODO reintroduce when migrated to netcore
public async Task<IEnumerable<string>> Get2FAProviders()
{
var userId = await SignInManager.GetVerifiedUserIdAsync();
@@ -127,7 +127,7 @@ namespace Umbraco.Web.Editors
return userFactors;
}
[SetAngularAntiForgeryTokens]
// [SetAngularAntiForgeryTokens] //TODO reintroduce when migrated to netcore
public async Task<IHttpActionResult> PostSend2FACode([FromBody]string provider)
{
if (provider.IsNullOrWhiteSpace())
@@ -148,7 +148,7 @@ namespace Umbraco.Web.Editors
return Ok();
}
[SetAngularAntiForgeryTokens]
// [SetAngularAntiForgeryTokens] //TODO reintroduce when migrated to netcore
public async Task<HttpResponseMessage> PostVerify2FACode(Verify2FACodeModel model)
{
if (ModelState.IsValid == false)

View File

@@ -4,10 +4,12 @@ using System.Threading.Tasks;
using System.Web;
using System.Web.Mvc;
using Microsoft.AspNetCore.Identity;
using Microsoft.Extensions.Options;
using Microsoft.Owin.Security;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Logging;
using Umbraco.Web.Mvc;
using Umbraco.Core.Services;
@@ -40,7 +42,7 @@ namespace Umbraco.Web.Editors
public BackOfficeController(
UmbracoFeatures features,
IGlobalSettings globalSettings,
IOptions<GlobalSettings> globalSettings,
IUmbracoContextAccessor umbracoContextAccessor,
ServiceContext services,
AppCaches appCaches,
@@ -140,7 +142,7 @@ namespace Umbraco.Web.Editors
if (defaultResponse == null) throw new ArgumentNullException("defaultResponse");
if (externalSignInResponse == null) throw new ArgumentNullException("externalSignInResponse");
ViewData.SetUmbracoPath(ConfigModelConversionsFromLegacy.ConvertGlobalSettings(GlobalSettings).GetUmbracoMvcArea(_hostingEnvironment));
ViewData.SetUmbracoPath(GlobalSettings.Value.GetUmbracoMvcArea(_hostingEnvironment));
//check if there is the TempData with the any token name specified, if so, assign to view bag and render the view
if (ViewData.FromTempData(TempData, ViewDataExtensions.TokenExternalSignInError) ||
@@ -254,8 +256,7 @@ namespace Umbraco.Web.Editors
var groups = Services.UserService.GetUserGroupsByAlias(autoLinkOptions.GetDefaultUserGroups(UmbracoContext, loginInfo));
var autoLinkUser = BackOfficeIdentityUser.CreateNew(
ConfigModelConversionsFromLegacy.ConvertGlobalSettings(GlobalSettings),
var autoLinkUser = BackOfficeIdentityUser.CreateNew(GlobalSettings.Value,
loginInfo.Email,
loginInfo.Email,
autoLinkOptions.GetDefaultCulture(UmbracoContext, loginInfo));

View File

@@ -1,7 +1,9 @@
using System;
using System.Web.Mvc;
using Microsoft.Extensions.Options;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Logging;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
@@ -25,7 +27,7 @@ namespace Umbraco.Web.Mvc
ActionInvoker = new RenderActionInvoker();
}
public RenderMvcController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
public RenderMvcController(IOptions<GlobalSettings> globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
: base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger)
{
ActionInvoker = new RenderActionInvoker();

View File

@@ -1,29 +0,0 @@
using System.Net;
using System.Web.Mvc;
using Umbraco.Core;
using Umbraco.Web.Composing;
namespace Umbraco.Web.Mvc
{
/// <summary>
/// Forces the response to have a specific http status code
/// </summary>
/// Migrated already to .Net Core
internal class StatusCodeResultAttribute : ActionFilterAttribute
{
private readonly HttpStatusCode _statusCode;
public StatusCodeResultAttribute(HttpStatusCode statusCode)
{
_statusCode = statusCode;
}
public override void OnActionExecuted(ActionExecutedContext filterContext)
{
base.OnActionExecuted(filterContext);
filterContext.HttpContext.Response.StatusCode = (int)_statusCode;
filterContext.HttpContext.Response.TrySkipIisCustomErrors = Current.Configs.WebRouting().TrySkipIisCustomErrors;
}
}
}

View File

@@ -56,7 +56,7 @@ namespace Umbraco.Web.Mvc
{
if (redirectToUmbracoLogin)
{
_redirectUrl = ConfigModelConversionsFromLegacy.ConvertGlobalSettings(Current.Configs.Global()).GetBackOfficePath(Current.HostingEnvironment).EnsureStartsWith("~");
_redirectUrl = ConfigModelConversionsFromLegacy.ConvertGlobalSettings(/*Current.Configs.Global()*/ null).GetBackOfficePath(Current.HostingEnvironment).EnsureStartsWith("~");
}
}

View File

@@ -1,5 +1,7 @@
using Umbraco.Core.Cache;
using Microsoft.Extensions.Options;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
@@ -21,7 +23,7 @@ namespace Umbraco.Web.Mvc
{
}
protected UmbracoAuthorizedController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
protected UmbracoAuthorizedController(IOptions<GlobalSettings> globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
: base(globalSettings, umbracoContextAccessor, services, appCaches, profilingLogger)
{
}

View File

@@ -1,12 +1,14 @@
using System;
using System.Web;
using System.Web.Mvc;
using Microsoft.Extensions.Options;
using Microsoft.Owin;
using Umbraco.Core.Cache;
using Umbraco.Web.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Logging;
using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Services;
using Umbraco.Web.Security;
@@ -23,7 +25,7 @@ namespace Umbraco.Web.Mvc
/// <summary>
/// Gets or sets the Umbraco context.
/// </summary>
public IGlobalSettings GlobalSettings { get; }
public IOptions<GlobalSettings> GlobalSettings { get; }
/// <summary>
/// Gets the Umbraco context.
@@ -69,7 +71,7 @@ namespace Umbraco.Web.Mvc
protected UmbracoController()
: this(
Current.Factory.GetInstance<IGlobalSettings>(),
Current.Factory.GetInstance<IOptions<GlobalSettings>>(),
Current.Factory.GetInstance<IUmbracoContextAccessor>(),
Current.Factory.GetInstance<ServiceContext>(),
Current.Factory.GetInstance<AppCaches>(),
@@ -78,7 +80,7 @@ namespace Umbraco.Web.Mvc
{
}
protected UmbracoController(IGlobalSettings globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
protected UmbracoController(IOptions<GlobalSettings> globalSettings, IUmbracoContextAccessor umbracoContextAccessor, ServiceContext services, AppCaches appCaches, IProfilingLogger profilingLogger)
{
GlobalSettings = globalSettings;
UmbracoContextAccessor = umbracoContextAccessor;

View File

@@ -16,7 +16,7 @@ namespace Umbraco.Web.Mvc
protected override void HandleNonHttpsRequest(AuthorizationContext filterContext)
{
// If Umbraco.Core.UseHttps is set, let base method handle redirect. Otherwise, we don't care.
if (Current.Configs.Global().UseHttps)
if (/*Current.Configs.Global().UseHttps*/ false)
{
base.HandleNonHttpsRequest(filterContext);
}
@@ -29,7 +29,7 @@ namespace Umbraco.Web.Mvc
public override void OnAuthorization(AuthorizationContext filterContext)
{
// If umbracoSSL is set, let base method handle checking for HTTPS. Otherwise, we don't care.
if (Current.Configs.Global().UseHttps)
if (/*Current.Configs.Global().UseHttps*/ false)
{
base.OnAuthorization(filterContext);
}

View File

@@ -3,9 +3,11 @@ using System.Text;
using System.Web;
using System.Web.Mvc;
using System.Web.WebPages;
using Microsoft.Extensions.Options;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Models.PublishedContent;
using Umbraco.Core.Services;
@@ -22,8 +24,8 @@ namespace Umbraco.Web.Mvc
/// </summary>
public abstract class UmbracoViewPage<TModel> : WebViewPage<TModel>
{
private readonly IGlobalSettings _globalSettings;
private readonly IContentSettings _contentSettings;
private readonly GlobalSettings _globalSettings;
private readonly ContentSettings _contentSettings;
private IUmbracoContext _umbracoContext;
private UmbracoHelper _helper;
@@ -105,18 +107,18 @@ namespace Umbraco.Web.Mvc
: this(
Current.Factory.GetInstance<ServiceContext>(),
Current.Factory.GetInstance<AppCaches>(),
Current.Factory.GetInstance<IGlobalSettings>(),
Current.Factory.GetInstance<IContentSettings>()
Current.Factory.GetInstance<IOptions<GlobalSettings>>(),
Current.Factory.GetInstance<IOptions<ContentSettings>>()
)
{
}
protected UmbracoViewPage(ServiceContext services, AppCaches appCaches, IGlobalSettings globalSettings, IContentSettings contentSettings)
protected UmbracoViewPage(ServiceContext services, AppCaches appCaches, IOptions<GlobalSettings> globalSettings, IOptions<ContentSettings> contentSettings)
{
Services = services;
AppCaches = appCaches;
_globalSettings = globalSettings ?? throw new ArgumentNullException(nameof(globalSettings));
_contentSettings = contentSettings ?? throw new ArgumentNullException(nameof(contentSettings));
_globalSettings = globalSettings.Value;
_contentSettings = contentSettings.Value;
}
// view logic below:

View File

@@ -73,8 +73,10 @@ namespace Umbraco.Web
{
return content.IsAllowedTemplate(
Current.Services.ContentTypeService,
Current.Configs.WebRouting().DisableAlternativeTemplates,
/*Current.Configs.WebRouting().DisableAlternativeTemplates,
Current.Configs.WebRouting().ValidateAlternativeTemplates,
TODO*/
false, false,
templateId);
}
@@ -83,8 +85,10 @@ namespace Umbraco.Web
return content.IsAllowedTemplate(
Current.Services.FileService,
Current.Services.ContentTypeService,
Current.Configs.WebRouting().DisableAlternativeTemplates,
Current.Configs.WebRouting().ValidateAlternativeTemplates,
/*Current.Configs.WebRouting().DisableAlternativeTemplates,
Current.Configs.WebRouting().ValidateAlternativeTemplates,
TODO*/
false, false,
templateAlias);
}

View File

@@ -8,6 +8,7 @@ using Owin;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Hosting;
using Umbraco.Web.Composing;
using Constants = Umbraco.Core.Constants;
@@ -68,7 +69,7 @@ namespace Umbraco.Web.Security
CookiePath = "/",
CookieSecure = globalSettings.UseHttps ? CookieSecureOption.Always : CookieSecureOption.SameAsRequest,
CookieHttpOnly = true,
CookieDomain = Current.Configs.Security().AuthCookieDomain
CookieDomain = new SecuritySettings().AuthCookieDomain // TODO inject settings
}, stage);
return app;

View File

@@ -13,6 +13,7 @@ using Microsoft.Owin.Security;
using Newtonsoft.Json;
using Umbraco.Core;
using Umbraco.Core.BackOffice;
using Umbraco.Core.Configuration.Models;
using Umbraco.Extensions;
using Umbraco.Web.Composing;
using Constants = Umbraco.Core.Constants;
@@ -68,7 +69,7 @@ namespace Umbraco.Web.Security
if (ex is FormatException || ex is JsonReaderException)
{
// this will occur if the cookie data is invalid
}
else
{
@@ -104,7 +105,7 @@ namespace Umbraco.Web.Security
/// <summary>
/// This will return the current back office identity.
/// </summary>
/// <param name="http"></param>
/// <param name="http"></param>
/// <returns>
/// Returns the current back office identity if an admin is authenticated otherwise null
/// </returns>
@@ -151,7 +152,7 @@ namespace Umbraco.Web.Security
public static AuthenticationTicket GetUmbracoAuthTicket(this HttpContextBase http)
{
if (http == null) throw new ArgumentNullException(nameof(http));
return GetAuthTicket(http, Current.Configs.Security().AuthCookieName);
return GetAuthTicket(http, /*Current.Configs.Security() TODO*/new SecuritySettings().AuthCookieName);
}
internal static AuthenticationTicket GetUmbracoAuthTicket(this HttpContext http)
@@ -163,7 +164,7 @@ namespace Umbraco.Web.Security
public static AuthenticationTicket GetUmbracoAuthTicket(this IOwinContext ctx)
{
if (ctx == null) throw new ArgumentNullException(nameof(ctx));
return GetAuthTicket(ctx, Current.Configs.Security().AuthCookieName);
return GetAuthTicket(ctx, /*Current.Configs.Security() TODO*/new SecuritySettings().AuthCookieName);
}
private static AuthenticationTicket GetAuthTicket(this IOwinContext owinCtx, string cookieName)
@@ -215,7 +216,7 @@ namespace Umbraco.Web.Security
catch (Exception)
{
// occurs when decryption fails
return null;
}
}
@@ -236,6 +237,6 @@ namespace Umbraco.Web.Security
return secureDataFormat.Unprotect(formsCookie);
}
}
}

View File

@@ -23,7 +23,7 @@ namespace Umbraco.Web.Security
{
_defaultUserGroups = defaultUserGroups ?? new[] { Constants.Security.EditorGroupAlias };
_autoLinkExternalAccount = autoLinkExternalAccount;
_defaultCulture = defaultCulture ?? Current.Configs.Global().DefaultUILanguage;
_defaultCulture = defaultCulture ?? /*Current.Configs.Global().DefaultUILanguage TODO */ "en-US";
}
private readonly string[] _defaultUserGroups;

View File

@@ -176,7 +176,6 @@
<Compile Include="Models\Membership\UmbracoMembershipMember.cs" />
<Compile Include="Mvc\HttpUmbracoFormRouteStringException.cs" />
<Compile Include="Mvc\ModelBindingExceptionFilter.cs" />
<Compile Include="Mvc\StatusCodeFilterAttribute.cs" />
<Compile Include="Mvc\SurfaceControllerTypeCollectionBuilder.cs" />
<Compile Include="Mvc\ValidateUmbracoFormRouteStringAttribute.cs" />
<Compile Include="AspNet\AspNetBackOfficeInfo.cs" />
@@ -244,7 +243,6 @@
<Compile Include="UmbracoModule.cs" />
<Compile Include="WebApi\EnableDetailedErrorsAttribute.cs" />
<Compile Include="WebApi\Filters\AppendUserModifiedHeaderAttribute.cs" />
<Compile Include="WebApi\Filters\CheckIfUserTicketDataIsStaleAttribute.cs" />
<Compile Include="WebApi\Filters\FeatureAuthorizeAttribute.cs" />
<Compile Include="WebApi\SessionHttpControllerRouteHandler.cs" />
<Compile Include="WebApi\UmbracoApiControllerTypeCollectionBuilder.cs" />
@@ -298,7 +296,6 @@
<Compile Include="WebApi\Filters\AngularAntiForgeryHelper.cs" />
<Compile Include="WebApi\Filters\DisableBrowserCacheAttribute.cs" />
<Compile Include="WebApi\Filters\FilterGrouping.cs" />
<Compile Include="WebApi\Filters\SetAngularAntiForgeryTokensAttribute.cs" />
<Compile Include="WebApi\Filters\ValidateAngularAntiForgeryTokenAttribute.cs" />
<Compile Include="WebApi\HttpControllerContextExtensions.cs" />
<Compile Include="Controllers\UmbRegisterController.cs" />

View File

@@ -10,7 +10,9 @@ using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Composing;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Legacy;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Configuration.UmbracoSettings;
using Umbraco.Core.Hosting;
using Umbraco.Core.IO;
using Umbraco.Core.Logging;
@@ -22,6 +24,7 @@ using Umbraco.Web.Hosting;
using Umbraco.Web.Logging;
using ConnectionStrings = Umbraco.Core.Configuration.Models.ConnectionStrings;
using Current = Umbraco.Web.Composing.Current;
using GlobalSettings = Umbraco.Core.Configuration.Models.GlobalSettings;
namespace Umbraco.Web
{
@@ -40,11 +43,12 @@ namespace Umbraco.Web
{
if (!Umbraco.Composing.Current.IsInitialized)
{
var configFactory = new ConfigsFactory();
//var configFactory = new ConfigsFactory();
var hostingSettings = configFactory.HostingSettings;
var globalSettings = configFactory.GlobalSettings;
var securitySettings = configFactory.SecuritySettings;
IHostingSettings hostingSettings = null;
IGlobalSettings globalSettings = null;
ISecuritySettings securitySettings = null;
IWebRoutingSettings webRoutingSettings = null;
var hostingEnvironment = new AspNetHostingEnvironment(hostingSettings);
var loggingConfiguration = new LoggingConfiguration(
@@ -54,10 +58,7 @@ namespace Umbraco.Web
var ioHelper = new IOHelper(hostingEnvironment);
var logger = SerilogLogger.CreateWithDefaultConfiguration(hostingEnvironment, loggingConfiguration);
var configs = configFactory.Create();
var backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, ioHelper, logger, configFactory.WebRoutingSettings);
var backOfficeInfo = new AspNetBackOfficeInfo(globalSettings, ioHelper, logger, webRoutingSettings);
var profiler = GetWebProfiler(hostingEnvironment);
Umbraco.Composing.Current.Initialize(logger,
ConfigModelConversionsFromLegacy.ConvertSecuritySettings(securitySettings),

View File

@@ -75,7 +75,7 @@ namespace Umbraco.Web
else if (pcr.Is404)
{
response.StatusCode = 404;
response.TrySkipIisCustomErrors = Current.Configs.WebRouting().TrySkipIisCustomErrors;
response.TrySkipIisCustomErrors = /*Current.Configs.WebRouting().TrySkipIisCustomErrors; TODO */ false;
if (response.TrySkipIisCustomErrors == false)
logger.Warn<UmbracoModule>("Status code is 404 yet TrySkipIisCustomErrors is false - IIS will take over.");

View File

@@ -6,6 +6,7 @@ using System.Web.Services;
using Umbraco.Core;
using Umbraco.Core.Cache;
using Umbraco.Core.Configuration;
using Umbraco.Core.Configuration.Legacy;
using Umbraco.Core.Logging;
using Umbraco.Core.Persistence;
using Umbraco.Core.Services;
@@ -31,7 +32,7 @@ namespace Umbraco.Web
}
protected UmbracoWebService()
: this(Current.ProfilingLogger, Current.UmbracoContextAccessor, Current.Services, Current.Configs.Global())
: this(Current.ProfilingLogger, Current.UmbracoContextAccessor, Current.Services, new GlobalSettings())
{
}

View File

@@ -1,128 +0,0 @@
using System;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Web.Http.Controllers;
using System.Web.Http.Filters;
using Umbraco.Core;
using Umbraco.Core.BackOffice;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Models.Membership;
using Umbraco.Infrastructure.Configuration;
using Umbraco.Web.Composing;
using Umbraco.Web.Security;
namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// This filter will check if the current Principal/Identity assigned to the request has stale data in it compared
/// to what is persisted for the current user and will update the current auth ticket with the correct data if required and output
/// a custom response header for the UI to be notified of it.
/// </summary>
/// <remarks>
/// This could/should be created as a filter on the BackOfficeCookieAuthenticationProvider just like the SecurityStampValidator does
/// </remarks>
public sealed class CheckIfUserTicketDataIsStaleAttribute : ActionFilterAttribute
{
// this is an attribute - no choice
private UmbracoMapper Mapper => Current.Mapper;
public override async Task OnActionExecutingAsync(HttpActionContext actionContext, CancellationToken cancellationToken)
{
await CheckStaleData(actionContext);
}
public override async Task OnActionExecutedAsync(HttpActionExecutedContext actionExecutedContext, CancellationToken cancellationToken)
{
await CheckStaleData(actionExecutedContext.ActionContext);
//we need new tokens and append the custom header if changes have been made
if (actionExecutedContext.ActionContext.Request.Properties.ContainsKey(typeof(CheckIfUserTicketDataIsStaleAttribute).Name))
{
var tokenFilter = new SetAngularAntiForgeryTokensAttribute();
tokenFilter.OnActionExecuted(actionExecutedContext);
//add the header
AppendUserModifiedHeaderAttribute.AppendHeader(actionExecutedContext);
}
}
private async Task CheckStaleData(HttpActionContext actionContext)
{
if (actionContext == null
|| actionContext.Request == null
|| actionContext.RequestContext == null
|| actionContext.RequestContext.Principal == null
|| actionContext.RequestContext.Principal.Identity == null)
{
return;
}
//don't execute if it's already been done
if (actionContext.Request.Properties.ContainsKey(typeof(CheckIfUserTicketDataIsStaleAttribute).Name))
return;
var identity = actionContext.RequestContext.Principal.Identity as UmbracoBackOfficeIdentity;
if (identity == null) return;
var userId = identity.Id.TryConvertTo<int>();
if (userId == false) return;
var user = Current.Services.UserService.GetUserById(userId.Result);
if (user == null) return;
//a list of checks to execute, if any of them pass then we resync
var checks = new Func<bool>[]
{
() => user.Username != identity.Username,
() =>
{
var culture = user.GetUserCulture(Current.Services.TextService, ConfigModelConversionsFromLegacy.ConvertGlobalSettings(Current.Configs.Global()));
return culture != null && culture.ToString() != identity.Culture;
},
() => user.AllowedSections.UnsortedSequenceEqual(identity.AllowedApplications) == false,
() => user.Groups.Select(x => x.Alias).UnsortedSequenceEqual(identity.Roles) == false,
() =>
{
var startContentIds = user.CalculateContentStartNodeIds(Current.Services.EntityService);
return startContentIds.UnsortedSequenceEqual(identity.StartContentNodes) == false;
},
() =>
{
var startMediaIds = user.CalculateMediaStartNodeIds(Current.Services.EntityService);
return startMediaIds.UnsortedSequenceEqual(identity.StartMediaNodes) == false;
}
};
if (checks.Any(check => check()))
{
await ReSync(user, actionContext);
}
}
/// <summary>
/// This will update the current request IPrincipal to be correct and re-create the auth ticket
/// </summary>
/// <param name="user"></param>
/// <param name="actionContext"></param>
/// <returns></returns>
private async Task ReSync(IUser user, HttpActionContext actionContext)
{
var owinCtx = actionContext.Request.TryGetOwinContext();
if (owinCtx)
{
var signInManager = owinCtx.Result.GetBackOfficeSignInManager();
var backOfficeIdentityUser = Mapper.Map<BackOfficeIdentityUser>(user);
await signInManager.SignInAsync(backOfficeIdentityUser, isPersistent: true, rememberBrowser: false);
//ensure the remainder of the request has the correct principal set
actionContext.Request.SetPrincipalForRequest(owinCtx.Result.Request.User);
//flag that we've made changes
actionContext.Request.Properties[typeof(CheckIfUserTicketDataIsStaleAttribute).Name] = true;
}
}
}
}

View File

@@ -1,59 +0,0 @@
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Http.Filters;
using Umbraco.Core;
using Umbraco.Web.Composing;
namespace Umbraco.Web.WebApi.Filters
{
/// <summary>
/// A filter to set the csrf cookie token based on angular conventions
/// </summary>
public sealed class SetAngularAntiForgeryTokensAttribute : ActionFilterAttribute
{
public override void OnActionExecuted(HttpActionExecutedContext context)
{
if (context.Response == null) return;
//DO not set the token cookies if the request has failed!!
if (context.Response.StatusCode != HttpStatusCode.OK) return;
//don't need to set the cookie if they already exist and they are valid
if (context.Request.Headers.GetCookies(Constants.Web.AngularCookieName).Any()
&& context.Request.Headers.GetCookies(Constants.Web.CsrfValidationCookieName).Any())
{
//if they are not valid for some strange reason - we need to continue setting valid ones
string failedReason;
if (AngularAntiForgeryHelper.ValidateHeaders(context.Request.Headers, out failedReason))
{
return;
}
}
string cookieToken, headerToken;
AngularAntiForgeryHelper.GetTokens(out cookieToken, out headerToken);
//We need to set 2 cookies: one is the cookie value that angular will use to set a header value on each request,
// the 2nd is the validation value generated by the anti-forgery helper that we use to validate the header token against.
var angularCookie = new CookieHeaderValue(Constants.Web.AngularCookieName, headerToken)
{
Path = "/",
//must be js readable
HttpOnly = false,
Secure = Current.Configs.Global().UseHttps
};
var validationCookie = new CookieHeaderValue(Constants.Web.CsrfValidationCookieName, cookieToken)
{
Path = "/",
HttpOnly = true,
Secure = Current.Configs.Global().UseHttps
};
context.Response.Headers.AddCookies(new[] { angularCookie, validationCookie });
}
}
}

View File

@@ -24,7 +24,7 @@ namespace Umbraco.Web.WebApi
[UmbracoAuthorize]
[DisableBrowserCache]
// [UmbracoWebApiRequireHttps]
[CheckIfUserTicketDataIsStale]
// [CheckIfUserTicketDataIsStale]
[UnhandedExceptionLoggerConfiguration]
[EnableDetailedErrors]
public abstract class UmbracoAuthorizedApiController : UmbracoApiController