1
0
mirror of https://github.com/bitwarden/server.git synced 2025-07-02 00:22:50 -05:00

Merge branch 'master' into feature/flexible-collections

This commit is contained in:
Vincent Salucci
2023-08-30 15:16:01 -05:00
70 changed files with 1252 additions and 466 deletions

View File

@ -116,6 +116,19 @@ public class ProjectsControllerTests : IClassFixture<ApiApplicationFactory>, IAs
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Theory]
[InlineData(PermissionType.RunAsAdmin)]
[InlineData(PermissionType.RunAsUserWithPermission)]
public async Task Create_AtMaxProjects_BadRequest(PermissionType permissionType)
{
var (_, organization) = await SetupProjectsWithAccessAsync(permissionType, 3);
var request = new ProjectCreateRequestModel { Name = _mockEncryptedString };
var response = await _client.PostAsJsonAsync($"/organizations/{organization.Id}/projects", request);
Assert.Equal(HttpStatusCode.BadRequest, response.StatusCode);
}
[Theory]
[InlineData(PermissionType.RunAsAdmin)]
[InlineData(PermissionType.RunAsUserWithPermission)]

View File

@ -709,6 +709,69 @@ public class SecretsControllerTests : IClassFixture<ApiApplicationFactory>, IAsy
Assert.Empty(secrets);
}
[Theory]
[InlineData(false, false)]
[InlineData(true, false)]
[InlineData(false, true)]
public async Task GetSecretsByIds_SmNotEnabled_NotFound(bool useSecrets, bool accessSecrets)
{
var (org, _) = await _organizationHelper.Initialize(useSecrets, accessSecrets);
await LoginAsync(_email);
var secret = await _secretRepository.CreateAsync(new Secret
{
OrganizationId = org.Id,
Key = _mockEncryptedString,
Value = _mockEncryptedString,
Note = _mockEncryptedString,
});
var request = new GetSecretsRequestModel { Ids = new[] { secret.Id } };
var response = await _client.PostAsJsonAsync("/secrets/get-by-ids", request);
Assert.Equal(HttpStatusCode.NotFound, response.StatusCode);
}
[Theory]
[InlineData(PermissionType.RunAsAdmin)]
[InlineData(PermissionType.RunAsUserWithPermission)]
public async Task GetSecretsByIds_Success(PermissionType permissionType)
{
var (org, _) = await _organizationHelper.Initialize(true, true);
await 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);
var accessPolicies = new List<BaseAccessPolicy>
{
new UserProjectAccessPolicy
{
GrantedProjectId = project.Id, OrganizationUserId = orgUser.Id, Read = true, Write = true,
},
};
await _accessPolicyRepository.CreateManyAsync(accessPolicies);
}
else
{
var (email, _) = await _organizationHelper.CreateNewUser(OrganizationUserType.Admin, true);
await LoginAsync(email);
}
var request = new GetSecretsRequestModel { Ids = secretIds };
var response = await _client.PostAsJsonAsync("/secrets/get-by-ids", request);
response.EnsureSuccessStatusCode();
var result = await response.Content.ReadFromJsonAsync<ListResponseModel<BaseSecretResponseModel>>();
Assert.NotNull(result);
Assert.NotEmpty(result!.Data);
Assert.Equal(secretIds.Count, result!.Data.Count());
}
private async Task<(Project Project, List<Guid> secretIds)> CreateSecretsAsync(Guid orgId, int numberToCreate = 3)
{
var project = await _projectRepository.CreateAsync(new Project

View File

@ -8,6 +8,7 @@ using Bit.Core.Exceptions;
using Bit.Core.SecretsManager.Commands.Projects.Interfaces;
using Bit.Core.SecretsManager.Entities;
using Bit.Core.SecretsManager.Models.Data;
using Bit.Core.SecretsManager.Queries.Projects.Interfaces;
using Bit.Core.SecretsManager.Repositories;
using Bit.Core.Services;
using Bit.Core.Test.SecretsManager.AutoFixture.ProjectsFixture;
@ -122,6 +123,24 @@ public class ProjectsControllerTests
.CreateAsync(Arg.Any<Project>(), Arg.Any<Guid>(), sutProvider.GetDependency<ICurrentContext>().ClientType);
}
[Theory]
[BitAutoData]
public async void Create_AtMaxProjects_Throws(SutProvider<ProjectsController> sutProvider,
Guid orgId, ProjectCreateRequestModel data)
{
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), data.ToProject(orgId),
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).ReturnsForAnyArgs(AuthorizationResult.Success());
sutProvider.GetDependency<IUserService>().GetProperUserId(default).ReturnsForAnyArgs(Guid.NewGuid());
sutProvider.GetDependency<IMaxProjectsQuery>().GetByOrgIdAsync(orgId).Returns(((short)3, true));
await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.CreateAsync(orgId, data));
await sutProvider.GetDependency<ICreateProjectCommand>().DidNotReceiveWithAnyArgs()
.CreateAsync(Arg.Any<Project>(), Arg.Any<Guid>(), sutProvider.GetDependency<ICurrentContext>().ClientType);
}
[Theory]
[BitAutoData]
public async void Create_Success(SutProvider<ProjectsController> sutProvider,

View File

@ -346,4 +346,105 @@ public class SecretsControllerTests
Assert.Null(result.Error);
}
}
[Theory]
[BitAutoData]
public async void GetSecretsByIds_NoSecretsFound_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
List<Secret> data)
{
var (ids, request) = BuildGetSecretsRequestModel(data);
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(new List<Secret>());
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetSecretsByIdsAsync(request));
}
[Theory]
[BitAutoData]
public async void GetSecretsByIds_SecretsFoundMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
List<Secret> data, Secret mockSecret)
{
var (ids, request) = BuildGetSecretsRequestModel(data);
ids.Add(mockSecret.Id);
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids))
.ReturnsForAnyArgs(new List<Secret> { mockSecret });
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetSecretsByIdsAsync(request));
}
[Theory]
[BitAutoData]
public async void GetSecretsByIds_OrganizationMisMatch_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
List<Secret> data)
{
var (ids, request) = BuildGetSecretsRequestModel(data);
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetSecretsByIdsAsync(request));
}
[Theory]
[BitAutoData]
public async void GetSecretsByIds_NoAccessToSecretsManager_ThrowsNotFound(
SutProvider<SecretsController> sutProvider, List<Secret> data)
{
var (ids, request) = BuildGetSecretsRequestModel(data);
var organizationId = SetOrganizations(ref data);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId))
.ReturnsForAnyArgs(false);
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetSecretsByIdsAsync(request));
}
[Theory]
[BitAutoData]
public async void GetSecretsByIds_AccessDenied_ThrowsNotFound(SutProvider<SecretsController> sutProvider,
List<Secret> data)
{
var (ids, request) = BuildGetSecretsRequestModel(data);
var organizationId = SetOrganizations(ref data);
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId))
.ReturnsForAnyArgs(true);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), data.First(),
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).ReturnsForAnyArgs(AuthorizationResult.Failed());
await Assert.ThrowsAsync<NotFoundException>(() => sutProvider.Sut.GetSecretsByIdsAsync(request));
}
[Theory]
[BitAutoData]
public async void GetSecretsByIds_Success(SutProvider<SecretsController> sutProvider, List<Secret> data)
{
var (ids, request) = BuildGetSecretsRequestModel(data);
var organizationId = SetOrganizations(ref data);
sutProvider.GetDependency<ISecretRepository>().GetManyByIds(Arg.Is(ids)).ReturnsForAnyArgs(data);
sutProvider.GetDependency<ICurrentContext>().AccessSecretsManager(Arg.Is(organizationId))
.ReturnsForAnyArgs(true);
sutProvider.GetDependency<IAuthorizationService>()
.AuthorizeAsync(Arg.Any<ClaimsPrincipal>(), data.First(),
Arg.Any<IEnumerable<IAuthorizationRequirement>>()).ReturnsForAnyArgs(AuthorizationResult.Success());
var results = await sutProvider.Sut.GetSecretsByIdsAsync(request);
Assert.Equal(data.Count, results.Data.Count());
}
private static (List<Guid> Ids, GetSecretsRequestModel request) BuildGetSecretsRequestModel(
IEnumerable<Secret> data)
{
var ids = data.Select(s => s.Id).ToList();
var request = new GetSecretsRequestModel { Ids = ids };
return (ids, request);
}
private static Guid SetOrganizations(ref List<Secret> data)
{
var organizationId = data.First().OrganizationId;
foreach (var s in data)
{
s.OrganizationId = organizationId;
}
return organizationId;
}
}

