diff --git a/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs b/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs index 90a2335c221e..f669e89eb0f6 100644 --- a/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs +++ b/test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs @@ -64,4 +64,13 @@ protected override void Dispose(bool disposing) base.Dispose(disposing); SqliteConnection.Dispose(); } + + /// + /// Helper for logging in via client secret. + /// Currently used for Secrets Manager service accounts + /// + public async Task LoginWithClientSecretAsync(Guid clientId, string clientSecret) + { + return await _identityApplicationFactory.TokenFromAccessTokenAsync(clientId, clientSecret); + } } diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/AccessPoliciesControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/AccessPoliciesControllerTests.cs index b8eb4a77009c..e1cce68704d5 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/AccessPoliciesControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/AccessPoliciesControllerTests.cs @@ -1,7 +1,7 @@ using System.Net; -using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; using Bit.Api.IntegrationTest.SecretsManager.Enums; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; @@ -28,6 +28,7 @@ public class AccessPoliciesControllerTests : IClassFixture(); _projectRepository = _factory.GetService(); _groupRepository = _factory.GetService(); + _loginHelper = new LoginHelper(_factory, _client); } public async Task InitializeAsync() @@ -54,12 +56,6 @@ public Task DisposeAsync() 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, false)] [InlineData(false, false, true)] @@ -71,7 +67,7 @@ private async Task LoginAsync(string email) public async Task CreateProjectAccessPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (projectId, serviceAccountId) = await CreateProjectAndServiceAccountAsync(org.Id); @@ -93,7 +89,7 @@ public async Task CreateProjectAccessPolicies_NoPermission() // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var (projectId, serviceAccountId) = await CreateProjectAndServiceAccountAsync(org.Id); var request = new AccessPoliciesCreateRequest @@ -115,7 +111,7 @@ public async Task CreateProjectAccessPolicies_NoPermission() public async Task CreateProjectAccessPolicies_MismatchedOrgIds_NotFound(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (projectId, serviceAccountId) = await CreateProjectAndServiceAccountAsync(org.Id, true); await SetupProjectAndServiceAccountPermissionAsync(permissionType, projectId, serviceAccountId); @@ -140,7 +136,7 @@ public async Task CreateProjectAccessPolicies_MismatchedOrgIds_NotFound(Permissi public async Task CreateProjectAccessPolicies_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (projectId, serviceAccountId) = await CreateProjectAndServiceAccountAsync(org.Id); await SetupProjectAndServiceAccountPermissionAsync(permissionType, projectId, serviceAccountId); @@ -159,7 +155,7 @@ public async Task CreateProjectAccessPolicies_Success(PermissionType permissionT var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(serviceAccountId, result!.ServiceAccountAccessPolicies.First().ServiceAccountId); + Assert.Equal(serviceAccountId, result.ServiceAccountAccessPolicies.First().ServiceAccountId); Assert.True(result.ServiceAccountAccessPolicies.First().Read); Assert.True(result.ServiceAccountAccessPolicies.First().Write); AssertHelper.AssertRecent(result.ServiceAccountAccessPolicies.First().RevisionDate); @@ -168,7 +164,7 @@ public async Task CreateProjectAccessPolicies_Success(PermissionType permissionT 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().Read, createdAccessPolicy.Read); Assert.Equal(result.ServiceAccountAccessPolicies.First().Write, createdAccessPolicy.Write); Assert.Equal(result.ServiceAccountAccessPolicies.First().Id, createdAccessPolicy.Id); AssertHelper.AssertRecent(createdAccessPolicy.CreationDate); @@ -186,7 +182,7 @@ public async Task CreateProjectAccessPolicies_Success(PermissionType permissionT public async Task UpdateAccessPolicy_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); const bool expectedRead = true; @@ -203,7 +199,7 @@ public async Task UpdateAccessPolicy_NoPermission() // Create a new account as a user await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); @@ -222,13 +218,13 @@ public async Task UpdateAccessPolicy_NoPermission() public async Task UpdateAccessPolicy_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy @@ -249,13 +245,13 @@ public async Task UpdateAccessPolicy_Success(PermissionType permissionType) var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(expectedRead, result!.Read); + 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(expectedRead, updatedAccessPolicy.Read); Assert.Equal(expectedWrite, updatedAccessPolicy.Write); AssertHelper.AssertRecent(updatedAccessPolicy.RevisionDate); } @@ -271,7 +267,7 @@ public async Task UpdateAccessPolicy_Success(PermissionType permissionType) public async Task DeleteAccessPolicy_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); var response = await _client.DeleteAsync($"/access-policies/{initData.AccessPolicyId}"); @@ -284,7 +280,7 @@ public async Task DeleteAccessPolicy_NoPermission() // Create a new account as a user await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); @@ -299,13 +295,13 @@ public async Task DeleteAccessPolicy_NoPermission() public async Task DeleteAccessPolicy_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy @@ -327,7 +323,7 @@ public async Task DeleteAccessPolicy_Success(PermissionType permissionType) public async Task GetProjectAccessPolicies_ReturnsEmpty() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -341,7 +337,7 @@ public async Task GetProjectAccessPolicies_ReturnsEmpty() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Empty(result!.UserAccessPolicies); + Assert.Empty(result.UserAccessPolicies); Assert.Empty(result.GroupAccessPolicies); Assert.Empty(result.ServiceAccountAccessPolicies); } @@ -357,7 +353,7 @@ public async Task GetProjectAccessPolicies_ReturnsEmpty() public async Task GetProjectAccessPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); @@ -371,7 +367,7 @@ public async Task GetProjectAccessPolicies_NoPermission() // Create a new account as a user await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); @@ -386,13 +382,13 @@ public async Task GetProjectAccessPolicies_NoPermission() public async Task GetProjectAccessPolicies(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy @@ -409,7 +405,7 @@ public async Task GetProjectAccessPolicies(PermissionType permissionType) var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result?.ServiceAccountAccessPolicies); - Assert.Single(result!.ServiceAccountAccessPolicies); + Assert.Single(result.ServiceAccountAccessPolicies); } [Theory] @@ -423,7 +419,7 @@ public async Task GetProjectAccessPolicies(PermissionType permissionType) public async Task GetPeoplePotentialGrantees_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync( @@ -437,12 +433,12 @@ public async Task GetPeoplePotentialGrantees_SmAccessDenied_NotFound(bool useSec public async Task GetPeoplePotentialGrantees_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); } var response = @@ -453,7 +449,7 @@ public async Task GetPeoplePotentialGrantees_Success(PermissionType permissionTy var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); } [Theory] @@ -467,7 +463,7 @@ public async Task GetPeoplePotentialGrantees_Success(PermissionType permissionTy public async Task GetServiceAccountPotentialGrantees_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync( @@ -481,7 +477,7 @@ public async Task GetServiceAccountPotentialGrantees_OnlyReturnsServiceAccountsW // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -498,7 +494,7 @@ public async Task GetServiceAccountPotentialGrantees_OnlyReturnsServiceAccountsW var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); - Assert.Empty(result!.Data); + Assert.Empty(result.Data); } [Theory] @@ -507,7 +503,7 @@ public async Task GetServiceAccountPotentialGrantees_OnlyReturnsServiceAccountsW public async Task GetServiceAccountsPotentialGrantees_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -518,7 +514,7 @@ public async Task GetServiceAccountsPotentialGrantees_Success(PermissionType per if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _accessPolicyRepository.CreateManyAsync( new List @@ -541,7 +537,7 @@ public async Task GetServiceAccountsPotentialGrantees_Success(PermissionType per var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(serviceAccount.Id, result.Data.First(x => x.Id == serviceAccount.Id).Id); } @@ -556,7 +552,7 @@ public async Task GetServiceAccountsPotentialGrantees_Success(PermissionType per public async Task GetProjectPotentialGrantees_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync( @@ -570,7 +566,7 @@ public async Task GetProjectPotentialGrantees_OnlyReturnsProjectsWithWriteAccess // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = _mockEncryptedString }); @@ -583,7 +579,7 @@ public async Task GetProjectPotentialGrantees_OnlyReturnsProjectsWithWriteAccess var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); - Assert.Empty(result!.Data); + Assert.Empty(result.Data); } [Theory] @@ -592,7 +588,7 @@ public async Task GetProjectPotentialGrantees_OnlyReturnsProjectsWithWriteAccess public async Task GetProjectPotentialGrantees_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -603,7 +599,7 @@ public async Task GetProjectPotentialGrantees_Success(PermissionType permissionT if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _accessPolicyRepository.CreateManyAsync( new List @@ -623,7 +619,7 @@ public async Task GetProjectPotentialGrantees_Success(PermissionType permissionT var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result?.Data); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(project.Id, result.Data.First(x => x.Id == project.Id).Id); } @@ -638,7 +634,7 @@ public async Task GetProjectPotentialGrantees_Success(PermissionType permissionT public async Task CreateServiceAccountGrantedPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -659,7 +655,7 @@ public async Task CreateServiceAccountGrantedPolicies_NoPermission() // Create a new account as a user var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -687,7 +683,7 @@ public async Task CreateServiceAccountGrantedPolicies_NoPermission() public async Task CreateServiceAccountGrantedPolicies_MismatchedOrgId_NotFound(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (projectId, serviceAccountId) = await CreateProjectAndServiceAccountAsync(org.Id, true); await SetupProjectAndServiceAccountPermissionAsync(permissionType, projectId, serviceAccountId); @@ -707,7 +703,7 @@ public async Task CreateServiceAccountGrantedPolicies_MismatchedOrgId_NotFound(P public async Task CreateServiceAccountGrantedPolicies_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (projectId, serviceAccountId) = await CreateProjectAndServiceAccountAsync(org.Id); await SetupProjectAndServiceAccountPermissionAsync(permissionType, projectId, serviceAccountId); @@ -723,13 +719,13 @@ public async Task CreateServiceAccountGrantedPolicies_Success(PermissionType per .ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(projectId, result.Data.First().GrantedProjectId); var createdAccessPolicy = await _accessPolicyRepository.GetByIdAsync(result.Data.First().Id); Assert.NotNull(createdAccessPolicy); - Assert.Equal(result.Data.First().Read, createdAccessPolicy!.Read); + Assert.Equal(result.Data.First().Read, createdAccessPolicy.Read); Assert.Equal(result.Data.First().Write, createdAccessPolicy.Write); Assert.Equal(result.Data.First().Id, createdAccessPolicy.Id); AssertHelper.AssertRecent(createdAccessPolicy.CreationDate); @@ -747,7 +743,7 @@ public async Task CreateServiceAccountGrantedPolicies_Success(PermissionType per public async Task GetServiceAccountGrantedPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); var response = await _client.GetAsync($"/service-accounts/{initData.ServiceAccountId}/granted-policies"); @@ -758,7 +754,7 @@ public async Task GetServiceAccountGrantedPolicies_SmAccessDenied_NotFound(bool public async Task GetServiceAccountGrantedPolicies_ReturnsEmpty() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -773,7 +769,7 @@ public async Task GetServiceAccountGrantedPolicies_ReturnsEmpty() .ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.Empty(result!.Data); + Assert.Empty(result.Data); } [Fact] @@ -782,7 +778,7 @@ public async Task GetServiceAccountGrantedPolicies_NoPermission_ReturnsEmpty() // Create a new account as a user await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var initData = await SetupAccessPolicyRequest(orgUser.OrganizationId); @@ -792,7 +788,7 @@ public async Task GetServiceAccountGrantedPolicies_NoPermission_ReturnsEmpty() .ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.Empty(result!.Data); + Assert.Empty(result.Data); } [Theory] @@ -801,13 +797,13 @@ public async Task GetServiceAccountGrantedPolicies_NoPermission_ReturnsEmpty() public async Task GetServiceAccountGrantedPolicies(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initData = await SetupAccessPolicyRequest(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy @@ -825,7 +821,7 @@ public async Task GetServiceAccountGrantedPolicies(PermissionType permissionType .ReadFromJsonAsync>(); Assert.NotNull(result?.Data); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(initData.ServiceAccountId, result.Data.First().ServiceAccountId); Assert.NotNull(result.Data.First().ServiceAccountName); Assert.NotNull(result.Data.First().GrantedProjectName); @@ -842,7 +838,7 @@ public async Task GetServiceAccountGrantedPolicies(PermissionType permissionType public async Task GetProjectPeopleAccessPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -858,7 +854,7 @@ public async Task GetProjectPeopleAccessPolicies_SmAccessDenied_NotFound(bool us public async Task GetProjectPeopleAccessPolicies_ReturnsEmpty() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -872,7 +868,7 @@ public async Task GetProjectPeopleAccessPolicies_ReturnsEmpty() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Empty(result!.UserAccessPolicies); + Assert.Empty(result.UserAccessPolicies); Assert.Empty(result.GroupAccessPolicies); } @@ -881,7 +877,7 @@ public async Task GetProjectPeopleAccessPolicies_NoPermission_NotFound() { await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var project = await _projectRepository.CreateAsync(new Project { @@ -900,7 +896,7 @@ public async Task GetProjectPeopleAccessPolicies_NoPermission_NotFound() public async Task GetProjectPeopleAccessPolicies_Success(PermissionType permissionType) { var (_, organizationUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (project, _) = await SetupProjectPeoplePermissionAsync(permissionType, organizationUser); @@ -910,7 +906,7 @@ public async Task GetProjectPeopleAccessPolicies_Success(PermissionType permissi var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result?.UserAccessPolicies); - Assert.Single(result!.UserAccessPolicies); + Assert.Single(result.UserAccessPolicies); } [Theory] @@ -924,7 +920,7 @@ public async Task GetProjectPeopleAccessPolicies_Success(PermissionType permissi public async Task PutProjectPeopleAccessPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (_, organizationUser) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (project, request) = await SetupProjectPeopleRequestAsync(PermissionType.RunAsAdmin, organizationUser); @@ -937,7 +933,7 @@ public async Task PutProjectPeopleAccessPolicies_NoPermission() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, organizationUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var project = await _projectRepository.CreateAsync(new Project { @@ -964,7 +960,7 @@ public async Task PutProjectPeopleAccessPolicies_NoPermission() public async Task PutProjectPeopleAccessPolicies_MismatchedOrgIds_NotFound(PermissionType permissionType) { var (_, organizationUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (project, request) = await SetupProjectPeopleRequestAsync(permissionType, organizationUser); var newOrg = await _organizationHelper.CreateSmOrganizationAsync(); @@ -989,7 +985,7 @@ public async Task PutProjectPeopleAccessPolicies_MismatchedOrgIds_NotFound(Permi public async Task PutProjectPeopleAccessPolicies_Success(PermissionType permissionType) { var (_, organizationUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (project, request) = await SetupProjectPeopleRequestAsync(permissionType, organizationUser); @@ -1000,14 +996,14 @@ public async Task PutProjectPeopleAccessPolicies_Success(PermissionType permissi Assert.NotNull(result); Assert.Equal(request.UserAccessPolicyRequests.First().GranteeId, - result!.UserAccessPolicies.First().OrganizationUserId); + result.UserAccessPolicies.First().OrganizationUserId); Assert.True(result.UserAccessPolicies.First().Read); Assert.True(result.UserAccessPolicies.First().Write); 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().Read, createdAccessPolicy.Read); Assert.Equal(result.UserAccessPolicies.First().Write, createdAccessPolicy.Write); Assert.Equal(result.UserAccessPolicies.First().Id, createdAccessPolicy.Id); } @@ -1023,7 +1019,7 @@ public async Task PutProjectPeopleAccessPolicies_Success(PermissionType permissi public async Task GetServiceAccountPeopleAccessPolicies_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { OrganizationId = org.Id, @@ -1038,7 +1034,7 @@ public async Task GetServiceAccountPeopleAccessPolicies_SmAccessDenied_NotFound( public async Task GetServiceAccountPeopleAccessPolicies_ReturnsEmpty() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -1052,7 +1048,7 @@ public async Task GetServiceAccountPeopleAccessPolicies_ReturnsEmpty() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Empty(result!.UserAccessPolicies); + Assert.Empty(result.UserAccessPolicies); Assert.Empty(result.GroupAccessPolicies); } @@ -1061,7 +1057,7 @@ public async Task GetServiceAccountPeopleAccessPolicies_NoPermission() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -1080,7 +1076,7 @@ public async Task GetServiceAccountPeopleAccessPolicies_NoPermission() public async Task GetServiceAccountPeopleAccessPolicies_Success(PermissionType permissionType) { var (_, organizationUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (serviceAccount, _) = await SetupServiceAccountPeoplePermissionAsync(permissionType, organizationUser); @@ -1090,7 +1086,7 @@ public async Task GetServiceAccountPeopleAccessPolicies_Success(PermissionType p var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result?.UserAccessPolicies); - Assert.Single(result!.UserAccessPolicies); + Assert.Single(result.UserAccessPolicies); } [Theory] @@ -1100,7 +1096,7 @@ public async Task GetServiceAccountPeopleAccessPolicies_Success(PermissionType p public async Task PutServiceAccountPeopleAccessPolicies_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets) { var (_, organizationUser) = await _organizationHelper.Initialize(useSecrets, accessSecrets, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (serviceAccount, request) = await SetupServiceAccountPeopleRequestAsync(PermissionType.RunAsAdmin, organizationUser); @@ -1113,7 +1109,7 @@ public async Task PutServiceAccountPeopleAccessPolicies_NoPermission() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, organizationUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -1141,7 +1137,7 @@ public async Task PutServiceAccountPeopleAccessPolicies_NoPermission() public async Task PutServiceAccountPeopleAccessPolicies_MismatchedOrgIds_NotFound(PermissionType permissionType) { var (_, organizationUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (serviceAccount, request) = await SetupServiceAccountPeopleRequestAsync(permissionType, organizationUser); var newOrg = await _organizationHelper.CreateSmOrganizationAsync(); @@ -1166,7 +1162,7 @@ public async Task PutServiceAccountPeopleAccessPolicies_MismatchedOrgIds_NotFoun public async Task PutServiceAccountPeopleAccessPolicies_Success(PermissionType permissionType) { var (_, organizationUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (serviceAccount, request) = await SetupServiceAccountPeopleRequestAsync(permissionType, organizationUser); @@ -1177,14 +1173,14 @@ public async Task PutServiceAccountPeopleAccessPolicies_Success(PermissionType p Assert.NotNull(result); Assert.Equal(request.UserAccessPolicyRequests.First().GranteeId, - result!.UserAccessPolicies.First().OrganizationUserId); + result.UserAccessPolicies.First().OrganizationUserId); Assert.True(result.UserAccessPolicies.First().Read); Assert.True(result.UserAccessPolicies.First().Write); 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().Read, createdAccessPolicy.Read); Assert.Equal(result.UserAccessPolicies.First().Write, createdAccessPolicy.Write); Assert.Equal(result.UserAccessPolicies.First().Id, createdAccessPolicy.Id); } @@ -1233,7 +1229,7 @@ private async Task SetupAccessPolicyRequest(Guid organizationI if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); organizationUser = orgUser; } @@ -1265,7 +1261,7 @@ private async Task SetupAccessPolicyRequest(Guid organizationI if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); organizationUser = orgUser; } @@ -1342,7 +1338,7 @@ private async Task SetupAccessPolicyRequest(Guid organizationI if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { new UserProjectAccessPolicy @@ -1361,35 +1357,6 @@ private async Task SetupAccessPolicyRequest(Guid organizationI } } - private async Task SetupUserServiceAccountAccessPolicyRequestAsync( - PermissionType permissionType, Guid userId, Guid serviceAccountId) - { - if (permissionType == PermissionType.RunAsUserWithPermission) - { - var (email, newOrgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); - var accessPolicies = new List - { - new UserServiceAccountAccessPolicy - { - GrantedServiceAccountId = serviceAccountId, - OrganizationUserId = newOrgUser.Id, - Read = true, - Write = true, - }, - }; - await _accessPolicyRepository.CreateManyAsync(accessPolicies); - } - - return new AccessPoliciesCreateRequest - { - UserAccessPolicyRequests = new List - { - new() { GranteeId = userId, Read = true, Write = true }, - }, - }; - } - private class RequestSetupData { public Guid ProjectId { get; set; } diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/ProjectsControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/ProjectsControllerTests.cs index 523998ee2881..95ddfd678e00 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/ProjectsControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/ProjectsControllerTests.cs @@ -1,7 +1,7 @@ using System.Net; -using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; using Bit.Api.IntegrationTest.SecretsManager.Enums; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; @@ -10,7 +10,6 @@ using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Repositories; using Bit.Test.Common.Helpers; -using Pipelines.Sockets.Unofficial.Arenas; using Xunit; namespace Bit.Api.IntegrationTest.SecretsManager.Controllers; @@ -24,6 +23,7 @@ public class ProjectsControllerTests : IClassFixture, IAs private readonly ApiApplicationFactory _factory; private readonly IProjectRepository _projectRepository; private readonly IAccessPolicyRepository _accessPolicyRepository; + private readonly LoginHelper _loginHelper; private string _email = null!; private SecretsManagerOrganizationHelper _organizationHelper = null!; @@ -34,6 +34,7 @@ public ProjectsControllerTests(ApiApplicationFactory factory) _client = _factory.CreateClient(); _projectRepository = _factory.GetService(); _accessPolicyRepository = _factory.GetService(); + _loginHelper = new LoginHelper(_factory, _client); } public async Task InitializeAsync() @@ -49,12 +50,6 @@ public Task DisposeAsync() 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, false)] [InlineData(false, false, true)] @@ -66,7 +61,7 @@ private async Task LoginAsync(string email) public async Task ListByOrganization_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync($"/organizations/{org.Id}/projects"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -77,7 +72,7 @@ public async Task ListByOrganization_UserWithoutPermission_EmptyList() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await CreateProjectsAsync(org.Id); @@ -86,7 +81,7 @@ public async Task ListByOrganization_UserWithoutPermission_EmptyList() var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.Empty(result!.Data); + Assert.Empty(result.Data); } [Theory] @@ -101,7 +96,7 @@ public async Task ListByOrganization_Success(PermissionType permissionType) var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(projectIds.Count, result.Data.Count()); } @@ -116,7 +111,7 @@ public async Task ListByOrganization_Success(PermissionType permissionType) public async Task Create_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var request = new ProjectCreateRequestModel { Name = _mockEncryptedString }; @@ -129,7 +124,7 @@ public async Task Create_SmAccessDenied_NotFound(bool useSecrets, bool accessSec [InlineData(PermissionType.RunAsUserWithPermission)] public async Task Create_AtMaxProjects_BadRequest(PermissionType permissionType) { - var (_, organization) = await SetupProjectsWithAccessAsync(permissionType, 3); + var (_, organization) = await SetupProjectsWithAccessAsync(permissionType); var request = new ProjectCreateRequestModel { Name = _mockEncryptedString }; var response = await _client.PostAsJsonAsync($"/organizations/{organization.Id}/projects", request); @@ -143,14 +138,14 @@ public async Task Create_AtMaxProjects_BadRequest(PermissionType permissionType) public async Task Create_Success(PermissionType permissionType) { var (org, adminOrgUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var orgUserId = adminOrgUser.Id; var currentUserId = adminOrgUser.UserId!.Value; if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); orgUserId = orgUser.Id; currentUserId = orgUser.UserId!.Value; } @@ -162,7 +157,7 @@ public async Task Create_Success(PermissionType permissionType) var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Name, result!.Name); + Assert.Equal(request.Name, result.Name); AssertHelper.AssertRecent(result.RevisionDate); AssertHelper.AssertRecent(result.CreationDate); @@ -196,7 +191,7 @@ public async Task Create_Success(PermissionType permissionType) public async Task Update_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initialProject = await _projectRepository.CreateAsync(new Project { @@ -244,7 +239,7 @@ public async Task Update_Success(PermissionType permissionType) public async Task Update_NonExistingProject_NotFound() { await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var request = new ProjectUpdateRequestModel { @@ -262,7 +257,7 @@ public async Task Update_MissingAccessPolicy_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var project = await _projectRepository.CreateAsync(new Project { @@ -292,7 +287,7 @@ public async Task Update_MissingAccessPolicy_NotFound() public async Task Get_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -313,7 +308,7 @@ public async Task Get_MissingAccessPolicy_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var createdProject = await _projectRepository.CreateAsync(new Project { @@ -330,7 +325,7 @@ public async Task Get_NonExistingProject_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var createdProject = await _projectRepository.CreateAsync(new Project { @@ -338,7 +333,7 @@ public async Task Get_NonExistingProject_NotFound() Name = _mockEncryptedString, }); - var deleteResponse = await _client.PostAsync("/projects/delete", JsonContent.Create(createdProject.Id)); + await _client.PostAsync("/projects/delete", JsonContent.Create(createdProject.Id)); var response = await _client.GetAsync($"/projects/{createdProject.Id}"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -372,7 +367,7 @@ public async Task Get_Success(PermissionType permissionType) public async Task Delete_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var projectIds = await CreateProjectsAsync(org.Id); @@ -385,7 +380,7 @@ public async Task Delete_MissingAccessPolicy_AccessDenied() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var projectIds = await CreateProjectsAsync(org.Id); @@ -394,7 +389,7 @@ public async Task Delete_MissingAccessPolicy_AccessDenied() var results = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(results); Assert.Equal(projectIds.OrderBy(x => x), - results!.Data.Select(x => x.Id).OrderBy(x => x)); + results.Data.Select(x => x.Id).OrderBy(x => x)); Assert.All(results.Data, item => Assert.Equal("access denied", item.Error)); } @@ -411,7 +406,7 @@ public async Task Delete_Success(PermissionType permissionType) var results = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(results); Assert.Equal(projectIds.OrderBy(x => x), - results!.Data.Select(x => x.Id).OrderBy(x => x)); + results.Data.Select(x => x.Id).OrderBy(x => x)); Assert.DoesNotContain(results.Data, x => x.Error != null); var projects = await _projectRepository.GetManyWithSecretsByIds(projectIds); @@ -438,7 +433,7 @@ private async Task> CreateProjectsAsync(Guid orgId, int numberToCreat int projectsToCreate = 3) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var projectIds = await CreateProjectsAsync(org.Id, projectsToCreate); if (permissionType == PermissionType.RunAsAdmin) @@ -447,7 +442,7 @@ private async Task> CreateProjectsAsync(Guid orgId, int numberToCreat } var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = projectIds.Select(projectId => new UserProjectAccessPolicy { @@ -467,7 +462,7 @@ private async Task> CreateProjectsAsync(Guid orgId, int numberToCreat private async Task SetupProjectWithAccessAsync(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initialProject = await _projectRepository.CreateAsync(new Project { @@ -481,7 +476,7 @@ private async Task SetupProjectWithAccessAsync(PermissionType permissio } var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsControllerTests.cs index 4932ad9b9b89..0ff7396eda13 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsControllerTests.cs @@ -1,7 +1,7 @@ using System.Net; -using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; using Bit.Api.IntegrationTest.SecretsManager.Enums; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; @@ -23,6 +23,7 @@ public class SecretsControllerTests : IClassFixture, IAsy private readonly ISecretRepository _secretRepository; private readonly IProjectRepository _projectRepository; private readonly IAccessPolicyRepository _accessPolicyRepository; + private readonly LoginHelper _loginHelper; private string _email = null!; private SecretsManagerOrganizationHelper _organizationHelper = null!; @@ -34,6 +35,7 @@ public SecretsControllerTests(ApiApplicationFactory factory) _secretRepository = _factory.GetService(); _projectRepository = _factory.GetService(); _accessPolicyRepository = _factory.GetService(); + _loginHelper = new LoginHelper(_factory, _client); } public async Task InitializeAsync() @@ -49,12 +51,6 @@ public Task DisposeAsync() 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, false)] [InlineData(false, false, true)] @@ -66,7 +62,7 @@ private async Task LoginAsync(string email) public async Task ListByOrganization_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync($"/organizations/{org.Id}/secrets"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -77,8 +73,8 @@ public async Task ListByOrganization_SmAccessDenied_NotFound(bool useSecrets, bo [InlineData(PermissionType.RunAsUserWithPermission)] public async Task ListByOrganization_Success(PermissionType permissionType) { - var (org, orgUserOwner) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + var (org, _) = await _organizationHelper.Initialize(true, true, true); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -90,7 +86,7 @@ public async Task ListByOrganization_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { @@ -122,7 +118,7 @@ public async Task ListByOrganization_Success(PermissionType permissionType) var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.NotEmpty(result!.Secrets); + Assert.NotEmpty(result.Secrets); Assert.Equal(secretIds.Count, result.Secrets.Count()); } @@ -137,7 +133,7 @@ public async Task ListByOrganization_Success(PermissionType permissionType) public async Task Create_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var request = new SecretCreateRequestModel { @@ -154,7 +150,7 @@ public async Task Create_SmAccessDenied_NotFound(bool useSecrets, bool accessSec public async Task CreateWithoutProject_RunAsAdmin_Success() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var request = new SecretCreateRequestModel { @@ -168,7 +164,7 @@ public async Task CreateWithoutProject_RunAsAdmin_Success() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Key, result!.Key); + Assert.Equal(request.Key, result.Key); Assert.Equal(request.Value, result.Value); Assert.Equal(request.Note, result.Note); AssertHelper.AssertRecent(result.RevisionDate); @@ -188,7 +184,7 @@ public async Task CreateWithoutProject_RunAsAdmin_Success() public async Task CreateWithDifferentProjectOrgId_RunAsAdmin_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var anotherOrg = await _organizationHelper.CreateSmOrganizationAsync(); var project = @@ -210,7 +206,7 @@ public async Task CreateWithDifferentProjectOrgId_RunAsAdmin_NotFound() public async Task CreateWithMultipleProjects_RunAsAdmin_BadRequest() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var projectA = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = "123A" }); var projectB = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = "123B" }); @@ -231,8 +227,8 @@ public async Task CreateWithMultipleProjects_RunAsAdmin_BadRequest() public async Task CreateWithoutProject_RunAsUser_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); + await _loginHelper.LoginAsync(email); var request = new SecretCreateRequestModel { @@ -251,9 +247,9 @@ public async Task CreateWithoutProject_RunAsUser_NotFound() public async Task CreateWithProject_Success(PermissionType permissionType) { var (org, orgAdminUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); - AccessClientType accessType = AccessClientType.NoAccessCheck; + var accessType = AccessClientType.NoAccessCheck; var project = await _projectRepository.CreateAsync(new Project() { @@ -267,12 +263,12 @@ public async Task CreateWithProject_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); accessType = AccessClientType.User; var accessPolicies = new List { - new Core.SecretsManager.Entities.UserProjectAccessPolicy + new UserProjectAccessPolicy { GrantedProjectId = project.Id, OrganizationUserId = orgUser.Id , Read = true, Write = true, }, @@ -296,7 +292,7 @@ public async Task CreateWithProject_Success(PermissionType permissionType) var secret = result.Secret; Assert.NotNull(secretResult); - Assert.Equal(secret.Id, secretResult!.Id); + Assert.Equal(secret.Id, secretResult.Id); Assert.Equal(secret.OrganizationId, secretResult.OrganizationId); Assert.Equal(secret.Key, secretResult.Key); Assert.Equal(secret.Value, secretResult.Value); @@ -316,7 +312,7 @@ public async Task CreateWithProject_Success(PermissionType permissionType) public async Task Get_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -336,7 +332,7 @@ public async Task Get_SmAccessDenied_NotFound(bool useSecrets, bool accessSecret public async Task Get_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project() { @@ -348,7 +344,7 @@ public async Task Get_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { @@ -361,8 +357,8 @@ public async Task Get_Success(PermissionType permissionType) } else { - var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.Admin, true); - await LoginAsync(email); + var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.Admin, true); + await _loginHelper.LoginAsync(email); } var secret = await _secretRepository.CreateAsync(new Secret @@ -395,7 +391,7 @@ public async Task Get_Success(PermissionType permissionType) public async Task GetSecretsByProject_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project { @@ -411,8 +407,8 @@ public async Task GetSecretsByProject_SmAccessDenied_NotFound(bool useSecrets, b public async Task GetSecretsByProject_UserWithNoPermission_EmptyList() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); + await _loginHelper.LoginAsync(email); var project = await _projectRepository.CreateAsync(new Project() { @@ -421,7 +417,7 @@ public async Task GetSecretsByProject_UserWithNoPermission_EmptyList() Name = _mockEncryptedString }); - var secret = await _secretRepository.CreateAsync(new Secret + await _secretRepository.CreateAsync(new Secret { OrganizationId = org.Id, Key = _mockEncryptedString, @@ -434,8 +430,8 @@ public async Task GetSecretsByProject_UserWithNoPermission_EmptyList() response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Empty(result!.Secrets); - Assert.Empty(result!.Projects); + Assert.Empty(result.Secrets); + Assert.Empty(result.Projects); } [Theory] @@ -444,7 +440,7 @@ public async Task GetSecretsByProject_UserWithNoPermission_EmptyList() public async Task GetSecretsByProject_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var project = await _projectRepository.CreateAsync(new Project() { @@ -456,7 +452,7 @@ public async Task GetSecretsByProject_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { @@ -501,7 +497,7 @@ public async Task GetSecretsByProject_Success(PermissionType permissionType) public async Task Update_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -525,32 +521,18 @@ public async Task Update_SmAccessDenied_NotFound(bool useSecrets, bool accessSec [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] + [InlineData(PermissionType.RunAsServiceAccountWithPermission)] public async Task Update_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); - var project = await _projectRepository.CreateAsync(new Project() { - Id = new Guid(), + Id = Guid.NewGuid(), 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); - } + await SetupProjectPermissionAndLoginAsync(permissionType, project); var secret = await _secretRepository.CreateAsync(new Secret { @@ -558,7 +540,7 @@ public async Task Update_Success(PermissionType permissionType) Key = _mockEncryptedString, Value = _mockEncryptedString, Note = _mockEncryptedString, - Projects = permissionType == PermissionType.RunAsUserWithPermission ? new List() { project } : null + Projects = permissionType != PermissionType.RunAsAdmin ? new List() { project } : null }); var request = new SecretUpdateRequestModel() @@ -566,7 +548,7 @@ public async Task Update_Success(PermissionType permissionType) Key = _mockEncryptedString, Value = "2.3Uk+WNBIoU5xzmVFNcoWzz==|1MsPIYuRfdOHfu/0uY6H2Q==|/98xy4wb6pHP1VTZ9JcNCYgQjEUMFPlqJgCwRk1YXKg=", Note = _mockEncryptedString, - ProjectIds = permissionType == PermissionType.RunAsUserWithPermission ? new Guid[] { project.Id } : null + ProjectIds = permissionType != PermissionType.RunAsAdmin ? new Guid[] { project.Id } : null }; var response = await _client.PutAsJsonAsync($"/secrets/{secret.Id}", request); @@ -595,7 +577,7 @@ public async Task Update_Success(PermissionType permissionType) public async Task UpdateWithDifferentProjectOrgId_RunAsAdmin_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var anotherOrg = await _organizationHelper.CreateSmOrganizationAsync(); var project = await _projectRepository.CreateAsync(new Project { Name = "123", OrganizationId = anotherOrg.Id }); @@ -624,7 +606,7 @@ public async Task UpdateWithDifferentProjectOrgId_RunAsAdmin_NotFound() public async Task UpdateWithMultipleProjects_BadRequest() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var projectA = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = "123A" }); var projectB = await _projectRepository.CreateAsync(new Project { OrganizationId = org.Id, Name = "123B" }); @@ -660,7 +642,7 @@ public async Task UpdateWithMultipleProjects_BadRequest() public async Task Delete_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -680,33 +662,34 @@ public async Task Delete_MissingAccessPolicy_AccessDenied() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); - var (_, secretIds) = await CreateSecretsAsync(org.Id, 3); + var (_, secretIds) = await CreateSecretsAsync(org.Id); var response = await _client.PostAsync("/secrets/delete", JsonContent.Create(secretIds)); var results = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(results); Assert.Equal(secretIds.OrderBy(x => x), - results!.Data.Select(x => x.Id).OrderBy(x => x)); + results.Data.Select(x => x.Id).OrderBy(x => x)); Assert.All(results.Data, item => Assert.Equal("access denied", item.Error)); } [Theory] [InlineData(PermissionType.RunAsAdmin)] [InlineData(PermissionType.RunAsUserWithPermission)] + [InlineData(PermissionType.RunAsServiceAccountWithPermission)] public async Task Delete_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (project, secretIds) = await CreateSecretsAsync(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { @@ -723,8 +706,8 @@ public async Task Delete_Success(PermissionType permissionType) var results = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(results?.Data); - Assert.Equal(secretIds.Count, results!.Data.Count()); - foreach (var result in results!.Data) + Assert.Equal(secretIds.Count, results.Data.Count()); + foreach (var result in results.Data) { Assert.Contains(result.Id, secretIds); Assert.Null(result.Error); @@ -745,7 +728,7 @@ public async Task Delete_Success(PermissionType permissionType) public async Task GetSecretsByIds_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -767,14 +750,14 @@ public async Task GetSecretsByIds_SmAccessDenied_NotFound(bool useSecrets, bool public async Task GetSecretsByIds_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var (project, secretIds) = await CreateSecretsAsync(org.Id); if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { @@ -788,7 +771,7 @@ public async Task GetSecretsByIds_Success(PermissionType permissionType) else { var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.Admin, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); } var request = new GetSecretsRequestModel { Ids = secretIds }; @@ -797,8 +780,8 @@ public async Task GetSecretsByIds_Success(PermissionType permissionType) response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.NotEmpty(result!.Data); - Assert.Equal(secretIds.Count, result!.Data.Count()); + Assert.NotEmpty(result.Data); + Assert.Equal(secretIds.Count, result.Data.Count()); } private async Task<(Project Project, List secretIds)> CreateSecretsAsync(Guid orgId, int numberToCreate = 3) @@ -826,4 +809,48 @@ private async Task<(Project Project, List secretIds)> CreateSecretsAsync(G return (project, secretIds); } + + private async Task SetupProjectPermissionAndLoginAsync(PermissionType permissionType, Project project) + { + switch (permissionType) + { + case PermissionType.RunAsAdmin: + { + await _loginHelper.LoginAsync(_email); + break; + } + case PermissionType.RunAsUserWithPermission: + { + var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); + await _loginHelper.LoginAsync(email); + + var accessPolicies = new List + { + new UserProjectAccessPolicy + { + GrantedProjectId = project.Id, OrganizationUserId = orgUser.Id, Read = true, Write = true, + }, + }; + await _accessPolicyRepository.CreateManyAsync(accessPolicies); + break; + } + case PermissionType.RunAsServiceAccountWithPermission: + { + var apiKeyDetails = await _organizationHelper.CreateNewServiceAccountApiKeyAsync(); + await _loginHelper.LoginWithApiKeyAsync(apiKeyDetails); + + var accessPolicies = new List + { + new ServiceAccountProjectAccessPolicy + { + GrantedProjectId = project.Id, ServiceAccountId = apiKeyDetails.ApiKey.ServiceAccountId, Read = true, Write = true, + }, + }; + await _accessPolicyRepository.CreateManyAsync(accessPolicies); + break; + } + default: + throw new ArgumentOutOfRangeException(nameof(permissionType), permissionType, null); + } + } } diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerEventsControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerEventsControllerTests.cs index 4c053c3a2eb1..036e307d39f2 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerEventsControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerEventsControllerTests.cs @@ -1,6 +1,7 @@ using System.Net; using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Core.SecretsManager.Entities; using Bit.Core.SecretsManager.Repositories; using Xunit; diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerPortingControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerPortingControllerTests.cs index c57ceb20d9a7..ba41c1e8629d 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerPortingControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsManagerPortingControllerTests.cs @@ -1,8 +1,7 @@ using System.Net; -using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Api.SecretsManager.Models.Request; -using Bit.Core.SecretsManager.Repositories; using Xunit; namespace Bit.Api.IntegrationTest.SecretsManager.Controllers; @@ -11,8 +10,7 @@ public class SecretsManagerPortingControllerTests : IClassFixture(); - _accessPolicyRepository = _factory.GetService(); + _loginHelper = new LoginHelper(_factory, _client); } public async Task InitializeAsync() @@ -38,12 +35,6 @@ public Task DisposeAsync() 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, false)] [InlineData(false, false, true)] @@ -55,7 +46,7 @@ private async Task LoginAsync(string email) public async Task Import_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var projectsList = new List(); var secretsList = new List(); @@ -76,7 +67,7 @@ public async Task Import_SmAccessDenied_NotFound(bool useSecrets, bool accessSec public async Task Export_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync($"sm/{org.Id}/export"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsTrashControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsTrashControllerTests.cs index 69837981f6c7..76396bdd64a8 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsTrashControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/SecretsTrashControllerTests.cs @@ -1,6 +1,6 @@ using System.Net; -using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Api.SecretsManager.Models.Response; using Bit.Core.Enums; using Bit.Core.SecretsManager.Repositories; @@ -17,6 +17,7 @@ public class SecretsTrashControllerTests : IClassFixture, private readonly HttpClient _client; private readonly ApiApplicationFactory _factory; private readonly ISecretRepository _secretRepository; + private readonly LoginHelper _loginHelper; private string _email = null!; private SecretsManagerOrganizationHelper _organizationHelper = null!; @@ -26,6 +27,7 @@ public SecretsTrashControllerTests(ApiApplicationFactory factory) _factory = factory; _client = _factory.CreateClient(); _secretRepository = _factory.GetService(); + _loginHelper = new LoginHelper(_factory, _client); } public async Task InitializeAsync() @@ -41,12 +43,6 @@ public Task DisposeAsync() 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, false)] [InlineData(false, false, true)] @@ -58,7 +54,7 @@ private async Task LoginAsync(string email) public async Task ListByOrganization_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync($"/secrets/{org.Id}/trash"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -69,7 +65,7 @@ public async Task ListByOrganization_NotAdmin_Unauthorized() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var response = await _client.GetAsync($"/secrets/{org.Id}/trash"); Assert.Equal(HttpStatusCode.Unauthorized, response.StatusCode); @@ -79,7 +75,7 @@ public async Task ListByOrganization_NotAdmin_Unauthorized() public async Task ListByOrganization_Success() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); await _secretRepository.CreateAsync(new Secret { @@ -114,7 +110,7 @@ public async Task ListByOrganization_Success() public async Task Empty_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var ids = new List { Guid.NewGuid() }; var response = await _client.PostAsJsonAsync($"/secrets/{org.Id}/trash/empty", ids); @@ -126,7 +122,7 @@ public async Task Empty_NotAdmin_Unauthorized() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var ids = new List { Guid.NewGuid() }; var response = await _client.PostAsJsonAsync($"/secrets/{org.Id}/trash/empty", ids); @@ -137,7 +133,7 @@ public async Task Empty_NotAdmin_Unauthorized() public async Task Empty_Invalid_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -155,7 +151,7 @@ public async Task Empty_Invalid_NotFound() public async Task Empty_Success() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -181,7 +177,7 @@ public async Task Empty_Success() public async Task Restore_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var ids = new List { Guid.NewGuid() }; var response = await _client.PostAsJsonAsync($"/secrets/{org.Id}/trash/restore", ids); @@ -193,7 +189,7 @@ public async Task Restore_NotAdmin_Unauthorized() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var ids = new List { Guid.NewGuid() }; var response = await _client.PostAsJsonAsync($"/secrets/{org.Id}/trash/restore", ids); @@ -204,7 +200,7 @@ public async Task Restore_NotAdmin_Unauthorized() public async Task Restore_Invalid_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { @@ -222,7 +218,7 @@ public async Task Restore_Invalid_NotFound() public async Task Restore_Success() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var secret = await _secretRepository.CreateAsync(new Secret { diff --git a/test/Api.IntegrationTest/SecretsManager/Controllers/ServiceAccountsControllerTests.cs b/test/Api.IntegrationTest/SecretsManager/Controllers/ServiceAccountsControllerTests.cs index a482d9b04e46..f25005b26959 100644 --- a/test/Api.IntegrationTest/SecretsManager/Controllers/ServiceAccountsControllerTests.cs +++ b/test/Api.IntegrationTest/SecretsManager/Controllers/ServiceAccountsControllerTests.cs @@ -1,7 +1,7 @@ using System.Net; -using System.Net.Http.Headers; using Bit.Api.IntegrationTest.Factories; using Bit.Api.IntegrationTest.SecretsManager.Enums; +using Bit.Api.IntegrationTest.SecretsManager.Helpers; using Bit.Api.Models.Response; using Bit.Api.SecretsManager.Models.Request; using Bit.Api.SecretsManager.Models.Response; @@ -24,6 +24,7 @@ public class ServiceAccountsControllerTests : IClassFixture(); _accessPolicyRepository = _factory.GetService(); _apiKeyRepository = _factory.GetService(); + _loginHelper = new LoginHelper(_factory, _client); } public async Task InitializeAsync() @@ -54,12 +56,6 @@ public Task DisposeAsync() 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, false)] [InlineData(false, false, true)] @@ -71,7 +67,7 @@ private async Task LoginAsync(string email) public async Task ListByOrganization_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync($"/organizations/{org.Id}/service-accounts"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -81,7 +77,7 @@ public async Task ListByOrganization_SmAccessDenied_NotFound(bool useSecrets, bo public async Task ListByOrganization_Admin_Success() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccountIds = await SetupGetServiceAccountsByOrganizationAsync(org); @@ -90,7 +86,7 @@ public async Task ListByOrganization_Admin_Success() var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(serviceAccountIds.Count, result.Data.Count()); } @@ -99,7 +95,7 @@ public async Task ListByOrganization_User_Success() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccountIds = await SetupGetServiceAccountsByOrganizationAsync(org); @@ -120,7 +116,7 @@ public async Task ListByOrganization_User_Success() var result = await response.Content.ReadFromJsonAsync>(); Assert.NotNull(result); - Assert.NotEmpty(result!.Data); + Assert.NotEmpty(result.Data); Assert.Equal(2, result.Data.Count()); } @@ -135,7 +131,7 @@ public async Task ListByOrganization_User_Success() public async Task GetByServiceAccountId_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -150,8 +146,8 @@ public async Task GetByServiceAccountId_SmAccessDenied_NotFound(bool useSecrets, [Fact] public async Task GetByServiceAccountId_ServiceAccountDoesNotExist_NotFound() { - var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _organizationHelper.Initialize(true, true, true); + await _loginHelper.LoginAsync(_email); var response = await _client.GetAsync($"/service-accounts/{new Guid()}"); Assert.Equal(HttpStatusCode.NotFound, response.StatusCode); @@ -162,7 +158,7 @@ public async Task GetByServiceAccountId_UserWithoutPermission_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -185,7 +181,7 @@ public async Task GetByServiceAccountId_Success(PermissionType permissionType) response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(serviceAccount.Id, result!.Id); + Assert.Equal(serviceAccount.Id, result.Id); Assert.Equal(serviceAccount.OrganizationId, result.OrganizationId); Assert.Equal(serviceAccount.Name, result.Name); Assert.Equal(serviceAccount.CreationDate, result.CreationDate); @@ -203,7 +199,7 @@ public async Task GetByServiceAccountId_Success(PermissionType permissionType) public async Task Create_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var request = new ServiceAccountCreateRequestModel { Name = _mockEncryptedString }; @@ -217,7 +213,7 @@ public async Task Create_SmAccessDenied_NotFound(bool useSecrets, bool accessSec public async Task Create_Success(PermissionType permissionType) { var (org, adminOrgUser) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var orgUserId = adminOrgUser.Id; var currentUserId = adminOrgUser.UserId!.Value; @@ -225,7 +221,7 @@ public async Task Create_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); orgUserId = orgUser.Id; currentUserId = orgUser.UserId!.Value; } @@ -237,7 +233,7 @@ public async Task Create_Success(PermissionType permissionType) var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Name, result!.Name); + Assert.Equal(request.Name, result.Name); AssertHelper.AssertRecent(result.RevisionDate); AssertHelper.AssertRecent(result.CreationDate); @@ -270,7 +266,7 @@ public async Task Create_Success(PermissionType permissionType) public async Task Update_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initialServiceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -289,7 +285,7 @@ public async Task Update_User_NoPermissions() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var initialServiceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -307,7 +303,7 @@ public async Task Update_User_NoPermissions() public async Task Update_NonExistingServiceAccount_NotFound() { await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var request = new ServiceAccountUpdateRequestModel { Name = _mockNewName }; @@ -328,7 +324,7 @@ public async Task Update_Success(PermissionType permissionType) response.EnsureSuccessStatusCode(); var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Name, result!.Name); + Assert.Equal(request.Name, result.Name); Assert.NotEqual(initialServiceAccount.Name, result.Name); AssertHelper.AssertRecent(result.RevisionDate); Assert.NotEqual(initialServiceAccount.RevisionDate, result.RevisionDate); @@ -353,7 +349,7 @@ public async Task Update_Success(PermissionType permissionType) public async Task Delete_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initialServiceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -372,7 +368,7 @@ public async Task Delete_MissingAccessPolicy_AccessDenied() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -405,12 +401,12 @@ public async Task Delete_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsAdmin) { - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); } else { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _accessPolicyRepository.CreateManyAsync(new List { new UserServiceAccountAccessPolicy @@ -443,7 +439,7 @@ public async Task Delete_Success(PermissionType permissionType) public async Task GetAccessTokens_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -460,7 +456,7 @@ public async Task GetAccessTokens_UserNoPermission_NotFound() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -485,7 +481,7 @@ public async Task GetAccessTokens_UserNoPermission_NotFound() public async Task GetAccessTokens_Success(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -496,7 +492,7 @@ public async Task GetAccessTokens_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsUserWithPermission) { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _accessPolicyRepository.CreateManyAsync(new List { new UserServiceAccountAccessPolicy @@ -540,7 +536,7 @@ public async Task GetAccessTokens_Success(PermissionType permissionType) public async Task CreateAccessToken_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -565,7 +561,7 @@ public async Task CreateAccessToken_SmAccessDenied_NotFound(bool useSecrets, boo public async Task CreateAccessToken_Admin() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -587,7 +583,7 @@ public async Task CreateAccessToken_Admin() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Name, result!.Name); + Assert.Equal(request.Name, result.Name); Assert.NotNull(result.ClientSecret); Assert.Equal(mockExpiresAt, result.ExpireAt); AssertHelper.AssertRecent(result.RevisionDate); @@ -599,7 +595,7 @@ public async Task CreateAccessToken_User_WithPermission() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -623,7 +619,7 @@ public async Task CreateAccessToken_User_WithPermission() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Name, result!.Name); + Assert.Equal(request.Name, result.Name); Assert.NotNull(result.ClientSecret); Assert.Equal(mockExpiresAt, result.ExpireAt); AssertHelper.AssertRecent(result.RevisionDate); @@ -635,7 +631,7 @@ public async Task CreateAccessToken_User_NoPermission() { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -660,7 +656,7 @@ public async Task CreateAccessToken_User_NoPermission() public async Task CreateAccessToken_ExpireAtNull_Admin() { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -681,7 +677,7 @@ public async Task CreateAccessToken_ExpireAtNull_Admin() var result = await response.Content.ReadFromJsonAsync(); Assert.NotNull(result); - Assert.Equal(request.Name, result!.Name); + Assert.Equal(request.Name, result.Name); Assert.NotNull(result.ClientSecret); Assert.Null(result.ExpireAt); AssertHelper.AssertRecent(result.RevisionDate); @@ -699,7 +695,7 @@ public async Task CreateAccessToken_ExpireAtNull_Admin() public async Task RevokeAccessToken_SmAccessDenied_NotFound(bool useSecrets, bool accessSecrets, bool organizationEnabled) { var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets, organizationEnabled); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -730,7 +726,7 @@ public async Task RevokeAccessToken_User_NoPermission(bool hasReadAccess) { var (org, _) = await _organizationHelper.Initialize(true, true, true); var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var serviceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -782,12 +778,12 @@ public async Task RevokeAccessToken_Success(PermissionType permissionType) if (permissionType == PermissionType.RunAsAdmin) { - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); } else { var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); await _accessPolicyRepository.CreateManyAsync(new List { new UserServiceAccountAccessPolicy @@ -847,7 +843,7 @@ private async Task> SetupGetServiceAccountsByOrganizationAsync(Organi private async Task SetupServiceAccountWithAccessAsync(PermissionType permissionType) { var (org, _) = await _organizationHelper.Initialize(true, true, true); - await LoginAsync(_email); + await _loginHelper.LoginAsync(_email); var initialServiceAccount = await _serviceAccountRepository.CreateAsync(new ServiceAccount { @@ -861,7 +857,7 @@ private async Task SetupServiceAccountWithAccessAsync(Permission } var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true); - await LoginAsync(email); + await _loginHelper.LoginAsync(email); var accessPolicies = new List { diff --git a/test/Api.IntegrationTest/SecretsManager/Enums/PermissionType.cs b/test/Api.IntegrationTest/SecretsManager/Enums/PermissionType.cs index 7f1c4d7b999f..972bc7f0bec0 100644 --- a/test/Api.IntegrationTest/SecretsManager/Enums/PermissionType.cs +++ b/test/Api.IntegrationTest/SecretsManager/Enums/PermissionType.cs @@ -4,4 +4,5 @@ public enum PermissionType { RunAsAdmin, RunAsUserWithPermission, + RunAsServiceAccountWithPermission, } diff --git a/test/Api.IntegrationTest/SecretsManager/Helpers/LoginHelper.cs b/test/Api.IntegrationTest/SecretsManager/Helpers/LoginHelper.cs new file mode 100644 index 000000000000..9de66bc11e3e --- /dev/null +++ b/test/Api.IntegrationTest/SecretsManager/Helpers/LoginHelper.cs @@ -0,0 +1,30 @@ +using System.Net.Http.Headers; +using Bit.Api.IntegrationTest.Factories; +using Bit.Core.SecretsManager.Models.Data; + +namespace Bit.Api.IntegrationTest.SecretsManager.Helpers; + +public class LoginHelper +{ + private readonly HttpClient _client; + private readonly ApiApplicationFactory _factory; + + public LoginHelper(ApiApplicationFactory factory, HttpClient client) + { + _factory = factory; + _client = client; + } + + public async Task LoginAsync(string email) + { + var tokens = await _factory.LoginAsync(email); + _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", tokens.Token); + } + + public async Task LoginWithApiKeyAsync(ApiKeyClientSecretDetails apiKeyDetails) + { + var token = await _factory.LoginWithClientSecretAsync(apiKeyDetails.ApiKey.Id, apiKeyDetails.ClientSecret); + _client.DefaultRequestHeaders.Authorization = new AuthenticationHeaderValue("Bearer", token); + _client.DefaultRequestHeaders.Add("service_account_id", apiKeyDetails.ApiKey.ServiceAccountId.ToString()); + } +} diff --git a/test/Api.IntegrationTest/SecretsManager/SecretsManagerOrganizationHelper.cs b/test/Api.IntegrationTest/SecretsManager/Helpers/SecretsManagerOrganizationHelper.cs similarity index 58% rename from test/Api.IntegrationTest/SecretsManager/SecretsManagerOrganizationHelper.cs rename to test/Api.IntegrationTest/SecretsManager/Helpers/SecretsManagerOrganizationHelper.cs index fea05de311f6..d2d03d979e98 100644 --- a/test/Api.IntegrationTest/SecretsManager/SecretsManagerOrganizationHelper.cs +++ b/test/Api.IntegrationTest/SecretsManager/Helpers/SecretsManagerOrganizationHelper.cs @@ -4,8 +4,12 @@ using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Repositories; +using Bit.Core.SecretsManager.Commands.AccessTokens.Interfaces; +using Bit.Core.SecretsManager.Entities; +using Bit.Core.SecretsManager.Models.Data; +using Bit.Core.SecretsManager.Repositories; -namespace Bit.Api.IntegrationTest.SecretsManager; +namespace Bit.Api.IntegrationTest.SecretsManager.Helpers; public class SecretsManagerOrganizationHelper { @@ -13,17 +17,20 @@ public class SecretsManagerOrganizationHelper private readonly string _ownerEmail; private readonly IOrganizationRepository _organizationRepository; private readonly IOrganizationUserRepository _organizationUserRepository; + private readonly IServiceAccountRepository _serviceAccountRepository; + private readonly ICreateAccessTokenCommand _createAccessTokenCommand; - public Organization _organization = null!; - public OrganizationUser _owner = null!; + private Organization _organization = null!; + private OrganizationUser _owner = null!; public SecretsManagerOrganizationHelper(ApiApplicationFactory factory, string ownerEmail) { _factory = factory; _organizationRepository = factory.GetService(); _organizationUserRepository = factory.GetService(); - _ownerEmail = ownerEmail; + _serviceAccountRepository = factory.GetService(); + _createAccessTokenCommand = factory.GetService(); } public async Task<(Organization organization, OrganizationUser owner)> Initialize(bool useSecrets, bool ownerAccessSecrets, bool organizationEnabled) @@ -58,8 +65,7 @@ public async Task CreateSmOrganizationAsync() { var email = $"integration-test{Guid.NewGuid()}@bitwarden.com"; await _factory.LoginWithNewAccount(email); - var (organization, owner) = - await OrganizationTestHelpers.SignUpAsync(_factory, ownerEmail: email, billingEmail: email); + var (organization, _) = await OrganizationTestHelpers.SignUpAsync(_factory, ownerEmail: email, billingEmail: email); return organization; } @@ -71,4 +77,29 @@ public async Task<(string email, OrganizationUser orgUser)> CreateNewUser(Organi return (email, orgUser); } + + public async Task CreateNewServiceAccountApiKeyAsync() + { + var serviceAccountId = Guid.NewGuid(); + var serviceAccount = new ServiceAccount + { + Id = serviceAccountId, + OrganizationId = _organization.Id, + Name = $"integration-test-{serviceAccountId}sa", + CreationDate = DateTime.UtcNow, + RevisionDate = DateTime.UtcNow + }; + await _serviceAccountRepository.CreateAsync(serviceAccount); + + var apiKey = new ApiKey + { + ServiceAccountId = serviceAccountId, + Name = "integration-token", + Key = Guid.NewGuid().ToString(), + ExpireAt = null, + Scope = "[\"api.secrets\"]", + EncryptedPayload = Guid.NewGuid().ToString() + }; + return await _createAccessTokenCommand.CreateAsync(apiKey); + } } diff --git a/test/IntegrationTestCommon/Factories/IdentityApplicationFactory.cs b/test/IntegrationTestCommon/Factories/IdentityApplicationFactory.cs index def8f5c14cd1..2dc23056d1dc 100644 --- a/test/IntegrationTestCommon/Factories/IdentityApplicationFactory.cs +++ b/test/IntegrationTestCommon/Factories/IdentityApplicationFactory.cs @@ -42,4 +42,23 @@ public async Task RegisterAsync(RegisterRequestModel model) return (root.GetProperty("access_token").GetString(), root.GetProperty("refresh_token").GetString()); } + + public async Task TokenFromAccessTokenAsync(Guid clientId, string clientSecret, + DeviceType deviceType = DeviceType.SDK) + { + var context = await Server.PostAsync("/connect/token", + new FormUrlEncodedContent(new Dictionary + { + { "scope", "api.secrets" }, + { "client_id", clientId.ToString() }, + { "client_secret", clientSecret }, + { "grant_type", "client_credentials" }, + { "deviceType", ((int)deviceType).ToString() } + })); + + using var body = await AssertHelper.AssertResponseTypeIs(context); + var root = body.RootElement; + + return root.GetProperty("access_token").GetString(); + } }