diff --git a/src/Api/Utilities/ServiceCollectionExtensions.cs b/src/Api/Utilities/ServiceCollectionExtensions.cs index 41c086e81f..c53c9f7692 100644 --- a/src/Api/Utilities/ServiceCollectionExtensions.cs +++ b/src/Api/Utilities/ServiceCollectionExtensions.cs @@ -1,7 +1,7 @@ using Bit.Api.Tools.Authorization; using Bit.Api.Vault.AuthorizationHandlers.Collections; -using Bit.Core.AdminConsole.OrganizationFeatures; using Bit.Core.AdminConsole.OrganizationFeatures.Groups.Authorization; +using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; using Bit.Core.IdentityServer; using Bit.Core.Settings; using Bit.Core.Utilities; @@ -107,6 +107,6 @@ public static class ServiceCollectionExtensions services.AddScoped(); services.AddScoped(); - services.AddScoped(); + services.AddScoped(); } } diff --git a/src/Core/AdminConsole/OrganizationFeatures/ManageUserRequirementHandler.cs b/src/Core/AdminConsole/OrganizationFeatures/ManageUserRequirementHandler.cs deleted file mode 100644 index 1ade49f7de..0000000000 --- a/src/Core/AdminConsole/OrganizationFeatures/ManageUserRequirementHandler.cs +++ /dev/null @@ -1,21 +0,0 @@ -#nullable enable - -using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; -using Bit.Core.Context; -using Bit.Core.Enums; -using Microsoft.AspNetCore.Http; - -namespace Bit.Core.AdminConsole.OrganizationFeatures; - -public class ManageUsersRequirement : IOrganizationRequirement; - -public class ManageUserRequirementHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) - : OrganizationRequirementHandler(currentContext, httpContextAccessor) -{ - private readonly ICurrentContext _currentContext = currentContext; - - protected override async Task Authorize(Guid organizationId, CurrentContextOrganization? organizationClaims) - => organizationClaims is { Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or - { Permissions.ManageUsers: true } - || await _currentContext.ProviderUserForOrgAsync(organizationId); -} diff --git a/src/Core/AdminConsole/OrganizationFeatures/ManageUsersRequirement.cs b/src/Core/AdminConsole/OrganizationFeatures/ManageUsersRequirement.cs new file mode 100644 index 0000000000..6e528d9f5d --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/ManageUsersRequirement.cs @@ -0,0 +1,16 @@ +#nullable enable + +using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; +using Bit.Core.Context; +using Bit.Core.Enums; + +namespace Bit.Core.AdminConsole.OrganizationFeatures; + +public class ManageUsersRequirement : IOrganizationRequirement +{ + public async Task AuthorizeAsync(Guid organizationId, CurrentContextOrganization? organizationClaims, ICurrentContext currentContext) + => organizationClaims is + { Type: OrganizationUserType.Owner or OrganizationUserType.Admin } or + { Permissions.ManageUsers: true } + || await currentContext.ProviderUserForOrgAsync(organizationId); +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationMemberRequirement.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationMemberRequirement.cs new file mode 100644 index 0000000000..3176ea1deb --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationMemberRequirement.cs @@ -0,0 +1,12 @@ +#nullable enable + +using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; +using Bit.Core.Context; + +namespace Bit.Core.AdminConsole.OrganizationFeatures; + +public class OrganizationMemberRequirement : IOrganizationRequirement +{ + public Task AuthorizeAsync(Guid organizationId, CurrentContextOrganization? organizationClaims, ICurrentContext currentContext) + => Task.FromResult(organizationClaims is not null); +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUserRequirementHandler.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUserRequirementHandler.cs deleted file mode 100644 index 3437321963..0000000000 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUserRequirementHandler.cs +++ /dev/null @@ -1,16 +0,0 @@ -#nullable enable - -using Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; -using Bit.Core.Context; -using Microsoft.AspNetCore.Http; - -namespace Bit.Core.AdminConsole.OrganizationFeatures; - -public class OrganizationMemberRequirement : IOrganizationRequirement; - -public class OrganizationMemberRequirementHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) - : OrganizationRequirementHandler(currentContext, httpContextAccessor) -{ - protected override Task Authorize(Guid organizationId, CurrentContextOrganization? organizationClaims) - => Task.FromResult(organizationClaims is not null); -} diff --git a/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationAuthorizeAttribute.cs b/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationAuthorizeAttribute.cs index d7eba2a277..6ad4764a98 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationAuthorizeAttribute.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationAuthorizeAttribute.cs @@ -1,8 +1,15 @@ -using Microsoft.AspNetCore.Authorization; +#nullable enable + +using Bit.Core.Context; +using Microsoft.AspNetCore.Authorization; namespace Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; -public interface IOrganizationRequirement : IAuthorizationRequirement; +public interface IOrganizationRequirement : IAuthorizationRequirement +{ + // TODO: avoid injecting all of ICurrentContext? + public Task AuthorizeAsync(Guid organizationId, CurrentContextOrganization? organizationClaims, ICurrentContext currentContext); +} public class OrganizationAuthorizeAttribute : AuthorizeAttribute, IAuthorizationRequirementData diff --git a/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationRequirementHandler.cs b/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationRequirementHandler.cs index 5b0c82832f..85303c67a2 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationRequirementHandler.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/Shared/Authorization/OrganizationRequirementHandler.cs @@ -6,13 +6,10 @@ using Microsoft.AspNetCore.Http; namespace Bit.Core.AdminConsole.OrganizationFeatures.Shared.Authorization; -public abstract class OrganizationRequirementHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) - : AuthorizationHandler - where T : IAuthorizationRequirement +public class OrganizationRequirementHandler(ICurrentContext currentContext, IHttpContextAccessor httpContextAccessor) + : AuthorizationHandler { - protected abstract Task Authorize(Guid organizationId, CurrentContextOrganization? organizationClaims); - - protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, T requirement) + protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, IOrganizationRequirement requirement) { var organizationId = httpContextAccessor.GetOrganizationId(); if (organizationId is null) @@ -22,7 +19,7 @@ public abstract class OrganizationRequirementHandler(ICurrentContext currentC var organization = currentContext.GetOrganization(organizationId.Value); - var authorized = await Authorize(organizationId.Value, organization); + var authorized = await requirement.AuthorizeAsync(organizationId.Value, organization, currentContext); if (authorized) {