1
0
mirror of https://github.com/bitwarden/server.git synced 2025-04-05 05:00:19 -05:00

try IAuthorizationRequirementData

This commit is contained in:
Thomas Rittson 2025-03-21 12:05:35 +10:00
parent 1c697544b8
commit dd67c41ed7
No known key found for this signature in database
GPG Key ID: CDDDA03861C35E27
3 changed files with 26 additions and 13 deletions

View File

@ -6,6 +6,7 @@ using Bit.Api.Vault.AuthorizationHandlers.Collections;
using Bit.Core; using Bit.Core;
using Bit.Core.AdminConsole.Enums; using Bit.Core.AdminConsole.Enums;
using Bit.Core.AdminConsole.Models.Data.Organizations.Policies; 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.Authorization;
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.Interfaces;
using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization;
@ -145,7 +146,7 @@ public class OrganizationUsersController : Controller
} }
[HttpGet("")] [HttpGet("")]
[Authorize(Policy = "owner")] [RoleRequirement(OrganizationUserType.Owner)]
public async Task<ListResponseModel<OrganizationUserUserDetailsResponseModel>> Get(Guid orgId, bool includeGroups = false, bool includeCollections = false) public async Task<ListResponseModel<OrganizationUserUserDetailsResponseModel>> Get(Guid orgId, bool includeGroups = false, bool includeCollections = false)
{ {
// var authorized = (await _authorizationService.AuthorizeAsync( // var authorized = (await _authorizationService.AuthorizeAsync(

View File

@ -27,10 +27,8 @@ using Bit.Core.OrganizationFeatures.OrganizationSubscriptions;
using Bit.Core.Tools.Entities; using Bit.Core.Tools.Entities;
using Bit.Core.Vault.Entities; using Bit.Core.Vault.Entities;
using Bit.Api.Auth.Models.Request.WebAuthn; using Bit.Api.Auth.Models.Request.WebAuthn;
using Bit.Core.AdminConsole.OrganizationFeatures;
using Bit.Core.Auth.Models.Data; using Bit.Core.Auth.Models.Data;
using Bit.Core.Auth.Identity.TokenProviders; using Bit.Core.Auth.Identity.TokenProviders;
using Bit.Core.Enums;
using Bit.Core.Tools.ImportFeatures; using Bit.Core.Tools.ImportFeatures;
using Bit.Core.Tools.ReportFeatures; 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 // - 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 // 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 // the handler is then implemented per domain to define who can do those things
config.AddPolicy("owner", policy // config.AddPolicy("owner", policy
=> policy.AddRequirements(new RoleRequirement(OrganizationUserType.Owner))); // => policy.AddRequirements(new RoleRequirementAttribute(OrganizationUserType.Owner)));
config.AddPolicy("admin", policy // config.AddPolicy("admin", policy
=> policy.AddRequirements(new RoleRequirement(OrganizationUserType.Admin))); // => policy.AddRequirements(new RoleRequirementAttribute(OrganizationUserType.Admin)));
}); });
services.AddScoped<AuthenticatorTokenProvider>(); services.AddScoped<AuthenticatorTokenProvider>();

View File

@ -6,11 +6,25 @@ using Microsoft.AspNetCore.Routing;
namespace Bit.Core.AdminConsole.OrganizationFeatures; namespace Bit.Core.AdminConsole.OrganizationFeatures;
public record RoleRequirement(OrganizationUserType Role) : IAuthorizationRequirement; public class RoleRequirementAttribute
: AuthorizeAttribute, IAuthorizationRequirement, IAuthorizationRequirementData
public class RoleAuthorizationHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) : AuthorizationHandler<RoleRequirement>
{ {
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirement requirement) public OrganizationUserType Role { get; set; }
public RoleRequirementAttribute(OrganizationUserType type)
{
Role = type;
}
public IEnumerable<IAuthorizationRequirement> GetRequirements()
{
yield return this;
}
}
public class RoleAuthorizationHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) : AuthorizationHandler<RoleRequirementAttribute>
{
protected override Task HandleRequirementAsync(AuthorizationHandlerContext context, RoleRequirementAttribute requirementAttribute)
{ {
if (httpContextAccessor.HttpContext is null) if (httpContextAccessor.HttpContext is null)
{ {
@ -26,9 +40,9 @@ public class RoleAuthorizationHandler(ICurrentContext currentContext, IHttpConte
// This could be an extension method on ClaimsPrincipal // This could be an extension method on ClaimsPrincipal
var orgClaims = currentContext.GetOrganization(orgId); var orgClaims = currentContext.GetOrganization(orgId);
if (orgClaims?.Type == requirement.Role) if (orgClaims?.Type == requirementAttribute.Role)
{ {
context.Succeed(requirement); context.Succeed(requirementAttribute);
} }
return Task.CompletedTask; return Task.CompletedTask;