using System.Security.Claims; using AutoFixture; using Bit.Api.AdminConsole.Authorization; using Bit.Core.AdminConsole.Enums.Provider; using Bit.Core.AdminConsole.Models.Data.Provider; using Bit.Core.AdminConsole.Repositories; using Bit.Core.Services; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using NSubstitute; using Xunit; namespace Bit.Api.Test.AdminConsole.Authorization; [SutProviderCustomize] public class OrganizationContextTests { [Theory, BitAutoData] public async Task IsProviderUserForOrganization_UserIsProviderUser_ReturnsTrue( Guid userId, Guid organizationId, Guid otherOrganizationId, SutProvider sutProvider) { var claimsPrincipal = new ClaimsPrincipal(); var providerUserOrganizations = new List { new() { OrganizationId = organizationId }, new() { OrganizationId = otherOrganizationId } }; sutProvider.GetDependency() .GetProperUserId(claimsPrincipal) .Returns(userId); sutProvider.GetDependency() .GetManyOrganizationDetailsByUserAsync(userId, ProviderUserStatusType.Confirmed) .Returns(providerUserOrganizations); var result = await sutProvider.Sut.IsProviderUserForOrganization(claimsPrincipal, organizationId); Assert.True(result); await sutProvider.GetDependency() .Received(1) .GetManyOrganizationDetailsByUserAsync(userId, ProviderUserStatusType.Confirmed); } public static IEnumerable UserIsNotProviderUserData() { // User has provider organizations, but not for the target organization yield return [ new List { new Fixture().Create() } ]; // User has no provider organizations yield return [Array.Empty()]; } [Theory, BitMemberAutoData(nameof(UserIsNotProviderUserData))] public async Task IsProviderUserForOrganization_UserIsNotProviderUser_ReturnsFalse( IEnumerable providerUserOrganizations, Guid userId, Guid organizationId, SutProvider sutProvider) { var claimsPrincipal = new ClaimsPrincipal(); sutProvider.GetDependency() .GetProperUserId(claimsPrincipal) .Returns(userId); sutProvider.GetDependency() .GetManyOrganizationDetailsByUserAsync(userId, ProviderUserStatusType.Confirmed) .Returns(providerUserOrganizations); var result = await sutProvider.Sut.IsProviderUserForOrganization(claimsPrincipal, organizationId); Assert.False(result); } [Theory, BitAutoData] public async Task IsProviderUserForOrganization_UserIdIsNull_ThrowsException( Guid organizationId, SutProvider sutProvider) { var claimsPrincipal = new ClaimsPrincipal(); sutProvider.GetDependency() .GetProperUserId(claimsPrincipal) .Returns((Guid?)null); var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.IsProviderUserForOrganization(claimsPrincipal, organizationId)); Assert.Equal(OrganizationContext.NoUserIdError, exception.Message); } [Theory, BitAutoData] public async Task IsProviderUserForOrganization_UsesCaching( Guid userId, Guid organizationId, SutProvider sutProvider) { var claimsPrincipal = new ClaimsPrincipal(); var providerUserOrganizations = new List { new() { OrganizationId = organizationId } }; sutProvider.GetDependency() .GetProperUserId(claimsPrincipal) .Returns(userId); sutProvider.GetDependency() .GetManyOrganizationDetailsByUserAsync(userId, ProviderUserStatusType.Confirmed) .Returns(providerUserOrganizations); await sutProvider.Sut.IsProviderUserForOrganization(claimsPrincipal, organizationId); await sutProvider.Sut.IsProviderUserForOrganization(claimsPrincipal, organizationId); await sutProvider.GetDependency() .Received(1) .GetManyOrganizationDetailsByUserAsync(userId, ProviderUserStatusType.Confirmed); } }