mirror of
https://github.com/bitwarden/server.git
synced 2025-04-05 05:00:19 -05:00
Cleaned up DTO models. Moved some validation steps around. A few quick fixes to address CR concerns. Still need to move a few things yet.
This commit is contained in:
parent
f3f2f41cfb
commit
ad3131f66e
@ -13,7 +13,8 @@ public class ScimUserRequestModel : BaseScimUserModel
|
||||
{
|
||||
public ScimUserRequestModel()
|
||||
: base(false)
|
||||
{ }
|
||||
{
|
||||
}
|
||||
|
||||
public OrganizationUserInvite ToOrganizationUserInvite(ScimProviderType scimProvider)
|
||||
{
|
||||
@ -28,7 +29,7 @@ public class ScimUserRequestModel : BaseScimUserModel
|
||||
};
|
||||
}
|
||||
|
||||
public OrganizationUserSingleEmailInvite ToRequest(
|
||||
public InviteOrganizationUsersRequest ToRequest(
|
||||
ScimProviderType scimProvider,
|
||||
InviteOrganization inviteOrganization,
|
||||
DateTimeOffset performedAt)
|
||||
@ -40,11 +41,18 @@ public class ScimUserRequestModel : BaseScimUserModel
|
||||
throw new BadRequestException();
|
||||
}
|
||||
|
||||
return new(
|
||||
return new InviteOrganizationUsersRequest(
|
||||
invites:
|
||||
[
|
||||
new Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite(
|
||||
email: email,
|
||||
externalId: ExternalIdForInvite(),
|
||||
accessSecretsManager: false // TODO do something about this
|
||||
)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedAt: performedAt,
|
||||
externalId: ExternalIdForInvite());
|
||||
performedBy: Guid.Empty, // SCIM does not have a user id
|
||||
performedAt: performedAt);
|
||||
}
|
||||
|
||||
private string EmailForInvite(ScimProviderType scimProvider)
|
||||
|
@ -19,5 +19,5 @@ public interface IInviteOrganizationUsersCommand
|
||||
/// </param>
|
||||
/// <returns>Response from InviteScimOrganiation<see cref="ScimInviteOrganizationUsersResponse"/></returns>
|
||||
Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(
|
||||
OrganizationUserSingleEmailInvite request);
|
||||
InviteOrganizationUsersRequest request);
|
||||
}
|
||||
|
@ -17,6 +17,7 @@ using Bit.Core.Tools.Models.Business;
|
||||
using Bit.Core.Tools.Services;
|
||||
using Microsoft.Extensions.Logging;
|
||||
using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.CreateOrganizationUser;
|
||||
using OrganizationUserInvite = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.OrganizationUserInvite;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers;
|
||||
|
||||
@ -41,21 +42,23 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
||||
public const string InvalidResultType = "Invalid result type.";
|
||||
|
||||
|
||||
public async Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(OrganizationUserSingleEmailInvite request)
|
||||
public async Task<CommandResult<ScimInviteOrganizationUsersResponse>> InviteScimOrganizationUserAsync(InviteOrganizationUsersRequest request)
|
||||
{
|
||||
var hasSecretsManagerStandalone = await paymentService.HasSecretsManagerStandalone(request.InviteOrganization);
|
||||
|
||||
// Maybe move this all back up
|
||||
var orgUsers = await organizationUserRepository.GetManyDetailsByOrganizationAsync(request.InviteOrganization.OrganizationId);
|
||||
|
||||
if (orgUsers.Any(existingUser =>
|
||||
request.Email.Equals(existingUser.Email, StringComparison.InvariantCultureIgnoreCase) ||
|
||||
request.ExternalId.Equals(existingUser.ExternalId, StringComparison.InvariantCultureIgnoreCase)))
|
||||
request.Invites.First().Email.Equals(existingUser.Email, StringComparison.InvariantCultureIgnoreCase) ||
|
||||
request.Invites.First().ExternalId.Equals(existingUser.ExternalId, StringComparison.InvariantCultureIgnoreCase)))
|
||||
{
|
||||
return new Failure<ScimInviteOrganizationUsersResponse>(
|
||||
new UserAlreadyExistsError(new ScimInviteOrganizationUsersResponse(request)));
|
||||
}
|
||||
// end of move
|
||||
|
||||
var result = await InviteOrganizationUsersAsync(new InviteOrganizationUsersRequest(request, hasSecretsManagerStandalone));
|
||||
var result = await InviteOrganizationUsersAsync(request);
|
||||
|
||||
switch (result)
|
||||
{
|
||||
@ -83,15 +86,7 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
||||
|
||||
private async Task<CommandResult<IEnumerable<OrganizationUser>>> InviteOrganizationUsersAsync(InviteOrganizationUsersRequest request)
|
||||
{
|
||||
var existingEmails = new HashSet<string>(await organizationUserRepository.SelectKnownEmailsAsync(
|
||||
request.InviteOrganization.OrganizationId, request.Invites.SelectMany(i => i.Emails), false),
|
||||
StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
var invitesToSend = request.Invites
|
||||
.SelectMany(invite => invite.Emails
|
||||
.Where(email => !existingEmails.Contains(email))
|
||||
.Select(email => OrganizationUserInviteDto.Create(email, invite, request.InviteOrganization.OrganizationId))
|
||||
).ToArray();
|
||||
var invitesToSend = (await FilterExistingUsersAsync(request)).ToArray();
|
||||
|
||||
if (invitesToSend.Length == 0)
|
||||
{
|
||||
@ -116,10 +111,10 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
||||
var validatedRequest = validationResult as Valid<InviteUserOrganizationValidationRequest>;
|
||||
|
||||
var organizationUserToInviteEntities = invitesToSend
|
||||
.Select(MapToDataModel(request.PerformedAt))
|
||||
.Select(MapToDataModel(request.PerformedAt, validatedRequest!.Value.InviteOrganization))
|
||||
.ToArray();
|
||||
|
||||
var organization = await organizationRepository.GetByIdAsync(validatedRequest!.Value.InviteOrganization.OrganizationId);
|
||||
var organization = await organizationRepository.GetByIdAsync(validatedRequest.Value.InviteOrganization.OrganizationId);
|
||||
|
||||
try
|
||||
{
|
||||
@ -151,6 +146,17 @@ public class InviteOrganizationUsersCommand(IEventService eventService,
|
||||
return new Success<IEnumerable<OrganizationUser>>(organizationUserToInviteEntities.Select(x => x.OrganizationUser));
|
||||
}
|
||||
|
||||
private async Task<IEnumerable<OrganizationUserInvite>> FilterExistingUsersAsync(InviteOrganizationUsersRequest request)
|
||||
{
|
||||
var existingEmails = new HashSet<string>(await organizationUserRepository.SelectKnownEmailsAsync(
|
||||
request.InviteOrganization.OrganizationId, request.Invites.Select(i => i.Email), false),
|
||||
StringComparer.InvariantCultureIgnoreCase);
|
||||
|
||||
return request.Invites
|
||||
.Where(invite => !existingEmails.Contains(invite.Email))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
private async Task RevertPasswordManagerChangesAsync(Valid<InviteUserOrganizationValidationRequest> validatedResult, Organization organization)
|
||||
{
|
||||
if (validatedResult.Value.PasswordManagerSubscriptionUpdate.SeatsRequiredToAdd > 0)
|
||||
|
@ -1,4 +1,5 @@
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
@ -11,13 +12,14 @@ public class CreateOrganizationUser
|
||||
public CollectionAccessSelection[] Collections { get; set; } = [];
|
||||
public Guid[] Groups { get; set; } = [];
|
||||
|
||||
public static Func<OrganizationUserInviteDto, CreateOrganizationUser> MapToDataModel(DateTimeOffset performedAt) =>
|
||||
public static Func<OrganizationUserInvite, CreateOrganizationUser> MapToDataModel(DateTimeOffset performedAt,
|
||||
InviteOrganization organization) =>
|
||||
o => new CreateOrganizationUser
|
||||
{
|
||||
OrganizationUser = new OrganizationUser
|
||||
{
|
||||
Id = CoreHelpers.GenerateComb(),
|
||||
OrganizationId = o.OrganizationId,
|
||||
OrganizationId = organization.OrganizationId,
|
||||
Email = o.Email.ToLowerInvariant(),
|
||||
Type = o.Type,
|
||||
Status = OrganizationUserStatusType.Invited,
|
||||
|
@ -19,11 +19,4 @@ public class InviteOrganizationUsersRequest
|
||||
PerformedBy = performedBy;
|
||||
PerformedAt = performedAt;
|
||||
}
|
||||
|
||||
public InviteOrganizationUsersRequest(OrganizationUserSingleEmailInvite request, bool hasStandaloneSecretsManager) :
|
||||
this([OrganizationUserInvite.Create(request, hasStandaloneSecretsManager)],
|
||||
request.InviteOrganization,
|
||||
Guid.Empty,
|
||||
request.PerformedAt)
|
||||
{ }
|
||||
}
|
||||
|
@ -16,12 +16,14 @@ public class ScimInviteOrganizationUsersResponse
|
||||
|
||||
}
|
||||
|
||||
public ScimInviteOrganizationUsersResponse(OrganizationUserSingleEmailInvite request)
|
||||
public ScimInviteOrganizationUsersResponse(InviteOrganizationUsersRequest request)
|
||||
{
|
||||
var userToInvite = request.Invites.First();
|
||||
|
||||
InvitedUser = new OrganizationUser
|
||||
{
|
||||
Email = request.Email,
|
||||
ExternalId = request.ExternalId
|
||||
Email = userToInvite.Email,
|
||||
ExternalId = userToInvite.ExternalId
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ public class InviteUserOrganizationValidationRequest
|
||||
SecretsManagerSubscriptionUpdate = smSubscriptionUpdate;
|
||||
}
|
||||
|
||||
public OrganizationUserInviteDto[] Invites { get; init; } = [];
|
||||
public OrganizationUserInvite[] Invites { get; init; } = [];
|
||||
public InviteOrganization InviteOrganization { get; init; }
|
||||
public Guid PerformedBy { get; init; }
|
||||
public DateTimeOffset PerformedAt { get; init; }
|
||||
|
@ -9,50 +9,53 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUse
|
||||
|
||||
public class OrganizationUserInvite
|
||||
{
|
||||
public string[] Emails { get; private init; } = [];
|
||||
public CollectionAccessSelection[] AssignedCollections { get; private init; } = [];
|
||||
public OrganizationUserType Type { get; private init; } = OrganizationUserType.User;
|
||||
public Permissions Permissions { get; private init; } = new();
|
||||
public string ExternalId { get; private init; } = string.Empty;
|
||||
public string Email { get; private init; }
|
||||
public CollectionAccessSelection[] AssignedCollections { get; private init; }
|
||||
public OrganizationUserType Type { get; private init; }
|
||||
public Permissions Permissions { get; private init; }
|
||||
public string ExternalId { get; private init; }
|
||||
public bool AccessSecretsManager { get; private init; }
|
||||
public Guid[] Groups { get; private init; } = [];
|
||||
public Guid[] Groups { get; private init; }
|
||||
|
||||
public static OrganizationUserInvite Create(string[] emails,
|
||||
IEnumerable<CollectionAccessSelection> accessibleCollections,
|
||||
public OrganizationUserInvite(string email, string externalId, bool accessSecretsManager) :
|
||||
this(
|
||||
email: email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: accessSecretsManager)
|
||||
{
|
||||
}
|
||||
|
||||
public OrganizationUserInvite(string email,
|
||||
IEnumerable<CollectionAccessSelection> assignedCollections,
|
||||
IEnumerable<Guid> groups,
|
||||
OrganizationUserType type,
|
||||
Permissions permissions,
|
||||
string externalId,
|
||||
bool accessSecretsManager)
|
||||
{
|
||||
ValidateEmailAddresses(emails);
|
||||
ValidateEmailAddress(email);
|
||||
|
||||
if (accessibleCollections?.Any(ValidateCollectionConfiguration) ?? false)
|
||||
var collections = assignedCollections?.ToArray() ?? [];
|
||||
|
||||
if (collections.Any(ValidateCollectionConfiguration))
|
||||
{
|
||||
throw new BadRequestException(InvalidCollectionConfigurationErrorMessage);
|
||||
}
|
||||
|
||||
return new OrganizationUserInvite
|
||||
{
|
||||
Emails = emails,
|
||||
AssignedCollections = accessibleCollections.ToArray(),
|
||||
Type = type,
|
||||
Permissions = permissions,
|
||||
ExternalId = externalId,
|
||||
AccessSecretsManager = accessSecretsManager
|
||||
};
|
||||
Email = email;
|
||||
AssignedCollections = collections;
|
||||
Groups = groups.ToArray();
|
||||
Type = type;
|
||||
Permissions = permissions ?? new Permissions();
|
||||
ExternalId = externalId;
|
||||
AccessSecretsManager = accessSecretsManager;
|
||||
}
|
||||
|
||||
public static OrganizationUserInvite Create(OrganizationUserSingleEmailInvite invite, bool hasStandaloneSecretsManager) =>
|
||||
Create([invite.Email],
|
||||
invite.AccessibleCollections,
|
||||
invite.Type,
|
||||
invite.Permissions,
|
||||
invite.ExternalId,
|
||||
hasStandaloneSecretsManager);
|
||||
|
||||
private static void ValidateEmailAddresses(string[] emails)
|
||||
{
|
||||
foreach (var email in emails)
|
||||
private static void ValidateEmailAddress(string email)
|
||||
{
|
||||
if (!email.IsValidEmail())
|
||||
{
|
||||
@ -60,4 +63,3 @@ public class OrganizationUserInvite
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,31 +0,0 @@
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Data;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
|
||||
public class OrganizationUserInviteDto
|
||||
{
|
||||
public string Email { get; private init; } = string.Empty;
|
||||
public CollectionAccessSelection[] AssignedCollections { get; private init; } = [];
|
||||
public string ExternalId { get; private init; } = string.Empty;
|
||||
public Permissions Permissions { get; private init; } = new();
|
||||
public OrganizationUserType Type { get; private init; } = OrganizationUserType.User;
|
||||
public bool AccessSecretsManager { get; private init; }
|
||||
public Guid OrganizationId { get; private init; } = Guid.Empty;
|
||||
public Guid[] Groups { get; private init; } = [];
|
||||
|
||||
public static OrganizationUserInviteDto Create(string email, OrganizationUserInvite invite, Guid organizationId)
|
||||
{
|
||||
return new OrganizationUserInviteDto
|
||||
{
|
||||
Email = email,
|
||||
AssignedCollections = invite.AssignedCollections,
|
||||
ExternalId = invite.ExternalId,
|
||||
Type = invite.Type,
|
||||
Permissions = invite.Permissions,
|
||||
AccessSecretsManager = invite.AccessSecretsManager,
|
||||
OrganizationId = organizationId,
|
||||
Groups = invite.Groups
|
||||
};
|
||||
}
|
||||
}
|
@ -1,55 +0,0 @@
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Utilities;
|
||||
using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.InviteOrganizationUserErrorMessages;
|
||||
using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.InviteOrganizationUserFunctions;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
|
||||
public record OrganizationUserSingleEmailInvite
|
||||
{
|
||||
public string Email { get; init; } = string.Empty;
|
||||
public CollectionAccessSelection[] AccessibleCollections { get; init; } = [];
|
||||
public Permissions Permissions { get; init; } = new();
|
||||
public OrganizationUserType Type { get; init; } = OrganizationUserType.User;
|
||||
public InviteOrganization InviteOrganization { get; private init; }
|
||||
public DateTimeOffset PerformedAt { get; private init; }
|
||||
public string ExternalId { get; private init; } = string.Empty;
|
||||
|
||||
public OrganizationUserSingleEmailInvite(string email,
|
||||
InviteOrganization inviteOrganization,
|
||||
DateTimeOffset performedAt,
|
||||
string externalId) : this(
|
||||
email: email,
|
||||
accessibleCollections: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions())
|
||||
{
|
||||
InviteOrganization = inviteOrganization;
|
||||
PerformedAt = performedAt;
|
||||
ExternalId = externalId;
|
||||
}
|
||||
|
||||
public OrganizationUserSingleEmailInvite(string email,
|
||||
IEnumerable<CollectionAccessSelection> accessibleCollections,
|
||||
OrganizationUserType type,
|
||||
Permissions permissions)
|
||||
{
|
||||
if (!email.IsValidEmail())
|
||||
{
|
||||
throw new BadRequestException(InvalidEmailErrorMessage);
|
||||
}
|
||||
|
||||
if (accessibleCollections?.Any(ValidateCollectionConfiguration) ?? false)
|
||||
{
|
||||
throw new BadRequestException(InvalidCollectionConfigurationErrorMessage);
|
||||
}
|
||||
|
||||
Email = email;
|
||||
AccessibleCollections = accessibleCollections.ToArray();
|
||||
Type = type;
|
||||
Permissions = permissions;
|
||||
}
|
||||
}
|
@ -4,6 +4,9 @@ namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUse
|
||||
|
||||
public static class InviteOrganizationUserFunctions
|
||||
{
|
||||
/// <summary>
|
||||
/// This
|
||||
/// </summary>
|
||||
public static Func<CollectionAccessSelection, bool> ValidateCollectionConfiguration => collectionAccessSelection =>
|
||||
collectionAccessSelection.Manage && (collectionAccessSelection.ReadOnly || collectionAccessSelection.HidePasswords);
|
||||
}
|
||||
|
@ -25,13 +25,6 @@ public class InviteUsersValidator(
|
||||
{
|
||||
public async Task<ValidationResult<InviteUserOrganizationValidationRequest>> ValidateAsync(InviteUserOrganizationValidationRequest request)
|
||||
{
|
||||
var organizationValidationResult = InviteUserOrganizationValidator.Validate(request.InviteOrganization);
|
||||
|
||||
if (organizationValidationResult is Invalid<InviteOrganization> organizationValidation)
|
||||
{
|
||||
return organizationValidation.Map(request);
|
||||
}
|
||||
|
||||
var subscriptionUpdate = new PasswordManagerSubscriptionUpdate(request);
|
||||
var passwordManagerValidationResult = PasswordManagerInviteUserValidator.Validate(subscriptionUpdate);
|
||||
|
||||
@ -45,6 +38,13 @@ public class InviteUsersValidator(
|
||||
return invalidEnvironment.Map(request);
|
||||
}
|
||||
|
||||
var organizationValidationResult = InviteUserOrganizationValidator.Validate(request.InviteOrganization, passwordManagerValidationResult as Valid<PasswordManagerSubscriptionUpdate>);
|
||||
|
||||
if (organizationValidationResult is Invalid<InviteOrganization> organizationValidation)
|
||||
{
|
||||
return organizationValidation.Map(request);
|
||||
}
|
||||
|
||||
var smSubscriptionUpdate = new SecretsManagerSubscriptionUpdate(request, subscriptionUpdate);
|
||||
var secretsManagerValidationResult = SecretsManagerInviteUserValidation.Validate(smSubscriptionUpdate);
|
||||
|
||||
|
@ -1,13 +1,15 @@
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
|
||||
namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization;
|
||||
|
||||
public static class InviteUserOrganizationValidator
|
||||
{
|
||||
public static ValidationResult<InviteOrganization> Validate(InviteOrganization inviteOrganization)
|
||||
public static ValidationResult<InviteOrganization> Validate(InviteOrganization inviteOrganization,
|
||||
Valid<PasswordManagerSubscriptionUpdate> passwordManagerValidationResult)
|
||||
{
|
||||
if (inviteOrganization.Seats is null)
|
||||
if (inviteOrganization.Seats is null || passwordManagerValidationResult.Value.SeatsRequiredToAdd is 0)
|
||||
{
|
||||
return new Valid<InviteOrganization>(inviteOrganization);
|
||||
}
|
||||
|
@ -1,52 +0,0 @@
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Exceptions;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
using Xunit;
|
||||
using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models.InviteOrganizationUserErrorMessages;
|
||||
|
||||
namespace Bit.Core.Test.AdminConsole.Models;
|
||||
|
||||
public class InviteOrganizationUserRequestTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void Create_WhenPassedInvalidEmail_ThrowsException(string email, OrganizationUserType type, Permissions permissions)
|
||||
{
|
||||
var action = () => new OrganizationUserSingleEmailInvite(email, [], type, permissions);
|
||||
|
||||
var exception = Assert.Throws<BadRequestException>(action);
|
||||
|
||||
Assert.Equal(InvalidEmailErrorMessage, exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void Create_WhenPassedInvalidCollectionAccessConfiguration_ThrowsException(OrganizationUserType type, Permissions permissions)
|
||||
{
|
||||
var validEmail = "test@email.com";
|
||||
|
||||
var invalidCollectionConfiguration = new CollectionAccessSelection { Manage = true, HidePasswords = true };
|
||||
|
||||
var action = () => new OrganizationUserSingleEmailInvite(validEmail, [invalidCollectionConfiguration], type, permissions);
|
||||
|
||||
var exception = Assert.Throws<BadRequestException>(action);
|
||||
|
||||
Assert.Equal(InvalidCollectionConfigurationErrorMessage, exception.Message);
|
||||
}
|
||||
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void Create_WhenPassedValidArguments_ReturnsInvite(OrganizationUserType type, Permissions permissions)
|
||||
{
|
||||
const string validEmail = "test@email.com";
|
||||
var validCollectionConfiguration = new CollectionAccessSelection { Id = Guid.NewGuid(), Manage = true };
|
||||
|
||||
var invite = new OrganizationUserSingleEmailInvite(validEmail, [validCollectionConfiguration], type, permissions);
|
||||
|
||||
Assert.NotNull(invite);
|
||||
Assert.Equal(validEmail, invite.Email);
|
||||
Assert.Contains(validCollectionConfiguration, invite.AccessibleCollections);
|
||||
}
|
||||
}
|
@ -13,17 +13,16 @@ public class InviteOrganizationUsersRequestTests
|
||||
{
|
||||
[Theory]
|
||||
[BitAutoData]
|
||||
public void Create_WhenPassedInvalidEmails_ThrowsException(string[] emails, OrganizationUserType type, Permissions permissions, string externalId)
|
||||
public void Constructor_WhenPassedInvalidEmail_ThrowsException(string email, OrganizationUserType type, Permissions permissions, string externalId)
|
||||
{
|
||||
var action = () => OrganizationUserInvite.Create(emails, [], type, permissions, externalId, false);
|
||||
|
||||
var exception = Assert.Throws<BadRequestException>(action);
|
||||
var exception = Assert.Throws<BadRequestException>(() =>
|
||||
new OrganizationUserInvite(email, [], [], type, permissions, externalId, false));
|
||||
|
||||
Assert.Contains(InvalidEmailErrorMessage, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WhenPassedInvalidCollectionAccessConfiguration_ThrowsException()
|
||||
public void Constructor_WhenPassedInvalidCollectionAccessConfiguration_ThrowsException()
|
||||
{
|
||||
const string validEmail = "test@email.com";
|
||||
|
||||
@ -33,23 +32,36 @@ public class InviteOrganizationUsersRequestTests
|
||||
HidePasswords = true
|
||||
};
|
||||
|
||||
var action = () => OrganizationUserInvite.Create([validEmail], [invalidCollectionConfiguration], default, default, default, false);
|
||||
|
||||
var exception = Assert.Throws<BadRequestException>(action);
|
||||
var exception = Assert.Throws<BadRequestException>(() =>
|
||||
new OrganizationUserInvite(
|
||||
email: validEmail,
|
||||
assignedCollections: [invalidCollectionConfiguration],
|
||||
groups: [],
|
||||
type: default,
|
||||
permissions: new Permissions(),
|
||||
externalId: string.Empty,
|
||||
accessSecretsManager: false));
|
||||
|
||||
Assert.Equal(InvalidCollectionConfigurationErrorMessage, exception.Message);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void Create_WhenPassedValidArguments_ReturnsInvite()
|
||||
public void Constructor_WhenPassedValidArguments_ReturnsInvite()
|
||||
{
|
||||
const string validEmail = "test@email.com";
|
||||
var validCollectionConfiguration = new CollectionAccessSelection { Id = Guid.NewGuid(), Manage = true };
|
||||
|
||||
var invite = OrganizationUserInvite.Create([validEmail], [validCollectionConfiguration], default, default, default, false);
|
||||
var invite = new OrganizationUserInvite(
|
||||
email: validEmail,
|
||||
assignedCollections: [validCollectionConfiguration],
|
||||
groups: [],
|
||||
type: default,
|
||||
permissions: null,
|
||||
externalId: null,
|
||||
accessSecretsManager: false);
|
||||
|
||||
Assert.NotNull(invite);
|
||||
Assert.Contains(validEmail, invite.Emails);
|
||||
Assert.Contains(validEmail, invite.Email);
|
||||
Assert.Contains(validCollectionConfiguration, invite.AssignedCollections);
|
||||
}
|
||||
}
|
||||
|
@ -7,15 +7,11 @@ namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.OrganizationUsers.Invi
|
||||
|
||||
public static class InviteUserOrganizationValidationRequestHelpers
|
||||
{
|
||||
public static InviteUserOrganizationValidationRequest GetInviteValidationRequestMock(OrganizationUserSingleEmailInvite request,
|
||||
public static InviteUserOrganizationValidationRequest GetInviteValidationRequestMock(InviteOrganizationUsersRequest request,
|
||||
InviteOrganization inviteOrganization) =>
|
||||
new()
|
||||
{
|
||||
Invites =
|
||||
[
|
||||
OrganizationUserInviteDto.Create(request.Email,
|
||||
OrganizationUserInvite.Create(request, inviteOrganization.UseSecretsManager), inviteOrganization.OrganizationId)
|
||||
],
|
||||
Invites = request.Invites,
|
||||
InviteOrganization = inviteOrganization,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = request.PerformedAt,
|
||||
|
@ -12,6 +12,7 @@ using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
using Bit.Core.Entities;
|
||||
using Bit.Core.Enums;
|
||||
using Bit.Core.Models.Commands;
|
||||
using Bit.Core.Models.Data;
|
||||
using Bit.Core.Models.Data.Organizations.OrganizationUsers;
|
||||
using Bit.Core.Models.StaticStore;
|
||||
using Bit.Core.OrganizationFeatures.OrganizationSubscriptions.Interface;
|
||||
@ -42,12 +43,22 @@ public class InviteOrganizationUserCommandTests
|
||||
// Arrange
|
||||
user.Email = address.Address;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
|
||||
var request = new OrganizationUserSingleEmailInvite(user.Email,
|
||||
organizationDto,
|
||||
timeProvider.GetUtcNow(),
|
||||
externalId);
|
||||
var request = new InviteOrganizationUsersRequest(
|
||||
invites: [
|
||||
new OrganizationUserInvite(
|
||||
email: user.Email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: true)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedBy: Guid.Empty,
|
||||
timeProvider.GetUtcNow());
|
||||
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.SelectKnownEmailsAsync(organization.Id, Arg.Any<IEnumerable<string>>(), false)
|
||||
@ -55,7 +66,7 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
sutProvider.GetDependency<IInviteUsersValidator>()
|
||||
.ValidateAsync(Arg.Any<InviteUserOrganizationValidationRequest>())
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, organizationDto)));
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, inviteOrganization)));
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.InviteScimOrganizationUserAsync(request);
|
||||
@ -90,12 +101,22 @@ public class InviteOrganizationUserCommandTests
|
||||
// Arrange
|
||||
orgUser.Email = address.Address;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
|
||||
var request = new OrganizationUserSingleEmailInvite(orgUser.Email,
|
||||
organizationDto,
|
||||
timeProvider.GetUtcNow(),
|
||||
externalId);
|
||||
var request = new InviteOrganizationUsersRequest(
|
||||
invites: [
|
||||
new OrganizationUserInvite(
|
||||
email: orgUser.Email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: true)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedBy: Guid.Empty,
|
||||
timeProvider.GetUtcNow());
|
||||
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.SelectKnownEmailsAsync(organization.Id, Arg.Any<IEnumerable<string>>(), false)
|
||||
@ -107,7 +128,7 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
sutProvider.GetDependency<IInviteUsersValidator>()
|
||||
.ValidateAsync(Arg.Any<InviteUserOrganizationValidationRequest>())
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, organizationDto)));
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, inviteOrganization)));
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.InviteScimOrganizationUserAsync(request);
|
||||
@ -118,7 +139,7 @@ public class InviteOrganizationUserCommandTests
|
||||
await sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.Received(1)
|
||||
.CreateManyAsync(Arg.Is<IEnumerable<CreateOrganizationUser>>(users =>
|
||||
users.Any(user => user.OrganizationUser.Email == request.Email)));
|
||||
users.Any(user => user.OrganizationUser.Email == request.Invites.First().Email)));
|
||||
|
||||
await sutProvider.GetDependency<ISendOrganizationInvitesCommand>()
|
||||
.Received(1)
|
||||
@ -142,12 +163,22 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
user.Email = address.Address;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
|
||||
var request = new OrganizationUserSingleEmailInvite(user.Email,
|
||||
organizationDto,
|
||||
timeProvider.GetUtcNow(),
|
||||
externalId);
|
||||
var request = new InviteOrganizationUsersRequest(
|
||||
invites: [
|
||||
new OrganizationUserInvite(
|
||||
email: user.Email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: true)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedBy: Guid.Empty,
|
||||
timeProvider.GetUtcNow());
|
||||
|
||||
sutProvider.GetDependency<IOrganizationUserRepository>()
|
||||
.SelectKnownEmailsAsync(organization.Id, Arg.Any<IEnumerable<string>>(), false)
|
||||
@ -196,20 +227,30 @@ public class InviteOrganizationUserCommandTests
|
||||
organization.MaxAutoscaleSeats = 2;
|
||||
ownerDetails.Type = OrganizationUserType.Owner;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
|
||||
var request = new OrganizationUserSingleEmailInvite(user.Email,
|
||||
organizationDto,
|
||||
timeProvider.GetUtcNow(),
|
||||
externalId);
|
||||
var request = new InviteOrganizationUsersRequest(
|
||||
invites: [
|
||||
new OrganizationUserInvite(
|
||||
email: user.Email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: true)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedBy: Guid.Empty,
|
||||
timeProvider.GetUtcNow());
|
||||
|
||||
var orgUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
|
||||
orgUserRepository
|
||||
.SelectKnownEmailsAsync(organizationDto.OrganizationId, Arg.Any<IEnumerable<string>>(), false)
|
||||
.SelectKnownEmailsAsync(inviteOrganization.OrganizationId, Arg.Any<IEnumerable<string>>(), false)
|
||||
.Returns([]);
|
||||
orgUserRepository
|
||||
.GetManyByMinimumRoleAsync(organizationDto.OrganizationId, OrganizationUserType.Owner)
|
||||
.GetManyByMinimumRoleAsync(inviteOrganization.OrganizationId, OrganizationUserType.Owner)
|
||||
.Returns([ownerDetails]);
|
||||
|
||||
sutProvider.GetDependency<IOrganizationRepository>()
|
||||
@ -218,8 +259,8 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
sutProvider.GetDependency<IInviteUsersValidator>()
|
||||
.ValidateAsync(Arg.Any<InviteUserOrganizationValidationRequest>())
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, organizationDto)
|
||||
.WithPasswordManagerUpdate(new PasswordManagerSubscriptionUpdate(organizationDto, organization.Seats.Value, 1))));
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, inviteOrganization)
|
||||
.WithPasswordManagerUpdate(new PasswordManagerSubscriptionUpdate(inviteOrganization, organization.Seats.Value, 1))));
|
||||
|
||||
// Act
|
||||
var result = await sutProvider.Sut.InviteScimOrganizationUserAsync(request);
|
||||
@ -227,12 +268,12 @@ public class InviteOrganizationUserCommandTests
|
||||
// Assert
|
||||
Assert.IsType<Success<ScimInviteOrganizationUsersResponse>>(result);
|
||||
|
||||
Assert.NotNull(organizationDto.MaxAutoScaleSeats);
|
||||
Assert.NotNull(inviteOrganization.MaxAutoScaleSeats);
|
||||
|
||||
await sutProvider.GetDependency<IMailService>()
|
||||
.Received(1)
|
||||
.SendOrganizationMaxSeatLimitReachedEmailAsync(organization,
|
||||
organizationDto.MaxAutoScaleSeats.Value,
|
||||
inviteOrganization.MaxAutoScaleSeats.Value,
|
||||
Arg.Is<IEnumerable<string>>(emails => emails.Any(email => email == ownerDetails.Email)));
|
||||
}
|
||||
|
||||
@ -253,22 +294,32 @@ public class InviteOrganizationUserCommandTests
|
||||
organization.MaxAutoscaleSeats = 2;
|
||||
ownerDetails.Type = OrganizationUserType.Owner;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
|
||||
var request = new OrganizationUserSingleEmailInvite(user.Email,
|
||||
organizationDto,
|
||||
timeProvider.GetUtcNow(),
|
||||
externalId);
|
||||
var request = new InviteOrganizationUsersRequest(
|
||||
invites: [
|
||||
new OrganizationUserInvite(
|
||||
email: user.Email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: true)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedBy: Guid.Empty,
|
||||
timeProvider.GetUtcNow());
|
||||
|
||||
var passwordManagerUpdate = new PasswordManagerSubscriptionUpdate(organizationDto, organization.Seats.Value, 1);
|
||||
var passwordManagerUpdate = new PasswordManagerSubscriptionUpdate(inviteOrganization, organization.Seats.Value, 1);
|
||||
|
||||
var orgUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
|
||||
orgUserRepository
|
||||
.SelectKnownEmailsAsync(organizationDto.OrganizationId, Arg.Any<IEnumerable<string>>(), false)
|
||||
.SelectKnownEmailsAsync(inviteOrganization.OrganizationId, Arg.Any<IEnumerable<string>>(), false)
|
||||
.Returns([]);
|
||||
orgUserRepository
|
||||
.GetManyByMinimumRoleAsync(organizationDto.OrganizationId, OrganizationUserType.Owner)
|
||||
.GetManyByMinimumRoleAsync(inviteOrganization.OrganizationId, OrganizationUserType.Owner)
|
||||
.Returns([ownerDetails]);
|
||||
|
||||
var orgRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||
@ -278,7 +329,7 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
sutProvider.GetDependency<IInviteUsersValidator>()
|
||||
.ValidateAsync(Arg.Any<InviteUserOrganizationValidationRequest>())
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, organizationDto)
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, inviteOrganization)
|
||||
.WithPasswordManagerUpdate(passwordManagerUpdate)));
|
||||
|
||||
// Act
|
||||
@ -288,7 +339,7 @@ public class InviteOrganizationUserCommandTests
|
||||
Assert.IsType<Success<ScimInviteOrganizationUsersResponse>>(result);
|
||||
|
||||
await sutProvider.GetDependency<IPaymentService>()
|
||||
.AdjustSeatsAsync(organization, organizationDto.Plan, passwordManagerUpdate.SeatsRequiredToAdd);
|
||||
.AdjustSeatsAsync(organization, inviteOrganization.Plan, passwordManagerUpdate.SeatsRequiredToAdd);
|
||||
|
||||
await orgRepository.Received(1).ReplaceAsync(Arg.Is<Organization>(x => x.Seats == passwordManagerUpdate.UpdatedSeatTotal));
|
||||
|
||||
@ -315,15 +366,25 @@ public class InviteOrganizationUserCommandTests
|
||||
organization.MaxAutoscaleSeats = 2;
|
||||
ownerDetails.Type = OrganizationUserType.Owner;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
|
||||
var request = new OrganizationUserSingleEmailInvite(user.Email,
|
||||
organizationDto,
|
||||
timeProvider.GetUtcNow(),
|
||||
externalId);
|
||||
var request = new InviteOrganizationUsersRequest(
|
||||
invites: [
|
||||
new OrganizationUserInvite(
|
||||
email: user.Email,
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: externalId,
|
||||
accessSecretsManager: true)
|
||||
],
|
||||
inviteOrganization: inviteOrganization,
|
||||
performedBy: Guid.Empty,
|
||||
timeProvider.GetUtcNow());
|
||||
|
||||
var secretsManagerSubscriptionUpdate = new SecretsManagerSubscriptionUpdate(
|
||||
organizationDto,
|
||||
inviteOrganization,
|
||||
organization.SmSeats.Value,
|
||||
1,
|
||||
organization.Seats.Value);
|
||||
@ -331,10 +392,10 @@ public class InviteOrganizationUserCommandTests
|
||||
var orgUserRepository = sutProvider.GetDependency<IOrganizationUserRepository>();
|
||||
|
||||
orgUserRepository
|
||||
.SelectKnownEmailsAsync(organizationDto.OrganizationId, Arg.Any<IEnumerable<string>>(), false)
|
||||
.SelectKnownEmailsAsync(inviteOrganization.OrganizationId, Arg.Any<IEnumerable<string>>(), false)
|
||||
.Returns([]);
|
||||
orgUserRepository
|
||||
.GetManyByMinimumRoleAsync(organizationDto.OrganizationId, OrganizationUserType.Owner)
|
||||
.GetManyByMinimumRoleAsync(inviteOrganization.OrganizationId, OrganizationUserType.Owner)
|
||||
.Returns([ownerDetails]);
|
||||
|
||||
var orgRepository = sutProvider.GetDependency<IOrganizationRepository>();
|
||||
@ -344,7 +405,7 @@ public class InviteOrganizationUserCommandTests
|
||||
|
||||
sutProvider.GetDependency<IInviteUsersValidator>()
|
||||
.ValidateAsync(Arg.Any<InviteUserOrganizationValidationRequest>())
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, organizationDto)
|
||||
.Returns(new Valid<InviteUserOrganizationValidationRequest>(GetInviteValidationRequestMock(request, inviteOrganization)
|
||||
.WithSecretsManagerUpdate(secretsManagerSubscriptionUpdate)));
|
||||
|
||||
// Act
|
||||
|
@ -1,6 +1,7 @@
|
||||
using Bit.Core.AdminConsole.Entities;
|
||||
using Bit.Core.AdminConsole.Models.Business;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization;
|
||||
using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager;
|
||||
using Bit.Core.AdminConsole.Shared.Validation;
|
||||
using Bit.Core.Billing.Models.StaticStore.Plans;
|
||||
using Bit.Test.Common.AutoFixture.Attributes;
|
||||
@ -14,7 +15,11 @@ public class InviteUserOrganizationValidationTests
|
||||
[BitAutoData]
|
||||
public void Validate_WhenOrganizationIsFreeTier_ShouldReturnValidResponse(Organization organization)
|
||||
{
|
||||
var result = InviteUserOrganizationValidator.Validate(new InviteOrganization(organization, new FreePlan()));
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
var validSubscriptionUpdate = new Valid<PasswordManagerSubscriptionUpdate>(
|
||||
new PasswordManagerSubscriptionUpdate(inviteOrganization, 0, 0));
|
||||
|
||||
var result = InviteUserOrganizationValidator.Validate(inviteOrganization, validSubscriptionUpdate);
|
||||
|
||||
Assert.IsType<Valid<InviteOrganization>>(result);
|
||||
}
|
||||
@ -25,8 +30,13 @@ public class InviteUserOrganizationValidationTests
|
||||
Organization organization)
|
||||
{
|
||||
organization.GatewayCustomerId = string.Empty;
|
||||
organization.Seats = 3;
|
||||
|
||||
var result = InviteUserOrganizationValidator.Validate(new InviteOrganization(organization, new FreePlan()));
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
var validSubscriptionUpdate = new Valid<PasswordManagerSubscriptionUpdate>(
|
||||
new PasswordManagerSubscriptionUpdate(inviteOrganization, 3, 1));
|
||||
|
||||
var result = InviteUserOrganizationValidator.Validate(inviteOrganization, validSubscriptionUpdate);
|
||||
|
||||
Assert.IsType<Invalid<InviteOrganization>>(result);
|
||||
Assert.Equal(OrganizationNoPaymentMethodFoundError.Code, (result as Invalid<InviteOrganization>)!.ErrorMessageString);
|
||||
@ -38,8 +48,14 @@ public class InviteUserOrganizationValidationTests
|
||||
Organization organization)
|
||||
{
|
||||
organization.GatewaySubscriptionId = string.Empty;
|
||||
organization.Seats = 3;
|
||||
organization.MaxAutoscaleSeats = 4;
|
||||
|
||||
var result = InviteUserOrganizationValidator.Validate(new InviteOrganization(organization, new FreePlan()));
|
||||
var inviteOrganization = new InviteOrganization(organization, new FreePlan());
|
||||
var validSubscriptionUpdate = new Valid<PasswordManagerSubscriptionUpdate>(
|
||||
new PasswordManagerSubscriptionUpdate(inviteOrganization, 3, 1));
|
||||
|
||||
var result = InviteUserOrganizationValidator.Validate(inviteOrganization, validSubscriptionUpdate);
|
||||
|
||||
Assert.IsType<Invalid<InviteOrganization>>(result);
|
||||
Assert.Equal(OrganizationNoSubscriptionFoundError.Code, (result as Invalid<InviteOrganization>)!.ErrorMessageString);
|
||||
|
@ -28,7 +28,7 @@ public class SecretsManagerInviteUserValidationTests
|
||||
|
||||
var request = new InviteUserOrganizationValidationRequest
|
||||
{
|
||||
Invites = [new OrganizationUserInviteDto()],
|
||||
Invites = [new OrganizationUserInvite("test@email.com", "", false)],
|
||||
InviteOrganization = organizationDto,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = default,
|
||||
@ -53,11 +53,18 @@ public class SecretsManagerInviteUserValidationTests
|
||||
var organizationDto = new InviteOrganization(organization, new FreePlan());
|
||||
var subscriptionUpdate = new PasswordManagerSubscriptionUpdate(organizationDto, 0, 0);
|
||||
|
||||
var invite = OrganizationUserInvite.Create(["email@test.com"], [], OrganizationUserType.User, new Permissions(), string.Empty, true);
|
||||
var invite = new OrganizationUserInvite(
|
||||
email: "email@test.com",
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: string.Empty,
|
||||
accessSecretsManager: true);
|
||||
|
||||
var request = new InviteUserOrganizationValidationRequest
|
||||
{
|
||||
Invites = [OrganizationUserInviteDto.Create(invite.Emails.First(), invite, organizationDto.OrganizationId)],
|
||||
Invites = [invite],
|
||||
InviteOrganization = organizationDto,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = default,
|
||||
@ -86,7 +93,14 @@ public class SecretsManagerInviteUserValidationTests
|
||||
|
||||
var request = new InviteUserOrganizationValidationRequest
|
||||
{
|
||||
Invites = [new OrganizationUserInviteDto()],
|
||||
Invites = [new OrganizationUserInvite(
|
||||
email: "email@test.com",
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: string.Empty,
|
||||
accessSecretsManager: true)],
|
||||
InviteOrganization = organizationDto,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = default,
|
||||
@ -116,7 +130,14 @@ public class SecretsManagerInviteUserValidationTests
|
||||
|
||||
var request = new InviteUserOrganizationValidationRequest
|
||||
{
|
||||
Invites = [OrganizationUserInviteDto.Create("email@test.com", OrganizationUserInvite.Create(["email@test.com"], [], OrganizationUserType.User, new Permissions(), string.Empty, true), organization.Id)],
|
||||
Invites = [new OrganizationUserInvite(
|
||||
email: "email@test.com",
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: string.Empty,
|
||||
accessSecretsManager: true)],
|
||||
InviteOrganization = organizationDto,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = default,
|
||||
@ -137,18 +158,26 @@ public class SecretsManagerInviteUserValidationTests
|
||||
public void Validate_GivenPasswordManagerSeatsAreTheSameAsSecretsManagerSeats_WhenAttemptingToAddASecretManagerSeatOnly_ThenShouldNotBeAllowedToAddSecretsManagerUsers(
|
||||
Organization organization)
|
||||
{
|
||||
organization.Seats = 0;
|
||||
organization.SmSeats = 4;
|
||||
organization.MaxAutoscaleSmSeats = 5;
|
||||
organization.UseSecretsManager = true;
|
||||
organization.PlanType = PlanType.EnterpriseAnnually;
|
||||
|
||||
var organizationDto = new InviteOrganization(organization, new Enterprise2023Plan(isAnnual: true));
|
||||
var subscriptionUpdate = new PasswordManagerSubscriptionUpdate(organizationDto, 0, 0);
|
||||
var inviteOrganization = new InviteOrganization(organization, new Enterprise2023Plan(isAnnual: true));
|
||||
var subscriptionUpdate = new PasswordManagerSubscriptionUpdate(inviteOrganization, 0, 0);
|
||||
|
||||
var request = new InviteUserOrganizationValidationRequest
|
||||
{
|
||||
Invites = [OrganizationUserInviteDto.Create("email@test.com", OrganizationUserInvite.Create(["email@test.com"], [], OrganizationUserType.User, new Permissions(), string.Empty, true), organization.Id)],
|
||||
InviteOrganization = organizationDto,
|
||||
Invites = [new OrganizationUserInvite(
|
||||
email: "email@test.com",
|
||||
assignedCollections: [],
|
||||
groups: [],
|
||||
type: OrganizationUserType.User,
|
||||
permissions: new Permissions(),
|
||||
externalId: string.Empty,
|
||||
accessSecretsManager: true)],
|
||||
InviteOrganization = inviteOrganization,
|
||||
PerformedBy = Guid.Empty,
|
||||
PerformedAt = default,
|
||||
OccupiedPmSeats = 0,
|
||||
|
Loading…
x
Reference in New Issue
Block a user