Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
18 commits
Select commit Hold shift + click to select a range
b480540
Use require modifier instead of setting null-suppressed default values
ronaldbarendse Apr 11, 2024
afa4c66
Only remove read-only properties when IgnoreReadOnlyProperties is set
ronaldbarendse Apr 11, 2024
57e9a2f
Obsolete UmbracoPath property and remove work-around for obsolete setter
ronaldbarendse Apr 11, 2024
a28cba1
Remove UmbracoPath setting and use constant instead
ronaldbarendse Apr 11, 2024
a2456f0
Remove usage of GetBackOfficePath
ronaldbarendse Apr 11, 2024
c5f0038
Add IHostingEnvironment.GetBackOfficePath() extension method
ronaldbarendse Apr 11, 2024
5cf5363
Add Constants.System.UmbracoPathSegment constant
ronaldbarendse Apr 11, 2024
1df865c
Update Constants.System XML docs
ronaldbarendse Apr 11, 2024
d8acaca
Replace StringBuilder with string interpolation
ronaldbarendse Apr 11, 2024
83aa61d
Fix syntax error
ronaldbarendse Apr 12, 2024
f3104cd
Merge branch 'v15/dev' into v14/feature/remove-umbracopath
ronaldbarendse Sep 9, 2024
b304111
Merge branch 'v15/dev' into v14/feature/remove-umbracopath
AndyButland Feb 20, 2025
3f4f887
Removed uses of obsoletes.
AndyButland Feb 20, 2025
c5cddab
Further obsolete messages.
AndyButland Feb 20, 2025
35574df
Cleaned up usings.
AndyButland Feb 20, 2025
0d6b324
Update src/Umbraco.Infrastructure/Install/FilePermissionHelper.cs
AndyButland Mar 3, 2025
b12ae05
Merge branch 'v16/dev' into v14/feature/remove-umbracopath
AndyButland Mar 3, 2025
7ec1d35
Merge branch 'v14/feature/remove-umbracopath' of https://github.com/u…
AndyButland Mar 3, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 14 additions & 3 deletions src/Umbraco.Cms.Api.Common/OpenApi/SubTypesSelector.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,31 @@ namespace Umbraco.Cms.Api.Common.OpenApi;

