diff --git a/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs b/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs index 3f977364f8..b447d6b418 100644 --- a/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs +++ b/test/Api.Test/Vault/AuthorizationHandlers/CollectionAuthorizationHandlerTests.cs @@ -3,6 +3,7 @@ using Bit.Api.Vault.AuthorizationHandlers.Collections; using Bit.Core; using Bit.Core.Context; using Bit.Core.Enums; +using Bit.Core.Models.Data; using Bit.Core.Test.AutoFixture; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; @@ -25,18 +26,24 @@ public class CollectionAuthorizationHandlerTests [BitAutoData(OrganizationUserType.Custom, false, false, true, false, false, true)] [BitAutoData(OrganizationUserType.Custom, false, false, false, true, false, true)] [BitAutoData(OrganizationUserType.Custom, false, false, false, false, true, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, false, false, false, false)] public async Task CanReadAllAccessAsync_ReturnsExpectedResult( OrganizationUserType userType, bool editAnyCollection, bool deleteAnyCollection, bool manageGroups, bool manageUsers, bool accessImportExport, bool expectedSuccess, Guid userId, SutProvider sutProvider, CurrentContextOrganization organization) { + var permissions = new Permissions + { + EditAnyCollection = editAnyCollection, + DeleteAnyCollection = deleteAnyCollection, + ManageGroups = manageGroups, + ManageUsers = manageUsers, + AccessImportExport = accessImportExport + }; + organization.Type = userType; - organization.Permissions.EditAnyCollection = editAnyCollection; - organization.Permissions.DeleteAnyCollection = deleteAnyCollection; - organization.Permissions.ManageGroups = manageGroups; - organization.Permissions.ManageUsers = manageUsers; - organization.Permissions.AccessImportExport = accessImportExport; + organization.Permissions = permissions; var context = new AuthorizationHandlerContext( new[] { CollectionOperations.ReadAll(organization.Id) }, @@ -75,10 +82,11 @@ public class CollectionAuthorizationHandlerTests [Theory, BitAutoData] public async Task HandleRequirementAsync_MissingUserId_Failure( + Guid organizationId, SutProvider sutProvider) { var context = new AuthorizationHandlerContext( - new[] { CollectionOperations.Create }, + new[] { CollectionOperations.ReadAll(organizationId) }, new ClaimsPrincipal(), null ); diff --git a/test/Api.Test/Vault/AuthorizationHandlers/GroupAuthorizationHandlerTests.cs b/test/Api.Test/Vault/AuthorizationHandlers/GroupAuthorizationHandlerTests.cs new file mode 100644 index 0000000000..8912c03656 --- /dev/null +++ b/test/Api.Test/Vault/AuthorizationHandlers/GroupAuthorizationHandlerTests.cs @@ -0,0 +1,119 @@ +using System.Security.Claims; +using Bit.Api.Vault.AuthorizationHandlers.Groups; +using Bit.Core; +using Bit.Core.Context; +using Bit.Core.Enums; +using Bit.Core.Models.Data; +using Bit.Core.Test.AutoFixture; +using Bit.Test.Common.AutoFixture; +using Bit.Test.Common.AutoFixture.Attributes; +using Microsoft.AspNetCore.Authorization; +using NSubstitute; +using Xunit; + +namespace Bit.Api.Test.Vault.AuthorizationHandlers; + +[SutProviderCustomize] +[FeatureServiceCustomize(FeatureFlagKeys.FlexibleCollections)] +public class GroupAuthorizationHandlerTests +{ + [Theory] + [BitAutoData(OrganizationUserType.Admin, false, false, false, false, false, true)] + [BitAutoData(OrganizationUserType.Owner, false, false, false, false, false, true)] + [BitAutoData(OrganizationUserType.User, false, false, false, false, false, false)] + [BitAutoData(OrganizationUserType.Custom, true, false, false, false, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, true, false, false, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, true, false, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, false, true, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, false, false, true, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, false, false, false, false)] + public async Task CanReadAllAccessAsync_ReturnsExpectedResult( + OrganizationUserType userType, bool editAnyCollection, bool deleteAnyCollection, + bool manageGroups, bool manageUsers, bool accessImportExport, bool expectedSuccess, + Guid userId, SutProvider sutProvider, + CurrentContextOrganization organization) + { + var permissions = new Permissions + { + EditAnyCollection = editAnyCollection, + DeleteAnyCollection = deleteAnyCollection, + ManageGroups = manageGroups, + ManageUsers = manageUsers, + AccessImportExport = accessImportExport + }; + + organization.Type = userType; + organization.Permissions = permissions; + + var context = new AuthorizationHandlerContext( + new[] { GroupOperations.ReadAll(organization.Id) }, + new ClaimsPrincipal(), + null); + + sutProvider.GetDependency().UserId.Returns(userId); + sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); + + await sutProvider.Sut.HandleAsync(context); + + Assert.True(expectedSuccess ? context.HasSucceeded : context.HasFailed); + } + + [Theory, BitAutoData] + public async Task CanReadAllAccessAsync_WithProviderUser_Success( + Guid userId, + SutProvider sutProvider, CurrentContextOrganization organization) + { + var context = new AuthorizationHandlerContext( + new[] { GroupOperations.ReadAll(organization.Id) }, + new ClaimsPrincipal(), + null); + + sutProvider.GetDependency() + .UserId + .Returns(userId); + sutProvider.GetDependency() + .ProviderUserForOrgAsync(organization.Id) + .Returns(true); + + await sutProvider.Sut.HandleAsync(context); + + Assert.True(context.HasSucceeded); + } + + [Theory, BitAutoData] + public async Task HandleRequirementAsync_MissingUserId_Failure( + Guid organizationId, + SutProvider sutProvider) + { + var context = new AuthorizationHandlerContext( + new[] { GroupOperations.ReadAll(organizationId) }, + new ClaimsPrincipal(), + null + ); + + // Simulate missing user id + sutProvider.GetDependency().UserId.Returns((Guid?)null); + + await sutProvider.Sut.HandleAsync(context); + Assert.True(context.HasFailed); + } + + [Theory, BitAutoData] + public async Task HandleRequirementAsync_MissingOrg_Failure( + Guid userId, + Guid organizationId, + SutProvider sutProvider) + { + var context = new AuthorizationHandlerContext( + new[] { GroupOperations.ReadAll(organizationId) }, + new ClaimsPrincipal(), + null + ); + + sutProvider.GetDependency().UserId.Returns(userId); + sutProvider.GetDependency().GetOrganization(Arg.Any()).Returns((CurrentContextOrganization)null); + + await sutProvider.Sut.HandleAsync(context); + Assert.True(context.HasFailed); + } +} diff --git a/test/Api.Test/Vault/AuthorizationHandlers/OrganizationUserAuthorizationHandlerTests.cs b/test/Api.Test/Vault/AuthorizationHandlers/OrganizationUserAuthorizationHandlerTests.cs new file mode 100644 index 0000000000..184d8b20a8 --- /dev/null +++ b/test/Api.Test/Vault/AuthorizationHandlers/OrganizationUserAuthorizationHandlerTests.cs @@ -0,0 +1,117 @@ +using System.Security.Claims; +using Bit.Api.Vault.AuthorizationHandlers.OrganizationUsers; +using Bit.Core; +using Bit.Core.Context; +using Bit.Core.Enums; +using Bit.Core.Models.Data; +using Bit.Core.Test.AutoFixture; +using Bit.Test.Common.AutoFixture; +using Bit.Test.Common.AutoFixture.Attributes; +using Microsoft.AspNetCore.Authorization; +using NSubstitute; +using Xunit; + +namespace Bit.Api.Test.Vault.AuthorizationHandlers; + +[SutProviderCustomize] +[FeatureServiceCustomize(FeatureFlagKeys.FlexibleCollections)] +public class OrganizationUserAuthorizationHandlerTests +{ + [Theory] + [BitAutoData(OrganizationUserType.Admin, false, false, false, false, true)] + [BitAutoData(OrganizationUserType.Owner, false, false, false, false, true)] + [BitAutoData(OrganizationUserType.User, false, false, false, false, false)] + [BitAutoData(OrganizationUserType.Custom, true, false, false, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, true, false, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, true, false, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, false, true, true)] + [BitAutoData(OrganizationUserType.Custom, false, false, false, false, false)] + public async Task CanReadAllAccessAsync_ReturnsExpectedResult( + OrganizationUserType userType, bool editAnyCollection, bool deleteAnyCollection, + bool manageGroups, bool manageUsers, bool expectedSuccess, + Guid userId, SutProvider sutProvider, + CurrentContextOrganization organization) + { + var permissions = new Permissions + { + EditAnyCollection = editAnyCollection, + DeleteAnyCollection = deleteAnyCollection, + ManageGroups = manageGroups, + ManageUsers = manageUsers + }; + + organization.Type = userType; + organization.Permissions = permissions; + + var context = new AuthorizationHandlerContext( + new[] { OrganizationUserOperations.ReadAll(organization.Id) }, + new ClaimsPrincipal(), + null); + + sutProvider.GetDependency().UserId.Returns(userId); + sutProvider.GetDependency().GetOrganization(organization.Id).Returns(organization); + + await sutProvider.Sut.HandleAsync(context); + + Assert.True(expectedSuccess ? context.HasSucceeded : context.HasFailed); + } + + [Theory, BitAutoData] + public async Task CanReadAllAccessAsync_WithProviderUser_Success( + Guid userId, + SutProvider sutProvider, CurrentContextOrganization organization) + { + var context = new AuthorizationHandlerContext( + new[] { OrganizationUserOperations.ReadAll(organization.Id) }, + new ClaimsPrincipal(), + null); + + sutProvider.GetDependency() + .UserId + .Returns(userId); + sutProvider.GetDependency() + .ProviderUserForOrgAsync(organization.Id) + .Returns(true); + + await sutProvider.Sut.HandleAsync(context); + + Assert.True(context.HasSucceeded); + } + + [Theory, BitAutoData] + public async Task HandleRequirementAsync_MissingUserId_Failure( + Guid organizationId, + SutProvider sutProvider) + { + var context = new AuthorizationHandlerContext( + new[] { OrganizationUserOperations.ReadAll(organizationId) }, + new ClaimsPrincipal(), + null + ); + + // Simulate missing user id + sutProvider.GetDependency().UserId.Returns((Guid?)null); + + await sutProvider.Sut.HandleAsync(context); + Assert.True(context.HasFailed); + } + + [Theory, BitAutoData] + public async Task HandleRequirementAsync_MissingOrg_Failure( + Guid userId, + Guid organizationId, + SutProvider sutProvider) + { + var context = new AuthorizationHandlerContext( + new[] { OrganizationUserOperations.ReadAll(organizationId) }, + new ClaimsPrincipal(), + null + ); + + sutProvider.GetDependency().UserId.Returns(userId); + sutProvider.GetDependency().GetOrganization(Arg.Any()).Returns((CurrentContextOrganization)null); + + await sutProvider.Sut.HandleAsync(context); + Assert.True(context.HasFailed); + } +}