Maintenance page when in upgrade state (#13551)

* Added functionality to show maintenance page and fixed issues with showing custom api controllers and 404 page, when umbraco had been in install or upgrade state

* Fixed Tests

* Fixed typo

* Fixed issue with login screen redirecting to website when in upgrade state, instead of backoffice
This commit is contained in:
Bjarke Berg
2022-12-14 08:14:19 +01:00
committed by GitHub
parent fd7778320a
commit 2d564a11b9
12 changed files with 217 additions and 29 deletions

View File

@@ -0,0 +1,27 @@
using System.Net;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Core.Web;
namespace Umbraco.Cms.Web.Common.ActionsResults;
/// <summary>
/// Returns the Umbraco maintenance result
/// </summary>
public class MaintenanceResult : IActionResult
{
/// <inheritdoc />
public async Task ExecuteResultAsync(ActionContext context)
{
HttpResponse response = context.HttpContext.Response;
response.Clear();
response.StatusCode = StatusCodes.Status503ServiceUnavailable;
var viewResult = new ViewResult { ViewName = "~/umbraco/UmbracoWebsite/Maintenance.cshtml" };
await viewResult.ExecuteResultAsync(context);
}
}

View File

@@ -3,7 +3,11 @@ using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.Features;
using Microsoft.AspNetCore.Mvc.Controllers;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.DependencyInjection;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Features;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.DependencyInjection;
namespace Umbraco.Cms.Web.Common.Authorization;
@@ -13,8 +17,20 @@ namespace Umbraco.Cms.Web.Common.Authorization;
public class FeatureAuthorizeHandler : AuthorizationHandler<FeatureAuthorizeRequirement>
{
private readonly UmbracoFeatures _umbracoFeatures;
private readonly IRuntimeState _runtimeState;
public FeatureAuthorizeHandler(UmbracoFeatures umbracoFeatures) => _umbracoFeatures = umbracoFeatures;
public FeatureAuthorizeHandler(UmbracoFeatures umbracoFeatures, IRuntimeState runtimeState)
{
_umbracoFeatures = umbracoFeatures;
_runtimeState = runtimeState;
}
[Obsolete("Use ctor that is not obsolete. This will be removed in v13.")]
public FeatureAuthorizeHandler(UmbracoFeatures umbracoFeatures)
:this(umbracoFeatures, StaticServiceProvider.Instance.GetRequiredService<IRuntimeState>())
{
}
protected override Task HandleRequirementAsync(
AuthorizationHandlerContext context,
@@ -35,6 +51,11 @@ public class FeatureAuthorizeHandler : AuthorizationHandler<FeatureAuthorizeRequ
private bool? IsAllowed(AuthorizationHandlerContext context)
{
if(_runtimeState.Level != RuntimeLevel.Run && _runtimeState.Level != RuntimeLevel.Upgrade)
{
return false;
}
Endpoint? endpoint = null;
switch (context.Resource)

View File

@@ -0,0 +1,42 @@
using Microsoft.AspNetCore.Mvc;
using Microsoft.AspNetCore.Mvc.Filters;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.ActionsResults;
namespace Umbraco.Cms.Web.Common.Controllers;
internal sealed class MaintenanceModeActionFilterAttribute : TypeFilterAttribute
{
public MaintenanceModeActionFilterAttribute() : base(typeof(MaintenanceModeActionFilter))
{
}
private sealed class MaintenanceModeActionFilter : IActionFilter
{
private readonly IRuntimeState _runtimeState;
private readonly IOptionsMonitor<GlobalSettings> _globalSettings;
public MaintenanceModeActionFilter(IRuntimeState runtimeState, IOptionsMonitor<GlobalSettings> globalSettings)
{
_runtimeState = runtimeState;
_globalSettings = globalSettings;
}
public void OnActionExecuting(ActionExecutingContext context)
{
if (_runtimeState.Level == RuntimeLevel.Upgrade && _globalSettings.CurrentValue.ShowMaintenancePageWhenInUpgradeState)
{
context.Result = new MaintenanceResult();
}
}
public void OnActionExecuted(ActionExecutedContext context)
{
}
}
}

View File

@@ -16,6 +16,7 @@ namespace Umbraco.Cms.Web.Common.Controllers;
/// </summary>
[ModelBindingException]
[PublishedRequestFilter]
[MaintenanceModeActionFilter]
public class RenderController : UmbracoPageController, IRenderController
{
private readonly ILogger<RenderController> _logger;

View File

@@ -216,7 +216,8 @@ public class UmbracoRequestMiddleware : IMiddleware
if (_umbracoRequestPaths.IsBackOfficeRequest(absPath)
|| (absPath.Value?.InvariantStartsWith($"/{_smidgeOptions.UrlOptions.CompositeFilePath}") ?? false)
|| (absPath.Value?.InvariantStartsWith($"/{_smidgeOptions.UrlOptions.BundleFilePath}") ?? false))
|| (absPath.Value?.InvariantStartsWith($"/{_smidgeOptions.UrlOptions.BundleFilePath}") ?? false)
|| _runtimeState.EnableInstaller())
{
LazyInitializer.EnsureInitialized(ref s_firstBackOfficeRequest, ref s_firstBackOfficeReqestFlag,
ref s_firstBackOfficeRequestLocker, () =>