Merge remote-tracking branch 'origin/v11/dev' into v12/dev

This commit is contained in:
Bjarke Berg
2023-03-08 11:01:06 +01:00
6 changed files with 65 additions and 10 deletions

View File

@@ -262,4 +262,9 @@ public class ContentSettings
/// </summary>
[DefaultValue(StaticDisallowedUploadFiles)]
public string[] DisallowedUploadedFileExtensions { get; set; } = StaticDisallowedUploadFiles.Split(',');
/// <summary>
/// Gets or sets the allowed external host for media. If empty only relative paths are allowed.
/// </summary>
public string[] AllowedMediaHosts { get; set; } = Array.Empty<string>();
}

View File

@@ -169,7 +169,10 @@ public class BackOfficeExamineSearcher : IBackOfficeExamineSearcher
var allLangs = _languageService.GetAllLanguages().Select(x => x.IsoCode.ToLowerInvariant()).ToList();
// the chars [*-_] in the query will mess everything up so let's remove those
query = Regex.Replace(query, "[\\*\\-_]", string.Empty);
// However we cannot just remove - and _ since these signify a space, so we instead replace them with that.
query = Regex.Replace(query, "[\\*]", string.Empty);
query = Regex.Replace(query, "[\\-_]", " ");
//check if text is surrounded by single or double quotes, if so, then exact match
var surroundedByQuotes = Regex.IsMatch(query, "^\".*?\"$")

View File

@@ -1,10 +1,14 @@
using System.Web;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using Umbraco.Cms.Core;
using Umbraco.Cms.Core.Configuration.Models;
using Umbraco.Cms.Core.IO;
using Umbraco.Cms.Core.Media;
using Umbraco.Cms.Core.Models;
using Umbraco.Cms.Web.Common.Attributes;
using Umbraco.Cms.Web.Common.DependencyInjection;
using Umbraco.Extensions;
namespace Umbraco.Cms.Web.BackOffice.Controllers;
@@ -17,13 +21,31 @@ public class ImagesController : UmbracoAuthorizedApiController
{
private readonly IImageUrlGenerator _imageUrlGenerator;
private readonly MediaFileManager _mediaFileManager;
private ContentSettings _contentSettings;
[Obsolete("Use non obsolete-constructor. Scheduled for removal in Umbraco 13.")]
public ImagesController(
MediaFileManager mediaFileManager,
IImageUrlGenerator imageUrlGenerator)
: this(mediaFileManager,
imageUrlGenerator,
StaticServiceProvider.Instance.GetRequiredService<IOptionsMonitor<ContentSettings>>())
{
}
[ActivatorUtilitiesConstructor]
public ImagesController(
MediaFileManager mediaFileManager,
IImageUrlGenerator imageUrlGenerator,
IOptionsMonitor<ContentSettings> contentSettingsMonitor)
{
_mediaFileManager = mediaFileManager;
_imageUrlGenerator = imageUrlGenerator;
_contentSettings = contentSettingsMonitor.CurrentValue;
contentSettingsMonitor.OnChange(x => _contentSettings = x);
}
/// <summary>
@@ -58,7 +80,7 @@ public class ImagesController : UmbracoAuthorizedApiController
var ext = Path.GetExtension(encodedImagePath);
// check if imagePath is local to prevent open redirect
if (!Uri.IsWellFormedUriString(encodedImagePath, UriKind.Relative))
if (!IsAllowed(encodedImagePath))
{
return Unauthorized();
}
@@ -90,12 +112,33 @@ public class ImagesController : UmbracoAuthorizedApiController
ImageCropMode = ImageCropMode.Max,
CacheBusterValue = rnd
});
if (Url.IsLocalUrl(imageUrl))
if (imageUrl is not null)
{
return new LocalRedirectResult(imageUrl, false);
return new RedirectResult(imageUrl, false);
}
return Unauthorized();
return NotFound();
}
private bool IsAllowed(string encodedImagePath)
{
if(Uri.IsWellFormedUriString(encodedImagePath, UriKind.Relative))
{
return true;
}
var builder = new UriBuilder(encodedImagePath);
foreach (var allowedMediaHost in _contentSettings.AllowedMediaHosts)
{
if (string.Equals(builder.Host, allowedMediaHost, StringComparison.InvariantCultureIgnoreCase))
{
return true;
}
}
return false;
}
/// <summary>

View File

@@ -1,6 +1,7 @@
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc.Filters;
using Umbraco.Cms.Core.Routing;
using Umbraco.Cms.Web.Common.ActionsResults;
using Umbraco.Cms.Web.Common.Routing;
namespace Umbraco.Cms.Web.Common.Controllers;
@@ -15,9 +16,11 @@ internal class PublishedRequestFilterAttribute : ResultFilterAttribute
/// </summary>
public override void OnResultExecuting(ResultExecutingContext context)
{
if (context.Result is not null)
if (context.Result is MaintenanceResult)
{
// If the result is already set, we just skip the execution
// If the result is already set to a maintenance result we can't do anything
// Since the umbraco pipeline has not run.
// Fortunately we don't need to either.
return;
}

View File

@@ -61,8 +61,9 @@ public class UmbracoVirtualPageRoute : IUmbracoVirtualPageRoute
if (controllerType != null)
{
// Get the controller for the endpoint
var controller = httpContext.RequestServices.GetRequiredService(controllerType);
// Get the controller for the endpoint. We need to fallback to ActivatorUtilities if the controller is not registered in DI.
var controller = httpContext.RequestServices.GetService(controllerType)
?? ActivatorUtilities.CreateInstance(httpContext.RequestServices, controllerType);
// Try and find the content if this is a virtual page
IPublishedContent? publishedContent = FindContent(

View File

@@ -3,7 +3,7 @@ angular.module("umbraco.install").controller("Umbraco.Install.UserController", f
$scope.majorVersion = Umbraco.Sys.ServerVariables.application.version;
$scope.passwordPattern = /.*/;
$scope.installer.current.model.subscribeToNewsLetter = $scope.installer.current.model.subscribeToNewsLetter || false;
setTelemetryLevelAndDescription($scope.installer.current.model.telemetryIndex ?? 1);
setTelemetryLevelAndDescription($scope.installer.current.model.telemetryIndex ?? 2);
if ($scope.installer.current.model.minNonAlphaNumericLength > 0) {
var exp = "";