Merge remote-tracking branch 'origin/netcore/netcore' into netcore/task/front-end-routing

# Conflicts:
#	src/Umbraco.Tests/PublishedContent/NuCacheChildrenTests.cs
#	src/Umbraco.Tests/Testing/UmbracoTestBase.cs
#	src/Umbraco.Web.BackOffice/Extensions/BackOfficeApplicationBuilderExtensions.cs
This commit is contained in:
Shannon
2020-12-16 16:18:10 +11:00
251 changed files with 2093 additions and 3884 deletions

View File

@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
@@ -7,40 +7,38 @@ using System.Net.Mime;
using System.Text;
using System.Xml;
using System.Xml.Linq;
using Microsoft.Extensions.Logging;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
using Microsoft.Extensions.Options;
using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Dictionary;
using Umbraco.Core.Hosting;
using Umbraco.Core.Mapping;
using Umbraco.Core.Models;
using Umbraco.Core.Packaging;
using Umbraco.Core.PropertyEditors;
using Umbraco.Core.Scoping;
using Umbraco.Core.Security;
using Umbraco.Core.Serialization;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Web.Models;
using Umbraco.Web.Models.ContentEditing;
using Constants = Umbraco.Core.Constants;
using Umbraco.Core.Mapping;
using Umbraco.Core.Security;
using Umbraco.Web.BackOffice.Filters;
using Umbraco.Web.Common.Attributes;
using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Common.Exceptions;
using Umbraco.Web.Editors;
using Umbraco.Web.Models;
using Umbraco.Web.Models.ContentEditing;
using ContentType = Umbraco.Core.Models.ContentType;
using Umbraco.Core.Configuration.Models;
using Microsoft.Extensions.Options;
using Umbraco.Core.Serialization;
using Microsoft.AspNetCore.Authorization;
using Umbraco.Web.Common.Authorization;
namespace Umbraco.Web.BackOffice.Controllers
{
/// <summary>
/// An API controller used for dealing with content types
/// </summary>
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
[PluginController(Constants.Web.Mvc.BackOfficeApiArea)]
public class ContentTypeController : ContentTypeControllerBase<IContentType>
{
// TODO: Split this controller apart so that authz is consistent, currently we need to authz each action individually.
@@ -65,7 +63,8 @@ namespace Umbraco.Web.BackOffice.Controllers
private readonly IMacroService _macroService;
private readonly IEntityService _entityService;
private readonly IHostingEnvironment _hostingEnvironment;
private readonly IConfigurationEditorJsonSerializer _jsonSerializer;
private readonly IConfigurationEditorJsonSerializer _configurationEditorJsonSerializer;
private readonly IJsonSerializer _jsonSerializer;
public ContentTypeController(
ICultureDictionary cultureDictionary,
@@ -91,7 +90,8 @@ namespace Umbraco.Web.BackOffice.Controllers
IEntityService entityService,
IHostingEnvironment hostingEnvironment,
EditorValidatorCollection editorValidatorCollection,
IConfigurationEditorJsonSerializer jsonSerializer)
IConfigurationEditorJsonSerializer configurationEditorJsonSerializer,
IJsonSerializer jsonSerializer)
: base(cultureDictionary,
editorValidatorCollection,
contentTypeService,
@@ -119,6 +119,7 @@ namespace Umbraco.Web.BackOffice.Controllers
_macroService = macroService;
_entityService = entityService;
_hostingEnvironment = hostingEnvironment;
_configurationEditorJsonSerializer = configurationEditorJsonSerializer;
_jsonSerializer = jsonSerializer;
}
@@ -220,7 +221,7 @@ namespace Umbraco.Web.BackOffice.Controllers
/// Gets all user defined properties.
/// </summary>
/// <returns></returns>
[Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)]
[Authorize(Policy = AuthorizationPolicies.TreeAccessAnyContentOrTypes)]
public IEnumerable<string> GetAllPropertyTypeAliases()
{
return _contentTypeService.GetAllPropertyTypeAliases();
@@ -626,8 +627,23 @@ namespace Umbraco.Web.BackOffice.Controllers
return NotFound();
}
var dataInstaller = new PackageDataInstallation(_loggerFactory.CreateLogger<PackageDataInstallation>(), _loggerFactory, _fileService, _macroService, _LocalizationService,
_dataTypeService, _entityService, _contentTypeService, _contentService, _propertyEditors, _scopeProvider, _shortStringHelper, Options.Create(_globalSettings), _localizedTextService, _jsonSerializer);
var dataInstaller = new PackageDataInstallation(
_loggerFactory.CreateLogger<PackageDataInstallation>(),
_loggerFactory,
_fileService,
_macroService,
_LocalizationService,
_dataTypeService,
_entityService,
_contentTypeService,
_contentService,
_propertyEditors,
_scopeProvider,
_shortStringHelper,
Options.Create(_globalSettings),
_localizedTextService,
_configurationEditorJsonSerializer,
_jsonSerializer);
var xd = new XmlDocument {XmlResolver = null};
xd.Load(filePath);
@@ -643,7 +659,7 @@ namespace Umbraco.Web.BackOffice.Controllers
}
catch (Exception ex)
{
_logger.LogError(ex, "Error cleaning up temporary udt file in App_Data: {File}", filePath);
_logger.LogError(ex, "Error cleaning up temporary udt file in {File}", filePath);
}
return Ok();

