using System.Net; using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; using Bit.Api.IntegrationTest.SecretsManager.Enums; using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; using Bit.Core.Enums; using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Repositories; using Bit.Test.Common.Helpers; using Xunit; namespace Bit.Api.IntegrationTest.SecretsManager.Controllers; public class AccessPoliciesControllerTest : IClassFixture, IAsyncLifetime { private const string _mockEncryptedString = "2.3Uk+WNBIoU5xzmVFNcoWzz==|1MsPIYuRfdOHfu/0uY6H2Q==|/98sp4wb6pHP1VTZ9JcNCYgQjEUMFPlqJgCwRk1YXKg="; private readonly IAccessPolicyRepository _accessPolicyRepository; private readonly HttpClient _client; private readonly ApiApplicationFactory _factory; private readonly IProjectRepository _projectRepository; private readonly IServiceAccountRepository _serviceAccountRepository; private string _email = null!; private SecretsManagerOrganizationHelper _organizationHelper = null!; public AccessPoliciesControllerTest(ApiApplicationFactory factory) { _factory = factory; _client = _factory.CreateClient(); _accessPolicyRepository = _factory.GetService(); _serviceAccountRepository = _factory.GetService(); _projectRepository = _factory.GetService(); } public async Task InitializeAsync() { _email = $"integration-test{Guid.NewGuid()}@bitwarden.com"; await _factory.LoginWithNewAccount(_email); _organizationHelper = new SecretsManagerOrganizationHelper(_factory, _email); } public Task DisposeAsync() { _client.Dispose(); return Task.CompletedTask; } private async Task LoginAsync(string email) { var tokens = await _factory.LoginAsync(email); _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokens.Token); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task CreateProjectAccessPolicies_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = _mockEncryptedString, }); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var request = new AccessPoliciesCreateRequest { ServiceAccountAccessPolicyRequests = new List { new() { GranteeId = serviceAccount.Id, Read = true, Write = true }, }, }; var response = await _client.PostAsJsonAsync($"/projects/{project.Id}/access-policies", request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task CreateProjectAccessPolicies(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = _mockEncryptedString, }); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy { GrantedProjectId = project.Id, OrganizationUserId = orgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(accessPolicies); } var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var request = new AccessPoliciesCreateRequest { ServiceAccountAccessPolicyRequests = new List { new() { GranteeId = serviceAccount.Id, Read = true, Write = true }, }, }; var response = await _client.PostAsJsonAsync($"/projects/{project.Id}/access-policies", request); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); Assert.Equal(serviceAccount.Id, result!.ServiceAccountAccessPolicies.First().ServiceAccountId); Assert.True(result.ServiceAccountAccessPolicies.First().Read); Assert.True(result.ServiceAccountAccessPolicies.First().Write); AssertHelper.AssertRecent(result.ServiceAccountAccessPolicies.First().RevisionDate); AssertHelper.AssertRecent(result.ServiceAccountAccessPolicies.First().CreationDate); var createdAccessPolicy = await _accessPolicyRepository.GetByIdAsync(result.ServiceAccountAccessPolicies.First().Id); Assert.NotNull(createdAccessPolicy); Assert.Equal(result.ServiceAccountAccessPolicies.First().Read, createdAccessPolicy!.Read); Assert.Equal(result.ServiceAccountAccessPolicies.First().Write, createdAccessPolicy.Write); Assert.Equal(result.ServiceAccountAccessPolicies.First().Id, createdAccessPolicy.Id); AssertHelper.AssertRecent(createdAccessPolicy.CreationDate); AssertHelper.AssertRecent(createdAccessPolicy.RevisionDate); } [Fact] public async Task CreateProjectAccessPolicies_NoPermission() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var project = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = _mockEncryptedString, }); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var request = new AccessPoliciesCreateRequest { ServiceAccountAccessPolicyRequests = new List { new() { GranteeId = serviceAccount.Id, Read = true, Write = true }, }, }; var response = await _client.PostAsJsonAsync($"/projects/{project.Id}/access-policies", request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task UpdateAccessPolicy_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); const bool expectedRead = true; const bool expectedWrite = false; var request = new AccessPolicyUpdateRequest { Read = expectedRead, Write = expectedWrite }; var response = await _client.PutAsJsonAsync($"/access-policies/{initData.AccessPolicyId}", request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task UpdateAccessPolicy_NoPermission() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); const bool expectedRead = true; const bool expectedWrite = false; var request = new AccessPolicyUpdateRequest { Read = expectedRead, Write = expectedWrite }; var response = await _client.PutAsJsonAsync($"/access-policies/{initData.AccessPolicyId}", request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task UpdateAccessPolicy(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy { GrantedProjectId = initData.ProjectId, OrganizationUserId = orgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(accessPolicies); } const bool expectedRead = true; const bool expectedWrite = false; var request = new AccessPolicyUpdateRequest { Read = expectedRead, Write = expectedWrite }; var response = await _client.PutAsJsonAsync($"/access-policies/{initData.AccessPolicyId}", request); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); Assert.Equal(expectedRead, result!.Read); Assert.Equal(expectedWrite, result.Write); AssertHelper.AssertRecent(result.RevisionDate); var updatedAccessPolicy = await _accessPolicyRepository.GetByIdAsync(result.Id); Assert.NotNull(updatedAccessPolicy); Assert.Equal(expectedRead, updatedAccessPolicy!.Read); Assert.Equal(expectedWrite, updatedAccessPolicy.Write); AssertHelper.AssertRecent(updatedAccessPolicy.RevisionDate); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task DeleteAccessPolicy_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); var response = await _client.DeleteAsync($"/access-policies/{initData.AccessPolicyId}"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task DeleteAccessPolicy_NoPermission() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); var response = await _client.DeleteAsync($"/access-policies/{initData.AccessPolicyId}"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task DeleteAccessPolicy(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy { GrantedProjectId = initData.ProjectId, OrganizationUserId = orgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(accessPolicies); } var response = await _client.DeleteAsync($"/access-policies/{initData.AccessPolicyId}"); response.EnsureSuccessStatusCode(); var test = await _accessPolicyRepository.GetByIdAsync(initData.AccessPolicyId); Assert.Null(test); } [Fact] public async Task GetProjectAccessPolicies_ReturnsEmpty() { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = _mockEncryptedString, }); var response = await _client.GetAsync($"/projects/{project.Id}/access-policies"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); Assert.Empty(result!.UserAccessPolicies); Assert.Empty(result!.GroupAccessPolicies); Assert.Empty(result!.ServiceAccountAccessPolicies); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task GetProjectAccessPolicies_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); var response = await _client.GetAsync($"/projects/{initData.ProjectId}/access-policies"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task GetProjectAccessPolicies_NoPermission() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); var response = await _client.GetAsync($"/projects/{initData.ProjectId}/access-policies"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task GetProjectAccessPolicies(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy { GrantedProjectId = initData.ProjectId, OrganizationUserId = orgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(accessPolicies); } var response = await _client.GetAsync($"/projects/{initData.ProjectId}/access-policies"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result?.ServiceAccountAccessPolicies); Assert.Single(result!.ServiceAccountAccessPolicies); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task GetPeoplePotentialGrantees_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var response = await _client.GetAsync( $"/organizations/{org.Id}/access-policies/people/potential-grantees"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task GetPeoplePotentialGrantees_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); } var response = await _client.GetAsync( $"/organizations/{org.Id}/access-policies/people/potential-grantees"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); Assert.NotEmpty(result!.Data); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task GetServiceAccountPotentialGrantees_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var response = await _client.GetAsync( $"/organizations/{org.Id}/access-policies/service-accounts/potential-grantees"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task GetServiceAccountPotentialGrantees_OnlyReturnsServiceAccountsWithWriteAccess() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var response = await _client.GetAsync( $"/organizations/{org.Id}/access-policies/service-accounts/potential-grantees"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); Assert.Empty(result!.Data); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task GetServiceAccountsPotentialGrantees_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); await _accessPolicyRepository.CreateManyAsync( new List { new UserServiceAccountAccessPolicy { GrantedServiceAccountId = serviceAccount.Id, OrganizationUserId = orgUser.Id, Read = true, Write = true, }, }); } var response = await _client.GetAsync( $"/organizations/{org.Id}/access-policies/service-accounts/potential-grantees"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); Assert.NotEmpty(result!.Data); Assert.Equal(serviceAccount.Id.ToString(), result!.Data.First(x => x.Id == serviceAccount.Id.ToString()).Id); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task CreateServiceAccountAccessPolicies_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, orgUser) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var request = new AccessPoliciesCreateRequest { UserAccessPolicyRequests = new List { new() { GranteeId = orgUser.Id, Read = true, Write = true }, }, }; var response = await _client.PostAsJsonAsync($"/service-accounts/{serviceAccount.Id}/access-policies", request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task CreateServiceAccountAccessPolicies(PermissionType permissionType) { var (org, orgUser) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var ownerOrgUserId = orgUser.Id; var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var request = new AccessPoliciesCreateRequest { UserAccessPolicyRequests = new List { new() { GranteeId = orgUser.Id, Read = true, Write = true }, }, }; if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, newOrgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var accessPolicies = new List { new UserServiceAccountAccessPolicy { GrantedServiceAccountId = serviceAccount.Id, OrganizationUserId = newOrgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(accessPolicies); request = new AccessPoliciesCreateRequest { UserAccessPolicyRequests = new List { new() { GranteeId = ownerOrgUserId, Read = true, Write = true }, }, }; } var response = await _client.PostAsJsonAsync($"/service-accounts/{serviceAccount.Id}/access-policies", request); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); Assert.Equal(ownerOrgUserId, result!.UserAccessPolicies.First(ap => ap.OrganizationUserId == ownerOrgUserId).OrganizationUserId); Assert.True(result.UserAccessPolicies.First().Read); Assert.True(result.UserAccessPolicies.First().Write); AssertHelper.AssertRecent(result.UserAccessPolicies.First().RevisionDate); AssertHelper.AssertRecent(result.UserAccessPolicies.First().CreationDate); var createdAccessPolicy = await _accessPolicyRepository.GetByIdAsync(result.UserAccessPolicies.First().Id); Assert.NotNull(createdAccessPolicy); Assert.Equal(result.UserAccessPolicies.First().Read, createdAccessPolicy!.Read); Assert.Equal(result.UserAccessPolicies.First().Write, createdAccessPolicy.Write); Assert.Equal(result.UserAccessPolicies.First().Id, createdAccessPolicy.Id); AssertHelper.AssertRecent(createdAccessPolicy.CreationDate); AssertHelper.AssertRecent(createdAccessPolicy.RevisionDate); } [Fact] public async Task CreateServiceAccountAccessPolicies_NoPermission() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var request = new AccessPoliciesCreateRequest { UserAccessPolicyRequests = new List { new() { GranteeId = orgUser.Id, Read = true, Write = true }, }, }; var response = await _client.PostAsJsonAsync($"/service-accounts/{serviceAccount.Id}/access-policies", request); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(false, false)] [InlineData(true, false)] [InlineData(false, true)] public async Task GetServiceAccountAccessPolicies_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); var response = await _client.GetAsync($"/service-accounts/{initData.ServiceAccountId}/access-policies"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Fact] public async Task GetServiceAccountAccessPolicies_ReturnsEmpty() { var (org, _) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, Name = _mockEncryptedString, }); var response = await _client.GetAsync($"/service-accounts/{serviceAccount.Id}/access-policies"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); Assert.Empty(result!.UserAccessPolicies); Assert.Empty(result!.GroupAccessPolicies); } [Fact] public async Task GetServiceAccountAccessPolicies_NoPermission() { // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); var response = await _client.GetAsync($"/service-accounts/{initData.ServiceAccountId}/access-policies"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] public async Task GetServiceAccountAccessPolicies(PermissionType permissionType) { var (org, owerOrgUser) = await _organizationHelper.Initialize(true, true); await LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); await LoginAsync(email); var accessPolicies = new List { new UserServiceAccountAccessPolicy { GrantedServiceAccountId = initData.ServiceAccountId, OrganizationUserId = orgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(accessPolicies); } var policies = new List { new UserServiceAccountAccessPolicy { GrantedServiceAccountId = initData.ServiceAccountId, OrganizationUserId = owerOrgUser.Id, Read = true, Write = true, }, }; await _accessPolicyRepository.CreateManyAsync(policies); var response = await _client.GetAsync($"/service-accounts/{initData.ServiceAccountId}/access-policies"); response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result?.UserAccessPolicies); Assert.NotEmpty(result!.UserAccessPolicies); Assert.Equal(owerOrgUser.Id, result.UserAccessPolicies.First(x => x.OrganizationUserId == owerOrgUser.Id).OrganizationUserId); } private async Task SetupAccessPolicyRequest(Guid organizationId) { var project = await _projectRepository.CreateAsync(new Project { OrganizationId = organizationId, Name = _mockEncryptedString, }); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = organizationId, Name = _mockEncryptedString, }); var accessPolicy = await _accessPolicyRepository.CreateManyAsync( new List { new ServiceAccountProjectAccessPolicy { Read = true, Write = true, ServiceAccountId = serviceAccount.Id, GrantedProjectId = project.Id, }, }); return new RequestSetupData { ProjectId = project.Id, ServiceAccountId = serviceAccount.Id, AccessPolicyId = accessPolicy.First().Id, }; } private class RequestSetupData { public Guid ProjectId { get; set; } public Guid AccessPolicyId { get; set; } public Guid ServiceAccountId { get; set; } } }