Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[BEEEP][SM-893] Add the ability to run SM integration tests as a service account #3187

Merged
merged 14 commits into from Mar 29, 2024
Merged
9 changes: 9 additions & 0 deletions test/Api.IntegrationTest/Factories/ApiApplicationFactory.cs
Expand Up @@ -53,4 +53,13 @@ public async Task<(string Token, string RefreshToken)> LoginAsync(string email =
{
return await _identityApplicationFactory.TokenFromPasswordAsync(email, masterPasswordHash);
}

/// <summary>
/// Helper for logging via client secret.
/// Currently used for Secrets Manager service accounts
/// </summary>
public async Task<string> LoginWithClientSecretAsync(Guid clientId, string clientSecret)
{
return await _identityApplicationFactory.TokenFromAccessTokenAsync(clientId, clientSecret);
}
}
30 changes: 30 additions & 0 deletions test/Api.IntegrationTest/Helpers/ClientTestHelper.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.Helpers;

public class ClientTestHelper
{
private readonly HttpClient _client;
private readonly ApiApplicationFactory _factory;

public ClientTestHelper(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());
}
}

Large diffs are not rendered by default.

@@ -1,6 +1,6 @@
using System.Net;
using System.Net.Http.Headers;
using Bit.Api.IntegrationTest.Factories;
using Bit.Api.IntegrationTest.Helpers;
using Bit.Api.IntegrationTest.SecretsManager.Enums;
using Bit.Api.Models.Response;
using Bit.Api.SecretsManager.Models.Request;
Expand All @@ -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;
Expand All @@ -24,6 +23,7 @@ public class ProjectsControllerTests : IClassFixture<ApiApplicationFactory>, IAs
private readonly ApiApplicationFactory _factory;
private readonly IProjectRepository _projectRepository;
private readonly IAccessPolicyRepository _accessPolicyRepository;
private readonly ClientTestHelper _clientTestHelper;

private string _email = null!;
private SecretsManagerOrganizationHelper _organizationHelper = null!;
Expand All @@ -34,6 +34,7 @@ public ProjectsControllerTests(ApiApplicationFactory factory)
_client = _factory.CreateClient();
_projectRepository = _factory.GetService<IProjectRepository>();
_accessPolicyRepository = _factory.GetService<IAccessPolicyRepository>();
_clientTestHelper = new ClientTestHelper(_factory, _client);
}

public async Task InitializeAsync()
Expand All @@ -49,20 +50,14 @@ 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)]
[InlineData(true, false)]
[InlineData(false, true)]
public async Task ListByOrganization_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets)
{
var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var response = await _client.GetAsync($"/organizations/{org.Id}/projects");
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
Expand All @@ -73,7 +68,7 @@ public async Task ListByOrganization_UserWithoutPermission_EmptyList()
{
var (org, _) = await _organizationHelper.Initialize(true, true);
var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

await CreateProjectsAsync(org.Id);

Expand Down Expand Up @@ -108,7 +103,7 @@ public async Task ListByOrganization_Success(PermissionType permissionType)
public async Task Create_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets)
{
var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var request = new ProjectCreateRequestModel { Name = _mockEncryptedString };

Expand All @@ -135,14 +130,14 @@ public async Task Create_AtMaxProjects_BadRequest(PermissionType permissionType)
public async Task Create_Success(PermissionType permissionType)
{
var (org, adminOrgUser) = await _organizationHelper.Initialize(true, true);
await LoginAsync(_email);
await _clientTestHelper.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 _clientTestHelper.LoginAsync(email);
orgUserId = orgUser.Id;
currentUserId = orgUser.UserId!.Value;
}
Expand Down Expand Up @@ -184,7 +179,7 @@ public async Task Create_Success(PermissionType permissionType)
public async Task Update_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets)
{
var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var initialProject = await _projectRepository.CreateAsync(new Project
{
Expand Down Expand Up @@ -232,7 +227,7 @@ public async Task Update_Success(PermissionType permissionType)
public async Task Update_NonExistingProject_NotFound()
{
await _organizationHelper.Initialize(true, true);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var request = new ProjectUpdateRequestModel
{
Expand All @@ -250,7 +245,7 @@ public async Task Update_MissingAccessPolicy_NotFound()
{
var (org, _) = await _organizationHelper.Initialize(true, true);
var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

var project = await _projectRepository.CreateAsync(new Project
{
Expand All @@ -276,7 +271,7 @@ public async Task Update_MissingAccessPolicy_NotFound()
public async Task Get_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets)
{
var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var project = await _projectRepository.CreateAsync(new Project
{
Expand All @@ -297,7 +292,7 @@ public async Task Get_MissingAccessPolicy_NotFound()
{
var (org, _) = await _organizationHelper.Initialize(true, true);
var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

var createdProject = await _projectRepository.CreateAsync(new Project
{
Expand All @@ -314,7 +309,7 @@ public async Task Get_NonExistingProject_NotFound()
{
var (org, _) = await _organizationHelper.Initialize(true, true);
var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

var createdProject = await _projectRepository.CreateAsync(new Project
{
Expand Down Expand Up @@ -352,7 +347,7 @@ public async Task Get_Success(PermissionType permissionType)
public async Task Delete_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets)
{
var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var projectIds = await CreateProjectsAsync(org.Id);

Expand All @@ -365,7 +360,7 @@ public async Task Delete_MissingAccessPolicy_AccessDenied()
{
var (org, _) = await _organizationHelper.Initialize(true, true);
var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

var projectIds = await CreateProjectsAsync(org.Id);

Expand Down Expand Up @@ -418,7 +413,7 @@ private async Task<List<Guid>> CreateProjectsAsync(Guid orgId, int numberToCreat
int projectsToCreate = 3)
{
var (org, _) = await _organizationHelper.Initialize(true, true);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);
var projectIds = await CreateProjectsAsync(org.Id, projectsToCreate);

if (permissionType == PermissionType.RunAsAdmin)
Expand All @@ -427,7 +422,7 @@ private async Task<List<Guid>> CreateProjectsAsync(Guid orgId, int numberToCreat
}

var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

var accessPolicies = projectIds.Select(projectId => new UserProjectAccessPolicy
{
Expand All @@ -447,7 +442,7 @@ private async Task<List<Guid>> CreateProjectsAsync(Guid orgId, int numberToCreat
private async Task<Project> SetupProjectWithAccessAsync(PermissionType permissionType)
{
var (org, _) = await _organizationHelper.Initialize(true, true);
await LoginAsync(_email);
await _clientTestHelper.LoginAsync(_email);

var initialProject = await _projectRepository.CreateAsync(new Project
{
Expand All @@ -461,7 +456,7 @@ private async Task<Project> SetupProjectWithAccessAsync(PermissionType permissio
}

var (email, orgUser) = await _organizationHelper.CreateNewUser(OrganizationUserType.User, true);
await LoginAsync(email);
await _clientTestHelper.LoginAsync(email);

var accessPolicies = new List<BaseAccessPolicy>
{
Expand Down