Add policies for content template handling (#15482)
This commit is contained in:
committed by
Bjarke Berg
parent
38f7df2b0c
commit
e8a81e30b1
@@ -826,6 +826,7 @@ public class ContentController : ContentControllerBase
|
||||
/// <param name="contentId">The content id to copy</param>
|
||||
/// <param name="name">The name of the blueprint</param>
|
||||
/// <returns></returns>
|
||||
[Authorize(Policy = AuthorizationPolicies.ContentPermissionCreateBlueprintFromId)]
|
||||
[HttpPost]
|
||||
public ActionResult<SimpleNotificationModel> CreateBlueprintFromContent(
|
||||
[FromQuery] int contentId,
|
||||
@@ -881,8 +882,9 @@ public class ContentController : ContentControllerBase
|
||||
/// <summary>
|
||||
/// Saves content
|
||||
/// </summary>
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
|
||||
[FileUploadCleanupFilter]
|
||||
[ContentSaveValidation]
|
||||
[ContentSaveValidation(skipUserAccessValidation:true)] // skip user access validation because we "only" require Settings access to create new blueprints from scratch
|
||||
public async Task<ActionResult<ContentItemDisplay<ContentVariantDisplay>?>?> PostSaveBlueprint(
|
||||
[ModelBinder(typeof(BlueprintItemBinder))] ContentItemSave contentItem)
|
||||
{
|
||||
@@ -2077,6 +2079,7 @@ public class ContentController : ContentControllerBase
|
||||
return Ok();
|
||||
}
|
||||
|
||||
[Authorize(Policy = AuthorizationPolicies.TreeAccessDocumentTypes)]
|
||||
[HttpDelete]
|
||||
[HttpPost]
|
||||
public IActionResult DeleteBlueprint(int id)
|
||||
|
||||
@@ -179,6 +179,13 @@ public static partial class UmbracoBuilderExtensions
|
||||
policy.Requirements.Add(new ContentPermissionsQueryStringRequirement(ActionDelete.ActionLetter));
|
||||
});
|
||||
|
||||
options.AddPolicy(AuthorizationPolicies.ContentPermissionCreateBlueprintFromId, policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add(backOfficeAuthenticationScheme);
|
||||
policy.Requirements.Add(
|
||||
new ContentPermissionsQueryStringRequirement(ActionCreateBlueprintFromContent.ActionLetter, "contentId"));
|
||||
});
|
||||
|
||||
options.AddPolicy(AuthorizationPolicies.BackOfficeAccess, policy =>
|
||||
{
|
||||
policy.AuthenticationSchemes.Add(backOfficeAuthenticationScheme);
|
||||
|
||||
@@ -20,9 +20,12 @@ namespace Umbraco.Cms.Web.BackOffice.Filters;
|
||||
/// </summary>
|
||||
internal sealed class ContentSaveValidationAttribute : TypeFilterAttribute
|
||||
{
|
||||
public ContentSaveValidationAttribute() : base(typeof(ContentSaveValidationFilter)) =>
|
||||
public ContentSaveValidationAttribute(bool skipUserAccessValidation = false)
|
||||
: base(typeof(ContentSaveValidationFilter))
|
||||
{
|
||||
Order = -3000; // More important than ModelStateInvalidFilter.FilterOrder
|
||||
|
||||
Arguments = new object[] { skipUserAccessValidation };
|
||||
}
|
||||
|
||||
private sealed class ContentSaveValidationFilter : IAsyncActionFilter
|
||||
{
|
||||
@@ -32,6 +35,7 @@ internal sealed class ContentSaveValidationAttribute : TypeFilterAttribute
|
||||
private readonly ILocalizationService _localizationService;
|
||||
private readonly ILoggerFactory _loggerFactory;
|
||||
private readonly IPropertyValidationService _propertyValidationService;
|
||||
private readonly bool _skipUserAccessValidation;
|
||||
|
||||
|
||||
public ContentSaveValidationFilter(
|
||||
@@ -40,7 +44,8 @@ internal sealed class ContentSaveValidationAttribute : TypeFilterAttribute
|
||||
IPropertyValidationService propertyValidationService,
|
||||
IAuthorizationService authorizationService,
|
||||
IBackOfficeSecurityAccessor backOfficeSecurityAccessor,
|
||||
ILocalizationService localizationService)
|
||||
ILocalizationService localizationService,
|
||||
bool skipUserAccessValidation)
|
||||
{
|
||||
_loggerFactory = loggerFactory ?? throw new ArgumentNullException(nameof(loggerFactory));
|
||||
_contentService = contentService ?? throw new ArgumentNullException(nameof(contentService));
|
||||
@@ -49,6 +54,7 @@ internal sealed class ContentSaveValidationAttribute : TypeFilterAttribute
|
||||
_authorizationService = authorizationService;
|
||||
_backOfficeSecurityAccessor = backOfficeSecurityAccessor;
|
||||
_localizationService = localizationService;
|
||||
_skipUserAccessValidation = skipUserAccessValidation;
|
||||
}
|
||||
|
||||
public async Task OnActionExecutionAsync(ActionExecutingContext context, ActionExecutionDelegate next)
|
||||
@@ -88,7 +94,7 @@ internal sealed class ContentSaveValidationAttribute : TypeFilterAttribute
|
||||
return;
|
||||
}
|
||||
|
||||
if (!await ValidateUserAccessAsync(model, context))
|
||||
if (_skipUserAccessValidation is false && await ValidateUserAccessAsync(model, context) is false)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -22,6 +22,7 @@ public static class AuthorizationPolicies
|
||||
public const string ContentPermissionProtectById = nameof(ContentPermissionProtectById);
|
||||
public const string ContentPermissionBrowseById = nameof(ContentPermissionBrowseById);
|
||||
public const string ContentPermissionDeleteById = nameof(ContentPermissionDeleteById);
|
||||
public const string ContentPermissionCreateBlueprintFromId = nameof(ContentPermissionCreateBlueprintFromId);
|
||||
|
||||
public const string MediaPermissionByResource = nameof(MediaPermissionByResource);
|
||||
public const string MediaPermissionPathById = nameof(MediaPermissionPathById);
|
||||
|
||||
Reference in New Issue
Block a user