public class SubTypesSelector : ISubTypesSelector
{
private readonly IOptions<GlobalSettings> _settings;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IHttpContextAccessor _httpContextAccessor;
private readonly IEnumerable<ISubTypesHandler> _subTypeHandlers;
private readonly IUmbracoJsonTypeInfoResolver _umbracoJsonTypeInfoResolver;

[Obsolete("The settings parameter is not required anymore, use the other constructor instead. Scheduled for removal in Umbraco 17.")]
public SubTypesSelector(
IOptions<GlobalSettings> settings,
IHostingEnvironment hostingEnvironment,
IHttpContextAccessor httpContextAccessor,
IEnumerable<ISubTypesHandler> subTypeHandlers,
IUmbracoJsonTypeInfoResolver umbracoJsonTypeInfoResolver)
{
_settings = settings;
_hostingEnvironment = hostingEnvironment;
_httpContextAccessor = httpContextAccessor;
_subTypeHandlers = subTypeHandlers;
_umbracoJsonTypeInfoResolver = umbracoJsonTypeInfoResolver;
}

public SubTypesSelector(
IHostingEnvironment hostingEnvironment,
IHttpContextAccessor httpContextAccessor,
IEnumerable<ISubTypesHandler> subTypeHandlers,
IUmbracoJsonTypeInfoResolver umbracoJsonTypeInfoResolver)
{
_hostingEnvironment = hostingEnvironment;
_httpContextAccessor = httpContextAccessor;
_subTypeHandlers = subTypeHandlers;
Expand All @@ -32,7 +43,7 @@ public SubTypesSelector(

public IEnumerable<Type> SubTypes(Type type)
{
var backOfficePath = _settings.Value.GetBackOfficePath(_hostingEnvironment);
var backOfficePath = _hostingEnvironment.GetBackOfficePath();
var swaggerPath = $"{backOfficePath}/swagger";

if (_httpContextAccessor.HttpContext?.Request.Path.StartsWithSegments(swaggerPath) ?? false)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
using Swashbuckle.AspNetCore.SwaggerGen;
using Swashbuckle.AspNetCore.SwaggerUI;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Web.Common.ApplicationBuilder;
using Umbraco.Extensions;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;
Expand All @@ -30,24 +30,21 @@ private void PostPipelineAction(IApplicationBuilder applicationBuilder)
IOptions<SwaggerGenOptions> swaggerGenOptions = applicationBuilder.ApplicationServices.GetRequiredService<IOptions<SwaggerGenOptions>>();

applicationBuilder.UseSwagger(swaggerOptions =>
{
swaggerOptions.RouteTemplate = SwaggerRouteTemplate(applicationBuilder);
});
{
swaggerOptions.RouteTemplate = SwaggerRouteTemplate(applicationBuilder);
});

applicationBuilder.UseSwaggerUI(swaggerUiOptions => SwaggerUiConfiguration(swaggerUiOptions, swaggerGenOptions.Value, applicationBuilder));
}

protected virtual bool SwaggerIsEnabled(IApplicationBuilder applicationBuilder)
{
IWebHostEnvironment webHostEnvironment = applicationBuilder.ApplicationServices.GetRequiredService<IWebHostEnvironment>();
return webHostEnvironment.IsProduction() is false;
}
=> applicationBuilder.ApplicationServices.GetRequiredService<IWebHostEnvironment>().IsProduction() is false;

protected virtual string SwaggerRouteTemplate(IApplicationBuilder applicationBuilder)
=> $"{GetUmbracoPath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger/{{documentName}}/swagger.json";
=> $"{GetBackOfficePath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger/{{documentName}}/swagger.json";

protected virtual string SwaggerUiRoutePrefix(IApplicationBuilder applicationBuilder)
=> $"{GetUmbracoPath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger";
=> $"{GetBackOfficePath(applicationBuilder).TrimStart(Constants.CharArrays.ForwardSlash)}/swagger";

protected virtual void SwaggerUiConfiguration(
SwaggerUIOptions swaggerUiOptions,
Expand All @@ -56,8 +53,7 @@ protected virtual void SwaggerUiConfiguration(
{
swaggerUiOptions.RoutePrefix = SwaggerUiRoutePrefix(applicationBuilder);

foreach ((var name, OpenApiInfo? apiInfo) in swaggerGenOptions.SwaggerGeneratorOptions.SwaggerDocs
.OrderBy(x => x.Value.Title))
foreach ((var name, OpenApiInfo? apiInfo) in swaggerGenOptions.SwaggerGeneratorOptions.SwaggerDocs.OrderBy(x => x.Value.Title))
{
swaggerUiOptions.SwaggerEndpoint($"{name}/swagger.json", $"{apiInfo.Title}");
}
Expand All @@ -70,11 +66,6 @@ protected virtual void SwaggerUiConfiguration(
swaggerUiOptions.OAuthUsePkce();
}

private string GetUmbracoPath(IApplicationBuilder applicationBuilder)
{
GlobalSettings settings = applicationBuilder.ApplicationServices.GetRequiredService<IOptions<GlobalSettings>>().Value;
IHostingEnvironment hostingEnvironment = applicationBuilder.ApplicationServices.GetRequiredService<IHostingEnvironment>();

return settings.GetBackOfficePath(hostingEnvironment);
}
private string GetBackOfficePath(IApplicationBuilder applicationBuilder)
=> applicationBuilder.ApplicationServices.GetRequiredService<IHostingEnvironment>().GetBackOfficePath();
}
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public class BackOfficeLoginModel
public bool UserIsAlreadyLoggedIn { get; set; }
}

[ApiExplorerSettings(IgnoreApi=true)]
[ApiExplorerSettings(IgnoreApi = true)]
[Route(LoginPath)]
public class BackOfficeLoginController : Controller
{
Expand All @@ -51,7 +51,7 @@ public async Task<IActionResult> Index(CancellationToken cancellationToken, Back

if (string.IsNullOrEmpty(model.UmbracoUrl))
{
model.UmbracoUrl = _hostingEnvironment.ToAbsolute(Constants.System.DefaultUmbracoPath);
model.UmbracoUrl = _hostingEnvironment.GetBackOfficePath();
}

if (string.IsNullOrEmpty(model.ReturnUrl))
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Diagnostics;
using Microsoft.AspNetCore.Hosting;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.Hosting;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Extensions;
using IHostingEnvironment = Umbraco.Cms.Core.Hosting.IHostingEnvironment;

Expand All @@ -20,14 +19,10 @@ internal static IApplicationBuilder UseProblemDetailsExceptionHandling(this IApp
=> applicationBuilder.UseWhen(
httpContext =>
{
GlobalSettings settings = httpContext.RequestServices
.GetRequiredService<IOptions<GlobalSettings>>().Value;
IHostingEnvironment hostingEnvironment =
httpContext.RequestServices.GetRequiredService<IHostingEnvironment>();
var officePath = settings.GetBackOfficePath(hostingEnvironment);
var backOfficePath = httpContext.RequestServices.GetRequiredService<IHostingEnvironment>().GetBackOfficePath();

// Only use the API exception handler when we are requesting an API
return httpContext.Request.Path.Value?.StartsWith($"{officePath}{Constants.Web.ManagementApiPath}") ?? false;
return httpContext.Request.Path.Value?.StartsWith($"{backOfficePath}{Constants.Web.ManagementApiPath}") ?? false;
},
innerBuilder =>
{
Expand Down Expand Up @@ -58,14 +53,13 @@ internal static IApplicationBuilder UseEndpoints(this IApplicationBuilder applic

applicationBuilder.UseEndpoints(endpoints =>
{
GlobalSettings settings = provider.GetRequiredService<IOptions<GlobalSettings>>().Value;
IHostingEnvironment hostingEnvironment = provider.GetRequiredService<IHostingEnvironment>();
var officePath = settings.GetBackOfficePath(hostingEnvironment);
var backOfficePath = provider.GetRequiredService<IHostingEnvironment>().GetBackOfficePath();

// Maps attribute routed controllers.
endpoints.MapControllers();

// Serve contract
endpoints.MapGet($"{officePath}{Constants.Web.ManagementApiPath}openapi.json", async context =>
endpoints.MapGet($"{backOfficePath}{Constants.Web.ManagementApiPath}openapi.json", async context =>
{
await context.Response.SendFileAsync(new EmbeddedFileProvider(typeof(ManagementApiComposer).Assembly).GetFileInfo("OpenApi.json"));
});
Expand Down
51 changes: 11 additions & 40 deletions src/Umbraco.Cms.Api.Management/Routing/BackOfficeAreaRoutes.cs
Original file line number Diff line number Diff line change
@@ -1,66 +1,37 @@
using System.Text;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Management.Controllers.Security;
using Umbraco.Cms.Api.Management.ServerEvents;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Routing;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Management.Routing;

/// <summary>
/// Creates routes for the back office area
/// Creates routes for the back office area.
/// </summary>
public sealed class BackOfficeAreaRoutes : IAreaRoutes
{
private readonly IRuntimeState _runtimeState;
private readonly string _umbracoPathSegment;

/// <summary>
/// Initializes a new instance of the <see cref="BackOfficeAreaRoutes" /> class.
/// Initializes a new instance of the <see cref="BackOfficeAreaRoutes" /> class.
/// </summary>
public BackOfficeAreaRoutes(
IOptions<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment,
IRuntimeState runtimeState)
{
_runtimeState = runtimeState;
_umbracoPathSegment = globalSettings.Value.GetUmbracoMvcArea(hostingEnvironment);
}
public BackOfficeAreaRoutes(IRuntimeState runtimeState)
=> _runtimeState = runtimeState;

[Obsolete("Use non-obsolete constructor. Scheduled for removal in Umbraco 16.")]
public BackOfficeAreaRoutes(
IOptions<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment,
IRuntimeState runtimeState,
UmbracoApiControllerTypeCollection apiControllers)
: this(globalSettings, hostingEnvironment, runtimeState)
{
}

/// <inheritdoc />
public void CreateRoutes(IEndpointRouteBuilder endpoints)
{


switch (_runtimeState.Level)
if (_runtimeState.Level is RuntimeLevel.Install or RuntimeLevel.Upgrade or RuntimeLevel.Run)
{
case RuntimeLevel.Install:
case RuntimeLevel.Upgrade:
case RuntimeLevel.Run:
MapMinimalBackOffice(endpoints);
endpoints.MapHub<BackofficeHub>(_umbracoPathSegment + Constants.Web.BackofficeSignalRHub);
endpoints.MapHub<ServerEventHub>(_umbracoPathSegment + Constants.Web.ServerEventSignalRHub);
break;
case RuntimeLevel.BootFailed:
case RuntimeLevel.Unknown:
case RuntimeLevel.Boot:
break;
MapMinimalBackOffice(endpoints);

endpoints.MapHub<BackofficeHub>(Constants.System.UmbracoPathSegment + Constants.Web.BackofficeSignalRHub);
endpoints.MapHub<ServerEventHub>(Constants.System.UmbracoPathSegment + Constants.Web.ServerEventSignalRHub);
}
}

Expand All @@ -70,7 +41,7 @@ public void CreateRoutes(IEndpointRouteBuilder endpoints)
private void MapMinimalBackOffice(IEndpointRouteBuilder endpoints)
{
endpoints.MapUmbracoRoute<BackOfficeDefaultController>(
_umbracoPathSegment,
Constants.System.UmbracoPathSegment,
null!,
string.Empty,
"Index",
Expand All @@ -82,7 +53,7 @@ private void MapMinimalBackOffice(IEndpointRouteBuilder endpoints)

endpoints.MapControllerRoute(
"catch-all-sections-to-client",
new StringBuilder(_umbracoPathSegment).Append("/{**slug}").ToString(),
$"{Constants.System.UmbracoPathSegment}/{{**slug}}",
new
{
Controller = ControllerExtensions.GetControllerName<BackOfficeDefaultController>(),
Expand Down
35 changes: 9 additions & 26 deletions src/Umbraco.Cms.Api.Management/Routing/PreviewRoutes.cs
Original file line number Diff line number Diff line change
@@ -1,13 +1,9 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Routing;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Api.Management.Preview;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.Hosting;
using Umbraco.Cms.Core.Services;
using Umbraco.Cms.Web.Common.Routing;
using Umbraco.Extensions;

namespace Umbraco.Cms.Api.Management.Routing;

Expand All @@ -17,36 +13,23 @@ namespace Umbraco.Cms.Api.Management.Routing;
public sealed class PreviewRoutes : IAreaRoutes
{
private readonly IRuntimeState _runtimeState;
private readonly string _umbracoPathSegment;

public PreviewRoutes(
IOptions<GlobalSettings> globalSettings,
IHostingEnvironment hostingEnvironment,
IRuntimeState runtimeState)
{
_runtimeState = runtimeState;
_umbracoPathSegment = globalSettings.Value.GetUmbracoMvcArea(hostingEnvironment);
}
public PreviewRoutes(IRuntimeState runtimeState)
=> _runtimeState = runtimeState;

public void CreateRoutes(IEndpointRouteBuilder endpoints)
{
switch (_runtimeState.Level)
if (_runtimeState.Level is RuntimeLevel.Install or RuntimeLevel.Upgrade or RuntimeLevel.Run)
{
case RuntimeLevel.Install:
case RuntimeLevel.Upgrade:
case RuntimeLevel.Run:
endpoints.MapHub<PreviewHub>(GetPreviewHubRoute());
break;
case RuntimeLevel.BootFailed:
case RuntimeLevel.Unknown:
case RuntimeLevel.Boot:
break;
endpoints.MapHub<PreviewHub>(GetPreviewHubRoute());
}
}

/// <summary>
/// Returns the path to the signalR hub used for preview
/// Gets the path to the SignalR hub used for preview.
/// </summary>
/// <returns>Path to signalR hub</returns>
public string GetPreviewHubRoute() => $"/{_umbracoPathSegment}/{nameof(PreviewHub)}";
/// <returns>
/// The path to the SignalR hub used for preview.
/// </returns>
public string GetPreviewHubRoute() => $"/{Constants.System.UmbracoPathSegment}/{nameof(PreviewHub)}";
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
@using Microsoft.AspNetCore.Mvc.TagHelpers
@using Microsoft.Extensions.Options;
@using Umbraco.Cms.Api.Management.Controllers.Security
@using Umbraco.Cms.Api.Management.Extensions
Expand All @@ -11,18 +10,18 @@
@using Umbraco.Cms.Core.Serialization
@using Umbraco.Cms.Web.Common.Hosting
@using Umbraco.Extensions
@inject IOptions<GlobalSettings> GlobalSettings
@inject IOptions<SecuritySettings> SecuritySettings
@inject IEmailSender EmailSender
@inject IHostingEnvironment HostingEnvironment
@inject IOptions<GlobalSettings> GlobalSettings
@inject IProfilerHtml ProfilerHtml
@inject IBackOfficeExternalLoginProviders ExternalLogins
@inject IBackOfficePathGenerator BackOfficePathGenerator
@inject IPackageManifestService PackageManifestService
@inject IJsonSerializer JsonSerializer
@{
bool.TryParse(Context.Request.Query["umbDebug"], out var isDebug);
var backOfficePath = GlobalSettings.Value.GetBackOfficePath(HostingEnvironment);
var backOfficePath = HostingEnvironment.GetBackOfficePath();
var loginLogoImage = Url.RouteUrl(BackOfficeGraphicsController.LoginLogoRouteName, new {Version= "1"});
var loginLogoImageAlternative = Url.RouteUrl(BackOfficeGraphicsController.LoginLogoAlternativeRouteName, new {Version= "1"});
var loginBackgroundImage = Url.RouteUrl(BackOfficeGraphicsController.LoginBackGroundRouteName, new {Version= "1"});
Expand All @@ -37,7 +36,7 @@
<html lang="@GlobalSettings.Value.DefaultUILanguage">
<head>
<meta charset="UTF-8"/>
<base href="@backOfficePath.EnsureEndsWith('/')"/>
<base href="@backOfficePath.EnsureEndsWith('/')" />
<link rel="icon" type="image/svg+xml" href="~/umbraco/login/favicon.svg"/>
<meta name="viewport" content="width=device-width, initial-scale=1.0"/>
<meta name="mobile-web-app-capable" content="yes"/>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,8 @@
@using Microsoft.Extensions.Options
@using Umbraco.Cms.Core.Configuration.Models
@using Umbraco.Cms.Core.Hosting
@using Umbraco.Cms.Core.Routing
@using Umbraco.Extensions
@inject IHostingEnvironment hostingEnvironment
@inject IOptions<GlobalSettings> globalSettings
@inject IHostingEnvironment HostingEnvironment
@{
var backOfficePath = globalSettings.Value.GetBackOfficePath(hostingEnvironment);
var backOfficePath = HostingEnvironment.GetBackOfficePath();
}
<!doctype html>
<html class="no-js" lang="en">
Expand All @@ -17,7 +13,7 @@

<title>Website is Under Maintainance</title>

<link rel="stylesheet" href="@WebPath.Combine(backOfficePath.TrimStart("~") , "website", "/nonodes.css")" />
<link rel="stylesheet" href="@WebPath.Combine(backOfficePath , "website", "/nonodes.css")" />
<style type="text/css">
body {
color:initial;
Expand Down
Loading