From dd67c41ed7c9ea7e990854317d9dd659f0cfee79 Mon Sep 17 00:00:00 2001 From: Thomas Rittson Date: Fri, 21 Mar 2025 12:05:35 +1000 Subject: [PATCH] try IAuthorizationRequirementData --- .../OrganizationUsersController.cs | 3 ++- src/Api/Startup.cs | 10 +++---- .../RoleAuthorizationHandler.cs | 26 ++++++++++++++----- 3 files changed, 26 insertions(+), 13 deletions(-) diff --git a/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs b/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs index 682f9776e1..afc2678dbf 100644 --- a/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs +++ b/src/Api/AdminConsole/Controllers/OrganizationUsersController.cs @@ -6,6 +6,7 @@ using Bit.Api.Vault.AuthorizationHandlers.Collections; using Bit.Core; using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; +using Bit.Core.AdminConsole.OrganizationFeatures; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Authorization; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; @@ -145,7 +146,7 @@ public class OrganizationUsersController : Controller } [HttpGet("")] - [Authorize(Policy = "owner")] + [RoleRequirement(OrganizationUserType.Owner)] public async Task> Get(Guid orgId, bool includeGroups = false, bool includeCollections = false) { // var authorized = (await _authorizationService.AuthorizeAsync( diff --git a/src/Api/Startup.cs b/src/Api/Startup.cs index 8ca6baf044..338fd68daa 100644 --- a/src/Api/Startup.cs +++ b/src/Api/Startup.cs @@ -27,10 +27,8 @@ using Bit.Core.OrganizationFeatures.OrganizationSubscriptions; using Bit.Core.Tools.Entities; using Bit.Core.Vault.Entities; using Bit.Api.Auth.Models.Request.WebAuthn; -using Bit.Core.AdminConsole.OrganizationFeatures; using Bit.Core.Auth.Models.Data; using Bit.Core.Auth.Identity.TokenProviders; -using Bit.Core.Enums; using Bit.Core.Tools.ImportFeatures; using Bit.Core.Tools.ReportFeatures; @@ -153,10 +151,10 @@ public class Startup // - does not allow for more complex conditional logic - e.g. providers can affect whether owners can view billing // Alternative: describe broad action/capability, e.g. ManageUsers, ManageGroups, ViewBilling, similar to CurrentContext today // the handler is then implemented per domain to define who can do those things - config.AddPolicy("owner", policy - => policy.AddRequirements(new RoleRequirement(OrganizationUserType.Owner))); - config.AddPolicy("admin", policy - => policy.AddRequirements(new RoleRequirement(OrganizationUserType.Admin))); + // config.AddPolicy("owner", policy + // => policy.AddRequirements(new RoleRequirementAttribute(OrganizationUserType.Owner))); + // config.AddPolicy("admin", policy + // => policy.AddRequirements(new RoleRequirementAttribute(OrganizationUserType.Admin))); }); services.AddScoped(); diff --git a/src/Core/AdminConsole/OrganizationFeatures/RoleAuthorizationHandler.cs b/src/Core/AdminConsole/OrganizationFeatures/RoleAuthorizationHandler.cs index b75565edba..6a873aa844 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/RoleAuthorizationHandler.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/RoleAuthorizationHandler.cs @@ -6,11 +6,25 @@ using Microsoft.AspNetCore.Routing; namespace Bit.Core.AdminConsole.OrganizationFeatures; -public record RoleRequirement(OrganizationUserType Role) : IAuthorizationRequirement; - -public class RoleAuthorizationHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) : AuthorizationHandler +public class RoleRequirementAttribute + : AuthorizeAttribute, IAuthorizationRequirement, IAuthorizationRequirementData { - protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirement requirement) + public OrganizationUserType Role { get; set; } + + public RoleRequirementAttribute(OrganizationUserType type) + { + Role = type; + } + + public IEnumerable GetRequirements() + { + yield return this; + } +} + +public class RoleAuthorizationHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) : AuthorizationHandler +{ + protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirementAttribute requirementAttribute) { if (httpContextAccessor.HttpContext is null) { @@ -26,9 +40,9 @@ public class RoleAuthorizationHandler(ICurrentContext currentContext, IHttpConte // This could be an extension method on ClaimsPrincipal var orgClaims = currentContext.GetOrganization(orgId); - if (orgClaims?.Type == requirement.Role) + if (orgClaims?.Type == requirementAttribute.Role) { - context.Succeed(requirement); + context.Succeed(requirementAttribute); } return Task.CompletedTask;