View File

@ -5,6 +5,7 @@ using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Enums;
using Bit.Core.Exceptions;
using Bit.Core.Models.Business;
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
using Bit.Core.Repositories;
using Bit.Core.SecretsManager.Commands.AccessTokens.Interfaces;
@ -106,7 +107,7 @@ public class ServiceAccountsControllerTests
.CreateAsync(Arg.Is<ServiceAccount>(sa => sa.Name == data.Name), Arg.Any<Guid>());
await sutProvider.GetDependency<IUpdateSecretsManagerSubscriptionCommand>().DidNotReceiveWithAnyArgs()
.AdjustServiceAccountsAsync(Arg.Any<Organization>(), Arg.Any<int>());
.UpdateSubscriptionAsync(Arg.Any<SecretsManagerSubscriptionUpdate>());
}
[Theory]
@ -124,7 +125,12 @@ public class ServiceAccountsControllerTests
.CreateAsync(Arg.Is<ServiceAccount>(sa => sa.Name == data.Name), Arg.Any<Guid>());
await sutProvider.GetDependency<IUpdateSecretsManagerSubscriptionCommand>().Received(1)
.AdjustServiceAccountsAsync(Arg.Is(organization), Arg.Is(newSlotsRequired));
.UpdateSubscriptionAsync(Arg.Is<SecretsManagerSubscriptionUpdate>(update =>
update.Autoscaling == true &&
update.SmServiceAccounts == organization.SmServiceAccounts + newSlotsRequired &&
!update.SmSeatsChanged &&
!update.MaxAutoscaleSmSeatsChanged &&
!update.MaxAutoscaleSmServiceAccountsChanged));
}
[Theory]

