Merge branch 'netcore/feature/simplify-config' into netcore/feature/aspnetcore-config

This commit is contained in:
Bjarke Berg
2020-03-17 14:10:06 +01:00
21 changed files with 67 additions and 87 deletions

View File

@@ -1,46 +0,0 @@
using System;
using Umbraco.Core.IO;
namespace Umbraco.Core.Configuration
{
public static class GlobalSettingsExtensions
{
private static string _mvcArea;
/// <summary>
/// This returns the string of the MVC Area route.
/// </summary>
/// <remarks>
/// This will return the MVC area that we will route all custom routes through like surface controllers, etc...
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
///
/// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something
/// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco".
/// </remarks>
public static string GetUmbracoMvcArea(this IGlobalSettings globalSettings, IIOHelper ioHelper)
{
if (_mvcArea != null) return _mvcArea;
_mvcArea = GetUmbracoMvcAreaNoCache(globalSettings, ioHelper);
return _mvcArea;
}
//TODO Move to IOHelper
internal static string GetUmbracoMvcAreaNoCache(this IGlobalSettings globalSettings, IIOHelper ioHelper)
{
if (ioHelper.BackOfficePath.IsNullOrWhiteSpace())
{
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
}
var path = ioHelper.BackOfficePath;
if (path.StartsWith(ioHelper.Root)) // beware of TrimStart, see U4-2518
path = path.Substring(ioHelper.Root.Length);
return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
}
}
}

View File

@@ -5,6 +5,8 @@ namespace Umbraco.Core.IO
{
public static class IOHelperExtensions
{
private static string _mvcArea;
/// <summary>
/// Tries to create a directory.
/// </summary>
@@ -35,5 +37,38 @@ namespace Umbraco.Core.IO
{
return "umbraco-test." + Guid.NewGuid().ToString("N").Substring(0, 8);
}
/// <summary>
/// This returns the string of the MVC Area route.
/// </summary>
/// <remarks>
/// This will return the MVC area that we will route all custom routes through like surface controllers, etc...
/// We will use the 'Path' (default ~/umbraco) to create it but since it cannot contain '/' and people may specify a path of ~/asdf/asdf/admin
/// we will convert the '/' to '-' and use that as the path. its a bit lame but will work.
///
/// We also make sure that the virtual directory (SystemDirectories.Root) is stripped off first, otherwise we'd end up with something
/// like "MyVirtualDirectory-Umbraco" instead of just "Umbraco".
/// </remarks>
public static string GetUmbracoMvcArea(this IIOHelper ioHelper)
{
if (_mvcArea != null) return _mvcArea;
_mvcArea = GetUmbracoMvcAreaNoCache(ioHelper);
return _mvcArea;
}
internal static string GetUmbracoMvcAreaNoCache(this IIOHelper ioHelper)
{
if (ioHelper.BackOfficePath.IsNullOrWhiteSpace())
{
throw new InvalidOperationException("Cannot create an MVC Area path without the umbracoPath specified");
}
var path = ioHelper.BackOfficePath;
if (path.StartsWith(ioHelper.Root)) // beware of TrimStart, see U4-2518
path = path.Substring(ioHelper.Root.Length);
return path.TrimStart('~').TrimStart('/').Replace('/', '-').Trim().ToLower();
}
}
}

View File

@@ -40,7 +40,7 @@ namespace Umbraco.Core
/// But if we've got this far we'll just have to assume it's front-end anyways.
///
/// </remarks>
internal static bool IsBackOfficeRequest(this Uri url, string applicationPath, IGlobalSettings globalSettings, IIOHelper ioHelper)
internal static bool IsBackOfficeRequest(this Uri url, string applicationPath, IIOHelper ioHelper)
{
applicationPath = applicationPath ?? string.Empty;
@@ -53,7 +53,7 @@ namespace Umbraco.Core
//if not, then def not back office
if (isUmbracoPath == false) return false;
var mvcArea = globalSettings.GetUmbracoMvcArea(ioHelper);
var mvcArea = ioHelper.GetUmbracoMvcArea();
//if its the normal /umbraco path
if (urlPath.InvariantEquals("/" + mvcArea)
|| urlPath.InvariantEquals("/" + mvcArea + "/"))

View File

@@ -39,7 +39,7 @@ namespace Umbraco.Tests.Configurations
globalSettingsMock.Setup(x => x.Path).Returns(() => path);
ioHelper.Root = rootPath;
Assert.AreEqual(outcome, globalSettings.GetUmbracoMvcAreaNoCache(ioHelper));
Assert.AreEqual(outcome, ioHelper.GetUmbracoMvcAreaNoCache());
}

View File

