[v14] Absolute media urls (#15503)
* Made a replaceble solution to support absolute urls for media/user avatars in the management API * PR suggestion Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * PR suggestion Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com> * PR suggestion/fix and added missing switch case --------- Co-authored-by: Sven Geusens <sge@umbraco.dk> Co-authored-by: Nikolaj Geisle <70372949+Zeegaan@users.noreply.github.com>
This commit is contained in:
@@ -1,8 +1,10 @@
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Api.Management.Factories;
|
||||
using Umbraco.Cms.Api.Management.Mapping.Media;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Mapping;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.DependencyInjection;
|
||||
|
||||
@@ -12,6 +14,8 @@ internal static class MediaBuilderExtensions
|
||||
{
|
||||
builder.Services.AddTransient<IMediaPresentationModelFactory, MediaPresentationModelFactory>();
|
||||
builder.Services.AddTransient<IMediaEditingPresentationFactory, MediaEditingPresentationFactory>();
|
||||
builder.Services.AddTransient<IUrlAssembler, DefaultUrlAssembler>();
|
||||
builder.Services.AddScoped<IAbsoluteUrlBuilder, DefaultAbsoluteUrlBuilder>();
|
||||
|
||||
builder.WithCollectionBuilder<MapDefinitionCollectionBuilder>().Add<MediaMapDefinition>();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Microsoft.Extensions.Options;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Content;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.Media;
|
||||
using Umbraco.Cms.Core.Configuration.Models;
|
||||
@@ -14,12 +15,18 @@ public class MediaPresentationModelFactory : IMediaPresentationModelFactory
|
||||
private readonly IUmbracoMapper _umbracoMapper;
|
||||
private readonly ContentSettings _contentSettings;
|
||||
private readonly MediaUrlGeneratorCollection _mediaUrlGenerators;
|
||||
private readonly IAbsoluteUrlBuilder _absoluteUrlBuilder;
|
||||
|
||||
public MediaPresentationModelFactory(IUmbracoMapper umbracoMapper, IOptions<ContentSettings> contentSettings, MediaUrlGeneratorCollection mediaUrlGenerators)
|
||||
public MediaPresentationModelFactory(
|
||||
IUmbracoMapper umbracoMapper,
|
||||
IOptions<ContentSettings> contentSettings,
|
||||
MediaUrlGeneratorCollection mediaUrlGenerators,
|
||||
IAbsoluteUrlBuilder absoluteUrlBuilder)
|
||||
{
|
||||
_umbracoMapper = umbracoMapper;
|
||||
_contentSettings = contentSettings.Value;
|
||||
_mediaUrlGenerators = mediaUrlGenerators;
|
||||
_absoluteUrlBuilder = absoluteUrlBuilder;
|
||||
}
|
||||
|
||||
public Task<MediaResponseModel> CreateResponseModelAsync(IMedia media)
|
||||
@@ -32,7 +39,7 @@ public class MediaPresentationModelFactory : IMediaPresentationModelFactory
|
||||
.Select(mediaUrl => new ContentUrlInfo
|
||||
{
|
||||
Culture = null,
|
||||
Url = mediaUrl
|
||||
Url = _absoluteUrlBuilder.ToAbsoluteUrl(mediaUrl).ToString(),
|
||||
})
|
||||
.ToArray();
|
||||
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Umbraco.Cms.Api.Management.ViewModels.User;
|
||||
using Umbraco.Cms.Api.Management.Routing;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.User;
|
||||
using Umbraco.Cms.Api.Management.ViewModels.User.Current;
|
||||
using Umbraco.Cms.Core.Cache;
|
||||
using Umbraco.Cms.Core.IO;
|
||||
@@ -17,19 +18,22 @@ public class UserPresentationFactory : IUserPresentationFactory
|
||||
private readonly MediaFileManager _mediaFileManager;
|
||||
private readonly IImageUrlGenerator _imageUrlGenerator;
|
||||
private readonly IUserGroupPresentationFactory _userGroupPresentationFactory;
|
||||
private readonly IAbsoluteUrlBuilder _absoluteUrlBuilder;
|
||||
|
||||
public UserPresentationFactory(
|
||||
IEntityService entityService,
|
||||
AppCaches appCaches,
|
||||
MediaFileManager mediaFileManager,
|
||||
IImageUrlGenerator imageUrlGenerator,
|
||||
IUserGroupPresentationFactory userGroupPresentationFactory)
|
||||
IUserGroupPresentationFactory userGroupPresentationFactory,
|
||||
IAbsoluteUrlBuilder absoluteUrlBuilder)
|
||||
{
|
||||
_entityService = entityService;
|
||||
_appCaches = appCaches;
|
||||
_mediaFileManager = mediaFileManager;
|
||||
_imageUrlGenerator = imageUrlGenerator;
|
||||
_userGroupPresentationFactory = userGroupPresentationFactory;
|
||||
_absoluteUrlBuilder = absoluteUrlBuilder;
|
||||
}
|
||||
|
||||
public UserResponseModel CreateResponseModel(IUser user)
|
||||
@@ -39,7 +43,8 @@ public class UserPresentationFactory : IUserPresentationFactory
|
||||
Id = user.Key,
|
||||
Email = user.Email,
|
||||
Name = user.Name ?? string.Empty,
|
||||
AvatarUrls = user.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileManager, _imageUrlGenerator),
|
||||
AvatarUrls = user.GetUserAvatarUrls(_appCaches.RuntimeCache, _mediaFileManager, _imageUrlGenerator)
|
||||
.Select(url => _absoluteUrlBuilder.ToAbsoluteUrl(url).ToString()),
|
||||
UserName = user.Username,
|
||||
LanguageIsoCode = user.Language,
|
||||
CreateDate = user.CreateDate,
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.Routing;
|
||||
using Umbraco.Cms.Core.Web;
|
||||
using Umbraco.Extensions;
|
||||
|
||||
namespace Umbraco.Cms.Api.Management.Routing;
|
||||
|
||||
public class DefaultAbsoluteUrlBuilder : IAbsoluteUrlBuilder
|
||||
{
|
||||
private readonly IUmbracoContextAccessor _umbracoContextAccessor;
|
||||
private readonly IUrlAssembler _urlAssembler;
|
||||
|
||||
public DefaultAbsoluteUrlBuilder(IUmbracoContextAccessor umbracoContextAccessor, IUrlAssembler urlAssembler)
|
||||
{
|
||||
_umbracoContextAccessor = umbracoContextAccessor;
|
||||
_urlAssembler = urlAssembler;
|
||||
}
|
||||
|
||||
public Uri ToAbsoluteUrl(string url)
|
||||
{
|
||||
IUmbracoContext umbracoContext = _umbracoContextAccessor.GetRequiredUmbracoContext();
|
||||
Uri current = umbracoContext.CleanedUmbracoUrl;
|
||||
|
||||
return _urlAssembler.AssembleUrl(url, current, UrlMode.Absolute);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
namespace Umbraco.Cms.Api.Management.Routing;
|
||||
|
||||
public interface IAbsoluteUrlBuilder
|
||||
{
|
||||
Uri ToAbsoluteUrl(string url);
|
||||
}
|
||||
@@ -1,4 +1,6 @@
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Umbraco.Cms.Core.DependencyInjection;
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
using Umbraco.Cms.Core.PropertyEditors;
|
||||
|
||||
namespace Umbraco.Cms.Core.Routing;
|
||||
@@ -10,11 +12,19 @@ public class DefaultMediaUrlProvider : IMediaUrlProvider
|
||||
{
|
||||
private readonly MediaUrlGeneratorCollection _mediaPathGenerators;
|
||||
private readonly UriUtility _uriUtility;
|
||||
private readonly IUrlAssembler _urlAssembler;
|
||||
|
||||
public DefaultMediaUrlProvider(MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility)
|
||||
public DefaultMediaUrlProvider(MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility, IUrlAssembler urlAssembler)
|
||||
{
|
||||
_mediaPathGenerators = mediaPathGenerators ?? throw new ArgumentNullException(nameof(mediaPathGenerators));
|
||||
_uriUtility = uriUtility;
|
||||
_urlAssembler = urlAssembler;
|
||||
}
|
||||
|
||||
[Obsolete("Use the constructor that has the IUrlAssembler instead. Scheduled to be removed in v15")]
|
||||
public DefaultMediaUrlProvider(MediaUrlGeneratorCollection mediaPathGenerators, UriUtility uriUtility)
|
||||
: this(mediaPathGenerators, uriUtility, StaticServiceProvider.Instance.GetRequiredService<IUrlAssembler>())
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
@@ -38,46 +48,10 @@ public class DefaultMediaUrlProvider : IMediaUrlProvider
|
||||
|
||||
if (_mediaPathGenerators.TryGetMediaPath(propType?.EditorAlias, value, out var path))
|
||||
{
|
||||
Uri url = AssembleUrl(path!, current, mode);
|
||||
Uri url = _urlAssembler.AssembleUrl(path!, current, mode);
|
||||
return UrlInfo.Url(url.ToString(), culture);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private Uri AssembleUrl(string path, Uri current, UrlMode mode)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(path)} cannot be null or whitespace", nameof(path));
|
||||
}
|
||||
|
||||
// the stored path is absolute so we just return it as is
|
||||
if (Uri.IsWellFormedUriString(path, UriKind.Absolute))
|
||||
{
|
||||
return new Uri(path);
|
||||
}
|
||||
|
||||
Uri uri;
|
||||
|
||||
if (current == null)
|
||||
{
|
||||
mode = UrlMode.Relative; // best we can do
|
||||
}
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case UrlMode.Absolute:
|
||||
uri = new Uri(current?.GetLeftPart(UriPartial.Authority) + path);
|
||||
break;
|
||||
case UrlMode.Relative:
|
||||
case UrlMode.Auto:
|
||||
uri = new Uri(path, UriKind.Relative);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(mode));
|
||||
}
|
||||
|
||||
return _uriUtility.MediaUriFromUmbraco(uri);
|
||||
}
|
||||
}
|
||||
|
||||
42
src/Umbraco.Core/Routing/DefaultUrlAssembler.cs
Normal file
42
src/Umbraco.Core/Routing/DefaultUrlAssembler.cs
Normal file
@@ -0,0 +1,42 @@
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Cms.Core.Routing;
|
||||
|
||||
public class DefaultUrlAssembler : IUrlAssembler
|
||||
{
|
||||
private readonly UriUtility _uriUtility;
|
||||
|
||||
public DefaultUrlAssembler(UriUtility uriUtility) => _uriUtility = uriUtility;
|
||||
|
||||
public Uri AssembleUrl(string path, Uri current, UrlMode mode)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(path))
|
||||
{
|
||||
throw new ArgumentException($"{nameof(path)} cannot be null or whitespace", nameof(path));
|
||||
}
|
||||
|
||||
// the path is absolute so we just return it as is
|
||||
if (Uri.IsWellFormedUriString(path, UriKind.Absolute))
|
||||
{
|
||||
return new Uri(path);
|
||||
}
|
||||
|
||||
Uri uri;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case UrlMode.Absolute:
|
||||
uri = new Uri(current.GetLeftPart(UriPartial.Authority) + path);
|
||||
break;
|
||||
case UrlMode.Relative:
|
||||
case UrlMode.Auto:
|
||||
case UrlMode.Default:
|
||||
uri = new Uri(path, UriKind.Relative);
|
||||
break;
|
||||
default:
|
||||
throw new ArgumentOutOfRangeException(nameof(mode));
|
||||
}
|
||||
|
||||
return _uriUtility.MediaUriFromUmbraco(uri);
|
||||
}
|
||||
}
|
||||
8
src/Umbraco.Core/Routing/IUrlAssembler.cs
Normal file
8
src/Umbraco.Core/Routing/IUrlAssembler.cs
Normal file
@@ -0,0 +1,8 @@
|
||||
using Umbraco.Cms.Core.Models.PublishedContent;
|
||||
|
||||
namespace Umbraco.Cms.Core.Routing;
|
||||
|
||||
public interface IUrlAssembler
|
||||
{
|
||||
Uri AssembleUrl(string path, Uri current, UrlMode mode);
|
||||
}
|
||||
Reference in New Issue
Block a user