Moves routing into IAreaRoutes, ensures back office is redirected if installed
This commit is contained in:
@@ -53,6 +53,8 @@
|
||||
public static class Mvc
|
||||
{
|
||||
public const string InstallArea = "UmbracoInstall";
|
||||
|
||||
public const string BackOfficeArea = "UmbracoBackOffice";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,23 +10,22 @@ using Umbraco.Web.WebAssets;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Controllers
|
||||
{
|
||||
[Area(Umbraco.Core.Constants.Web.Mvc.BackOfficeArea)]
|
||||
public class BackOfficeController : Controller
|
||||
{
|
||||
private readonly IRuntimeMinifier _runtimeMinifier;
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
private readonly IUmbracoApplicationLifetime _umbracoApplicationLifetime;
|
||||
|
||||
public BackOfficeController(IRuntimeMinifier runtimeMinifier, IGlobalSettings globalSettings, IHostingEnvironment hostingEnvironment, IUmbracoApplicationLifetime umbracoApplicationLifetime)
|
||||
public BackOfficeController(IRuntimeMinifier runtimeMinifier, IGlobalSettings globalSettings, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_runtimeMinifier = runtimeMinifier;
|
||||
_globalSettings = globalSettings;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
_umbracoApplicationLifetime = umbracoApplicationLifetime;
|
||||
}
|
||||
|
||||
// GET
|
||||
public IActionResult Index()
|
||||
[HttpGet]
|
||||
public IActionResult Default()
|
||||
{
|
||||
return View();
|
||||
}
|
||||
@@ -36,6 +35,7 @@ namespace Umbraco.Web.BackOffice.Controllers
|
||||
/// </summary>
|
||||
/// <returns></returns>
|
||||
[MinifyJavaScriptResult(Order = 0)]
|
||||
[HttpGet]
|
||||
public async Task<IActionResult> Application()
|
||||
{
|
||||
var result = await _runtimeMinifier.GetScriptForLoadingBackOfficeAsync(_globalSettings, _hostingEnvironment);
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using SixLabors.ImageSharp.Web.DependencyInjection;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Web.BackOffice.Routing;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
@@ -15,18 +16,8 @@ namespace Umbraco.Extensions
|
||||
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
// TODO: This is temporary, 'umbraco' cannot be hard coded, needs to use GetUmbracoMvcArea()
|
||||
// but actually we need to route all back office stuff in a back office area like we do in v8
|
||||
|
||||
// TODO: We will also need to detect runtime state here and redirect to the installer,
|
||||
// Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install
|
||||
// when required, example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/
|
||||
|
||||
endpoints.MapControllerRoute("Backoffice", "/umbraco/{Action}", new
|
||||
{
|
||||
Controller = "BackOffice",
|
||||
Action = "Default"
|
||||
});
|
||||
var backOfficeRoutes = app.ApplicationServices.GetRequiredService<BackOfficeAreaRoutes>();
|
||||
backOfficeRoutes.CreateRoutes(endpoints);
|
||||
});
|
||||
|
||||
app.UseUmbracoRuntimeMinification();
|
||||
|
||||
55
src/Umbraco.Web.BackOffice/Routing/BackOfficeAreaRoutes.cs
Normal file
55
src/Umbraco.Web.BackOffice/Routing/BackOfficeAreaRoutes.cs
Normal file
@@ -0,0 +1,55 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Web.BackOffice.Controllers;
|
||||
using Umbraco.Web.Common.Routing;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Routing
|
||||
{
|
||||
public class BackOfficeAreaRoutes : IAreaRoutes
|
||||
{
|
||||
private readonly IGlobalSettings _globalSettings;
|
||||
private readonly IHostingEnvironment _hostingEnvironment;
|
||||
|
||||
public BackOfficeAreaRoutes(IGlobalSettings globalSettings, IHostingEnvironment hostingEnvironment)
|
||||
{
|
||||
_globalSettings = globalSettings;
|
||||
_hostingEnvironment = hostingEnvironment;
|
||||
}
|
||||
|
||||
public void CreateRoutes(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var umbracoPath = _globalSettings.GetUmbracoMvcArea(_hostingEnvironment);
|
||||
|
||||
// TODO: We need to auto-route "Umbraco Api Controllers" for the back office
|
||||
|
||||
// TODO: We will also need to detect runtime state here and redirect to the installer,
|
||||
// Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install
|
||||
// when required, example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/
|
||||
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"Umbraco_back_office", // TODO: Same name as before but we should change these so they have a convention
|
||||
Constants.Web.Mvc.BackOfficeArea,
|
||||
$"{umbracoPath}/{{Action}}/{{id?}}",
|
||||
new { controller = ControllerExtensions.GetControllerName<BackOfficeController>(), action = "Default" },
|
||||
// Limit the action/id to only allow characters - this is so this route doesn't hog all other
|
||||
// routes like: /umbraco/channels/word.aspx, etc...
|
||||
// (Not that we have to worry about too many of those these days, there still might be a need for these constraints).
|
||||
new
|
||||
{
|
||||
action = @"[a-zA-Z]*",
|
||||
id = @"[a-zA-Z]*"
|
||||
});
|
||||
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"Umbraco_preview", // TODO: Same name as before but we should change these so they have a convention
|
||||
Constants.Web.Mvc.BackOfficeArea,
|
||||
$"{umbracoPath}/preview/{{Action}}/{{editor?}}",
|
||||
// TODO: Change this to use ControllerExtensions.GetControllerName once the PreviewController is moved to Umbraco.Web.BackOffice.Controllers
|
||||
new { controller = "Preview", action = "Index" });
|
||||
}
|
||||
}
|
||||
}
|
||||
14
src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs
Normal file
14
src/Umbraco.Web.BackOffice/Runtime/BackOfficeComposer.cs
Normal file
@@ -0,0 +1,14 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
using Umbraco.Web.BackOffice.Routing;
|
||||
|
||||
namespace Umbraco.Web.BackOffice.Runtime
|
||||
{
|
||||
public class BackOfficeComposer : IComposer
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
composition.RegisterUnique<BackOfficeAreaRoutes>();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -10,7 +10,7 @@ namespace Umbraco.Extensions
|
||||
/// </summary>
|
||||
/// <param name="controllerType"></param>
|
||||
/// <returns></returns>
|
||||
internal static string GetControllerName(Type controllerType)
|
||||
public static string GetControllerName(Type controllerType)
|
||||
{
|
||||
if (!controllerType.Name.EndsWith("Controller"))
|
||||
{
|
||||
@@ -24,7 +24,7 @@ namespace Umbraco.Extensions
|
||||
/// </summary>
|
||||
/// <param name="controllerInstance"></param>
|
||||
/// <returns></returns>
|
||||
internal static string GetControllerName(this Controller controllerInstance)
|
||||
public static string GetControllerName(this Controller controllerInstance)
|
||||
{
|
||||
return GetControllerName(controllerInstance.GetType());
|
||||
}
|
||||
@@ -35,7 +35,7 @@ namespace Umbraco.Extensions
|
||||
/// <typeparam name="T"></typeparam>
|
||||
/// <returns></returns>
|
||||
/// <remarks></remarks>
|
||||
internal static string GetControllerName<T>()
|
||||
public static string GetControllerName<T>()
|
||||
{
|
||||
return GetControllerName(typeof(T));
|
||||
}
|
||||
|
||||
32
src/Umbraco.Web.Common/Extensions/LinkGeneratorExtensions.cs
Normal file
32
src/Umbraco.Web.Common/Extensions/LinkGeneratorExtensions.cs
Normal file
@@ -0,0 +1,32 @@
|
||||
using System;
|
||||
using Umbraco.Core;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using System.Reflection;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
public static class LinkGeneratorExtensions
|
||||
{
|
||||
/// <summary>
|
||||
/// Return the back office url if the back office is installed
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetBackOfficeUrl(this LinkGenerator linkGenerator)
|
||||
{
|
||||
|
||||
Type backOfficeControllerType;
|
||||
try
|
||||
{
|
||||
backOfficeControllerType = Assembly.Load("Umbraco.Web.BackOffice")?.GetType("Umbraco.Web.BackOffice.Controllers.BackOfficeController");
|
||||
if (backOfficeControllerType == null) return "/"; // this would indicate that the installer is installed without the back office
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return "/"; // this would indicate that the installer is installed without the back office
|
||||
}
|
||||
|
||||
return linkGenerator.GetPathByAction("Default", ControllerExtensions.GetControllerName(backOfficeControllerType), new { area = Constants.Web.Mvc.BackOfficeArea });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,10 +1,6 @@
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Web;
|
||||
using Umbraco.Web.Common.Install;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
@@ -19,60 +15,14 @@ namespace Umbraco.Extensions
|
||||
{
|
||||
app.UseEndpoints(endpoints =>
|
||||
{
|
||||
var runtime = app.ApplicationServices.GetRequiredService<IRuntimeState>();
|
||||
var logger = app.ApplicationServices.GetRequiredService<ILogger>();
|
||||
var uriUtility = app.ApplicationServices.GetRequiredService<UriUtility>();
|
||||
switch (runtime.Level)
|
||||
{
|
||||
case RuntimeLevel.Install:
|
||||
case RuntimeLevel.Upgrade:
|
||||
|
||||
var installPath = uriUtility.ToAbsolute(Constants.SystemDirectories.Install).EnsureEndsWith('/');
|
||||
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"umbraco-install-api",
|
||||
Umbraco.Core.Constants.Web.Mvc.InstallArea,
|
||||
$"{installPath}api/{{Action}}",
|
||||
new { controller = "InstallApi" });
|
||||
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"umbraco-install",
|
||||
Umbraco.Core.Constants.Web.Mvc.InstallArea,
|
||||
$"{installPath}{{controller}}/{{Action}}",
|
||||
new { controller = "Install", action = "Index" });
|
||||
|
||||
// TODO: Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install,
|
||||
// example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/
|
||||
|
||||
// register catch all because if we are in install/upgrade mode then we'll catch everything and redirect
|
||||
endpoints.MapGet("{*url}", context =>
|
||||
{
|
||||
var uri = context.Request.GetEncodedUrl();
|
||||
// redirect to install
|
||||
ReportRuntime(logger, runtime.Level, "Umbraco must install or upgrade.");
|
||||
|
||||
var installUrl = $"{installPath}?redir=true&url={uri}";
|
||||
context.Response.Redirect(installUrl, false);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
break;
|
||||
}
|
||||
var backOfficeRoutes = app.ApplicationServices.GetRequiredService<InstallAreaRoutes>();
|
||||
backOfficeRoutes.CreateRoutes(endpoints);
|
||||
});
|
||||
|
||||
return app;
|
||||
}
|
||||
|
||||
private static bool _reported;
|
||||
private static RuntimeLevel _reportedLevel;
|
||||
|
||||
private static void ReportRuntime(ILogger logger, RuntimeLevel level, string message)
|
||||
{
|
||||
if (_reported && _reportedLevel == level) return;
|
||||
_reported = true;
|
||||
_reportedLevel = level;
|
||||
logger.Warn(typeof(UmbracoInstallApplicationBuilderExtensions), message);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,14 +4,39 @@ using System.Linq.Expressions;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Web.Common.Controllers;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Web.WebApi;
|
||||
using Microsoft.AspNetCore.Mvc.Routing;
|
||||
using Umbraco.Web.Common.Install;
|
||||
|
||||
namespace Umbraco.Extensions
|
||||
{
|
||||
public static class HttpUrlHelperExtensions
|
||||
|
||||
public static class UrlHelperExtensions
|
||||
{
|
||||
|
||||
/// <summary>
|
||||
/// Return the back office url if the back office is installed
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetBackOfficeUrl(this IUrlHelper url)
|
||||
{
|
||||
var backOfficeControllerType = Type.GetType("Umbraco.Web.BackOffice.Controllers");
|
||||
if (backOfficeControllerType == null) return "/"; // this would indicate that the installer is installed without the back office
|
||||
return url.Action("Default", ControllerExtensions.GetControllerName(backOfficeControllerType), new { area = Constants.Web.Mvc.BackOfficeArea });
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the installer API url
|
||||
/// </summary>
|
||||
/// <param name="url"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetInstallerApiUrl(this IUrlHelper url)
|
||||
{
|
||||
// there is no default action here so we need to get it by action and trim the action
|
||||
return url.Action("GetSetup", ControllerExtensions.GetControllerName<InstallApiController>(), new { area = Constants.Web.Mvc.InstallArea })
|
||||
.TrimEnd("GetSetup");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Return the Url for a Web Api service
|
||||
/// </summary>
|
||||
@@ -1,55 +0,0 @@
|
||||
using System;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Web.Install
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures authorization occurs for the installer if it has already completed.
|
||||
/// If install has not yet occurred then the authorization is successful.
|
||||
/// </summary>
|
||||
public class HttpInstallAuthorizeAttribute : TypeFilterAttribute
|
||||
{
|
||||
public HttpInstallAuthorizeAttribute() : base(typeof(HttpInstallAuthorizeFilter))
|
||||
{
|
||||
}
|
||||
|
||||
private class HttpInstallAuthorizeFilter : IAuthorizationFilter
|
||||
{
|
||||
public void OnAuthorization(AuthorizationFilterContext authorizationFilterContext)
|
||||
{
|
||||
var serviceProvider = authorizationFilterContext.HttpContext.RequestServices;
|
||||
var runtimeState = serviceProvider.GetService<IRuntimeState>();
|
||||
var umbracoContext = serviceProvider.GetService<IUmbracoContext>();
|
||||
var logger = serviceProvider.GetService<ILogger>();
|
||||
|
||||
if (!IsAllowed(runtimeState, umbracoContext, logger))
|
||||
{
|
||||
authorizationFilterContext.Result = new ForbidResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private static bool IsAllowed(IRuntimeState runtimeState, IUmbracoContext umbracoContext, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
// if not configured (install or upgrade) then we can continue
|
||||
// otherwise we need to ensure that a user is logged in
|
||||
return runtimeState.Level == RuntimeLevel.Install
|
||||
|| runtimeState.Level == RuntimeLevel.Upgrade
|
||||
|| (umbracoContext?.Security?.ValidateCurrentUser() ?? false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error<HttpInstallAuthorizeAttribute>(ex, "An error occurred determining authorization");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -23,7 +23,7 @@ namespace Umbraco.Web.Common.Install
|
||||
[UmbracoApiController]
|
||||
[TypeFilter(typeof(HttpResponseExceptionFilter))]
|
||||
[TypeFilter(typeof(AngularJsonOnlyConfigurationAttribute))]
|
||||
[HttpInstallAuthorize]
|
||||
[Web.Install.InstallAuthorize]
|
||||
[Area(Umbraco.Core.Constants.Web.Mvc.InstallArea)]
|
||||
public class InstallApiController : ControllerBase
|
||||
{
|
||||
|
||||
93
src/Umbraco.Web.Common/Install/InstallAreaRoutes.cs
Normal file
93
src/Umbraco.Web.Common/Install/InstallAreaRoutes.cs
Normal file
@@ -0,0 +1,93 @@
|
||||
using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.AspNetCore.Http.Extensions;
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
using System.Threading.Tasks;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Logging;
|
||||
using Umbraco.Extensions;
|
||||
using Umbraco.Web.Common.Routing;
|
||||
|
||||
namespace Umbraco.Web.Common.Install
|
||||
{
|
||||
|
||||
public class InstallAreaRoutes : IAreaRoutes
|
||||
{
|
||||
private readonly IRuntimeState _runtime;
|
||||
private readonly ILogger _logger;
|
||||
private readonly UriUtility _uriUtility;
|
||||
private readonly LinkGenerator _linkGenerator;
|
||||
|
||||
public InstallAreaRoutes(IRuntimeState runtime, ILogger logger, UriUtility uriUtility, LinkGenerator linkGenerator)
|
||||
{
|
||||
_runtime = runtime;
|
||||
_logger = logger;
|
||||
_uriUtility = uriUtility;
|
||||
_linkGenerator = linkGenerator;
|
||||
}
|
||||
|
||||
public void CreateRoutes(IEndpointRouteBuilder endpoints)
|
||||
{
|
||||
var installPath = _uriUtility.ToAbsolute(Umbraco.Core.Constants.SystemDirectories.Install).EnsureEndsWith('/');
|
||||
|
||||
switch (_runtime.Level)
|
||||
{
|
||||
case RuntimeLevel.Install:
|
||||
case RuntimeLevel.Upgrade:
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"umbraco-install-api",
|
||||
Umbraco.Core.Constants.Web.Mvc.InstallArea,
|
||||
$"{installPath}api/{{Action}}",
|
||||
new { controller = ControllerExtensions.GetControllerName<InstallApiController>() });
|
||||
|
||||
endpoints.MapAreaControllerRoute(
|
||||
"umbraco-install",
|
||||
Umbraco.Core.Constants.Web.Mvc.InstallArea,
|
||||
$"{installPath}{{controller}}/{{Action}}",
|
||||
new { controller = ControllerExtensions.GetControllerName<InstallController>(), action = "Index" });
|
||||
|
||||
// TODO: Potentially switch this to dynamic routing so we can essentially disable/overwrite the back office routes to redirect to install,
|
||||
// example https://www.strathweb.com/2019/08/dynamic-controller-routing-in-asp-net-core-3-0/
|
||||
|
||||
// register catch all because if we are in install/upgrade mode then we'll catch everything and redirect
|
||||
endpoints.MapGet("{*url}", context =>
|
||||
{
|
||||
var uri = context.Request.GetEncodedUrl();
|
||||
// redirect to install
|
||||
ReportRuntime(_logger, _runtime.Level, "Umbraco must install or upgrade.");
|
||||
|
||||
var installUrl = $"{installPath}?redir=true&url={uri}";
|
||||
context.Response.Redirect(installUrl, false);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
break;
|
||||
case RuntimeLevel.Run:
|
||||
|
||||
// when we are in run mode redirect to the back office if the installer endpoint is hit
|
||||
endpoints.MapGet($"{installPath}{{controller?}}/{{Action?}}", context =>
|
||||
{
|
||||
// redirect to umbraco
|
||||
context.Response.Redirect(_linkGenerator.GetBackOfficeUrl(), false);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
break;
|
||||
case RuntimeLevel.BootFailed:
|
||||
case RuntimeLevel.Unknown:
|
||||
case RuntimeLevel.Boot:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
private static bool _reported;
|
||||
private static RuntimeLevel _reportedLevel;
|
||||
|
||||
private static void ReportRuntime(ILogger logger, RuntimeLevel level, string message)
|
||||
{
|
||||
if (_reported && _reportedLevel == level) return;
|
||||
_reported = true;
|
||||
_reportedLevel = level;
|
||||
logger.Warn(typeof(UmbracoInstallApplicationBuilderExtensions), message);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,34 +3,37 @@ using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Filters;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Configuration;
|
||||
using Umbraco.Core.Hosting;
|
||||
using Umbraco.Core.Logging;
|
||||
|
||||
namespace Umbraco.Web.Common.Install
|
||||
namespace Umbraco.Web.Install
|
||||
{
|
||||
/// <summary>
|
||||
/// Ensures authorization occurs for the installer if it has already completed.
|
||||
/// If install has not yet occurred then the authorization is successful.
|
||||
/// </summary>
|
||||
public class InstallAuthorizeAttribute : TypeFilterAttribute
|
||||
{
|
||||
public InstallAuthorizeAttribute() : base(typeof(InstallAuthorizeFilter))
|
||||
public InstallAuthorizeAttribute() : base(typeof(HttpInstallAuthorizeFilter))
|
||||
{
|
||||
}
|
||||
|
||||
private class InstallAuthorizeFilter : IAuthorizationFilter
|
||||
private class HttpInstallAuthorizeFilter : IAuthorizationFilter
|
||||
{
|
||||
public void OnAuthorization(AuthorizationFilterContext context)
|
||||
public void OnAuthorization(AuthorizationFilterContext authorizationFilterContext)
|
||||
{
|
||||
var sp = context.HttpContext.RequestServices;
|
||||
var runtimeState = sp.GetRequiredService<IRuntimeState>();
|
||||
var umbracoContextAccessor = sp.GetRequiredService<IUmbracoContextAccessor>();
|
||||
var globalSettings = sp.GetRequiredService<IGlobalSettings>();
|
||||
var hostingEnvironment = sp.GetRequiredService<IHostingEnvironment>();
|
||||
var serviceProvider = authorizationFilterContext.HttpContext.RequestServices;
|
||||
var runtimeState = serviceProvider.GetService<IRuntimeState>();
|
||||
var umbracoContext = serviceProvider.GetService<IUmbracoContext>();
|
||||
var logger = serviceProvider.GetService<ILogger>();
|
||||
|
||||
if (!IsAllowed(runtimeState, umbracoContextAccessor))
|
||||
if (!IsAllowed(runtimeState, umbracoContext, logger))
|
||||
{
|
||||
context.Result = new RedirectResult(globalSettings.GetBackOfficePath(hostingEnvironment));
|
||||
authorizationFilterContext.Result = new ForbidResult();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private bool IsAllowed(IRuntimeState runtimeState, IUmbracoContextAccessor umbracoContextAccessor)
|
||||
private static bool IsAllowed(IRuntimeState runtimeState, IUmbracoContext umbracoContext, ILogger logger)
|
||||
{
|
||||
try
|
||||
{
|
||||
@@ -38,13 +41,15 @@ namespace Umbraco.Web.Common.Install
|
||||
// otherwise we need to ensure that a user is logged in
|
||||
return runtimeState.Level == RuntimeLevel.Install
|
||||
|| runtimeState.Level == RuntimeLevel.Upgrade
|
||||
|| umbracoContextAccessor.UmbracoContext.Security.ValidateCurrentUser();
|
||||
|| (umbracoContext?.Security?.ValidateCurrentUser() ?? false);
|
||||
}
|
||||
catch (Exception)
|
||||
catch (Exception ex)
|
||||
{
|
||||
logger.Error<InstallAuthorizeAttribute>(ex, "An error occurred determining authorization");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -51,8 +51,10 @@ namespace Umbraco.Web.Common.Install
|
||||
[TypeFilter(typeof(StatusCodeResultAttribute), Arguments = new object []{System.Net.HttpStatusCode.ServiceUnavailable})]
|
||||
public async Task<ActionResult> Index()
|
||||
{
|
||||
var umbracoPath = Url.GetBackOfficeUrl();
|
||||
|
||||
if (_runtime.Level == RuntimeLevel.Run)
|
||||
return Redirect(_globalSettings.UmbracoPath.EnsureEndsWith('/'));
|
||||
return Redirect(umbracoPath);
|
||||
|
||||
if (_runtime.Level == RuntimeLevel.Upgrade)
|
||||
{
|
||||
@@ -69,8 +71,8 @@ namespace Umbraco.Web.Common.Install
|
||||
}
|
||||
}
|
||||
|
||||
// gen the install base urlAddUmbracoCore
|
||||
ViewData.SetInstallApiBaseUrl(Url.GetUmbracoApiService("GetSetup", "InstallApi", Umbraco.Core.Constants.Web.Mvc.InstallArea).TrimEnd("GetSetup"));
|
||||
// gen the install base url
|
||||
ViewData.SetInstallApiBaseUrl(Url.GetInstallerApiUrl());
|
||||
|
||||
// get the base umbraco folder
|
||||
ViewData.SetUmbracoBaseFolder(_hostingEnvironment.ToAbsolute(_globalSettings.UmbracoPath));
|
||||
|
||||
13
src/Umbraco.Web.Common/Install/InstallerComposer.cs
Normal file
13
src/Umbraco.Web.Common/Install/InstallerComposer.cs
Normal file
@@ -0,0 +1,13 @@
|
||||
using Umbraco.Core;
|
||||
using Umbraco.Core.Composing;
|
||||
|
||||
namespace Umbraco.Web.Common.Install
|
||||
{
|
||||
public class InstallerComposer : IComposer
|
||||
{
|
||||
public void Compose(Composition composition)
|
||||
{
|
||||
composition.RegisterUnique<InstallAreaRoutes>();
|
||||
}
|
||||
}
|
||||
}
|
||||
16
src/Umbraco.Web.Common/Routing/IAreaRoutes.cs
Normal file
16
src/Umbraco.Web.Common/Routing/IAreaRoutes.cs
Normal file
@@ -0,0 +1,16 @@
|
||||
using Microsoft.AspNetCore.Routing;
|
||||
|
||||
namespace Umbraco.Web.Common.Routing
|
||||
{
|
||||
/// <summary>
|
||||
/// Used to create routes for a route area
|
||||
/// </summary>
|
||||
public interface IAreaRoutes
|
||||
{
|
||||
// TODO: It could be possible to just get all collections of IAreaRoutes and route them all instead of relying
|
||||
// on individual ext methods. This would reduce the amount of code in Startup, but could also mean there's less control over startup
|
||||
// if someone wanted that. Maybe we can just have both.
|
||||
|
||||
void CreateRoutes(IEndpointRouteBuilder endpoints);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
@{
|
||||
Layout = null;
|
||||
}
|
||||
<!doctype html>
|
||||
<html lang="en">
|
||||
<head>
|
||||
|
||||
</head>
|
||||
|
||||
<body>
|
||||
|
||||
<h1>Hello!</h1>
|
||||
|
||||
<p>TODO: Import the default.cshtml back office page</p>
|
||||
|
||||
</body>
|
||||
</html>
|
||||
Reference in New Issue
Block a user