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; using Microsoft.AspNetCore.Http; using NSubstitute; using Xunit; namespace Bit.Api.Test.AdminConsole.Authorization; [SutProviderCustomize] public class OrganizationRequirementHandlerTests { [Theory, BitAutoData] public async Task IfNoOrganizationId_Throws(SutProvider sutProvider) { // Arrange 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.Equal(OrganizationRequirementHelpers.NoOrgIdError, exception.Message); Assert.False(authContext.HasSucceeded); } [Theory, BitAutoData] public async Task IfInvalidOrganizationId_Throws(SutProvider sutProvider) { // Arrange 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(OrganizationRequirementHelpers.NoOrgIdError, exception.Message); Assert.False(authContext.HasSucceeded); } [Theory, BitAutoData] public async Task DoesNotAuthorize_IfAuthorizeAsync_ReturnsFalse(SutProvider sutProvider, Guid organizationId) { // Arrange route values ArrangeRouteAndUser(sutProvider, organizationId.ToString()); // Arrange requirement var testRequirement = Substitute.For(); testRequirement .AuthorizeAsync(null, Arg.Any>>()) .ReturnsForAnyArgs(false); var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null); // Act await sutProvider.Sut.HandleAsync(authContext); // Assert await testRequirement.Received(1).AuthorizeAsync(null, Arg.Any>>()); Assert.False(authContext.HasSucceeded); } [Theory, BitAutoData] public async Task Authorizes_IfAuthorizeAsync_ReturnsTrue(SutProvider sutProvider, Guid organizationId) { // Arrange route values ArrangeRouteAndUser(sutProvider, organizationId.ToString()); // Arrange requirement var testRequirement = Substitute.For(); testRequirement .AuthorizeAsync(null, Arg.Any>>()) .ReturnsForAnyArgs(true); var authContext = new AuthorizationHandlerContext([testRequirement], new ClaimsPrincipal(), null); // Act await sutProvider.Sut.HandleAsync(authContext); // Assert await testRequirement.Received(1).AuthorizeAsync(null, Arg.Any>>()); Assert.True(authContext.HasSucceeded); } 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()); } }