@@ -47,9 +47,8 @@ namespace Umbraco.Tests.CoreThings
{
var ioHelper = TestHelper.IOHelper;
ioHelper.Root = virtualPath;
var globalConfig = SettingsForTests.GenerateMockGlobalSettings();
var source = new Uri(input);
Assert.AreEqual(expected, source.IsBackOfficeRequest(virtualPath, globalConfig, ioHelper));
Assert.AreEqual(expected, source.IsBackOfficeRequest(virtualPath, ioHelper));
}
[TestCase("http://www.domain.com/install", true)]

View File

@@ -42,7 +42,7 @@ namespace Umbraco.Tests.Security
var runtime = Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Install);
var mgr = new BackOfficeCookieManager(
Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbracoContext), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache);
Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbracoContext), runtime, IOHelper, AppCaches.RequestCache);
var result = mgr.ShouldAuthenticateRequest(Mock.Of<IOwinContext>(), new Uri("http://localhost/umbraco"));
@@ -65,7 +65,7 @@ namespace Umbraco.Tests.Security
new AspNetCookieManager(httpContextAccessor));
var runtime = Mock.Of<IRuntimeState>(x => x.Level == RuntimeLevel.Run);
var mgr = new BackOfficeCookieManager(Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbCtx), runtime, TestObjects.GetGlobalSettings(), IOHelper, AppCaches.RequestCache);
var mgr = new BackOfficeCookieManager(Mock.Of<IUmbracoContextAccessor>(accessor => accessor.UmbracoContext == umbCtx), runtime, IOHelper, AppCaches.RequestCache);
var request = new Mock<OwinRequest>();
request.Setup(owinRequest => owinRequest.Uri).Returns(new Uri("http://localhost/umbraco"));

View File

@@ -43,11 +43,10 @@ namespace Umbraco.Web
/// Configures SignalR.
/// </summary>
/// <param name="app">The app builder.</param>
/// <param name="globalSettings"></param>
/// <param name="ioHelper"></param>
public static IAppBuilder UseSignalR(this IAppBuilder app, IGlobalSettings globalSettings, IIOHelper ioHelper)
public static IAppBuilder UseSignalR(this IAppBuilder app, IIOHelper ioHelper)
{
var umbracoPath = globalSettings.GetUmbracoMvcArea(ioHelper);
var umbracoPath = ioHelper.GetUmbracoMvcArea();
var signalrPath = HttpRuntime.AppDomainAppVirtualPath + umbracoPath + "/BackOffice/signalr";
return app.MapSignalR(signalrPath, new HubConfiguration { EnableDetailedErrors = true });
}

View File

@@ -534,7 +534,7 @@ namespace Umbraco.Web.Editors
var action = urlHelper.Action("ValidatePasswordResetCode", "BackOffice",
new
{
area = GlobalSettings.GetUmbracoMvcArea(_ioHelper),
area = _ioHelper.GetUmbracoMvcArea(),
u = userId,
r = code
});

View File

@@ -389,7 +389,7 @@ namespace Umbraco.Web.Editors
if (defaultResponse == null) throw new ArgumentNullException("defaultResponse");
if (externalSignInResponse == null) throw new ArgumentNullException("externalSignInResponse");
ViewData.SetUmbracoPath(GlobalSettings.GetUmbracoMvcArea(_ioHelper));
ViewData.SetUmbracoPath(_ioHelper.GetUmbracoMvcArea());
//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) ||

View File

@@ -487,7 +487,7 @@ namespace Umbraco.Web.Editors
var action = urlHelper.Action("VerifyInvite", "BackOffice",
new
{
area = GlobalSettings.GetUmbracoMvcArea(_ioHelper),
area = _ioHelper.GetUmbracoMvcArea(),
invite = inviteToken
});

View File

@@ -19,7 +19,7 @@ namespace Umbraco.Web.Mvc
/// Creates a custom individual route for the specified controller plugin. Individual routes
/// are required by controller plugins to map to a unique URL based on ID.
/// </summary>
/// <param name="globalSettings"></param>
/// <param name="ioHelper"></param>
/// <param name="controllerName"></param>
/// <param name="controllerType"></param>
/// <param name="routes">An existing route collection</param>
@@ -42,7 +42,6 @@ namespace Umbraco.Web.Mvc
/// <remarks>
/// </remarks>
internal static Route RouteControllerPlugin(this AreaRegistration area,
IGlobalSettings globalSettings,
IIOHelper ioHelper,
string controllerName, Type controllerType, RouteCollection routes,
string controllerSuffixName, string defaultAction, object defaultId,
@@ -59,7 +58,7 @@ namespace Umbraco.Web.Mvc
if (routes == null) throw new ArgumentNullException(nameof(routes));
if (defaultId == null) throw new ArgumentNullException(nameof(defaultId));
var umbracoArea = globalSettings.GetUmbracoMvcArea(ioHelper);
var umbracoArea = ioHelper.GetUmbracoMvcArea();
//routes are explicitly named with controller names and IDs
var url = umbracoArea + "/" +

View File

@@ -11,12 +11,10 @@ namespace Umbraco.Web.Mvc
/// </summary>
internal class BackOfficeArea : AreaRegistration
{
private readonly IGlobalSettings _globalSettings;
private readonly IIOHelper _ioHelper;
public BackOfficeArea(IGlobalSettings globalSettings, IIOHelper ioHelper)
public BackOfficeArea(IIOHelper ioHelper)
{
_globalSettings = globalSettings;
_ioHelper = ioHelper;
}
@@ -51,6 +49,6 @@ namespace Umbraco.Web.Mvc
new[] {typeof (BackOfficeController).Namespace});
}
public override string AreaName => _globalSettings.GetUmbracoMvcArea(_ioHelper);
public override string AreaName => _ioHelper.GetUmbracoMvcArea();
}
}

