v14: Merge NewBackOfficeSettings into SecuritySettings. (#15586)
* Merge NewBackOfficeSettings into SecuritySettings. * Apply suggestions from code review Co-authored-by: Kenn Jacobsen <kja@umbraco.dk> * Remove hardcoded callback path --------- Co-authored-by: Kenn Jacobsen <kja@umbraco.dk>
This commit is contained in:
@@ -2,8 +2,8 @@ using Microsoft.AspNetCore.Builder;
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.Configuration;
|
||||
using Umbraco.Cms.Web.Common.ApplicationBuilder;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.DependencyInjection;
|
||||
@@ -12,10 +12,9 @@ internal static class BackOfficeCorsPolicyBuilderExtensions
|
||||
{
|
||||
internal static IUmbracoBuilder AddCorsPolicy(this IUmbracoBuilder builder)
|
||||
{
|
||||
// FIXME: Get the correct settings once NewBackOfficeSettings is merged with relevant existing settings from Core
|
||||
Uri? backOfficeHost = builder.Config
|
||||
.GetSection($"{Constants.Configuration.ConfigPrefix}NewBackOffice")
|
||||
.Get<NewBackOfficeSettings>()?.BackOfficeHost;
|
||||
.GetSection(Constants.Configuration.ConfigSecurity)
|
||||
.Get<SecuritySettings>()?.BackOfficeHost;
|
||||
|
||||
if (backOfficeHost is null)
|
||||
{
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Api.Common.Configuration;
|
||||
using Umbraco.Cms.Api.Common.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Configuration;
|
||||
@@ -8,7 +7,6 @@ using Umbraco.Cms.Api.Management.Serialization;
|
||||
using Umbraco.Cms.Api.Management.Services;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.Configuration;
|
||||
using Umbraco.Cms.Web.Common.ApplicationBuilder;
|
||||
|
||||
namespace Umbraco.Extensions;
|
||||
@@ -78,11 +76,6 @@ public static class UmbracoBuilderExtensions
|
||||
applicationBuilder => { },
|
||||
applicationBuilder => applicationBuilder.UseEndpoints()));
|
||||
});
|
||||
|
||||
// FIXME: when this is moved to core, make the AddUmbracoOptions extension private again and remove core InternalsVisibleTo for Umbraco.Cms.Api.Management
|
||||
builder.AddUmbracoOptions<NewBackOfficeSettings>();
|
||||
// FIXME: remove this when NewBackOfficeSettings is moved to core
|
||||
services.AddSingleton<IValidateOptions<NewBackOfficeSettings>, NewBackOfficeSettingsValidator>();
|
||||
}
|
||||
|
||||
return builder;
|
||||
|
||||
@@ -3,7 +3,7 @@ using Microsoft.Extensions.Hosting;
|
||||
using Microsoft.Extensions.Options;
|
||||
using OpenIddict.Abstractions;
|
||||
using Umbraco.Cms.Core;
|
||||
using Umbraco.Cms.Core.Models.Configuration;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
using Umbraco.Cms.Core.Services;
|
||||
using Umbraco.Cms.Infrastructure.Security;
|
||||
|
||||
@@ -14,12 +14,12 @@ public class BackOfficeApplicationManager : OpenIdDictApplicationManagerBase, IB
|
||||
private readonly IWebHostEnvironment _webHostEnvironment;
|
||||
private readonly IRuntimeState _runtimeState;
|
||||
private readonly Uri? _backOfficeHost;
|
||||
private readonly string? _authorizeCallbackPathName;
|
||||
private readonly string _authorizeCallbackPathName;
|
||||
|
||||
public BackOfficeApplicationManager(
|
||||
IOpenIddictApplicationManager applicationManager,
|
||||
IWebHostEnvironment webHostEnvironment,
|
||||
IOptions<NewBackOfficeSettings> securitySettings,
|
||||
IOptions<SecuritySettings> securitySettings,
|
||||
IRuntimeState runtimeState)
|
||||
: base(applicationManager)
|
||||
{
|
||||
@@ -101,14 +101,14 @@ public class BackOfficeApplicationManager : OpenIdDictApplicationManagerBase, IB
|
||||
ClientId = Constants.OAuthClientIds.BackOffice,
|
||||
RedirectUris =
|
||||
{
|
||||
CallbackUrlFor(_backOfficeHost ?? backOfficeUrl, _authorizeCallbackPathName ?? "/umbraco")
|
||||
CallbackUrlFor(_backOfficeHost ?? backOfficeUrl, _authorizeCallbackPathName)
|
||||
},
|
||||
Type = OpenIddictConstants.ClientTypes.Public,
|
||||
PostLogoutRedirectUris =
|
||||
{
|
||||
CallbackUrlFor(_backOfficeHost ?? backOfficeUrl, _authorizeCallbackPathName ?? "/umbraco/login"),
|
||||
CallbackUrlFor(_backOfficeHost ?? backOfficeUrl, _authorizeCallbackPathName + "/login"),
|
||||
// FIXME: remove when we no longer use Umbraco.Web.UI project
|
||||
CallbackUrlFor(_backOfficeHost ?? backOfficeUrl, _authorizeCallbackPathName ?? "/umbraco")
|
||||
CallbackUrlFor(_backOfficeHost ?? backOfficeUrl, _authorizeCallbackPathName)
|
||||
},
|
||||
Permissions =
|
||||
{
|
||||
|
||||
@@ -25,6 +25,7 @@ public class SecuritySettings
|
||||
|
||||
internal const int StaticMemberDefaultLockoutTimeInMinutes = 30 * 24 * 60;
|
||||
internal const int StaticUserDefaultLockoutTimeInMinutes = 30 * 24 * 60;
|
||||
internal const string StaticAuthorizeCallbackPathName = "/umbraco";
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value indicating whether to keep the user logged in.
|
||||
@@ -116,4 +117,15 @@ public class SecuritySettings
|
||||
/// </summary>
|
||||
[DefaultValue(StaticAllowConcurrentLogins)]
|
||||
public bool AllowConcurrentLogins { get; set; } = StaticAllowConcurrentLogins;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a value of the back-office host URI. Use this when running the back-office client and the Management API on different hosts. Leave empty when running both on the same host.
|
||||
/// </summary>
|
||||
public Uri? BackOfficeHost { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// The path to use for authorization callback. Will be appended to the BackOfficeHost.
|
||||
/// </summary>
|
||||
[DefaultValue(StaticAuthorizeCallbackPathName)]
|
||||
public string AuthorizeCallbackPathName { get; set; } = StaticAuthorizeCallbackPathName;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
|
||||
namespace Umbraco.Cms.Core.Configuration.Models.Validation;
|
||||
|
||||
public class SecuritySettingsValidator : ConfigurationValidatorBase, IValidateOptions<SecuritySettings>
|
||||
{
|
||||
public ValidateOptionsResult Validate(string? name, SecuritySettings options)
|
||||
{
|
||||
if (options.BackOfficeHost != null)
|
||||
{
|
||||
if (options.BackOfficeHost.IsAbsoluteUri == false)
|
||||
{
|
||||
return ValidateOptionsResult.Fail($"{nameof(SecuritySettings.BackOfficeHost)} must be an absolute URL");
|
||||
}
|
||||
|
||||
if (options.BackOfficeHost.PathAndQuery != "/")
|
||||
{
|
||||
return ValidateOptionsResult.Fail($"{nameof(SecuritySettings.BackOfficeHost)} must not have any path or query");
|
||||
}
|
||||
}
|
||||
|
||||
return ValidateOptionsResult.Success;
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ namespace Umbraco.Cms.Core.DependencyInjection;
|
||||
/// </summary>
|
||||
public static partial class UmbracoBuilderExtensions
|
||||
{
|
||||
internal static IUmbracoBuilder AddUmbracoOptions<TOptions>(this IUmbracoBuilder builder, Action<OptionsBuilder<TOptions>>? configure = null)
|
||||
private static IUmbracoBuilder AddUmbracoOptions<TOptions>(this IUmbracoBuilder builder, Action<OptionsBuilder<TOptions>>? configure = null)
|
||||
where TOptions : class
|
||||
{
|
||||
UmbracoOptionsAttribute? umbracoOptionsAttribute = typeof(TOptions).GetCustomAttribute<UmbracoOptionsAttribute>();
|
||||
@@ -45,6 +45,7 @@ public static partial class UmbracoBuilderExtensions
|
||||
builder.Services.AddSingleton<IValidateOptions<HealthChecksSettings>, HealthChecksSettingsValidator>();
|
||||
builder.Services.AddSingleton<IValidateOptions<RequestHandlerSettings>, RequestHandlerSettingsValidator>();
|
||||
builder.Services.AddSingleton<IValidateOptions<UnattendedSettings>, UnattendedSettingsValidator>();
|
||||
builder.Services.AddSingleton<IValidateOptions<SecuritySettings>, SecuritySettingsValidator>();
|
||||
|
||||
// Register configuration sections.
|
||||
builder
|
||||
|
||||
@@ -1,12 +0,0 @@
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models.Configuration;
|
||||
|
||||
// FIXME: merge this class with relevant existing settings from Core and clean up
|
||||
[UmbracoOptions($"{Umbraco.Cms.Core.Constants.Configuration.ConfigPrefix}NewBackOffice")]
|
||||
public class NewBackOfficeSettings
|
||||
{
|
||||
public Uri? BackOfficeHost { get; set; } = null;
|
||||
|
||||
public string? AuthorizeCallbackPathName { get; set; } = null;
|
||||
}
|
||||
@@ -1,25 +0,0 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Core.Configuration.Models.Validation;
|
||||
|
||||
namespace Umbraco.Cms.Core.Models.Configuration;
|
||||
|
||||
// TODO: merge this class with relevant existing settings validators from Core and clean up
|
||||
public class NewBackOfficeSettingsValidator : ConfigurationValidatorBase, IValidateOptions<NewBackOfficeSettings>
|
||||
{
|
||||
public ValidateOptionsResult Validate(string? name, NewBackOfficeSettings options)
|
||||
{
|
||||
if (options.BackOfficeHost != null)
|
||||
{
|
||||
if (options.BackOfficeHost.IsAbsoluteUri == false)
|
||||
{
|
||||
return ValidateOptionsResult.Fail($"{nameof(NewBackOfficeSettings.BackOfficeHost)} must be an absolute URL");
|
||||
}
|
||||
if (options.BackOfficeHost.PathAndQuery != "/")
|
||||
{
|
||||
return ValidateOptionsResult.Fail($"{nameof(NewBackOfficeSettings.BackOfficeHost)} must not have any path or query");
|
||||
}
|
||||
}
|
||||
|
||||
return ValidateOptionsResult.Success;
|
||||
}
|
||||
}
|
||||
@@ -38,10 +38,6 @@
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>DynamicProxyGenAssembly2</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
<!-- TODO: remove this when new backoffice config etc. can be moved to core -->
|
||||
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo">
|
||||
<_Parameter1>Umbraco.Cms.Api.Management</_Parameter1>
|
||||
</AssemblyAttribute>
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
||||
Reference in New Issue
Block a user