Skip to content

Commit

Permalink
Fix elevating TrnVerificationLevel when matching an existing account (#…
Browse files Browse the repository at this point in the history
  • Loading branch information
gunndabad authored Jan 12, 2024
1 parent 87c9f5d commit ac2ab8e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 10 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,30 +54,45 @@ public async Task<IActionResult> OnPost()
}

var authenticationState = _journey.AuthenticationState;
authenticationState.EnsureOAuthState();

var journeyTrnVerificationLevel = authenticationState.OAuthState.TrnMatchPolicy == TrnMatchPolicy.Strict ?
TrnVerificationLevel.Medium :
TrnVerificationLevel.Low;

var lookupState = await _dbContext.JourneyTrnLookupStates
.SingleOrDefaultAsync(s => s.JourneyId == authenticationState.JourneyId);

var user = await _dbContext.Users.SingleAsync(u => u.EmailAddress == authenticationState.TrnOwnerEmailAddress);

var emailChanged = user.EmailAddress != Email;

user.EmailAddress = Email;

bool trnVerificationLevelChanged = false;
if (user.TrnVerificationLevel < journeyTrnVerificationLevel)
{
user.TrnVerificationLevel = journeyTrnVerificationLevel;
trnVerificationLevelChanged = true;
}

if (lookupState is not null)
{
lookupState.Locked = _clock.UtcNow;
lookupState.UserId = user.UserId;
}

if (emailChanged)
var changes = Events.UserUpdatedEventChanges.None |
(emailChanged ? Events.UserUpdatedEventChanges.EmailAddress : 0) |
(trnVerificationLevelChanged ? Events.UserUpdatedEventChanges.TrnVerificationLevel : 0);

if (changes != Events.UserUpdatedEventChanges.None)
{
user.Updated = _clock.UtcNow;

_dbContext.AddEvent(new Events.UserUpdatedEvent()
{
Source = Events.UserUpdatedEventSource.TrnMatchedToExistingUser,
Changes = Events.UserUpdatedEventChanges.EmailAddress,
Changes = changes,
CreatedUtc = _clock.UtcNow,
User = user,
UpdatedByUserId = user.UserId,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -301,19 +301,30 @@ public async Task Post_SubmittedEmailDoesNotMatchEnteredOrMatchedEmail_Rerenders
}

[Theory]
[InlineData(false)]
[InlineData(true)]
public async Task Post_ValidRequest_UpdatesUserAndRedirectsToNextPage(bool newEmailChosen)
[InlineData(false, TrnMatchPolicy.Default, TrnVerificationLevel.Low, TrnVerificationLevel.Low)]
[InlineData(false, TrnMatchPolicy.Default, TrnVerificationLevel.Medium, TrnVerificationLevel.Medium)]
[InlineData(false, TrnMatchPolicy.Strict, TrnVerificationLevel.Low, TrnVerificationLevel.Medium)]
[InlineData(false, TrnMatchPolicy.Strict, TrnVerificationLevel.Medium, TrnVerificationLevel.Medium)]
[InlineData(true, TrnMatchPolicy.Default, TrnVerificationLevel.Low, TrnVerificationLevel.Low)]
[InlineData(true, TrnMatchPolicy.Default, TrnVerificationLevel.Medium, TrnVerificationLevel.Medium)]
[InlineData(true, TrnMatchPolicy.Strict, TrnVerificationLevel.Low, TrnVerificationLevel.Medium)]
[InlineData(true, TrnMatchPolicy.Strict, TrnVerificationLevel.Medium, TrnVerificationLevel.Medium)]
public async Task Post_ValidRequest_UpdatesUserAndRedirectsToNextPage(
bool newEmailChosen,
TrnMatchPolicy trnMatchPolicy,
TrnVerificationLevel existingTrnVerificationLevel,
TrnVerificationLevel expectedNewTrnVerificationLevel)
{
// Arrange
var email = Faker.Internet.Email();
var existingTrnOwner = await TestData.CreateUser(hasTrn: true);
var existingTrnOwner = await TestData.CreateUser(hasTrn: true, trnVerificationLevel: existingTrnVerificationLevel);
var chosenEmail = newEmailChosen ? email : existingTrnOwner.EmailAddress;

var authStateHelper = await CreateAuthenticationStateHelper(
c => c.TrnLookupCompletedForExistingTrnAndOwnerEmailVerified(existingTrnOwner, email),
CustomScopes.Trn,
trnRequirementType: null);
trnRequirementType: null,
trnMatchPolicy: trnMatchPolicy);

var request = new HttpRequestMessage(HttpMethod.Post, $"/sign-in/trn/choose-email?{authStateHelper.ToQueryParam()}")
{
Expand All @@ -340,12 +351,13 @@ public async Task Post_ValidRequest_UpdatesUserAndRedirectsToNextPage(bool newEm

Assert.NotNull(user);
Assert.Equal(chosenEmail, user.EmailAddress);
Assert.Equal(expectedNewTrnVerificationLevel, user.TrnVerificationLevel);

return user.UserId;
});

// Should get a UserUpdatedEvent if the email address was changed
if (newEmailChosen)
// Should get a UserUpdatedEvent if the email address or TrnVerificationLevel was changed
if (newEmailChosen || existingTrnVerificationLevel != expectedNewTrnVerificationLevel)
{
EventObserver.AssertEventsSaved(
e =>
Expand All @@ -354,6 +366,18 @@ public async Task Post_ValidRequest_UpdatesUserAndRedirectsToNextPage(bool newEm
Assert.Equal(Clock.UtcNow, userUpdatedEvent.CreatedUtc);
Assert.Equal(UserUpdatedEventSource.TrnMatchedToExistingUser, userUpdatedEvent.Source);
Assert.Equal(userId, userUpdatedEvent.User.UserId);

if (newEmailChosen)
{
Assert.Equal(chosenEmail, userUpdatedEvent.User.EmailAddress);
Assert.True(userUpdatedEvent.Changes.HasFlag(UserUpdatedEventChanges.EmailAddress));
}

if (existingTrnVerificationLevel != expectedNewTrnVerificationLevel)
{
Assert.Equal(expectedNewTrnVerificationLevel, userUpdatedEvent.User.TrnVerificationLevel);
Assert.True(userUpdatedEvent.Changes.HasFlag(UserUpdatedEventChanges.TrnVerificationLevel));
}
});
}
else
Expand Down

0 comments on commit ac2ab8e

Please sign in to comment.