From 99cb6954a95121397a882b8bfe836618d49392ec Mon Sep 17 00:00:00 2001 From: Thomas Rittson Date: Wed, 2 Apr 2025 13:05:28 +1000 Subject: [PATCH] fix tests for real --- .../OrganizationRequirementHandler.cs | 7 +++++-- .../OrganizationRequirementHelpers.cs | 6 ++++-- .../OrganizationRequirementHandlerTests.cs | 18 ++++++++++-------- 3 files changed, 19 insertions(+), 12 deletions(-) diff --git a/src/Api/AdminConsole/Authorization/OrganizationRequirementHandler.cs b/src/Api/AdminConsole/Authorization/OrganizationRequirementHandler.cs index fdcb8b2d3e..6a8218bbdf 100644 --- a/src/Api/AdminConsole/Authorization/OrganizationRequirementHandler.cs +++ b/src/Api/AdminConsole/Authorization/OrganizationRequirementHandler.cs @@ -17,12 +17,15 @@ public class OrganizationRequirementHandler( IUserService userService) : AuthorizationHandler { + 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) { var httpContext = httpContextAccessor.HttpContext; 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(); @@ -31,7 +34,7 @@ public class OrganizationRequirementHandler( var userId = userService.GetProperUserId(httpContext.User); 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 IsProviderUserForOrg() => httpContextAccessor.HttpContext.IsProviderUserForOrgAsync(providerUserRepository, userId.Value, organizationId); diff --git a/src/Api/AdminConsole/Authorization/OrganizationRequirementHelpers.cs b/src/Api/AdminConsole/Authorization/OrganizationRequirementHelpers.cs index 92271b1c05..c58120b7da 100644 --- a/src/Api/AdminConsole/Authorization/OrganizationRequirementHelpers.cs +++ b/src/Api/AdminConsole/Authorization/OrganizationRequirementHelpers.cs @@ -4,13 +4,15 @@ namespace Bit.Api.AdminConsole.Authorization; public static class OrganizationRequirementHelpers { + public const string NoOrgIdError = + "A route decorated with with '[Authorize]' should include a route value named 'orgId' either through the [Controller] attribute or through a '[Http*]' attribute."; + public static Guid GetOrganizationId(this HttpContext httpContext) { httpContext.GetRouteData().Values.TryGetValue("orgId", out var orgIdParam); if (orgIdParam == null || !Guid.TryParse(orgIdParam.ToString(), out var orgId)) { - throw new InvalidOperationException( - "A route decorated with with '[Authorize]' should include a route value named 'orgId' either through the [Controller] attribute or through a '[Http*]' attribute."); + throw new InvalidOperationException(NoOrgIdError); } return orgId; diff --git a/test/Api.Test/AdminConsole/Authorization/OrganizationRequirementHandlerTests.cs b/test/Api.Test/AdminConsole/Authorization/OrganizationRequirementHandlerTests.cs index d3f65a9d2d..9c165c4732 100644 --- a/test/Api.Test/AdminConsole/Authorization/OrganizationRequirementHandlerTests.cs +++ b/test/Api.Test/AdminConsole/Authorization/OrganizationRequirementHandlerTests.cs @@ -1,5 +1,6 @@ using System.Security.Claims; using Bit.Api.AdminConsole.Authorization; +using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Microsoft.AspNetCore.Authorization; @@ -16,13 +17,13 @@ public class OrganizationRequirementHandlerTests public async Task IfNoOrganizationId_Throws(SutProvider sutProvider) { // Arrange - ArrangeRouteValues(sutProvider, null); // no orgId in route + ArrangeRouteAndUser(sutProvider, null); // no orgId in route var testRequirement = Substitute.For(); var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null); // Act var exception = await Assert.ThrowsAsync(() => 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); } @@ -30,13 +31,13 @@ public class OrganizationRequirementHandlerTests public async Task IfInvalidOrganizationId_Throws(SutProvider sutProvider) { // Arrange - ArrangeRouteValues(sutProvider, "malformed guid"); + ArrangeRouteAndUser(sutProvider, "malformed guid"); var testRequirement = Substitute.For(); var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null); // Act - var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.HandleAsync(authContext)); - Assert.Contains("No organizationId found", exception.Message); + var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.HandleAsync(authContext)); + Assert.Contains(OrganizationRequirementHelpers.NoOrgIdError, exception.Message); Assert.False(authContext.HasSucceeded); } @@ -44,7 +45,7 @@ public class OrganizationRequirementHandlerTests public async Task DoesNotAuthorize_IfAuthorizeAsync_ReturnsFalse(SutProvider sutProvider, Guid organizationId) { // Arrange route values - ArrangeRouteValues(sutProvider, organizationId.ToString()); + ArrangeRouteAndUser(sutProvider, organizationId.ToString()); // Arrange requirement var testRequirement = Substitute.For(); @@ -65,7 +66,7 @@ public class OrganizationRequirementHandlerTests public async Task Authorizes_IfAuthorizeAsync_ReturnsTrue(SutProvider sutProvider, Guid organizationId) { // Arrange route values - ArrangeRouteValues(sutProvider, organizationId.ToString()); + ArrangeRouteAndUser(sutProvider, organizationId.ToString()); // Arrange requirement var testRequirement = Substitute.For(); @@ -82,10 +83,11 @@ public class OrganizationRequirementHandlerTests Assert.True(authContext.HasSucceeded); } - private static void ArrangeRouteValues(SutProvider sutProvider, string orgIdRouteValue) + private static void ArrangeRouteAndUser(SutProvider sutProvider, string orgIdRouteValue) { var httpContext = new DefaultHttpContext(); httpContext.Request.RouteValues["orgId"] = orgIdRouteValue; sutProvider.GetDependency().HttpContext = httpContext; + sutProvider.GetDependency().GetProperUserId(Arg.Any()).Returns(Guid.NewGuid()); } }