From 36b3a2b62a90bec2b98b276f4d7d6596b527fcfa Mon Sep 17 00:00:00 2001 From: Shannon Date: Mon, 30 Nov 2020 19:38:55 +1100 Subject: [PATCH] fixes media authz resource policies --- .../ContentPermissionsResourceHandler.cs | 1 - .../Authorization/MediaPermissionsResource.cs | 20 +++++++++++++++ .../MediaPermissionsResourceHandler.cs | 25 +++++++------------ .../MediaPermissionsResourceRequirement.cs | 12 ++------- .../BackOfficeServiceCollectionExtensions.cs | 6 +++++ .../MediaItemSaveValidationAttribute.cs | 13 +++++++--- .../Authorization/AuthorizationPolicies.cs | 2 ++ 7 files changed, 48 insertions(+), 31 deletions(-) create mode 100644 src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResource.cs diff --git a/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResourceHandler.cs b/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResourceHandler.cs index 34d76392cc..bcd8ef9add 100644 --- a/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResourceHandler.cs +++ b/src/Umbraco.Web.BackOffice/Authorization/ContentPermissionsResourceHandler.cs @@ -24,7 +24,6 @@ namespace Umbraco.Web.BackOffice.Authorization protected override Task IsAuthorized(AuthorizationHandlerContext context, ContentPermissionsResourceRequirement requirement, ContentPermissionsResource resource) { - var permissionResult = resource.NodeId.HasValue ? _contentPermissions.CheckPermissions( resource.NodeId.Value, diff --git a/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResource.cs b/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResource.cs new file mode 100644 index 0000000000..5b1ed92f5f --- /dev/null +++ b/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResource.cs @@ -0,0 +1,20 @@ +using Umbraco.Core.Models; + +namespace Umbraco.Web.BackOffice.Authorization +{ + public class MediaPermissionsResource + { + public MediaPermissionsResource(IMedia media) + { + Media = media; + } + + public MediaPermissionsResource(int nodeId) + { + NodeId = nodeId; + } + + public int? NodeId { get; } + public IMedia Media { get; } + } +} diff --git a/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceHandler.cs b/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceHandler.cs index 8b016bf466..6c5280a19c 100644 --- a/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceHandler.cs +++ b/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceHandler.cs @@ -8,7 +8,7 @@ namespace Umbraco.Web.BackOffice.Authorization /// /// Used to authorize if the user has the correct permission access to the content for the specified /// - public class MediaPermissionsResourceHandler : MustSatisfyRequirementAuthorizationHandler + public class MediaPermissionsResourceHandler : MustSatisfyRequirementAuthorizationHandler { private readonly IBackOfficeSecurityAccessor _backofficeSecurityAccessor; private readonly MediaPermissions _mediaPermissions; @@ -21,23 +21,16 @@ namespace Umbraco.Web.BackOffice.Authorization _mediaPermissions = mediaPermissions; } - protected override Task IsAuthorized(AuthorizationHandlerContext context, MediaPermissionsResourceRequirement requirement, IMedia resource) + protected override Task IsAuthorized(AuthorizationHandlerContext context, MediaPermissionsResourceRequirement requirement, MediaPermissionsResource resource) { - var permissionResult = MediaPermissions.MediaAccess.NotFound; - - if (resource != null) - { - permissionResult = _mediaPermissions.CheckPermissions( - resource, - _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser); - } - else if (requirement.NodeId.HasValue) - { - permissionResult = _mediaPermissions.CheckPermissions( + var permissionResult = resource.NodeId.HasValue + ? _mediaPermissions.CheckPermissions( _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser, - requirement.NodeId.Value, - out _); - } + resource.NodeId.Value, + out _) + : _mediaPermissions.CheckPermissions( + resource.Media, + _backofficeSecurityAccessor.BackOfficeSecurity.CurrentUser); return Task.FromResult(permissionResult != MediaPermissions.MediaAccess.Denied); } diff --git a/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceRequirement.cs b/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceRequirement.cs index 0cd51c9c15..3087e4b258 100644 --- a/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceRequirement.cs +++ b/src/Umbraco.Web.BackOffice/Authorization/MediaPermissionsResourceRequirement.cs @@ -2,20 +2,12 @@ namespace Umbraco.Web.BackOffice.Authorization { + /// /// An authorization requirement for /// public class MediaPermissionsResourceRequirement : IAuthorizationRequirement { - public MediaPermissionsResourceRequirement() - { - } - - public MediaPermissionsResourceRequirement(int nodeId) - { - NodeId = nodeId; - } - - public int? NodeId { get; } + } } diff --git a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs index 3b9eb28881..d13a908034 100644 --- a/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs +++ b/src/Umbraco.Web.BackOffice/Extensions/BackOfficeServiceCollectionExtensions.cs @@ -105,6 +105,12 @@ namespace Umbraco.Extensions private static void CreatePolicies(AuthorizationOptions options, string backOfficeAuthenticationScheme) { + options.AddPolicy(AuthorizationPolicies.MediaPermissionByResource, policy => + { + policy.AuthenticationSchemes.Add(backOfficeAuthenticationScheme); + policy.Requirements.Add(new MediaPermissionsResourceRequirement()); + }); + options.AddPolicy(AuthorizationPolicies.MediaPermissionPathById, policy => { policy.AuthenticationSchemes.Add(backOfficeAuthenticationScheme); diff --git a/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs b/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs index 52ec08e4b4..3ba2b408ef 100644 --- a/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs +++ b/src/Umbraco.Web.BackOffice/Filters/MediaItemSaveValidationAttribute.cs @@ -9,6 +9,7 @@ using Umbraco.Core.Models; using Umbraco.Core.Security; using Umbraco.Core.Services; using Umbraco.Web.BackOffice.Authorization; +using Umbraco.Web.Common.Authorization; using Umbraco.Web.Models.ContentEditing; namespace Umbraco.Web.BackOffice.Filters @@ -107,11 +108,15 @@ namespace Umbraco.Web.BackOffice.Filters return false; } - var requirement = contentToCheck == null - ? new MediaPermissionsResourceRequirement(contentIdToCheck) - : new MediaPermissionsResourceRequirement(); + var resource = contentToCheck == null + ? new MediaPermissionsResource(contentIdToCheck) + : new MediaPermissionsResource(contentToCheck); + + var authorizationResult = await _authorizationService.AuthorizeAsync( + actionContext.HttpContext.User, + resource, + AuthorizationPolicies.MediaPermissionByResource); - var authorizationResult = await _authorizationService.AuthorizeAsync(actionContext.HttpContext.User, contentToCheck, requirement); if (!authorizationResult.Succeeded) { actionContext.Result = new ForbidResult(); diff --git a/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs b/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs index 2227912a7e..56070f5033 100644 --- a/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs +++ b/src/Umbraco.Web.Common/Authorization/AuthorizationPolicies.cs @@ -24,7 +24,9 @@ public const string ContentPermissionBrowseById = nameof(ContentPermissionBrowseById); public const string ContentPermissionDeleteById = nameof(ContentPermissionDeleteById); + public const string MediaPermissionByResource = nameof(MediaPermissionByResource); public const string MediaPermissionPathById = nameof(MediaPermissionPathById); + // Single section access