using System.Security.Claims; using Bit.Api.SecretsManager.Controllers; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.Test.SecretsManager.Enums; using Bit.Core.Context; using Bit.Core.Enums; using Bit.Core.Exceptions; using Bit.Core.SecretsManager.Commands.AccessPolicies.Interfaces; using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Models.Data; using Bit.Core.SecretsManager.Repositories; using Bit.Core.Services; using Bit.Core.Test.SecretsManager.AutoFixture.ProjectsFixture; using Bit.Test.Common.AutoFixture; using Bit.Test.Common.AutoFixture.Attributes; using Bit.Test.Common.Helpers; using Microsoft.AspNetCore.Authorization; using NSubstitute; using NSubstitute.ReturnsExtensions; using Xunit; namespace Bit.Api.Test.SecretsManager.Controllers; [ControllerCustomize(typeof(AccessPoliciesController))] [SutProviderCustomize] [ProjectCustomize] [JsonDocumentCustomize] public class AccessPoliciesControllerTests { private const int _overMax = 16; private static AccessPoliciesCreateRequest AddRequestsOverMax(AccessPoliciesCreateRequest request) { var newRequests = new List(); for (var i = 0; i < _overMax; i++) { newRequests.Add(new AccessPolicyRequest { GranteeId = new Guid(), Read = true, Write = true }); } request.UserAccessPolicyRequests = newRequests; return request; } private static List AddRequestsOverMax(List request) { for (var i = 0; i < _overMax; i++) { request.Add(new GrantedAccessPolicyRequest { GrantedId = new Guid() }); } return request; } private static PeopleAccessPoliciesRequestModel SetRequestToCanReadWrite(PeopleAccessPoliciesRequestModel request) { foreach (var ap in request.UserAccessPolicyRequests) { ap.Read = true; ap.Write = true; } foreach (var ap in request.GroupAccessPolicyRequests) { ap.Read = true; ap.Write = true; } return request; } private static void SetupAdmin(SutProvider sutProvider, Guid organizationId) { sutProvider.GetDependency().AccessSecretsManager(default).ReturnsForAnyArgs(true); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid()); sutProvider.GetDependency().OrganizationAdmin(organizationId).Returns(true); } private static void SetupUserWithPermission(SutProvider sutProvider, Guid organizationId) { sutProvider.GetDependency().AccessSecretsManager(default).ReturnsForAnyArgs(true); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid()); sutProvider.GetDependency().OrganizationAdmin(organizationId).Returns(false); sutProvider.GetDependency().OrganizationUser(default).ReturnsForAnyArgs(true); } private static void SetupUserWithoutPermission(SutProvider sutProvider, Guid organizationId) { sutProvider.GetDependency().AccessSecretsManager(default).ReturnsForAnyArgs(true); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid()); sutProvider.GetDependency().OrganizationAdmin(organizationId).Returns(false); sutProvider.GetDependency().OrganizationUser(default).ReturnsForAnyArgs(true); } private static void SetupPermission(SutProvider sutProvider, PermissionType permissionType, Guid orgId) { switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, orgId); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, orgId); break; } } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetProjectAccessPolicies_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, Guid id, Project data) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); sutProvider.GetDependency().AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.NoAccessCheck) .Returns((true, true)); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.User) .Returns((true, true)); break; } var result = await sutProvider.Sut.GetProjectAccessPoliciesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByGrantedProjectIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.Empty(result.GroupAccessPolicies); Assert.Empty(result.UserAccessPolicies); Assert.Empty(result.ServiceAccountAccessPolicies); } [Theory] [BitAutoData] public async void GetProjectAccessPolicies_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id, Project data) { SetupUserWithoutPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); sutProvider.GetDependency().AccessToProjectAsync(default, default, default) .Returns((false, false)); await Assert.ThrowsAsync(() => sutProvider.Sut.GetProjectAccessPoliciesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetManyByGrantedProjectIdAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetProjectAccessPolicies_Success( PermissionType permissionType, SutProvider sutProvider, Guid id, Project data, UserProjectAccessPolicy resultAccessPolicy) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); sutProvider.GetDependency().AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.NoAccessCheck) .Returns((true, true)); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.User) .Returns((true, true)); break; } sutProvider.GetDependency().GetManyByGrantedProjectIdAsync(default, default) .ReturnsForAnyArgs(new List { resultAccessPolicy }); var result = await sutProvider.Sut.GetProjectAccessPoliciesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByGrantedProjectIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.Empty(result.GroupAccessPolicies); Assert.NotEmpty(result.UserAccessPolicies); Assert.Empty(result.ServiceAccountAccessPolicies); } [Theory] [BitAutoData] public async void GetProjectAccessPolicies_ProjectsExist_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id, Project data, UserProjectAccessPolicy resultAccessPolicy) { SetupUserWithoutPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); sutProvider.GetDependency().AccessToProjectAsync(default, default, default) .Returns((false, false)); sutProvider.GetDependency().GetManyByGrantedProjectIdAsync(default, default) .ReturnsForAnyArgs(new List { resultAccessPolicy }); await Assert.ThrowsAsync(() => sutProvider.Sut.GetProjectAccessPoliciesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetManyByGrantedProjectIdAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetServiceAccountGrantedPolicies_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, Guid id, ServiceAccount data) { sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .UserHasWriteAccessToServiceAccount(default, default) .ReturnsForAnyArgs(true); break; } var result = await sutProvider.Sut.GetServiceAccountGrantedPoliciesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByServiceAccountIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any(), Arg.Any()); Assert.Empty(result.Data); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetServiceAccountGrantedPolicies_Success( PermissionType permissionType, SutProvider sutProvider, Guid id, ServiceAccount data, ServiceAccountProjectAccessPolicy resultAccessPolicy) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); break; } sutProvider.GetDependency().GetManyByServiceAccountIdAsync(default, default, default) .ReturnsForAnyArgs(new List { resultAccessPolicy }); var result = await sutProvider.Sut.GetServiceAccountGrantedPoliciesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByServiceAccountIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any(), Arg.Any()); Assert.NotEmpty(result.Data); } [Theory] [BitAutoData] public async void CreateProjectAccessPolicies_RequestMoreThanMax_Throws( SutProvider sutProvider, Guid id, Project mockProject, UserProjectAccessPolicy data, AccessPoliciesCreateRequest request) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(mockProject); sutProvider.GetDependency().CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); request = AddRequestsOverMax(request); await Assert.ThrowsAsync(() => sutProvider.Sut.CreateProjectAccessPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateProjectAccessPolicies_ProjectDoesNotExist_Throws( SutProvider sutProvider, Guid id, AccessPoliciesCreateRequest request) { await Assert.ThrowsAsync(() => sutProvider.Sut.CreateProjectAccessPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateProjectAccessPolicies_DuplicatePolicy_Throws( SutProvider sutProvider, Guid id, Project mockProject, UserProjectAccessPolicy data, AccessPoliciesCreateRequest request) { var dup = new AccessPolicyRequest { GranteeId = Guid.NewGuid(), Read = true, Write = true }; request.UserAccessPolicyRequests = new[] { dup, dup }; mockProject.Id = id; sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(mockProject); sutProvider.GetDependency().CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); await Assert.ThrowsAsync(() => sutProvider.Sut.CreateProjectAccessPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateProjectAccessPolicies_NoAccess_Throws( SutProvider sutProvider, Guid id, Project mockProject, UserProjectAccessPolicy data, AccessPoliciesCreateRequest request) { mockProject.Id = id; sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(mockProject); var policies = request.ToBaseAccessPoliciesForProject(id, mockProject.OrganizationId); foreach (var policy in policies) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), policy, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Failed()); } sutProvider.GetDependency().CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); await Assert.ThrowsAsync(() => sutProvider.Sut.CreateProjectAccessPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateProjectAccessPolicies_Success( SutProvider sutProvider, Guid id, Project mockProject, UserProjectAccessPolicy data, AccessPoliciesCreateRequest request) { mockProject.Id = id; sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(mockProject); var policies = request.ToBaseAccessPoliciesForProject(id, mockProject.OrganizationId); foreach (var policy in policies) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), policy, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Success()); } sutProvider.GetDependency().CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); await sutProvider.Sut.CreateProjectAccessPoliciesAsync(id, request); await sutProvider.GetDependency().Received(1) .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateServiceAccountGrantedPolicies_RequestMoreThanMax_Throws( SutProvider sutProvider, Guid id, ServiceAccount serviceAccount, ServiceAccountProjectAccessPolicy data, List request) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(serviceAccount); sutProvider.GetDependency() .CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); request = AddRequestsOverMax(request); await Assert.ThrowsAsync(() => sutProvider.Sut.CreateServiceAccountGrantedPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateServiceAccountGrantedPolicies_ServiceAccountDoesNotExist_Throws( SutProvider sutProvider, Guid id, List request) { await Assert.ThrowsAsync(() => sutProvider.Sut.CreateServiceAccountGrantedPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateServiceAccountGrantedPolicies_DuplicatePolicy_Throws( SutProvider sutProvider, Guid id, ServiceAccount serviceAccount, ServiceAccountProjectAccessPolicy data, List request) { var dup = new GrantedAccessPolicyRequest { GrantedId = Guid.NewGuid(), Read = true, Write = true }; request.Add(dup); request.Add(dup); sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(serviceAccount); sutProvider.GetDependency() .CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); await Assert.ThrowsAsync(() => sutProvider.Sut.CreateServiceAccountGrantedPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateServiceAccountGrantedPolicies_NoAccess_Throws( SutProvider sutProvider, Guid id, ServiceAccount serviceAccount, ServiceAccountProjectAccessPolicy data, List request) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(serviceAccount); sutProvider.GetDependency() .CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); foreach (var policy in request) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), policy, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Failed()); } await Assert.ThrowsAsync(() => sutProvider.Sut.CreateServiceAccountGrantedPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void CreateServiceAccountGrantedPolicies_Success( SutProvider sutProvider, Guid id, ServiceAccount serviceAccount, ServiceAccountProjectAccessPolicy data, List request) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(serviceAccount); sutProvider.GetDependency() .CreateManyAsync(default) .ReturnsForAnyArgs(new List { data }); foreach (var policy in request) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), policy, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Success()); } await sutProvider.Sut.CreateServiceAccountGrantedPoliciesAsync(id, request); await sutProvider.GetDependency().Received(1) .CreateManyAsync(Arg.Any>()); } [Theory] [BitAutoData] public async void UpdateAccessPolicies_NoAccess_Throws( SutProvider sutProvider, Guid id, UserProjectAccessPolicy data, AccessPolicyUpdateRequest request) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), data, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Failed()); sutProvider.GetDependency().GetByIdAsync(id).Returns(data); sutProvider.GetDependency().UpdateAsync(default, default, default) .ReturnsForAnyArgs(data); await Assert.ThrowsAsync(() => sutProvider.Sut.UpdateAccessPolicyAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .UpdateAsync(Arg.Any(), Arg.Is(request.Read), Arg.Is(request.Write)); } [Theory] [BitAutoData] public async void UpdateAccessPolicies_Success( SutProvider sutProvider, Guid id, UserProjectAccessPolicy data, AccessPolicyUpdateRequest request) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), data, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Success()); sutProvider.GetDependency().GetByIdAsync(id).Returns(data); sutProvider.GetDependency().UpdateAsync(default, default, default) .ReturnsForAnyArgs(data); await sutProvider.Sut.UpdateAccessPolicyAsync(id, request); await sutProvider.GetDependency().Received(1) .UpdateAsync(Arg.Any(), Arg.Is(request.Read), Arg.Is(request.Write)); } [Theory] [BitAutoData] public async void DeleteAccessPolicies_NoAccess_Throws(SutProvider sutProvider, Guid id) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), new UserProjectAccessPolicy(), Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Failed()); sutProvider.GetDependency().DeleteAsync(default).ReturnsNull(); await Assert.ThrowsAsync(() => sutProvider.Sut.DeleteAccessPolicyAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .DeleteAsync(Arg.Any()); } [Theory] [BitAutoData] public async void DeleteAccessPolicies_Success(SutProvider sutProvider, Guid id) { sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), new UserProjectAccessPolicy(), Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Success()); sutProvider.GetDependency().DeleteAsync(default).ReturnsNull(); await sutProvider.Sut.DeleteAccessPolicyAsync(id); await sutProvider.GetDependency().Received(1) .DeleteAsync(Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetPeoplePotentialGrantees_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, Guid id) { SetupPermission(sutProvider, permissionType, id); sutProvider.GetDependency().GetPeopleGranteesAsync(default, default) .ReturnsForAnyArgs(new PeopleGrantees { UserGrantees = new List(), GroupGrantees = new List() }); var result = await sutProvider.Sut.GetPeoplePotentialGranteesAsync(id); await sutProvider.GetDependency().Received(1) .GetPeopleGranteesAsync(id, Arg.Any()); Assert.Empty(result.Data); } [Theory] [BitAutoData] public async void GetPeoplePotentialGrantees_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id) { sutProvider.GetDependency().OrganizationAdmin(id).Returns(false); sutProvider.GetDependency().AccessSecretsManager(default).ReturnsForAnyArgs(false); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid()); sutProvider.GetDependency().GetPeopleGranteesAsync(default, default) .ReturnsForAnyArgs(new PeopleGrantees { UserGrantees = new List(), GroupGrantees = new List() }); await Assert.ThrowsAsync(() => sutProvider.Sut.GetPeoplePotentialGranteesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetPeopleGranteesAsync(id, Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetPeoplePotentialGrantees_Success( PermissionType permissionType, SutProvider sutProvider, Guid id, GroupGrantee groupGrantee) { SetupPermission(sutProvider, permissionType, id); sutProvider.GetDependency().GetPeopleGranteesAsync(default, default) .ReturnsForAnyArgs(new PeopleGrantees { UserGrantees = new List(), GroupGrantees = new List { groupGrantee } }); var result = await sutProvider.Sut.GetPeoplePotentialGranteesAsync(id); await sutProvider.GetDependency().Received(1) .GetPeopleGranteesAsync(id, Arg.Any()); Assert.NotEmpty(result.Data); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetServiceAccountsPotentialGrantees_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, Guid id) { SetupPermission(sutProvider, permissionType, id); var result = await sutProvider.Sut.GetServiceAccountsPotentialGranteesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByOrganizationIdWriteAccessAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.Empty(result.Data); } [Theory] [BitAutoData] public async void GetServiceAccountsPotentialGranteesAsync_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id) { sutProvider.GetDependency().OrganizationAdmin(id).Returns(false); sutProvider.GetDependency().AccessSecretsManager(default).ReturnsForAnyArgs(false); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid()); await Assert.ThrowsAsync(() => sutProvider.Sut.GetServiceAccountsPotentialGranteesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetManyByOrganizationIdWriteAccessAsync(Arg.Any(), Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetServiceAccountsPotentialGranteesAsync_Success( PermissionType permissionType, SutProvider sutProvider, Guid id, ServiceAccount mockServiceAccount) { SetupPermission(sutProvider, permissionType, id); sutProvider.GetDependency() .GetManyByOrganizationIdWriteAccessAsync(default, default, default) .ReturnsForAnyArgs(new List { mockServiceAccount }); var result = await sutProvider.Sut.GetServiceAccountsPotentialGranteesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByOrganizationIdWriteAccessAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.NotEmpty(result.Data); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetProjectPotentialGrantees_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, Guid id) { SetupPermission(sutProvider, permissionType, id); var result = await sutProvider.Sut.GetProjectPotentialGranteesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByOrganizationIdWriteAccessAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.Empty(result.Data); } [Theory] [BitAutoData] public async void GetProjectPotentialGrantees_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id) { sutProvider.GetDependency().OrganizationAdmin(id).Returns(false); sutProvider.GetDependency().AccessSecretsManager(default).ReturnsForAnyArgs(false); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid()); await Assert.ThrowsAsync(() => sutProvider.Sut.GetProjectPotentialGranteesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetManyByOrganizationIdWriteAccessAsync(Arg.Any(), Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetProjectPotentialGrantees_Success( PermissionType permissionType, SutProvider sutProvider, Guid id, Project mockProject) { SetupPermission(sutProvider, permissionType, id); sutProvider.GetDependency() .GetManyByOrganizationIdWriteAccessAsync(default, default, default) .ReturnsForAnyArgs(new List { mockProject }); var result = await sutProvider.Sut.GetProjectPotentialGranteesAsync(id); await sutProvider.GetDependency().Received(1) .GetManyByOrganizationIdWriteAccessAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.NotEmpty(result.Data); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetProjectPeopleAccessPolicies_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, Guid id, Project data) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); sutProvider.GetDependency().AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.NoAccessCheck) .Returns((true, true)); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.User) .Returns((true, true)); break; } var result = await sutProvider.Sut.GetProjectPeopleAccessPoliciesAsync(id); await sutProvider.GetDependency().Received(1) .GetPeoplePoliciesByGrantedProjectIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.Empty(result.GroupAccessPolicies); Assert.Empty(result.UserAccessPolicies); } [Theory] [BitAutoData] public async void GetProjectPeopleAccessPolicies_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id, Project data) { SetupUserWithoutPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); sutProvider.GetDependency().AccessToProjectAsync(default, default, default) .Returns((false, false)); await Assert.ThrowsAsync(() => sutProvider.Sut.GetProjectPeopleAccessPoliciesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetPeoplePoliciesByGrantedProjectIdAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void GetProjectPeopleAccessPolicies_ProjectsExist_UserWithoutPermission_Throws( SutProvider sutProvider, Guid id, Project data, UserProjectAccessPolicy resultAccessPolicy) { SetupUserWithoutPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); sutProvider.GetDependency().AccessToProjectAsync(default, default, default) .Returns((false, false)); sutProvider.GetDependency().GetPeoplePoliciesByGrantedProjectIdAsync(default, default) .ReturnsForAnyArgs(new List { resultAccessPolicy }); await Assert.ThrowsAsync(() => sutProvider.Sut.GetProjectPeopleAccessPoliciesAsync(id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetPeoplePoliciesByGrantedProjectIdAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetProjectPeopleAccessPolicies_Success( PermissionType permissionType, SutProvider sutProvider, Guid id, Project data, UserProjectAccessPolicy resultUserPolicy, GroupProjectAccessPolicy resultGroupPolicy) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); sutProvider.GetDependency().AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.NoAccessCheck) .Returns((true, true)); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .AccessToProjectAsync(Arg.Any(), Arg.Any(), AccessClientType.User) .Returns((true, true)); break; } sutProvider.GetDependency().GetPeoplePoliciesByGrantedProjectIdAsync(default, default) .ReturnsForAnyArgs(new List { resultUserPolicy, resultGroupPolicy }); var result = await sutProvider.Sut.GetProjectPeopleAccessPoliciesAsync(id); await sutProvider.GetDependency().Received(1) .GetPeoplePoliciesByGrantedProjectIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(id)), Arg.Any()); Assert.NotEmpty(result.GroupAccessPolicies); Assert.NotEmpty(result.UserAccessPolicies); } [Theory] [BitAutoData] public async void PutProjectPeopleAccessPolicies_ProjectDoesNotExist_Throws( SutProvider sutProvider, Guid id, PeopleAccessPoliciesRequestModel request) { await Assert.ThrowsAsync(() => sutProvider.Sut.PutProjectPeopleAccessPoliciesAsync(id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceProjectPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutProjectPeopleAccessPoliciesAsync_DuplicatePolicy_Throws( SutProvider sutProvider, Project project, PeopleAccessPoliciesRequestModel request) { var dup = new AccessPolicyRequest { GranteeId = Guid.NewGuid(), Read = true, Write = true }; request.UserAccessPolicyRequests = new[] { dup, dup }; sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(project); await Assert.ThrowsAsync(() => sutProvider.Sut.PutProjectPeopleAccessPoliciesAsync(project.Id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceProjectPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutProjectPeopleAccessPoliciesAsync_NoAccess_Throws( SutProvider sutProvider, Project project, PeopleAccessPoliciesRequestModel request) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(project); var peoplePolicies = request.ToProjectPeopleAccessPolicies(project.Id, project.OrganizationId); sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), peoplePolicies, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Failed()); await Assert.ThrowsAsync(() => sutProvider.Sut.PutProjectPeopleAccessPoliciesAsync(project.Id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceProjectPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutProjectPeopleAccessPoliciesAsync_Success( SutProvider sutProvider, Guid userId, Project project, PeopleAccessPoliciesRequestModel request) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(project); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(userId); var peoplePolicies = request.ToProjectPeopleAccessPolicies(project.Id, project.OrganizationId); sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), peoplePolicies, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Success()); sutProvider.GetDependency().ReplaceProjectPeopleAsync(peoplePolicies, Arg.Any()) .Returns(peoplePolicies.ToBaseAccessPolicies()); await sutProvider.Sut.PutProjectPeopleAccessPoliciesAsync(project.Id, request); await sutProvider.GetDependency().Received(1) .ReplaceProjectPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void GetServiceAccountPeopleAccessPoliciesAsync_ServiceAccountDoesntExist_ThrowsNotFound( SutProvider sutProvider, ServiceAccount data) { sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsNull(); await Assert.ThrowsAsync(() => sutProvider.Sut.GetServiceAccountPeopleAccessPoliciesAsync(data.Id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetPeoplePoliciesByGrantedServiceAccountIdAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetServiceAccountPeopleAccessPoliciesAsync_ReturnsEmptyList( PermissionType permissionType, SutProvider sutProvider, ServiceAccount data) { sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .UserHasWriteAccessToServiceAccount(default, default) .ReturnsForAnyArgs(true); break; } var result = await sutProvider.Sut.GetServiceAccountPeopleAccessPoliciesAsync(data.Id); await sutProvider.GetDependency().Received(1) .GetPeoplePoliciesByGrantedServiceAccountIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(data.Id)), Arg.Any()); Assert.Empty(result.UserAccessPolicies); Assert.Empty(result.GroupAccessPolicies); } [Theory] [BitAutoData] public async void GetServiceAccountPeopleAccessPoliciesAsync_UserWithoutPermission_Throws( SutProvider sutProvider, ServiceAccount data) { SetupUserWithoutPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); sutProvider.GetDependency().UserHasWriteAccessToServiceAccount(default, default) .ReturnsForAnyArgs(false); await Assert.ThrowsAsync(() => sutProvider.Sut.GetServiceAccountPeopleAccessPoliciesAsync(data.Id)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .GetPeoplePoliciesByGrantedServiceAccountIdAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData(PermissionType.RunAsAdmin)] [BitAutoData(PermissionType.RunAsUserWithPermission)] public async void GetServiceAccountPeopleAccessPoliciesAsync_Success( PermissionType permissionType, SutProvider sutProvider, ServiceAccount data, UserServiceAccountAccessPolicy resultAccessPolicy) { sutProvider.GetDependency().GetByIdAsync(default).ReturnsForAnyArgs(data); switch (permissionType) { case PermissionType.RunAsAdmin: SetupAdmin(sutProvider, data.OrganizationId); break; case PermissionType.RunAsUserWithPermission: SetupUserWithPermission(sutProvider, data.OrganizationId); sutProvider.GetDependency() .UserHasWriteAccessToServiceAccount(default, default) .ReturnsForAnyArgs(true); break; } sutProvider.GetDependency().GetPeoplePoliciesByGrantedServiceAccountIdAsync(default, default) .ReturnsForAnyArgs(new List { resultAccessPolicy }); var result = await sutProvider.Sut.GetServiceAccountPeopleAccessPoliciesAsync(data.Id); await sutProvider.GetDependency().Received(1) .GetPeoplePoliciesByGrantedServiceAccountIdAsync(Arg.Is(AssertHelper.AssertPropertyEqual(data.Id)), Arg.Any()); Assert.Empty(result.GroupAccessPolicies); Assert.NotEmpty(result.UserAccessPolicies); } [Theory] [BitAutoData] public async void PutServiceAccountPeopleAccessPolicies_ServiceAccountDoesNotExist_Throws( SutProvider sutProvider, ServiceAccount data, PeopleAccessPoliciesRequestModel request) { await Assert.ThrowsAsync(() => sutProvider.Sut.PutServiceAccountPeopleAccessPoliciesAsync(data.Id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceServiceAccountPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutServiceAccountPeopleAccessPolicies_DuplicatePolicy_Throws( SutProvider sutProvider, ServiceAccount data, PeopleAccessPoliciesRequestModel request) { var dup = new AccessPolicyRequest { GranteeId = Guid.NewGuid(), Read = true, Write = true }; request.UserAccessPolicyRequests = new[] { dup, dup }; sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsForAnyArgs(data); await Assert.ThrowsAsync(() => sutProvider.Sut.PutServiceAccountPeopleAccessPoliciesAsync(data.Id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceServiceAccountPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutServiceAccountPeopleAccessPolicies_NotCanReadWrite_Throws( SutProvider sutProvider, ServiceAccount data, PeopleAccessPoliciesRequestModel request) { request.UserAccessPolicyRequests.First().Read = false; sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsForAnyArgs(data); await Assert.ThrowsAsync(() => sutProvider.Sut.PutServiceAccountPeopleAccessPoliciesAsync(data.Id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceServiceAccountPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutServiceAccountPeopleAccessPolicies_NoAccess_Throws( SutProvider sutProvider, ServiceAccount data, PeopleAccessPoliciesRequestModel request) { request = SetRequestToCanReadWrite(request); sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsForAnyArgs(data); var peoplePolicies = request.ToServiceAccountPeopleAccessPolicies(data.Id, data.OrganizationId); sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), peoplePolicies, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Failed()); await Assert.ThrowsAsync(() => sutProvider.Sut.PutServiceAccountPeopleAccessPoliciesAsync(data.Id, request)); await sutProvider.GetDependency().DidNotReceiveWithAnyArgs() .ReplaceServiceAccountPeopleAsync(Arg.Any(), Arg.Any()); } [Theory] [BitAutoData] public async void PutServiceAccountPeopleAccessPolicies_Success( SutProvider sutProvider, ServiceAccount data, Guid userId, PeopleAccessPoliciesRequestModel request) { request = SetRequestToCanReadWrite(request); sutProvider.GetDependency().GetProperUserId(default).ReturnsForAnyArgs(userId); sutProvider.GetDependency().GetByIdAsync(data.Id).ReturnsForAnyArgs(data); var peoplePolicies = request.ToServiceAccountPeopleAccessPolicies(data.Id, data.OrganizationId); sutProvider.GetDependency() .AuthorizeAsync(Arg.Any(), peoplePolicies, Arg.Any>()).ReturnsForAnyArgs(AuthorizationResult.Success()); sutProvider.GetDependency().ReplaceServiceAccountPeopleAsync(peoplePolicies, Arg.Any()) .Returns(peoplePolicies.ToBaseAccessPolicies()); await sutProvider.Sut.PutServiceAccountPeopleAccessPoliciesAsync(data.Id, request); await sutProvider.GetDependency().Received(1) .ReplaceServiceAccountPeopleAsync(Arg.Any(), Arg.Any()); } }