From 3fe4337c3d09e18d9ef3e97a3f06beb061ce47ba Mon Sep 17 00:00:00 2001 From: Kevin Jump Date: Mon, 16 Sep 2024 12:08:03 +0100 Subject: [PATCH] set custom authorization polcies (not just 'settings access') --- .../SyncAuthorizationPolicies.cs | 55 ++++++++++++++++++- .../uSyncBackOfficeBuilderExtensions.cs | 12 ++-- .../Controllers/uSyncControllerBase.cs | 6 +- .../usync-assets/package-lock.json | 4 +- .../usync-assets/package.json | 2 +- 5 files changed, 66 insertions(+), 13 deletions(-) diff --git a/uSync.BackOffice/Authorization/SyncAuthorizationPolicies.cs b/uSync.BackOffice/Authorization/SyncAuthorizationPolicies.cs index 8ebfc8e5..51f7344d 100644 --- a/uSync.BackOffice/Authorization/SyncAuthorizationPolicies.cs +++ b/uSync.BackOffice/Authorization/SyncAuthorizationPolicies.cs @@ -1,4 +1,12 @@ -namespace uSync.BackOffice.Authorization; +using Microsoft.AspNetCore.Authorization; + +using System.Threading.Tasks; +using Umbraco.Cms.Api.Management.Security.Authorization; +using Umbraco.Cms.Core.Models.Membership; +using Umbraco.Cms.Core.Security.Authorization; +using Umbraco.Extensions; + +namespace uSync.BackOffice.Authorization; /// /// Security policy constants used in Umbraco by uSync @@ -10,3 +18,48 @@ public static class SyncAuthorizationPolicies /// public const string TreeAccessuSync = nameof(TreeAccessuSync); } + +/// +/// this is identical to the internal AllowedApplicationRequirement, but because +/// that is internal, we have to replicate all the code. +/// +public sealed class uSyncApplicationRequirement : IAuthorizationRequirement +{ + /// + /// list of applications that this requirement will check against. + /// + public string[] Applications { get; } + + /// + /// create a new requirement for the given applications + /// + /// + public uSyncApplicationRequirement(params string[] applications) + { + Applications = applications; + } +} + +/// +/// public version of internal Umbraco AllowedApplicationHandler - so we can secure to a tree. +/// +public sealed class uSyncAllowedApplicationHandler : MustSatisfyRequirementAuthorizationHandler +{ + private readonly IAuthorizationHelper _authorizationHelper; + + /// + /// new handler for the given authorization helper + /// + public uSyncAllowedApplicationHandler(IAuthorizationHelper authorizationHelper) + => _authorizationHelper = authorizationHelper; + + /// + /// check to see if this is authorized + /// + protected override Task IsAuthorized(AuthorizationHandlerContext context, uSyncApplicationRequirement requirement) + { + var allowed = _authorizationHelper.TryGetUmbracoUser(context.User, out IUser? user) + && user.AllowedSections.ContainsAny(requirement.Applications); + return Task.FromResult(allowed); + } +} diff --git a/uSync.BackOffice/uSyncBackOfficeBuilderExtensions.cs b/uSync.BackOffice/uSyncBackOfficeBuilderExtensions.cs index d419ff41..893372f3 100644 --- a/uSync.BackOffice/uSyncBackOfficeBuilderExtensions.cs +++ b/uSync.BackOffice/uSyncBackOfficeBuilderExtensions.cs @@ -11,6 +11,7 @@ using Umbraco.Cms.Core.Notifications; using Umbraco.Cms.Web.Common.ApplicationBuilder; +using uSync.BackOffice.Authorization; using uSync.BackOffice.Boot; using uSync.BackOffice.Cache; using uSync.BackOffice.Configuration; @@ -84,6 +85,7 @@ public static IUmbracoBuilder AdduSync(this IUmbracoBuilder builder, Action(); + builder.Services.AddSingleton(); builder.Services.AddAuthorization(o => CreatePolicies(o)); builder.Services.AddTransient(); @@ -246,10 +248,10 @@ internal static void AddHandlerNotifications(this IUmbracoBuilder builder) private static void CreatePolicies(AuthorizationOptions options, string backofficeAuthenticationScheme = Constants.Security.BackOfficeAuthenticationType) { - //options.AddPolicy(SyncAuthorizationPolicies.TreeAccessuSync, policy => - //{ - // policy.AuthenticationSchemes.Add(backofficeAuthenticationScheme); - // policy.Requirements.Add(new TreeRequirement(uSync.Trees.uSync)); - //}); + options.AddPolicy(SyncAuthorizationPolicies.TreeAccessuSync, policy => + { + policy.AuthenticationSchemes.Add(backofficeAuthenticationScheme); + policy.Requirements.Add(new uSyncApplicationRequirement(Constants.Applications.Settings)); + }); } } diff --git a/uSync.Backoffice.Management.Api/Controllers/uSyncControllerBase.cs b/uSync.Backoffice.Management.Api/Controllers/uSyncControllerBase.cs index 986c2e6d..50b5b1e2 100644 --- a/uSync.Backoffice.Management.Api/Controllers/uSyncControllerBase.cs +++ b/uSync.Backoffice.Management.Api/Controllers/uSyncControllerBase.cs @@ -4,19 +4,17 @@ using Umbraco.Cms.Api.Common.Attributes; using Umbraco.Cms.Api.Common.Filters; using Umbraco.Cms.Core; -using Umbraco.Cms.Web.Common.Authorization; using uSync.Backoffice.Management.Api.Configuration; +using uSync.BackOffice.Authorization; namespace uSync.Backoffice.Management.Api.Controllers; [ApiController] [uSyncVersionedRoute("")] -[Authorize(Policy = AuthorizationPolicies.BackOfficeAccess)] +[Authorize(Policy = SyncAuthorizationPolicies.TreeAccessuSync)] [MapToApi(uSyncClient.Api.ApiName)] -// [JsonOptionsName(uSyncClient.Api.ApiName)] [JsonOptionsName(Constants.JsonOptionsNames.BackOffice)] - public class uSyncControllerBase { } diff --git a/uSync.Backoffice.Management.Client/usync-assets/package-lock.json b/uSync.Backoffice.Management.Client/usync-assets/package-lock.json index 8cd131fc..6ae927e8 100644 --- a/uSync.Backoffice.Management.Client/usync-assets/package-lock.json +++ b/uSync.Backoffice.Management.Client/usync-assets/package-lock.json @@ -1,12 +1,12 @@ { "name": "@jumoo/usync", - "version": "14.2.1-build.20240914.1", + "version": "14.2.1", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "@jumoo/usync", - "version": "14.2.1-build.20240914.1", + "version": "14.2.1", "license": "MPL-2.0", "devDependencies": { "@hey-api/openapi-ts": "^0.53.0", diff --git a/uSync.Backoffice.Management.Client/usync-assets/package.json b/uSync.Backoffice.Management.Client/usync-assets/package.json index e19a3104..8b3bd66a 100644 --- a/uSync.Backoffice.Management.Client/usync-assets/package.json +++ b/uSync.Backoffice.Management.Client/usync-assets/package.json @@ -2,7 +2,7 @@ "name": "@jumoo/usync", "license": "MPL-2.0", "type": "module", - "version": "14.2.1-build.20240914.1", + "version": "14.2.1", "main": "./dist/usync.js", "types": "./dist/index.d.ts", "module": "./dist/usync.js",