View File

@@ -6,6 +6,7 @@ using System.Net;
using System.Net.Mime;
using System.Text;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Extensions.Logging;
@@ -22,7 +23,6 @@ using Umbraco.Core.Media;
using Umbraco.Core.Models;
using Umbraco.Core.Models.ContentEditing;
using Umbraco.Core.Models.Entities;
using Umbraco.Core.Models.Membership;
using Umbraco.Core.Models.Validation;
using Umbraco.Core.Persistence;
using Umbraco.Core.Persistence.Querying;
@@ -32,17 +32,15 @@ using Umbraco.Core.Serialization;
using Umbraco.Core.Services;
using Umbraco.Core.Strings;
using Umbraco.Extensions;
using Umbraco.Web.BackOffice.ActionResults;
using Umbraco.Web.BackOffice.Authorization;
using Umbraco.Web.BackOffice.Filters;
using Umbraco.Web.BackOffice.ModelBinders;
using Umbraco.Web.BackOffice.ActionResults;
using Umbraco.Web.Common.Attributes;
using Umbraco.Web.Common.Authorization;
using Umbraco.Web.Common.Exceptions;
using Umbraco.Web.ContentApps;
using Umbraco.Web.Models.ContentEditing;
using Constants = Umbraco.Core.Constants;
using Microsoft.AspNetCore.Authorization;
using Umbraco.Web.Common.Authorization;
using Umbraco.Web.BackOffice.Authorization;
namespace Umbraco.Web.BackOffice.Controllers
{
@@ -702,7 +700,7 @@ namespace Umbraco.Web.BackOffice.Controllers
return NotFound("The passed id doesn't exist");
}
var tempFiles = new PostedFiles();
//in case we pass a path with a folder in it, we will create it and upload media to it.
if (!string.IsNullOrEmpty(path))
@@ -882,7 +880,7 @@ namespace Umbraco.Web.BackOffice.Controllers
if (validatePermissions)
{
var requirement = new MediaPermissionsResourceRequirement();
var authorizationResult = await _authorizationService.AuthorizeAsync(User, _mediaService.GetById(intParentId), requirement);
var authorizationResult = await _authorizationService.AuthorizeAsync(User, new MediaPermissionsResource(_mediaService.GetById(intParentId)), requirement);
if (!authorizationResult.Succeeded)
{
throw new HttpResponseException(
@@ -893,7 +891,7 @@ namespace Umbraco.Web.BackOffice.Controllers
NotificationStyle.Warning)));
}
}
return intParentId;
}
@@ -909,7 +907,7 @@ namespace Umbraco.Web.BackOffice.Controllers
throw new HttpResponseException(HttpStatusCode.NotFound);
}
var toMove = _mediaService.GetById(model.Id);
if (toMove == null)
{
@@ -957,7 +955,7 @@ namespace Umbraco.Web.BackOffice.Controllers
return toMove;
}
public PagedResult<EntityBasic> GetPagedReferences(int id, string entityType, int pageNumber = 1, int pageSize = 100)
{

View File

@@ -1,8 +1,14 @@
using System;
using System.IO;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.Options;
using SixLabors.ImageSharp.Web.DependencyInjection;
using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
using Umbraco.Core.Hosting;
using Umbraco.Web.BackOffice.Middleware;
using Umbraco.Web.BackOffice.Plugins;
using Umbraco.Web.BackOffice.Routing;
using Umbraco.Web.Common.Security;
@@ -13,6 +19,7 @@ namespace Umbraco.Extensions
/// </summary>
public static class BackOfficeApplicationBuilderExtensions
{
app.UseUmbracoPlugins();
public static IApplicationBuilder UseUmbracoBackOffice(this IApplicationBuilder app)
{
// NOTE: This method will have been called after UseRouting, UseAuthentication, UseAuthorization
@@ -43,6 +50,30 @@ namespace Umbraco.Extensions
return app;
}
public static IApplicationBuilder UseUmbracoPlugins(this IApplicationBuilder app)
{
var hostingEnvironment = app.ApplicationServices.GetRequiredService<IHostingEnvironment>();
var umbracoPluginSettings = app.ApplicationServices.GetRequiredService<IOptions<UmbracoPluginSettings>>();
var pluginFolder = hostingEnvironment.MapPathContentRoot(Constants.SystemDirectories.AppPlugins);
// Ensure the plugin folder exists
Directory.CreateDirectory(pluginFolder);
var fileProvider = new UmbracoPluginPhysicalFileProvider(
pluginFolder,
umbracoPluginSettings);
app.UseStaticFiles(new StaticFileOptions
{
FileProvider = fileProvider,
RequestPath = Constants.SystemDirectories.AppPlugins
});
return app;
}
public static IApplicationBuilder UseUmbracoPreview(this IApplicationBuilder app)
{
// TODO: I'm unsure this middleware will execute before the endpoint, we'll have to see
@@ -56,7 +87,6 @@ namespace Umbraco.Extensions
return app;
}
private static IApplicationBuilder UseBackOfficeUserManagerAuditing(this IApplicationBuilder app)
{
var auditer = app.ApplicationServices.GetRequiredService<BackOfficeUserManagerAuditer>();

View File

@@ -0,0 +1,53 @@
// Copyright (c) Umbraco.
// See LICENSE for more details.
using System.IO;
using Microsoft.Extensions.FileProviders;
using Microsoft.Extensions.FileProviders.Physical;
using Microsoft.Extensions.Options;
using Umbraco.Core;
using Umbraco.Core.Configuration.Models;
namespace Umbraco.Web.BackOffice.Plugins
{
/// <summary>
/// Looks up files using the on-disk file system and check file extensions are on a allow list
/// </summary>
/// <remarks>
/// When the environment variable "DOTNET_USE_POLLING_FILE_WATCHER" is set to "1" or "true", calls to
/// <see cref="PhysicalFileProvider.Watch" /> will use <see cref="PollingFileChangeToken" />.
/// </remarks>
public class UmbracoPluginPhysicalFileProvider : PhysicalFileProvider, IFileProvider
{
private readonly IOptions<UmbracoPluginSettings> _options;
/// <summary>
/// Initializes a new instance of the <see cref="UmbracoPluginPhysicalFileProvider"/> class, at the given root directory.
/// </summary>
/// <param name="root">The root directory. This should be an absolute path.</param>
/// <param name="options">The configuration options.</param>
/// <param name="filters">Specifies which files or directories are excluded.</param>
public UmbracoPluginPhysicalFileProvider(string root, IOptions<UmbracoPluginSettings> options, ExclusionFilters filters = ExclusionFilters.Sensitive)
: base(root, filters) => _options = options;
/// <summary>
/// Locate a file at the given path by directly mapping path segments to physical directories.
/// </summary>
/// <remarks>
/// The path needs to pass the <see cref="ExclusionFilters"/> and the <see cref="UmbracoPluginSettings.BrowsableFileExtensions"/> to be found.
/// </remarks>
/// <param name="subpath">A path under the root directory</param>
/// <returns>The file information. Caller must check <see cref="IFileInfo.Exists"/> property. </returns>
public new IFileInfo GetFileInfo(string subpath)
{
var extension = Path.GetExtension(subpath);
var subPathInclAppPluginsFolder = Path.Combine(Constants.SystemDirectories.AppPlugins, subpath);
if (!_options.Value.BrowsableFileExtensions.Contains(extension))
{
return new NotFoundFileInfo(subPathInclAppPluginsFolder);
}
return base.GetFileInfo(subPathInclAppPluginsFolder);
}
}
}