View File

@ -32,7 +32,7 @@ internal class CurrentContextBuilder : ISpecimenBuilder
}
var obj = new Fixture().WithAutoNSubstitutions().Create<ICurrentContext>();
obj.Organizations = context.Create<List<CurrentContentOrganization>>();
obj.Organizations = context.Create<List<CurrentContextOrganization>>();
return obj;
}
}

View File

@ -137,6 +137,7 @@ public class SecretsManagerOrganizationCustomization : ICustomization
fixture.Customize<Organization>(composer => composer
.With(o => o.Id, organizationId)
.With(o => o.UseSecretsManager, true)
.With(o => o.SecretsManagerBeta, false)
.With(o => o.PlanType, planType)
.With(o => o.Plan, StaticStore.GetPasswordManagerPlan(planType).Name)
.With(o => o.MaxAutoscaleSmSeats, (int?)null)

View File

@ -95,6 +95,38 @@ public class AddSecretsManagerSubscriptionCommandTests
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationEnrolledInSmBeta(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = true;
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organization is enrolled in Secrets Manager Beta", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task SignUpAsync_ThrowsException_WhenOrganizationAlreadyHasSecretsManager(
SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = false;
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.SignUpAsync(organization, 10, 10));
Assert.Contains("Organization already uses Secrets Manager", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
private static async Task VerifyDependencyNotCalledAsync(SutProvider<AddSecretsManagerSubscriptionCommand> sutProvider)
{
await sutProvider.GetDependency<IPaymentService>().DidNotReceive()

View File

@ -125,8 +125,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
var update = new SecretsManagerSubscriptionUpdate(organization, autoscaling);
update.AdjustSeats(2);
var update = new SecretsManagerSubscriptionUpdate(organization, autoscaling).AdjustSeats(2);
sutProvider.GetDependency<IGlobalSettings>().SelfHosted.Returns(true);
@ -151,6 +150,23 @@ public class UpdateSecretsManagerSubscriptionCommandTests
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData]
public async Task UpdateSubscriptionAsync_OrganizationEnrolledInSmBeta_ThrowsException(
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider,
Organization organization)
{
organization.UseSecretsManager = true;
organization.SecretsManagerBeta = true;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Organization is enrolled in Secrets Manager Beta", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
[Theory]
[BitAutoData(PlanType.EnterpriseAnnually)]
[BitAutoData(PlanType.EnterpriseMonthly)]
@ -163,8 +179,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
{
organization.PlanType = planType;
organization.GatewayCustomerId = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("No payment method found.", exception.Message);
@ -183,8 +198,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
{
organization.PlanType = planType;
organization.GatewaySubscriptionId = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("No subscription found.", exception.Message);
@ -223,8 +237,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var expectedSmServiceAccounts = organizationServiceAccounts + smServiceAccountsAdjustment;
var expectedSmServiceAccountsExcludingBase = expectedSmServiceAccounts - plan.BaseServiceAccount.GetValueOrDefault();
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustServiceAccounts(10);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustServiceAccounts(10);
await sutProvider.Sut.UpdateSubscriptionAsync(update);
@ -247,7 +260,6 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmSeats = 9;
var update = new SecretsManagerSubscriptionUpdate(organization, false)
{
SmSeats = 10,
@ -267,8 +279,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmSeats = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
@ -283,8 +294,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustSeats(-2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustSeats(-2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Cannot use autoscaling to subtract seats.", exception.Message);
@ -299,8 +309,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.PlanType = planType;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustSeats(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustSeats(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("You have reached the maximum number of Secrets Manager seats (2) for this plan",
@ -317,8 +326,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
organization.SmSeats = 9;
organization.MaxAutoscaleSmSeats = 10;
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustSeats(2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustSeats(2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Secrets Manager seat limit has been reached.", exception.Message);
@ -375,7 +383,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
sutProvider.GetDependency<IOrganizationUserRepository>().GetOccupiedSmSeatCountByOrganizationIdAsync(organization.Id).Returns(8);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Your organization currently has 8 Secrets Manager seats. Your plan only allows 7 Secrets Manager seats. Remove some Secrets Manager users", exception.Message);
Assert.Contains("8 users are currently occupying Secrets Manager seats. You cannot decrease your subscription below your current occupied seat count", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -385,7 +393,6 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmServiceAccounts = 250;
var update = new SecretsManagerSubscriptionUpdate(organization, false)
{
SmServiceAccounts = 300,
@ -405,11 +412,10 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.SmServiceAccounts = null;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustServiceAccounts(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustServiceAccounts(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Organization has no Service Accounts limit, no need to adjust Service Accounts", exception.Message);
Assert.Contains("Organization has no service accounts limit, no need to adjust service accounts", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -419,8 +425,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
Organization organization,
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustServiceAccounts(-2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustServiceAccounts(-2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Cannot use autoscaling to subtract service accounts.", exception.Message);
@ -435,8 +440,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
SutProvider<UpdateSecretsManagerSubscriptionCommand> sutProvider)
{
organization.PlanType = planType;
var update = new SecretsManagerSubscriptionUpdate(organization, false);
update.AdjustServiceAccounts(1);
var update = new SecretsManagerSubscriptionUpdate(organization, false).AdjustServiceAccounts(1);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("You have reached the maximum number of service accounts (3) for this plan",
@ -453,8 +457,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
organization.SmServiceAccounts = 9;
organization.MaxAutoscaleSmServiceAccounts = 10;
var update = new SecretsManagerSubscriptionUpdate(organization, true);
update.AdjustServiceAccounts(2);
var update = new SecretsManagerSubscriptionUpdate(organization, true).AdjustServiceAccounts(2);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Secrets Manager service account limit has been reached.", exception.Message);
@ -492,7 +495,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var exception = await Assert.ThrowsAsync<BadRequestException>(
() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Plan has a minimum of 200 Service Accounts", exception.Message);
Assert.Contains("Plan has a minimum of 200 service accounts", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -516,7 +519,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
.Returns(currentServiceAccounts);
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Your organization currently has 301 Service Accounts. Your plan only allows 201 Service Accounts. Remove some Service Accounts", exception.Message);
Assert.Contains("Your organization currently has 301 service accounts. You cannot decrease your subscription below your current service account usage", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}
@ -588,7 +591,7 @@ public class UpdateSecretsManagerSubscriptionCommandTests
var update = new SecretsManagerSubscriptionUpdate(organization, false) { MaxAutoscaleSmServiceAccounts = 3 };
var exception = await Assert.ThrowsAsync<BadRequestException>(() => sutProvider.Sut.UpdateSubscriptionAsync(update));
Assert.Contains("Your plan does not allow Service Accounts autoscaling.", exception.Message);
Assert.Contains("Your plan does not allow service accounts autoscaling.", exception.Message);
await VerifyDependencyNotCalledAsync(sutProvider);
}

View File

@ -648,6 +648,7 @@ public class OrganizationServiceTests
[OrganizationUser(type: OrganizationUserType.Owner, status: OrganizationUserStatusType.Confirmed)] OrganizationUser savingUser,
SutProvider<OrganizationService> sutProvider)
{
organization.PlanType = PlanType.EnterpriseAnnually;
InviteUserHelper_ArrangeValidPermissions(organization, savingUser, sutProvider);
// Set up some invites to grant access to SM

View File

@ -273,8 +273,8 @@ public class CoreHelpersTests
{ "sstamp", user.SecurityStamp },
}.ToList();
var actual = CoreHelpers.BuildIdentityClaims(user, Array.Empty<CurrentContentOrganization>(),
Array.Empty<CurrentContentProvider>(), isPremium);
var actual = CoreHelpers.BuildIdentityClaims(user, Array.Empty<CurrentContextOrganization>(),
Array.Empty<CurrentContextProvider>(), isPremium);
foreach (var claim in expected)
{
@ -289,23 +289,23 @@ public class CoreHelpersTests
var fixture = new Fixture().WithAutoNSubstitutions();
foreach (var organizationUserType in Enum.GetValues<OrganizationUserType>().Except(new[] { OrganizationUserType.Custom }))
{
var org = fixture.Create<CurrentContentOrganization>();
var org = fixture.Create<CurrentContextOrganization>();
org.Type = organizationUserType;
var expected = new KeyValuePair<string, string>($"org{organizationUserType.ToString().ToLower()}", org.Id.ToString());
var actual = CoreHelpers.BuildIdentityClaims(user, new[] { org }, Array.Empty<CurrentContentProvider>(), false);
var actual = CoreHelpers.BuildIdentityClaims(user, new[] { org }, Array.Empty<CurrentContextProvider>(), false);
Assert.Contains(expected, actual);
}
}
[Theory, BitAutoData, UserCustomize]
public void BuildIdentityClaims_CustomOrganizationUserClaims_Success(User user, CurrentContentOrganization org)
public void BuildIdentityClaims_CustomOrganizationUserClaims_Success(User user, CurrentContextOrganization org)
{
var fixture = new Fixture().WithAutoNSubstitutions();
org.Type = OrganizationUserType.Custom;
var actual = CoreHelpers.BuildIdentityClaims(user, new[] { org }, Array.Empty<CurrentContentProvider>(), false);
var actual = CoreHelpers.BuildIdentityClaims(user, new[] { org }, Array.Empty<CurrentContextProvider>(), false);
foreach (var (permitted, claimName) in org.Permissions.ClaimsMap)
{
var claim = new KeyValuePair<string, string>(claimName, org.Id.ToString());
@ -325,10 +325,10 @@ public class CoreHelpersTests
public void BuildIdentityClaims_ProviderClaims_Success(User user)
{
var fixture = new Fixture().WithAutoNSubstitutions();
var providers = new List<CurrentContentProvider>();
var providers = new List<CurrentContextProvider>();
foreach (var providerUserType in Enum.GetValues<ProviderUserType>())
{
var provider = fixture.Create<CurrentContentProvider>();
var provider = fixture.Create<CurrentContextProvider>();
provider.Type = providerUserType;
providers.Add(provider);
}
@ -357,7 +357,7 @@ public class CoreHelpersTests
}
}
var actual = CoreHelpers.BuildIdentityClaims(user, Array.Empty<CurrentContentOrganization>(), providers, false);
var actual = CoreHelpers.BuildIdentityClaims(user, Array.Empty<CurrentContextOrganization>(), providers, false);
foreach (var claim in claims)
{
Assert.Contains(claim, actual);
@ -416,4 +416,25 @@ public class CoreHelpersTests
{
Assert.Equal(expected, CoreHelpers.ObfuscateEmail(input));
}
[Theory]
[InlineData("user@example.com")]
[InlineData("user@example.com ")]
[InlineData("user.name@example.com")]
public void GetEmailDomain_Success(string email)
{
Assert.Equal("example.com", CoreHelpers.GetEmailDomain(email));
}
[Theory]
[InlineData("")]
[InlineData(null)]
[InlineData("userexample.com")]
[InlineData("user@")]
[InlineData("@example.com")]
[InlineData("user@ex@ample.com")]
public void GetEmailDomain_ReturnsNull(string wrongEmail)
{
Assert.Null(CoreHelpers.GetEmailDomain(wrongEmail));
}
}

View File

@ -530,6 +530,7 @@ public class IdentityServerSsoTests
var organization = await organizationRepository.CreateAsync(new Organization
{
Name = "Test Org",
UsePolicies = true
});
var organizationUserRepository = factory.Services.GetRequiredService<IOrganizationUserRepository>();

View File

@ -556,7 +556,7 @@ public class IdentityServerTests : IClassFixture<IdentityApplicationFactory>
var organizationUserRepository = _factory.Services.GetService<IOrganizationUserRepository>();
var policyRepository = _factory.Services.GetService<IPolicyRepository>();
var organization = new Bit.Core.Entities.Organization { Id = organizationId, Enabled = true, UseSso = ssoPolicyEnabled };
var organization = new Bit.Core.Entities.Organization { Id = organizationId, Enabled = true, UseSso = ssoPolicyEnabled, UsePolicies = true };
await organizationRepository.CreateAsync(organization);
var user = await userRepository.GetByEmailAsync(username);