From 59b579f0718cc2c260af99ae17543ea0444aa943 Mon Sep 17 00:00:00 2001 From: jrmccannon Date: Mon, 17 Mar 2025 13:27:37 -0500 Subject: [PATCH] Refactored to use new ValidationResult pattern. added mapping method. --- src/Core/AdminConsole/Errors/Error.cs | 5 +++ .../InviteOrganizationUsersCommand.cs | 1 + ...InviteUserOrganizationValidationRequest.cs | 3 +- .../CannotAutoScaleOnSelfHostError.cs | 9 +++++ .../InviteOrganizationUserValidation.cs | 36 ++++++++++--------- .../InviteUserValidationErrorMessages.cs | 22 ------------ .../Validation/Organization/Errors.cs | 16 +++++++++ .../InvitingUserOrganizationValidation.cs | 8 ++--- .../Validation/PasswordManager/Errors.cs | 24 +++++++++++++ .../PasswordManagerInviteUserValidation.cs | 16 ++++----- .../PasswordManagerSubscriptionUpdate.cs | 2 +- .../InviteUsers/Validation/Payments/Errors.cs | 10 ++++++ .../InviteUserPaymentValidation.cs | 4 ++- .../PaymentsSubscription.cs | 0 .../InviteUsers/Validation/Provider/Errors.cs | 13 +++++++ ...itingUserOrganizationProviderValidation.cs | 8 ++--- .../{Models => Provider}/ProviderDto.cs | 7 ++-- .../Validation/SecretsManager/Errors.cs | 32 +++++++++++++++++ .../SecretsManagerInviteUserValidation.cs | 26 +++++++------- .../SecretsManagerSubscriptionUpdate.cs | 3 +- .../Validation/ValidationResult.cs | 15 -------- .../Shared/Validation/ValidationResult.cs | 31 +++++++++++++++- .../Billing/Extensions/BillingExtensions.cs | 2 +- ...serOrganizationValidationRequestHelpers.cs | 3 +- .../InviteOrganizationUserCommandTests.cs | 7 ++-- .../InviteUserOrganizationValidationTests.cs | 8 +++-- .../InviteUserPaymentValidationTests.cs | 4 ++- ...asswordManagerInviteUserValidationTests.cs | 8 ++--- ...SecretsManagerInviteUserValidationTests.cs | 11 +++--- 29 files changed, 226 insertions(+), 108 deletions(-) create mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/GlobalSettings/CannotAutoScaleOnSelfHostError.cs delete mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserValidationErrorMessages.cs create mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/Errors.cs rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{ => Organization}/InvitingUserOrganizationValidation.cs (68%) create mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/Errors.cs rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{ => PasswordManager}/PasswordManagerInviteUserValidation.cs (76%) rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{Models => PasswordManager}/PasswordManagerSubscriptionUpdate.cs (97%) create mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/Errors.cs rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{ => Payments}/InviteUserPaymentValidation.cs (74%) rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{Models => Payments}/PaymentsSubscription.cs (100%) create mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/Errors.cs rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{ => Provider}/InvitingUserOrganizationProviderValidation.cs (61%) rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{Models => Provider}/ProviderDto.cs (67%) create mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/Errors.cs rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{ => SecretsManager}/SecretsManagerInviteUserValidation.cs (55%) rename src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/{Models => SecretsManager}/SecretsManagerSubscriptionUpdate.cs (94%) delete mode 100644 src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/ValidationResult.cs diff --git a/src/Core/AdminConsole/Errors/Error.cs b/src/Core/AdminConsole/Errors/Error.cs index 6c8eed41a4..7ad057d6ed 100644 --- a/src/Core/AdminConsole/Errors/Error.cs +++ b/src/Core/AdminConsole/Errors/Error.cs @@ -1,3 +1,8 @@ namespace Bit.Core.AdminConsole.Errors; public record Error(string Message, T ErroredValue); + +public static class ErrorMappers +{ + public static Error ToError(this Error errorA, B erroredValue) => new(errorA.Message, erroredValue); +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUsersCommand.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUsersCommand.cs index e25851f17d..fbd5f5eecf 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUsersCommand.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUsersCommand.cs @@ -2,6 +2,7 @@ using Bit.Core.AdminConsole.Interfaces; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Context; using Bit.Core.Entities; using Bit.Core.Enums; diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Models/InviteUserOrganizationValidationRequest.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Models/InviteUserOrganizationValidationRequest.cs index 6b6bea35c2..f24b32d318 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Models/InviteUserOrganizationValidationRequest.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Models/InviteUserOrganizationValidationRequest.cs @@ -1,5 +1,6 @@ using Bit.Core.AdminConsole.Models.Business; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/GlobalSettings/CannotAutoScaleOnSelfHostError.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/GlobalSettings/CannotAutoScaleOnSelfHostError.cs new file mode 100644 index 0000000000..3ea620d60d --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/GlobalSettings/CannotAutoScaleOnSelfHostError.cs @@ -0,0 +1,9 @@ +using Bit.Core.AdminConsole.Errors; +using Bit.Core.Settings; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.GlobalSettings; + +public record CannotAutoScaleOnSelfHostError(IGlobalSettings InvalidSettings) : Error(Code, InvalidSettings) +{ + public const string Code = "CannotAutoScaleOnSelfHost"; +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteOrganizationUserValidation.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteOrganizationUserValidation.cs index 6800c456bb..700969e246 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteOrganizationUserValidation.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteOrganizationUserValidation.cs @@ -1,20 +1,21 @@ using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.GlobalSettings; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Provider; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; using Bit.Core.AdminConsole.Repositories; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Repositories; using Bit.Core.Services; using Bit.Core.Settings; -using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.InviteUserValidationErrorMessages; -using SecretsManagerSubscriptionUpdate = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models.SecretsManagerSubscriptionUpdate; +using SecretsManagerSubscriptionUpdate = Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager.SecretsManagerSubscriptionUpdate; namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; -// TODO move into own file ... and change name to validator -public interface IInviteUsersValidation -{ - Task> ValidateAsync(InviteUserOrganizationValidationRequest request); -} +public interface IInviteUsersValidation : IValidator; public class InviteUsersValidation( IGlobalSettings globalSettings, @@ -26,14 +27,14 @@ public class InviteUsersValidation( { if (ValidateEnvironment(globalSettings) is Invalid invalidEnvironment) { - return new Invalid(invalidEnvironment.ErrorMessageString); + return invalidEnvironment.Map(request); } var organizationValidationResult = InvitingUserOrganizationValidation.Validate(request.InviteOrganization); if (organizationValidationResult is Invalid organizationValidation) { - return new Invalid(organizationValidation.ErrorMessageString); + return organizationValidation.Map(request); } var subscriptionUpdate = new PasswordManagerSubscriptionUpdate(request); @@ -41,7 +42,7 @@ public class InviteUsersValidation( if (passwordManagerValidationResult is Invalid invalidSubscriptionUpdate) { - return new Invalid(invalidSubscriptionUpdate.ErrorMessageString); + return invalidSubscriptionUpdate.Map(request); } var smSubscriptionUpdate = new SecretsManagerSubscriptionUpdate(request, subscriptionUpdate); @@ -49,7 +50,7 @@ public class InviteUsersValidation( if (secretsManagerValidationResult is Invalid invalidSmSubscriptionUpdate) { - return new Invalid(invalidSmSubscriptionUpdate.ErrorMessageString); + return invalidSmSubscriptionUpdate.Map(request); } var provider = await providerRepository.GetByOrganizationIdAsync(request.InviteOrganization.OrganizationId); @@ -59,16 +60,19 @@ public class InviteUsersValidation( if (providerValidationResult is Invalid invalidProviderValidation) { - return new Invalid(invalidProviderValidation.ErrorMessageString); + return invalidProviderValidation.Map(request); } } - var paymentSubscription = await paymentService.GetSubscriptionAsync(await organizationRepository.GetByIdAsync(request.InviteOrganization.OrganizationId)); - var paymentValidationResult = InviteUserPaymentValidation.Validate(new PaymentsSubscription(paymentSubscription, request.InviteOrganization)); + var paymentSubscription = await paymentService.GetSubscriptionAsync( + await organizationRepository.GetByIdAsync(request.InviteOrganization.OrganizationId)); + + var paymentValidationResult = InviteUserPaymentValidation.Validate( + new PaymentsSubscription(paymentSubscription, request.InviteOrganization)); if (paymentValidationResult is Invalid invalidPaymentValidation) { - return new Invalid(invalidPaymentValidation.ErrorMessageString); + return invalidPaymentValidation.Map(request); } return new Valid(new InviteUserOrganizationValidationRequest( @@ -79,6 +83,6 @@ public class InviteUsersValidation( public static ValidationResult ValidateEnvironment(IGlobalSettings globalSettings) => globalSettings.SelfHosted - ? new Invalid(CannotAutoScaleOnSelfHostedError) + ? new Invalid(new CannotAutoScaleOnSelfHostError(globalSettings)) : new Valid(globalSettings); } diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserValidationErrorMessages.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserValidationErrorMessages.cs deleted file mode 100644 index 5d7239b6af..0000000000 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserValidationErrorMessages.cs +++ /dev/null @@ -1,22 +0,0 @@ -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; - -public static class InviteUserValidationErrorMessages -{ - public const string CannotAutoScaleOnSelfHostedError = "Cannot autoscale on self-hosted instance."; - public const string ProviderBillableSeatLimitError = "Seat limit has been reached. Please contact your provider to add more seats."; - public const string ProviderResellerSeatLimitError = "Seat limit has been reached. Contact your provider to purchase additional seats."; - public const string CancelledSubscriptionError = "Cannot autoscale with a canceled subscription."; - public const string NoPaymentMethodFoundError = "No payment method found."; - public const string NoSubscriptionFoundError = "No subscription found."; - - // Password Manger Invite Users Error Messages - public const string SeatLimitHasBeenReachedError = "Seat limit has been reached."; - public const string PlanDoesNotAllowAdditionalSeats = "Plan does not allow additional seats."; - public const string PlanOnlyAllowsMaxAdditionalSeats = "Organization plan allows a maximum of {0} additional seats."; - - // Secrets Manager Invite Users Error Messages - public const string OrganizationNoSecretsManager = "Organization has no access to Secrets Manager"; - public const string SecretsManagerSeatLimitReached = "Secrets Manager seat limit has been reached."; - public const string SecretsManagerCannotExceedPasswordManager = "You cannot have more Secrets Manager seats than Password Manager seats."; - public const string SecretsManagerAdditionalSeatLimitReached = "You have reached the maximum number of Secrets Manager seats ({0}) for this plan."; -} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/Errors.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/Errors.cs new file mode 100644 index 0000000000..5d072ca17d --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/Errors.cs @@ -0,0 +1,16 @@ +using Bit.Core.AdminConsole.Errors; +using Bit.Core.AdminConsole.Models.Business; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization; + +public record OrganizationNoPaymentMethodFoundError(InviteOrganization InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "No payment method found."; +} + +public record OrganizationNoSubscriptionFoundError(InviteOrganization InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "No subscription found."; +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InvitingUserOrganizationValidation.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/InvitingUserOrganizationValidation.cs similarity index 68% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InvitingUserOrganizationValidation.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/InvitingUserOrganizationValidation.cs index 949c9b8ad0..d3f9e24743 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InvitingUserOrganizationValidation.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Organization/InvitingUserOrganizationValidation.cs @@ -1,7 +1,7 @@ using Bit.Core.AdminConsole.Models.Business; -using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.InviteUserValidationErrorMessages; +using Bit.Core.AdminConsole.Shared.Validation; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization; public static class InvitingUserOrganizationValidation { @@ -14,12 +14,12 @@ public static class InvitingUserOrganizationValidation if (string.IsNullOrWhiteSpace(inviteOrganization.GatewayCustomerId)) { - return new Invalid(NoPaymentMethodFoundError); + return new Invalid(new OrganizationNoPaymentMethodFoundError(inviteOrganization)); } if (string.IsNullOrWhiteSpace(inviteOrganization.GatewaySubscriptionId)) { - return new Invalid(NoSubscriptionFoundError); + return new Invalid(new OrganizationNoSubscriptionFoundError(inviteOrganization)); } return new Valid(inviteOrganization); diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/Errors.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/Errors.cs new file mode 100644 index 0000000000..c06213c2b3 --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/Errors.cs @@ -0,0 +1,24 @@ +using Bit.Core.AdminConsole.Errors; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; + +public record PasswordManagerSeatLimitHasBeenReachedError(PasswordManagerSubscriptionUpdate InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "Seat limit has been reached."; +} + +public record PasswordManagerPlanDoesNotAllowAdditionalSeatsError(PasswordManagerSubscriptionUpdate InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "Plan does not allow additional seats."; +} + +public record PasswordManagerPlanOnlyAllowsMaxAdditionalSeatsError(PasswordManagerSubscriptionUpdate InvalidRequest) + : Error(GetErrorMessage(InvalidRequest), InvalidRequest) +{ + private static string GetErrorMessage(PasswordManagerSubscriptionUpdate invalidRequest) => + string.Format(Code, invalidRequest.PasswordManagerPlan.MaxAdditionalSeats); + + public const string Code = "Organization plan allows a maximum of {0} additional seats."; +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidation.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/PasswordManagerInviteUserValidation.cs similarity index 76% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidation.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/PasswordManagerInviteUserValidation.cs index 1412d5749d..9d2ec464de 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidation.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/PasswordManagerInviteUserValidation.cs @@ -1,12 +1,10 @@ -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; -using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.InviteUserValidationErrorMessages; +using Bit.Core.AdminConsole.Shared.Validation; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; public static class PasswordManagerInviteUserValidation { // NOTE This is only for validating adding users to an organization, not removing - public static ValidationResult Validate(PasswordManagerSubscriptionUpdate subscriptionUpdate) { if (subscriptionUpdate.Seats is null) @@ -22,19 +20,21 @@ public static class PasswordManagerInviteUserValidation if (subscriptionUpdate.UpdatedSeatTotal is not null && subscriptionUpdate.MaxAutoScaleSeats is not null && subscriptionUpdate.UpdatedSeatTotal > subscriptionUpdate.MaxAutoScaleSeats) { - return new Invalid(SeatLimitHasBeenReachedError); + return new Invalid( + new PasswordManagerSeatLimitHasBeenReachedError(subscriptionUpdate)); } if (subscriptionUpdate.PasswordManagerPlan.HasAdditionalSeatsOption is false) { - return new Invalid(PlanDoesNotAllowAdditionalSeats); + return new Invalid( + new PasswordManagerPlanDoesNotAllowAdditionalSeatsError(subscriptionUpdate)); } // Apparently MaxAdditionalSeats is never set. Can probably be removed. if (subscriptionUpdate.AdditionalSeats > subscriptionUpdate.PasswordManagerPlan.MaxAdditionalSeats) { - return new Invalid(string.Format(PlanOnlyAllowsMaxAdditionalSeats, - subscriptionUpdate.PasswordManagerPlan.MaxAdditionalSeats)); + return new Invalid( + new PasswordManagerPlanOnlyAllowsMaxAdditionalSeatsError(subscriptionUpdate)); } return new Valid(subscriptionUpdate); diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/PasswordManagerSubscriptionUpdate.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/PasswordManagerSubscriptionUpdate.cs similarity index 97% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/PasswordManagerSubscriptionUpdate.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/PasswordManagerSubscriptionUpdate.cs index 67f9c6cb5e..257c7b3217 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/PasswordManagerSubscriptionUpdate.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManager/PasswordManagerSubscriptionUpdate.cs @@ -2,7 +2,7 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; using Bit.Core.Models.StaticStore; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; public class PasswordManagerSubscriptionUpdate { diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/Errors.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/Errors.cs new file mode 100644 index 0000000000..02c33f5375 --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/Errors.cs @@ -0,0 +1,10 @@ +using Bit.Core.AdminConsole.Errors; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Payments; + +public record PaymentCancelledSubscriptionError(PaymentsSubscription InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "Cannot autoscale with a canceled subscription."; +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidation.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/InviteUserPaymentValidation.cs similarity index 74% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidation.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/InviteUserPaymentValidation.cs index 15cc938795..cc17a673f9 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidation.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/InviteUserPaymentValidation.cs @@ -1,4 +1,6 @@ using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Payments; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Billing.Constants; using Bit.Core.Billing.Enums; @@ -15,7 +17,7 @@ public static class InviteUserPaymentValidation if (subscription.SubscriptionStatus == StripeConstants.SubscriptionStatus.Canceled) { - return new Invalid(InviteUserValidationErrorMessages.CancelledSubscriptionError); + return new Invalid(new PaymentCancelledSubscriptionError(subscription)); } return new Valid(subscription); diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/PaymentsSubscription.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/PaymentsSubscription.cs similarity index 100% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/PaymentsSubscription.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Payments/PaymentsSubscription.cs diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/Errors.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/Errors.cs new file mode 100644 index 0000000000..d40211c8a6 --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/Errors.cs @@ -0,0 +1,13 @@ +using Bit.Core.AdminConsole.Errors; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Provider; + +public record ProviderBillableSeatLimitError(ProviderDto InvalidRequest) : Error(Code, InvalidRequest) +{ + public const string Code = "Seat limit has been reached. Please contact your provider to add more seats."; +} + +public record ProviderResellerSeatLimitError(ProviderDto InvalidRequest) : Error(Code, InvalidRequest) +{ + public const string Code = "Seat limit has been reached. Contact your provider to purchase additional seats."; +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InvitingUserOrganizationProviderValidation.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/InvitingUserOrganizationProviderValidation.cs similarity index 61% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InvitingUserOrganizationProviderValidation.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/InvitingUserOrganizationProviderValidation.cs index dc9b7202da..95907676df 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InvitingUserOrganizationProviderValidation.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/InvitingUserOrganizationProviderValidation.cs @@ -1,8 +1,8 @@ using Bit.Core.AdminConsole.Enums.Provider; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Billing.Extensions; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Provider; public static class InvitingUserOrganizationProviderValidation { @@ -12,12 +12,12 @@ public static class InvitingUserOrganizationProviderValidation { if (provider.IsBillable()) { - return new Invalid(InviteUserValidationErrorMessages.ProviderBillableSeatLimitError); + return new Invalid(new ProviderBillableSeatLimitError(provider)); } if (provider.Type == ProviderType.Reseller) { - return new Invalid(InviteUserValidationErrorMessages.ProviderResellerSeatLimitError); + return new Invalid(new ProviderResellerSeatLimitError(provider)); } } diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/ProviderDto.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/ProviderDto.cs similarity index 67% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/ProviderDto.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/ProviderDto.cs index 35d255a0dd..05bb487e07 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/ProviderDto.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Provider/ProviderDto.cs @@ -1,7 +1,6 @@ -using Bit.Core.AdminConsole.Entities.Provider; -using Bit.Core.AdminConsole.Enums.Provider; +using Bit.Core.AdminConsole.Enums.Provider; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Provider; public class ProviderDto { @@ -10,7 +9,7 @@ public class ProviderDto public ProviderStatusType Status { get; init; } public bool Enabled { get; init; } - public static ProviderDto FromProviderEntity(Provider provider) + public static ProviderDto FromProviderEntity(Entities.Provider.Provider provider) { return new ProviderDto { ProviderId = provider.Id, Type = provider.Type, Status = provider.Status, Enabled = provider.Enabled }; } diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/Errors.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/Errors.cs new file mode 100644 index 0000000000..227665a0c5 --- /dev/null +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/Errors.cs @@ -0,0 +1,32 @@ +using Bit.Core.AdminConsole.Errors; + +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; + +public record OrganizationNoSecretsManagerError(SecretsManagerSubscriptionUpdate InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "Organization has no access to Secrets Manager"; +} + +public record SecretsManagerAdditionalSeatLimitReachedError(SecretsManagerSubscriptionUpdate InvalidRequest) + : Error(GetErrorMessage(InvalidRequest), InvalidRequest) +{ + public const string Code = "You have reached the maximum number of Secrets Manager seats ({0}) for this plan."; + + public static string GetErrorMessage(SecretsManagerSubscriptionUpdate invalidRequest) => + string.Format(Code, + invalidRequest.SecretsManagerPlan.BaseSeats + + invalidRequest.SecretsManagerPlan.MaxAdditionalSeats.GetValueOrDefault()); +} + +public record SecretsManagerSeatLimitReachedError(SecretsManagerSubscriptionUpdate InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "Secrets Manager seat limit has been reached."; +} + +public record SecretsManagerCannotExceedPasswordManagerError(SecretsManagerSubscriptionUpdate InvalidRequest) + : Error(Code, InvalidRequest) +{ + public const string Code = "You cannot have more Secrets Manager seats than Password Manager seats."; +} diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidation.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/SecretsManagerInviteUserValidation.cs similarity index 55% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidation.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/SecretsManagerInviteUserValidation.cs index 1293f15e4f..f5f83b6d2e 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidation.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/SecretsManagerInviteUserValidation.cs @@ -1,7 +1,6 @@ -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; -using static Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.InviteUserValidationErrorMessages; +using Bit.Core.AdminConsole.Shared.Validation; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; public static class SecretsManagerInviteUserValidation { @@ -10,33 +9,34 @@ public static class SecretsManagerInviteUserValidation subscriptionUpdate switch { { UseSecretsManger: false, AdditionalSeats: > 0 } => - new Invalid(OrganizationNoSecretsManager), + new Invalid( + new OrganizationNoSecretsManagerError(subscriptionUpdate)), { UseSecretsManger: false, AdditionalSeats: 0 } or { UseSecretsManger: true, Seats: null } => new Valid(subscriptionUpdate), { UseSecretsManger: true, SecretsManagerPlan.HasAdditionalSeatsOption: false } => new Invalid( - string.Format(SecretsManagerAdditionalSeatLimitReached, - subscriptionUpdate.SecretsManagerPlan.BaseSeats + - subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats.GetValueOrDefault())), + new SecretsManagerAdditionalSeatLimitReachedError(subscriptionUpdate)), { UseSecretsManger: true, SecretsManagerPlan.MaxAdditionalSeats: var planMaxSeats } when planMaxSeats < subscriptionUpdate.AdditionalSeats => new Invalid( - string.Format(SecretsManagerAdditionalSeatLimitReached, - subscriptionUpdate.SecretsManagerPlan.BaseSeats + - subscriptionUpdate.SecretsManagerPlan.MaxAdditionalSeats.GetValueOrDefault())), + new SecretsManagerAdditionalSeatLimitReachedError(subscriptionUpdate)), { UseSecretsManger: true, UpdatedSeatTotal: var updateSeatTotal, MaxAutoScaleSeats: var maxAutoScaleSeats } when updateSeatTotal > maxAutoScaleSeats => - new Invalid(SecretsManagerSeatLimitReached), + new Invalid( + new SecretsManagerSeatLimitReachedError(subscriptionUpdate)), { + UseSecretsManger: true, PasswordManagerUpdatedSeatTotal: var passwordManagerUpdatedSeatTotal, UpdatedSeatTotal: var secretsManagerUpdatedSeatTotal - } when passwordManagerUpdatedSeatTotal < secretsManagerUpdatedSeatTotal => - new Invalid(SecretsManagerCannotExceedPasswordManager), + } + when passwordManagerUpdatedSeatTotal < secretsManagerUpdatedSeatTotal => + new Invalid( + new SecretsManagerCannotExceedPasswordManagerError(subscriptionUpdate)), _ => new Valid(subscriptionUpdate) }; diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/SecretsManagerSubscriptionUpdate.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/SecretsManagerSubscriptionUpdate.cs similarity index 94% rename from src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/SecretsManagerSubscriptionUpdate.cs rename to src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/SecretsManagerSubscriptionUpdate.cs index 5d284ec9b3..946632f57d 100644 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/Models/SecretsManagerSubscriptionUpdate.cs +++ b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManager/SecretsManagerSubscriptionUpdate.cs @@ -1,8 +1,9 @@ using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; using Bit.Core.Models.StaticStore; -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; public class SecretsManagerSubscriptionUpdate { diff --git a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/ValidationResult.cs b/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/ValidationResult.cs deleted file mode 100644 index 065eb90440..0000000000 --- a/src/Core/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/ValidationResult.cs +++ /dev/null @@ -1,15 +0,0 @@ -namespace Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; - -public abstract record ValidationResult(T Value, IEnumerable Errors) -{ - public bool IsValid => !Errors.Any(); - - public string ErrorMessageString => string.Join(" ", Errors); -} - -public record Valid(T Value) : ValidationResult(Value, []); - -public record Invalid(IEnumerable Errors) : ValidationResult(default, Errors) -{ - public Invalid(string error) : this([error]) { } -} diff --git a/src/Core/AdminConsole/Shared/Validation/ValidationResult.cs b/src/Core/AdminConsole/Shared/Validation/ValidationResult.cs index e25103e701..ba78601637 100644 --- a/src/Core/AdminConsole/Shared/Validation/ValidationResult.cs +++ b/src/Core/AdminConsole/Shared/Validation/ValidationResult.cs @@ -6,10 +6,39 @@ public abstract record ValidationResult; public record Valid : ValidationResult { + public Valid() { } + + public Valid(T Value) + { + this.Value = Value; + } + public T Value { get; init; } } public record Invalid : ValidationResult { - public IEnumerable> Errors { get; init; } + public IEnumerable> Errors { get; init; } = []; + + public string ErrorMessageString => string.Join(" ", Errors.Select(e => e.Message)); + + public Invalid() { } + + public Invalid(Error error) : this([error]) { } + + public Invalid(IEnumerable> errors) + { + Errors = errors; + } +} + +public static class ValidationResultMappers +{ + public static ValidationResult Map(this ValidationResult validationResult, B invalidValue) => + validationResult switch + { + Valid => new Valid(invalidValue), + Invalid invalid => new Invalid(invalid.Errors.Select(x => x.ToError(invalidValue))), + _ => throw new ArgumentOutOfRangeException(nameof(validationResult), "Unhandled validation result type") + }; } diff --git a/src/Core/Billing/Extensions/BillingExtensions.cs b/src/Core/Billing/Extensions/BillingExtensions.cs index fc3c94b663..a94e690e59 100644 --- a/src/Core/Billing/Extensions/BillingExtensions.cs +++ b/src/Core/Billing/Extensions/BillingExtensions.cs @@ -1,7 +1,7 @@ using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Entities.Provider; using Bit.Core.AdminConsole.Enums.Provider; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Provider; using Bit.Core.Billing.Enums; using Bit.Core.Entities; using Bit.Core.Enums; diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Helpers/InviteUserOrganizationValidationRequestHelpers.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Helpers/InviteUserOrganizationValidationRequestHelpers.cs index 9d259ef1d9..4e047ac626 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Helpers/InviteUserOrganizationValidationRequestHelpers.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Helpers/InviteUserOrganizationValidationRequestHelpers.cs @@ -1,6 +1,7 @@ using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; namespace Bit.Core.Test.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Helpers; diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUserCommandTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUserCommandTests.cs index 53db502cb9..9cbd5b9c52 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUserCommandTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/InviteOrganizationUserCommandTests.cs @@ -1,10 +1,13 @@ using System.Net.Mail; using Bit.Core.AdminConsole.Entities; +using Bit.Core.AdminConsole.Errors; using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Entities; using Bit.Core.Enums; using Bit.Core.Models.Commands; @@ -158,7 +161,7 @@ public class InviteOrganizationUserCommandTests sutProvider.GetDependency() .ValidateAsync(Arg.Any()) - .Returns(new Invalid(errorMessage)); + .Returns(new Invalid(new Error(errorMessage, new InviteUserOrganizationValidationRequest()))); // Act var result = await sutProvider.Sut.InviteScimOrganizationUserAsync(request); diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserOrganizationValidationTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserOrganizationValidationTests.cs index c519821205..4c95f31557 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserOrganizationValidationTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserOrganizationValidationTests.cs @@ -1,6 +1,7 @@ using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Models.Business; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Organization; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Test.Common.AutoFixture.Attributes; using Xunit; @@ -27,7 +28,8 @@ public class InviteUserOrganizationValidationTests var result = InvitingUserOrganizationValidation.Validate(new InviteOrganization(organization)); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.NoPaymentMethodFoundError, result.ErrorMessageString); + + Assert.Equal(OrganizationNoPaymentMethodFoundError.Code, (result as Invalid).ErrorMessageString); } [Theory] @@ -40,6 +42,6 @@ public class InviteUserOrganizationValidationTests var result = InvitingUserOrganizationValidation.Validate(new InviteOrganization(organization)); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.NoSubscriptionFoundError, result.ErrorMessageString); + Assert.Equal(OrganizationNoSubscriptionFoundError.Code, (result as Invalid).ErrorMessageString); } } diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidationTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidationTests.cs index fffa20038e..a26fbaaaea 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidationTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/InviteUserPaymentValidationTests.cs @@ -2,6 +2,8 @@ using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Payments; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Billing.Constants; using Bit.Core.Billing.Enums; using Bit.Test.Common.AutoFixture.Attributes; @@ -36,7 +38,7 @@ public class InviteUserPaymentValidationTests }); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.CancelledSubscriptionError, result.ErrorMessageString); + Assert.Equal(PaymentCancelledSubscriptionError.Code, (result as Invalid).ErrorMessageString); } [Fact] diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidationTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidationTests.cs index e2808db5c7..8064e9e37f 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidationTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/PasswordManagerInviteUserValidationTests.cs @@ -1,7 +1,7 @@ using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Models.Business; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Billing.Enums; using Bit.Test.Common.AutoFixture.Attributes; using Xunit; @@ -61,7 +61,7 @@ public class PasswordManagerInviteUserValidationTests var result = PasswordManagerInviteUserValidation.Validate(subscriptionUpdate); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.SeatLimitHasBeenReachedError, result.ErrorMessageString); + Assert.Equal(PasswordManagerSeatLimitHasBeenReachedError.Code, (result as Invalid).ErrorMessageString); } [Theory] @@ -80,6 +80,6 @@ public class PasswordManagerInviteUserValidationTests var result = PasswordManagerInviteUserValidation.Validate(subscriptionUpdate); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.PlanDoesNotAllowAdditionalSeats, result.ErrorMessageString); + Assert.Equal(PasswordManagerPlanDoesNotAllowAdditionalSeatsError.Code, (result as Invalid).ErrorMessageString); } } diff --git a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidationTests.cs b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidationTests.cs index 5ace6219e7..8f49e4a514 100644 --- a/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidationTests.cs +++ b/test/Core.Test/AdminConsole/OrganizationFeatures/OrganizationUsers/InviteUsers/Validation/SecretsManagerInviteUserValidationTests.cs @@ -1,8 +1,9 @@ using Bit.Core.AdminConsole.Entities; using Bit.Core.AdminConsole.Models.Business; using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Models; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation; -using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.Models; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.PasswordManager; +using Bit.Core.AdminConsole.OrganizationFeatures.OrganizationUsers.InviteUsers.Validation.SecretsManager; +using Bit.Core.AdminConsole.Shared.Validation; using Bit.Core.Billing.Enums; using Bit.Core.Enums; using Bit.Core.Models.Data; @@ -68,7 +69,7 @@ public class SecretsManagerInviteUserValidationTests var result = SecretsManagerInviteUserValidation.Validate(update); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.OrganizationNoSecretsManager, result.ErrorMessageString); + Assert.Equal(OrganizationNoSecretsManagerError.Code, (result as Invalid).ErrorMessageString); } [Theory] @@ -127,7 +128,7 @@ public class SecretsManagerInviteUserValidationTests var result = SecretsManagerInviteUserValidation.Validate(update); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.SecretsManagerSeatLimitReached, result.ErrorMessageString); + Assert.Equal(SecretsManagerSeatLimitReachedError.Code, (result as Invalid).ErrorMessageString); } [Theory] @@ -158,6 +159,6 @@ public class SecretsManagerInviteUserValidationTests var result = SecretsManagerInviteUserValidation.Validate(update); Assert.IsType>(result); - Assert.Equal(InviteUserValidationErrorMessages.SecretsManagerCannotExceedPasswordManager, result.ErrorMessageString); + Assert.Equal(SecretsManagerCannotExceedPasswordManagerError.Code, (result as Invalid).ErrorMessageString); } }