View File

@@ -77,7 +77,7 @@ namespace Umbraco.Web.Mvc
{
foreach (var s in surfaceControllers)
{
var route = this.RouteControllerPlugin(_globalSettings, _ioHelper, s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface");
var route = this.RouteControllerPlugin(_ioHelper, s.ControllerName, s.ControllerType, routes, "", "Index", UrlParameter.Optional, "surface");
//set the route handler to our SurfaceRouteHandler
route.RouteHandler = new SurfaceRouteHandler();
}
@@ -92,7 +92,7 @@ namespace Umbraco.Web.Mvc
{
foreach (var s in apiControllers)
{
this.RouteControllerPlugin(_globalSettings, _ioHelper, s.ControllerName, s.ControllerType, routes, "", "", UrlParameter.Optional, "api",
this.RouteControllerPlugin(_ioHelper, s.ControllerName, s.ControllerType, routes, "", "", UrlParameter.Optional, "api",
isMvc: false,
areaPathPrefix: s.IsBackOffice ? "backoffice" : null);
}

View File

@@ -172,7 +172,7 @@ namespace Umbraco.Web.Runtime
UmbracoApiControllerTypeCollection apiControllerTypes,
IIOHelper ioHelper)
{
var umbracoPath = globalSettings.GetUmbracoMvcArea(ioHelper);
var umbracoPath = ioHelper.GetUmbracoMvcArea();
// create the front-end route
var defaultRoute = RouteTable.Routes.MapRoute(
@@ -189,7 +189,7 @@ namespace Umbraco.Web.Runtime
RouteTable.Routes.RegisterArea<UmbracoInstallArea>();
// register all back office routes
RouteTable.Routes.RegisterArea(new BackOfficeArea(globalSettings, ioHelper));
RouteTable.Routes.RegisterArea(new BackOfficeArea(ioHelper));
// plugin controllers must come first because the next route will catch many things
RoutePluginControllers(globalSettings, surfaceControllerTypes, apiControllerTypes, ioHelper);
@@ -209,7 +209,7 @@ namespace Umbraco.Web.Runtime
UmbracoApiControllerTypeCollection apiControllerTypes,
IIOHelper ioHelper)
{
var umbracoPath = globalSettings.GetUmbracoMvcArea(ioHelper);
var umbracoPath = ioHelper.GetUmbracoMvcArea();
// need to find the plugin controllers and route them
var pluginControllers = surfaceControllerTypes.Concat(apiControllerTypes).ToArray();

View File

@@ -345,7 +345,7 @@ namespace Umbraco.Web.Security
CookieName = Constants.Security.BackOfficeExternalCookieName,
ExpireTimeSpan = TimeSpan.FromMinutes(5),
//Custom cookie manager so we can filter requests
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache),
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, ioHelper, requestCache),
CookiePath = "/",
CookieSecure = globalSettings.UseHttps ? CookieSecureOption.Always : CookieSecureOption.SameAsRequest,
CookieHttpOnly = true,
@@ -397,7 +397,7 @@ namespace Umbraco.Web.Security
if (runtimeState.Level != RuntimeLevel.Run) return app;
var authOptions = app.CreateUmbracoCookieAuthOptions(umbracoContextAccessor, globalSettings, runtimeState, securitySettings, ioHelper, requestCache);
app.Use(typeof(PreviewAuthenticationMiddleware), authOptions, Current.Configs.Global(), ioHelper);
app.Use(typeof(PreviewAuthenticationMiddleware), authOptions, ioHelper);
// This middleware must execute at least on PostAuthentication, by default it is on Authorize
// The middleware needs to execute after the RoleManagerModule executes which is during PostAuthenticate,

View File

@@ -23,21 +23,19 @@ namespace Umbraco.Web.Security
{
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
private readonly IRuntimeState _runtime;
private readonly IGlobalSettings _globalSettings;
private readonly IIOHelper _ioHelper;
private readonly IRequestCache _requestCache;
private readonly string[] _explicitPaths;
private readonly string _getRemainingSecondsPath;
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache)
: this(umbracoContextAccessor, runtime, globalSettings, ioHelper,requestCache, null)
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IIOHelper ioHelper, IRequestCache requestCache)
: this(umbracoContextAccessor, runtime, ioHelper,requestCache, null)
{ }
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IGlobalSettings globalSettings, IIOHelper ioHelper, IRequestCache requestCache, IEnumerable<string> explicitPaths)
public BackOfficeCookieManager(IUmbracoContextAccessor umbracoContextAccessor, IRuntimeState runtime, IIOHelper ioHelper, IRequestCache requestCache, IEnumerable<string> explicitPaths)
{
_umbracoContextAccessor = umbracoContextAccessor;
_runtime = runtime;
_globalSettings = globalSettings;
_ioHelper = ioHelper;
_requestCache = requestCache;
_explicitPaths = explicitPaths?.ToArray();
@@ -105,7 +103,7 @@ namespace Umbraco.Web.Security
(checkForceAuthTokens && owinContext.Get<bool?>(Constants.Security.ForceReAuthFlag) != null)
|| (checkForceAuthTokens && _requestCache.IsAvailable && _requestCache.Get(Constants.Security.ForceReAuthFlag) != null)
//check back office
|| request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper)
|| request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _ioHelper)
//check installer
|| request.Uri.IsInstallerRequest(_ioHelper))
{

View File

@@ -12,7 +12,6 @@ namespace Umbraco.Web.Security
internal class PreviewAuthenticationMiddleware : OwinMiddleware
{
private readonly UmbracoBackOfficeCookieAuthOptions _cookieOptions;
private readonly IGlobalSettings _globalSettings;
private readonly IIOHelper _ioHelper;
/// <summary>
@@ -22,10 +21,9 @@ namespace Umbraco.Web.Security
/// <param name="cookieOptions"></param>
/// <param name="globalSettings"></param>
public PreviewAuthenticationMiddleware(OwinMiddleware next,
UmbracoBackOfficeCookieAuthOptions cookieOptions, IGlobalSettings globalSettings, IIOHelper ioHelper) : base(next)
UmbracoBackOfficeCookieAuthOptions cookieOptions, IIOHelper ioHelper) : base(next)
{
_cookieOptions = cookieOptions;
_globalSettings = globalSettings;
_ioHelper = ioHelper;
}
@@ -43,7 +41,7 @@ namespace Umbraco.Web.Security
var isPreview = request.HasPreviewCookie()
&& claimsPrincipal != null
&& request.Uri != null
&& request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper) == false;
&& request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _ioHelper) == false;
if (isPreview)
{
//If we've gotten this far it means a preview cookie has been set and a front-end umbraco document request is executing.

View File

@@ -31,7 +31,7 @@ namespace Umbraco.Web.Security
public static async Task ValidateSessionAsync(TimeSpan validateInterval, CookieValidateIdentityContext context, IGlobalSettings globalSettings, IIOHelper ioHelper)
{
if (context.Request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, globalSettings, ioHelper) == false)
if (context.Request.Uri.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, ioHelper) == false)
return;
var valid = await ValidateSessionAsync(validateInterval, context.OwinContext, context.Options.CookieManager, context.Options.SystemClock, context.Properties.IssuedUtc, context.Identity, globalSettings);

View File

@@ -42,7 +42,7 @@ namespace Umbraco.Web.Security
TicketDataFormat = new UmbracoSecureDataFormat(LoginTimeoutMinutes, secureDataFormat1);
//Custom cookie manager so we can filter requests
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, globalSettings, ioHelper, requestCache, explicitPaths);
CookieManager = new BackOfficeCookieManager(umbracoContextAccessor, runtimeState, ioHelper, requestCache, explicitPaths);
}
/// <summary>

View File

@@ -184,7 +184,7 @@ namespace Umbraco.Web
{
var request = GetRequestFromContext();
if (request?.Url != null
&& request.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _globalSettings, _ioHelper) == false
&& request.Url.IsBackOfficeRequest(HttpRuntime.AppDomainAppVirtualPath, _ioHelper) == false
&& Security.CurrentUser != null)
{
var previewToken = _cookieManager.GetPreviewCookieValue(); // may be null or empty

View File

@@ -76,7 +76,7 @@ namespace Umbraco.Web
ConfigureUmbracoAuthentication(app);
app
.UseSignalR(GlobalSettings, IOHelper)
.UseSignalR(IOHelper)
.FinalizeMiddlewareConfiguration();
}