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

fix tests for real

This commit is contained in:
Thomas Rittson 2025-04-02 13:05:28 +10:00
parent 047307b48a
commit 99cb6954a9
No known key found for this signature in database
GPG Key ID: CDDDA03861C35E27
3 changed files with 19 additions and 12 deletions

View File

@ -17,12 +17,15 @@ public class OrganizationRequirementHandler(
IUserService userService) IUserService userService)
: AuthorizationHandler<IOrganizationRequirement> : AuthorizationHandler<IOrganizationRequirement>
{ {
public const string NoHttpContextError = "This method should only be called in the context of an HTTP Request.";
public const string NoUserIdError = "This method should only be called on the private api with a logged in user.";
protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, IOrganizationRequirement requirement) protected override async Task HandleRequirementAsync(AuthorizationHandlerContext context, IOrganizationRequirement requirement)
{ {
var httpContext = httpContextAccessor.HttpContext; var httpContext = httpContextAccessor.HttpContext;
if (httpContext == null) if (httpContext == null)
{ {
throw new InvalidOperationException("This method should only be called in the context of an HTTP Request."); throw new InvalidOperationException(NoHttpContextError);
} }
var organizationId = httpContext.GetOrganizationId(); var organizationId = httpContext.GetOrganizationId();
@ -31,7 +34,7 @@ public class OrganizationRequirementHandler(
var userId = userService.GetProperUserId(httpContext.User); var userId = userService.GetProperUserId(httpContext.User);
if (userId == null) if (userId == null)
{ {
throw new InvalidOperationException("This method should only be called on the private api with a logged in user."); throw new InvalidOperationException(NoUserIdError);
} }
Task<bool> IsProviderUserForOrg() => httpContextAccessor.HttpContext.IsProviderUserForOrgAsync(providerUserRepository, userId.Value, organizationId); Task<bool> IsProviderUserForOrg() => httpContextAccessor.HttpContext.IsProviderUserForOrgAsync(providerUserRepository, userId.Value, organizationId);

View File

@ -4,13 +4,15 @@ namespace Bit.Api.AdminConsole.Authorization;
public static class OrganizationRequirementHelpers public static class OrganizationRequirementHelpers
{ {
public const string NoOrgIdError =
"A route decorated with with '[Authorize<Requirement>]' should include a route value named 'orgId' either through the [Controller] attribute or through a '[Http*]' attribute.";
public static Guid GetOrganizationId(this HttpContext httpContext) public static Guid GetOrganizationId(this HttpContext httpContext)
{ {
httpContext.GetRouteData().Values.TryGetValue("orgId", out var orgIdParam); httpContext.GetRouteData().Values.TryGetValue("orgId", out var orgIdParam);
if (orgIdParam == null || !Guid.TryParse(orgIdParam.ToString(), out var orgId)) if (orgIdParam == null || !Guid.TryParse(orgIdParam.ToString(), out var orgId))
{ {
throw new InvalidOperationException( throw new InvalidOperationException(NoOrgIdError);
"A route decorated with with '[Authorize<Requirement>]' should include a route value named 'orgId' either through the [Controller] attribute or through a '[Http*]' attribute.");
} }
return orgId; return orgId;

View File

@ -1,5 +1,6 @@
using System.Security.Claims; using System.Security.Claims;
using Bit.Api.AdminConsole.Authorization; using Bit.Api.AdminConsole.Authorization;
using Bit.Core.Services;
using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture;
using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.AutoFixture.Attributes;
using Microsoft.AspNetCore.Authorization; using Microsoft.AspNetCore.Authorization;
@ -16,13 +17,13 @@ public class OrganizationRequirementHandlerTests
public async Task IfNoOrganizationId_Throws(SutProvider<OrganizationRequirementHandler> sutProvider) public async Task IfNoOrganizationId_Throws(SutProvider<OrganizationRequirementHandler> sutProvider)
{ {
// Arrange // Arrange
ArrangeRouteValues(sutProvider, null); // no orgId in route ArrangeRouteAndUser(sutProvider, null); // no orgId in route
var testRequirement = Substitute.For<IOrganizationRequirement>(); var testRequirement = Substitute.For<IOrganizationRequirement>();
var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null); var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null);
// Act // Act
var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => sutProvider.Sut.HandleAsync(authContext)); var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => sutProvider.Sut.HandleAsync(authContext));
Assert.Contains("should include a route value named 'orgId'", exception.Message); Assert.Equal(OrganizationRequirementHelpers.NoOrgIdError, exception.Message);
Assert.False(authContext.HasSucceeded); Assert.False(authContext.HasSucceeded);
} }
@ -30,13 +31,13 @@ public class OrganizationRequirementHandlerTests
public async Task IfInvalidOrganizationId_Throws(SutProvider<OrganizationRequirementHandler> sutProvider) public async Task IfInvalidOrganizationId_Throws(SutProvider<OrganizationRequirementHandler> sutProvider)
{ {
// Arrange // Arrange
ArrangeRouteValues(sutProvider, "malformed guid"); ArrangeRouteAndUser(sutProvider, "malformed guid");
var testRequirement = Substitute.For<IOrganizationRequirement>(); var testRequirement = Substitute.For<IOrganizationRequirement>();
var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null); var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null);
// Act // Act
var exception = await Assert.ThrowsAsync<Exception>(() => sutProvider.Sut.HandleAsync(authContext)); var exception = await Assert.ThrowsAsync<InvalidOperationException>(() => sutProvider.Sut.HandleAsync(authContext));
Assert.Contains("No organizationId found", exception.Message); Assert.Contains(OrganizationRequirementHelpers.NoOrgIdError, exception.Message);
Assert.False(authContext.HasSucceeded); Assert.False(authContext.HasSucceeded);
} }
@ -44,7 +45,7 @@ public class OrganizationRequirementHandlerTests
public async Task DoesNotAuthorize_IfAuthorizeAsync_ReturnsFalse(SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId) public async Task DoesNotAuthorize_IfAuthorizeAsync_ReturnsFalse(SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId)
{ {
// Arrange route values // Arrange route values
ArrangeRouteValues(sutProvider, organizationId.ToString()); ArrangeRouteAndUser(sutProvider, organizationId.ToString());
// Arrange requirement // Arrange requirement
var testRequirement = Substitute.For<IOrganizationRequirement>(); var testRequirement = Substitute.For<IOrganizationRequirement>();
@ -65,7 +66,7 @@ public class OrganizationRequirementHandlerTests
public async Task Authorizes_IfAuthorizeAsync_ReturnsTrue(SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId) public async Task Authorizes_IfAuthorizeAsync_ReturnsTrue(SutProvider<OrganizationRequirementHandler> sutProvider, Guid organizationId)
{ {
// Arrange route values // Arrange route values
ArrangeRouteValues(sutProvider, organizationId.ToString()); ArrangeRouteAndUser(sutProvider, organizationId.ToString());
// Arrange requirement // Arrange requirement
var testRequirement = Substitute.For<IOrganizationRequirement>(); var testRequirement = Substitute.For<IOrganizationRequirement>();
@ -82,10 +83,11 @@ public class OrganizationRequirementHandlerTests
Assert.True(authContext.HasSucceeded); Assert.True(authContext.HasSucceeded);
} }
private static void ArrangeRouteValues(SutProvider<OrganizationRequirementHandler> sutProvider, string orgIdRouteValue) private static void ArrangeRouteAndUser(SutProvider<OrganizationRequirementHandler> sutProvider, string orgIdRouteValue)
{ {
var httpContext = new DefaultHttpContext(); var httpContext = new DefaultHttpContext();
httpContext.Request.RouteValues["orgId"] = orgIdRouteValue; httpContext.Request.RouteValues["orgId"] = orgIdRouteValue;
sutProvider.GetDependency<IHttpContextAccessor>().HttpContext = httpContext; sutProvider.GetDependency<IHttpContextAccessor>().HttpContext = httpContext;
sutProvider.GetDependency<IUserService>().GetProperUserId(Arg.Any<ClaimsPrincipal>()).Returns(Guid.NewGuid());
} }
} }