From 7d8df767cde94df8bffa8efe042647c76314d3d4 Mon Sep 17 00:00:00 2001
From: Jared Snider <116684653+JaredSnider-Bitwarden@users.noreply.github.com>
Date: Thu, 12 Sep 2024 15:24:47 -0400
Subject: [PATCH] Auth/PM-11945 - Registration with Email Verification - Fix
Org Sponsored Free Family Plan not working (#4772)
* PM-11945 - Rename RegisterUserWithOptionalOrgInvite to RegisterUserViaOrgInvite as the org invite isn't optional in the function - just the overall process of registration.
* PM-11945 - Yet another rename
* PM-11945 - Wire up call to RegisterUserViaOrgSponsoredFreeFamilyPlanInviteToken and test.
* PM-11945 - RegisterUserCommandTests - test new method
* PM-11949 - Rename tests
* PM-11945 - AccountsControllerTests.cs - add integration test for RegistrationWithEmailVerification_WithOrgSponsoredFreeFamilyPlanInviteToken_Succeeds
* PM-11945 - Adjust naming per PR feedback to match docs.
* PM-11945 - More renaming
---
.../Accounts/RegisterFinishRequestModel.cs | 1 +
.../Registration/IRegisterUserCommand.cs | 4 +-
.../Implementations/RegisterUserCommand.cs | 61 ++++++++++--
.../Controllers/AccountsController.cs | 11 ++-
.../Registration/RegisterUserCommandTests.cs | 92 +++++++++++++++++--
.../Controllers/AccountsControllerTests.cs | 79 ++++++++++++++++
.../Controllers/AccountsControllerTests.cs | 12 +--
7 files changed, 231 insertions(+), 29 deletions(-)
diff --git a/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs b/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs
index 87a0cacdc..d9b3e10da 100644
--- a/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs
+++ b/src/Core/Auth/Models/Api/Request/Accounts/RegisterFinishRequestModel.cs
@@ -31,6 +31,7 @@ public class RegisterFinishRequestModel : IValidatableObject
public Guid? OrganizationUserId { get; set; }
public string? OrgInviteToken { get; set; }
+ public string? OrgSponsoredFreeFamilyPlanToken { get; set; }
public User ToUser()
{
diff --git a/src/Core/Auth/UserFeatures/Registration/IRegisterUserCommand.cs b/src/Core/Auth/UserFeatures/Registration/IRegisterUserCommand.cs
index 259dfd759..bd742de8b 100644
--- a/src/Core/Auth/UserFeatures/Registration/IRegisterUserCommand.cs
+++ b/src/Core/Auth/UserFeatures/Registration/IRegisterUserCommand.cs
@@ -24,7 +24,7 @@ public interface IRegisterUserCommand
/// The org invite token sent to the user via email
/// The associated org user guid that was created at the time of invite
///
- public Task RegisterUserWithOptionalOrgInvite(User user, string masterPasswordHash, string orgInviteToken, Guid? orgUserId);
+ public Task RegisterUserViaOrganizationInviteToken(User user, string masterPasswordHash, string orgInviteToken, Guid? orgUserId);
///
/// Creates a new user with a given master password hash, sends a welcome email, and raises the signup reference event.
@@ -37,4 +37,6 @@ public interface IRegisterUserCommand
///
public Task RegisterUserViaEmailVerificationToken(User user, string masterPasswordHash, string emailVerificationToken);
+ public Task RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(User user, string masterPasswordHash, string orgSponsoredFreeFamilyPlanInviteToken);
+
}
diff --git a/src/Core/Auth/UserFeatures/Registration/Implementations/RegisterUserCommand.cs b/src/Core/Auth/UserFeatures/Registration/Implementations/RegisterUserCommand.cs
index 9d6a3bb3b..937a44e82 100644
--- a/src/Core/Auth/UserFeatures/Registration/Implementations/RegisterUserCommand.cs
+++ b/src/Core/Auth/UserFeatures/Registration/Implementations/RegisterUserCommand.cs
@@ -6,6 +6,7 @@ using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Context;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
+using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
@@ -37,6 +38,8 @@ public class RegisterUserCommand : IRegisterUserCommand
private readonly IUserService _userService;
private readonly IMailService _mailService;
+ private readonly IValidateRedemptionTokenCommand _validateRedemptionTokenCommand;
+
private readonly string _disabledUserRegistrationExceptionMsg = "Open registration has been disabled by the system administrator.";
public RegisterUserCommand(
@@ -49,7 +52,8 @@ public class RegisterUserCommand : IRegisterUserCommand
IDataProtectorTokenFactory registrationEmailVerificationTokenDataFactory,
ICurrentContext currentContext,
IUserService userService,
- IMailService mailService
+ IMailService mailService,
+ IValidateRedemptionTokenCommand validateRedemptionTokenCommand
)
{
_globalSettings = globalSettings;
@@ -66,6 +70,7 @@ public class RegisterUserCommand : IRegisterUserCommand
_userService = userService;
_mailService = mailService;
+ _validateRedemptionTokenCommand = validateRedemptionTokenCommand;
}
@@ -81,8 +86,7 @@ public class RegisterUserCommand : IRegisterUserCommand
return result;
}
-
- public async Task RegisterUserWithOptionalOrgInvite(User user, string masterPasswordHash,
+ public async Task RegisterUserViaOrganizationInviteToken(User user, string masterPasswordHash,
string orgInviteToken, Guid? orgUserId)
{
ValidateOrgInviteToken(orgInviteToken, orgUserId, user);
@@ -233,13 +237,8 @@ public class RegisterUserCommand : IRegisterUserCommand
public async Task RegisterUserViaEmailVerificationToken(User user, string masterPasswordHash,
string emailVerificationToken)
{
- // We validate open registration on send of initial email and here b/c a user could technically start the
- // account creation process while open registration is enabled and then finish it after it has been
- // disabled by the self hosted admin.
- if (_globalSettings.DisableUserRegistration)
- {
- throw new BadRequestException(_disabledUserRegistrationExceptionMsg);
- }
+
+ ValidateOpenRegistrationAllowed();
var tokenable = ValidateRegistrationEmailVerificationTokenable(emailVerificationToken, user.Email);
@@ -260,6 +259,48 @@ public class RegisterUserCommand : IRegisterUserCommand
return result;
}
+ public async Task RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(User user, string masterPasswordHash,
+ string orgSponsoredFreeFamilyPlanInviteToken)
+ {
+ ValidateOpenRegistrationAllowed();
+ await ValidateOrgSponsoredFreeFamilyPlanInviteToken(orgSponsoredFreeFamilyPlanInviteToken, user.Email);
+
+ user.EmailVerified = true;
+ user.ApiKey = CoreHelpers.SecureRandomString(30); // API key can't be null.
+
+ var result = await _userService.CreateUserAsync(user, masterPasswordHash);
+ if (result == IdentityResult.Success)
+ {
+ await _mailService.SendWelcomeEmailAsync(user);
+ await _referenceEventService.RaiseEventAsync(new ReferenceEvent(ReferenceEventType.Signup, user, _currentContext));
+ }
+
+ return result;
+ }
+
+ private void ValidateOpenRegistrationAllowed()
+ {
+ // We validate open registration on send of initial email and here b/c a user could technically start the
+ // account creation process while open registration is enabled and then finish it after it has been
+ // disabled by the self hosted admin.Ï
+ if (_globalSettings.DisableUserRegistration)
+ {
+ throw new BadRequestException(_disabledUserRegistrationExceptionMsg);
+ }
+ }
+
+ private async Task ValidateOrgSponsoredFreeFamilyPlanInviteToken(string orgSponsoredFreeFamilyPlanInviteToken, string userEmail)
+ {
+ var (valid, sponsorship) = await _validateRedemptionTokenCommand.ValidateRedemptionTokenAsync(orgSponsoredFreeFamilyPlanInviteToken, userEmail);
+
+ if (!valid)
+ {
+ throw new BadRequestException("Invalid org sponsored free family plan token.");
+ }
+
+ }
+
+
private RegistrationEmailVerificationTokenable ValidateRegistrationEmailVerificationTokenable(string emailVerificationToken, string userEmail)
{
_registrationEmailVerificationTokenDataFactory.TryUnprotect(emailVerificationToken, out var tokenable);
diff --git a/src/Identity/Controllers/AccountsController.cs b/src/Identity/Controllers/AccountsController.cs
index c3cad4a4a..74a58ee2f 100644
--- a/src/Identity/Controllers/AccountsController.cs
+++ b/src/Identity/Controllers/AccountsController.cs
@@ -75,7 +75,7 @@ public class AccountsController : Controller
public async Task PostRegister([FromBody] RegisterRequestModel model)
{
var user = model.ToUser();
- var identityResult = await _registerUserCommand.RegisterUserWithOptionalOrgInvite(user, model.MasterPasswordHash,
+ var identityResult = await _registerUserCommand.RegisterUserViaOrganizationInviteToken(user, model.MasterPasswordHash,
model.Token, model.OrganizationUserId);
// delaysEnabled false is only for the new registration with email verification process
return await ProcessRegistrationResult(identityResult, user, delaysEnabled: true);
@@ -151,12 +151,19 @@ public class AccountsController : Controller
if (!string.IsNullOrEmpty(model.OrgInviteToken) && model.OrganizationUserId.HasValue)
{
- identityResult = await _registerUserCommand.RegisterUserWithOptionalOrgInvite(user, model.MasterPasswordHash,
+ identityResult = await _registerUserCommand.RegisterUserViaOrganizationInviteToken(user, model.MasterPasswordHash,
model.OrgInviteToken, model.OrganizationUserId);
return await ProcessRegistrationResult(identityResult, user, delaysEnabled);
}
+ if (!string.IsNullOrEmpty(model.OrgSponsoredFreeFamilyPlanToken))
+ {
+ identityResult = await _registerUserCommand.RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(user, model.MasterPasswordHash, model.OrgSponsoredFreeFamilyPlanToken);
+
+ return await ProcessRegistrationResult(identityResult, user, delaysEnabled);
+ }
+
identityResult = await _registerUserCommand.RegisterUserViaEmailVerificationToken(user, model.MasterPasswordHash, model.EmailVerificationToken);
return await ProcessRegistrationResult(identityResult, user, delaysEnabled);
diff --git a/test/Core.Test/Auth/UserFeatures/Registration/RegisterUserCommandTests.cs b/test/Core.Test/Auth/UserFeatures/Registration/RegisterUserCommandTests.cs
index d61a34541..60db00ab9 100644
--- a/test/Core.Test/Auth/UserFeatures/Registration/RegisterUserCommandTests.cs
+++ b/test/Core.Test/Auth/UserFeatures/Registration/RegisterUserCommandTests.cs
@@ -7,6 +7,7 @@ using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Auth.UserFeatures.Registration.Implementations;
using Bit.Core.Entities;
using Bit.Core.Exceptions;
+using Bit.Core.OrganizationFeatures.OrganizationSponsorships.FamiliesForEnterprise.Interfaces;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Settings;
@@ -84,12 +85,11 @@ public class RegisterUserCommandTests
.RaiseEventAsync(Arg.Any());
}
- // RegisterUserWithOptionalOrgInvite tests
-
+ // RegisterUserWithOrganizationInviteToken tests
// Simple happy path test
[Theory]
[BitAutoData]
- public async Task RegisterUserWithOptionalOrgInvite_NoOrgInviteOrOrgUserIdOrReferenceData_Succeeds(
+ public async Task RegisterUserViaOrganizationInviteToken_NoOrgInviteOrOrgUserIdOrReferenceData_Succeeds(
SutProvider sutProvider, User user, string masterPasswordHash)
{
// Arrange
@@ -100,7 +100,7 @@ public class RegisterUserCommandTests
.Returns(IdentityResult.Success);
// Act
- var result = await sutProvider.Sut.RegisterUserWithOptionalOrgInvite(user, masterPasswordHash, null, null);
+ var result = await sutProvider.Sut.RegisterUserViaOrganizationInviteToken(user, masterPasswordHash, null, null);
// Assert
Assert.True(result.Succeeded);
@@ -119,7 +119,7 @@ public class RegisterUserCommandTests
[BitAutoData(false, null)]
[BitAutoData(true, "sampleInitiationPath")]
[BitAutoData(true, "Secrets Manager trial")]
- public async Task RegisterUserWithOptionalOrgInvite_ComplexHappyPath_Succeeds(bool addUserReferenceData, string initiationPath,
+ public async Task RegisterUserViaOrganizationInviteToken_ComplexHappyPath_Succeeds(bool addUserReferenceData, string initiationPath,
SutProvider sutProvider, User user, string masterPasswordHash, OrganizationUser orgUser, string orgInviteToken, Guid orgUserId, Policy twoFactorPolicy)
{
// Arrange
@@ -158,7 +158,7 @@ public class RegisterUserCommandTests
user.ReferenceData = addUserReferenceData ? $"{{\"initiationPath\":\"{initiationPath}\"}}" : null;
// Act
- var result = await sutProvider.Sut.RegisterUserWithOptionalOrgInvite(user, masterPasswordHash, orgInviteToken, orgUserId);
+ var result = await sutProvider.Sut.RegisterUserViaOrganizationInviteToken(user, masterPasswordHash, orgInviteToken, orgUserId);
// Assert
await sutProvider.GetDependency()
@@ -227,7 +227,7 @@ public class RegisterUserCommandTests
[BitAutoData("invalidOrgInviteToken")]
[BitAutoData("nullOrgInviteToken")]
[BitAutoData("nullOrgUserId")]
- public async Task RegisterUserWithOptionalOrgInvite_MissingOrInvalidOrgInviteDataWithDisabledOpenRegistration_ThrowsBadRequestException(string scenario,
+ public async Task RegisterUserViaOrganizationInviteToken_MissingOrInvalidOrgInviteDataWithDisabledOpenRegistration_ThrowsBadRequestException(string scenario,
SutProvider sutProvider, User user, string masterPasswordHash, OrganizationUser orgUser, string orgInviteToken, Guid? orgUserId)
{
// Arrange
@@ -257,7 +257,7 @@ public class RegisterUserCommandTests
}
// Act & Assert
- var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.RegisterUserWithOptionalOrgInvite(user, masterPasswordHash, orgInviteToken, orgUserId));
+ var exception = await Assert.ThrowsAsync(() => sutProvider.Sut.RegisterUserViaOrganizationInviteToken(user, masterPasswordHash, orgInviteToken, orgUserId));
Assert.Equal("Open registration has been disabled by the system administrator.", exception.Message);
}
@@ -265,7 +265,7 @@ public class RegisterUserCommandTests
[BitAutoData("invalidOrgInviteToken")]
[BitAutoData("nullOrgInviteToken")]
[BitAutoData("nullOrgUserId")]
- public async Task RegisterUserWithOptionalOrgInvite_MissingOrInvalidOrgInviteDataWithEnabledOpenRegistration_ThrowsBadRequestException(string scenario,
+ public async Task RegisterUserViaOrganizationInviteToken_MissingOrInvalidOrgInviteDataWithEnabledOpenRegistration_ThrowsBadRequestException(string scenario,
SutProvider sutProvider, User user, string masterPasswordHash, OrganizationUser orgUser, string orgInviteToken, Guid? orgUserId)
{
// Arrange
@@ -307,7 +307,7 @@ public class RegisterUserCommandTests
// Act
var exception = await Assert.ThrowsAsync(() =>
- sutProvider.Sut.RegisterUserWithOptionalOrgInvite(user, masterPasswordHash, orgInviteToken, orgUserId));
+ sutProvider.Sut.RegisterUserViaOrganizationInviteToken(user, masterPasswordHash, orgInviteToken, orgUserId));
Assert.Equal(expectedErrorMessage, exception.Message);
}
@@ -381,4 +381,76 @@ public class RegisterUserCommandTests
}
+
+
+ // RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken
+
+
+ [Theory]
+ [BitAutoData]
+ public async Task RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken_Succeeds(SutProvider sutProvider, User user, string masterPasswordHash,
+ string orgSponsoredFreeFamilyPlanInviteToken)
+ {
+ // Arrange
+ sutProvider.GetDependency()
+ .ValidateRedemptionTokenAsync(orgSponsoredFreeFamilyPlanInviteToken, user.Email)
+ .Returns((true, new OrganizationSponsorship()));
+
+ sutProvider.GetDependency()
+ .CreateUserAsync(user, masterPasswordHash)
+ .Returns(IdentityResult.Success);
+
+ // Act
+ var result = await sutProvider.Sut.RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(user, masterPasswordHash, orgSponsoredFreeFamilyPlanInviteToken);
+
+ // Assert
+ Assert.True(result.Succeeded);
+
+ await sutProvider.GetDependency()
+ .Received(1)
+ .CreateUserAsync(Arg.Is(u => u.Name == user.Name && u.EmailVerified == true && u.ApiKey != null), masterPasswordHash);
+
+ await sutProvider.GetDependency()
+ .Received(1)
+ .SendWelcomeEmailAsync(user);
+
+ await sutProvider.GetDependency()
+ .Received(1)
+ .RaiseEventAsync(Arg.Is(refEvent => refEvent.Type == ReferenceEventType.Signup));
+ }
+
+ [Theory]
+ [BitAutoData]
+ public async Task RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken_InvalidToken_ThrowsBadRequestException(SutProvider sutProvider, User user,
+ string masterPasswordHash, string orgSponsoredFreeFamilyPlanInviteToken)
+ {
+ // Arrange
+ sutProvider.GetDependency()
+ .ValidateRedemptionTokenAsync(orgSponsoredFreeFamilyPlanInviteToken, user.Email)
+ .Returns((false, new OrganizationSponsorship()));
+
+ // Act & Assert
+ var result = await Assert.ThrowsAsync(() =>
+ sutProvider.Sut.RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(user, masterPasswordHash, orgSponsoredFreeFamilyPlanInviteToken));
+ Assert.Equal("Invalid org sponsored free family plan token.", result.Message);
+
+ }
+
+ [Theory]
+ [BitAutoData]
+ public async Task RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken_DisabledOpenRegistration_ThrowsBadRequestException(SutProvider sutProvider, User user,
+ string masterPasswordHash, string orgSponsoredFreeFamilyPlanInviteToken)
+ {
+ // Arrange
+ sutProvider.GetDependency()
+ .DisableUserRegistration = true;
+
+ // Act & Assert
+ var result = await Assert.ThrowsAsync(() =>
+ sutProvider.Sut.RegisterUserViaOrganizationSponsoredFreeFamilyPlanInviteToken(user, masterPasswordHash, orgSponsoredFreeFamilyPlanInviteToken));
+ Assert.Equal("Open registration has been disabled by the system administrator.", result.Message);
+
+ }
+
+
}
diff --git a/test/Identity.IntegrationTest/Controllers/AccountsControllerTests.cs b/test/Identity.IntegrationTest/Controllers/AccountsControllerTests.cs
index c5f10aacb..dcf2740c0 100644
--- a/test/Identity.IntegrationTest/Controllers/AccountsControllerTests.cs
+++ b/test/Identity.IntegrationTest/Controllers/AccountsControllerTests.cs
@@ -4,6 +4,7 @@ using Bit.Core.Auth.Models.Api.Request.Accounts;
using Bit.Core.Auth.Models.Business.Tokenables;
using Bit.Core.Entities;
using Bit.Core.Enums;
+using Bit.Core.Models.Business.Tokenables;
using Bit.Core.Repositories;
using Bit.Core.Services;
using Bit.Core.Tokens;
@@ -322,6 +323,84 @@ public class AccountsControllerTests : IClassFixture
Assert.Equal(kdfParallelism, user.KdfParallelism);
}
+
+ [Theory, BitAutoData]
+ public async Task RegistrationWithEmailVerification_WithOrgSponsoredFreeFamilyPlanInviteToken_Succeeds(
+ [StringLength(1000)] string masterPasswordHash, [StringLength(50)] string masterPasswordHint, string userSymmetricKey,
+ KeysRequestModel userAsymmetricKeys, int kdfMemory, int kdfParallelism, Guid orgSponsorshipId)
+ {
+
+ // Localize factory to just this test.
+ var localFactory = new IdentityApplicationFactory();
+
+ // Hardcoded, valid org sponsored free family plan invite token data
+ var email = "jsnider+local10000008@bitwarden.com";
+ var orgSponsoredFreeFamilyPlanToken = "BWOrganizationSponsorship_CfDJ8HFsgwUNr89EtnCal5H72cx11wdMdD5_FSNMJoXJKp9migo8ZXi2Qx8GOM2b8IccesQEvZxzX_VDvhaaFi1NZc7-5bdadsfaPiwvzy28qwaW5-iF72vncmixArxKt8_FrJCqvn-5Yh45DvUWeOUBl1fPPx6LB4lgf6DcFkFZaHKOxIEywkFWEX9IWsLAfBfhU9K7AYZ02kxLRgXDK_eH3SKY0luoyUbRLBJRq1J9WnAQNcPLx9GOywQDUGRNvQGYmrzpAdq8y3MgUby_XD2NBf4-Vfr_0DIYPlGVJz0Ab1CwKbQ5G9vTXrFbbHQni40GVgohTq6WeVwk-PBMW9kjBw2rHO8QzWUb4whn831y-dEC";
+
+ var orgSponsorship = new OrganizationSponsorship
+ {
+ Id = orgSponsorshipId,
+ PlanSponsorshipType = PlanSponsorshipType.FamiliesForEnterprise,
+ OfferedToEmail = email
+ };
+
+ var orgSponsorshipOfferTokenable = new OrganizationSponsorshipOfferTokenable(orgSponsorship) { };
+
+ localFactory.SubstituteService>(dataProtectorTokenFactory =>
+ {
+ dataProtectorTokenFactory.TryUnprotect(Arg.Is(orgSponsoredFreeFamilyPlanToken), out Arg.Any())
+ .Returns(callInfo =>
+ {
+ callInfo[1] = orgSponsorshipOfferTokenable;
+ return true;
+ });
+ });
+
+ localFactory.SubstituteService(organizationSponsorshipRepository =>
+ {
+ organizationSponsorshipRepository.GetByIdAsync(orgSponsorshipId)
+ .Returns(orgSponsorship);
+ });
+
+ var registerFinishReqModel = new RegisterFinishRequestModel
+ {
+ Email = email,
+ MasterPasswordHash = masterPasswordHash,
+ MasterPasswordHint = masterPasswordHint,
+ OrgSponsoredFreeFamilyPlanToken = orgSponsoredFreeFamilyPlanToken,
+ Kdf = KdfType.PBKDF2_SHA256,
+ KdfIterations = AuthConstants.PBKDF2_ITERATIONS.Default,
+ UserSymmetricKey = userSymmetricKey,
+ UserAsymmetricKeys = userAsymmetricKeys,
+ KdfMemory = kdfMemory,
+ KdfParallelism = kdfParallelism
+ };
+
+ var postRegisterFinishHttpContext = await localFactory.PostRegisterFinishAsync(registerFinishReqModel);
+
+ Assert.Equal(StatusCodes.Status200OK, postRegisterFinishHttpContext.Response.StatusCode);
+
+ var database = localFactory.GetDatabaseContext();
+ var user = await database.Users
+ .SingleAsync(u => u.Email == email);
+
+ Assert.NotNull(user);
+
+ // Assert user properties match the request model
+ Assert.Equal(email, user.Email);
+ Assert.NotEqual(masterPasswordHash, user.MasterPassword); // We execute server side hashing
+ Assert.NotNull(user.MasterPassword);
+ Assert.Equal(masterPasswordHint, user.MasterPasswordHint);
+ Assert.Equal(userSymmetricKey, user.Key);
+ Assert.Equal(userAsymmetricKeys.EncryptedPrivateKey, user.PrivateKey);
+ Assert.Equal(userAsymmetricKeys.PublicKey, user.PublicKey);
+ Assert.Equal(KdfType.PBKDF2_SHA256, user.Kdf);
+ Assert.Equal(AuthConstants.PBKDF2_ITERATIONS.Default, user.KdfIterations);
+ Assert.Equal(kdfMemory, user.KdfMemory);
+ Assert.Equal(kdfParallelism, user.KdfParallelism);
+ }
+
+
[Theory, BitAutoData]
public async Task PostRegisterVerificationEmailClicked_Success(
[Required, StringLength(20)] string name,
diff --git a/test/Identity.Test/Controllers/AccountsControllerTests.cs b/test/Identity.Test/Controllers/AccountsControllerTests.cs
index 3abaa8a0b..8acebbabe 100644
--- a/test/Identity.Test/Controllers/AccountsControllerTests.cs
+++ b/test/Identity.Test/Controllers/AccountsControllerTests.cs
@@ -111,7 +111,7 @@ public class AccountsControllerTests : IDisposable
var passwordHash = "abcdef";
var token = "123456";
var userGuid = new Guid();
- _registerUserCommand.RegisterUserWithOptionalOrgInvite(Arg.Any(), passwordHash, token, userGuid)
+ _registerUserCommand.RegisterUserViaOrganizationInviteToken(Arg.Any(), passwordHash, token, userGuid)
.Returns(Task.FromResult(IdentityResult.Success));
var request = new RegisterRequestModel
{
@@ -125,7 +125,7 @@ public class AccountsControllerTests : IDisposable
await _sut.PostRegister(request);
- await _registerUserCommand.Received(1).RegisterUserWithOptionalOrgInvite(Arg.Any(), passwordHash, token, userGuid);
+ await _registerUserCommand.Received(1).RegisterUserViaOrganizationInviteToken(Arg.Any(), passwordHash, token, userGuid);
}
[Fact]
@@ -134,7 +134,7 @@ public class AccountsControllerTests : IDisposable
var passwordHash = "abcdef";
var token = "123456";
var userGuid = new Guid();
- _registerUserCommand.RegisterUserWithOptionalOrgInvite(Arg.Any(), passwordHash, token, userGuid)
+ _registerUserCommand.RegisterUserViaOrganizationInviteToken(Arg.Any(), passwordHash, token, userGuid)
.Returns(Task.FromResult(IdentityResult.Failed()));
var request = new RegisterRequestModel
{
@@ -219,7 +219,7 @@ public class AccountsControllerTests : IDisposable
var user = model.ToUser();
- _registerUserCommand.RegisterUserWithOptionalOrgInvite(Arg.Any(), masterPasswordHash, orgInviteToken, organizationUserId)
+ _registerUserCommand.RegisterUserViaOrganizationInviteToken(Arg.Any(), masterPasswordHash, orgInviteToken, organizationUserId)
.Returns(Task.FromResult(IdentityResult.Success));
// Act
@@ -227,7 +227,7 @@ public class AccountsControllerTests : IDisposable
// Assert
Assert.NotNull(result);
- await _registerUserCommand.Received(1).RegisterUserWithOptionalOrgInvite(Arg.Is(u =>
+ await _registerUserCommand.Received(1).RegisterUserViaOrganizationInviteToken(Arg.Is(u =>
u.Email == user.Email &&
u.MasterPasswordHint == user.MasterPasswordHint &&
u.Kdf == user.Kdf &&
@@ -270,7 +270,7 @@ public class AccountsControllerTests : IDisposable
new IdentityError { Code = duplicateUserEmailErrorCode, Description = duplicateUserEmailErrorDesc }
);
- _registerUserCommand.RegisterUserWithOptionalOrgInvite(Arg.Is(u =>
+ _registerUserCommand.RegisterUserViaOrganizationInviteToken(Arg.Is(u =>
u.Email == user.Email &&
u.MasterPasswordHint == user.MasterPasswordHint &&
u.Kdf == user.Kdf &&