Skip to content
This repository was archived by the owner on Dec 20, 2018. It is now read-only.

Commit b7d5a46

Browse files
committed
Fix regression with ChangePhoneNumber tokens
1 parent 9d937ca commit b7d5a46

2 files changed

Lines changed: 35 additions & 10 deletions

File tree

src/Microsoft.AspNetCore.Identity.Specification.Tests/UserManagerSpecificationTests.cs

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1532,6 +1532,24 @@ public async Task CanChangePhoneNumber()
15321532
Assert.NotEqual(stamp, await manager.GetSecurityStampAsync(user));
15331533
}
15341534

1535+
/// <summary>
1536+
/// Test.
1537+
/// </summary>
1538+
/// <returns>Task</returns>
1539+
[Fact]
1540+
public async Task ChangePhoneNumberTokenIsInt()
1541+
{
1542+
if (ShouldSkipDbTests())
1543+
{
1544+
return;
1545+
}
1546+
var manager = CreateManager();
1547+
var user = CreateTestUser(phoneNumber: "123-456-7890");
1548+
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
1549+
var token1 = await manager.GenerateChangePhoneNumberTokenAsync(user, "111-111-1111");
1550+
Assert.True(int.TryParse(token1, out var ignored));
1551+
}
1552+
15351553
/// <summary>
15361554
/// Test.
15371555
/// </summary>
@@ -1550,7 +1568,7 @@ public async Task ChangePhoneNumberFailsWithWrongToken()
15501568
var stamp = await manager.GetSecurityStampAsync(user);
15511569
IdentityResultAssert.IsFailure(await manager.ChangePhoneNumberAsync(user, "111-111-1111", "bogus"),
15521570
"Invalid token.");
1553-
IdentityResultAssert.VerifyLogMessage(manager.Logger, $"VerifyUserTokenAsync() failed with purpose: ChangePhoneNumber:111-111-1111 for user { await manager.GetUserIdAsync(user)}.");
1571+
IdentityResultAssert.VerifyLogMessage(manager.Logger, $"VerifyChangePhoneNumberTokenAsync() failed for user { await manager.GetUserIdAsync(user)}.");
15541572
Assert.False(await manager.IsPhoneNumberConfirmedAsync(user));
15551573
Assert.Equal("123-456-7890", await manager.GetPhoneNumberAsync(user));
15561574
Assert.Equal(stamp, await manager.GetSecurityStampAsync(user));
@@ -1605,7 +1623,7 @@ public async Task CanVerifyPhoneNumber()
16051623
Assert.True(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num2));
16061624
Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token2, num1));
16071625
Assert.False(await manager.VerifyChangePhoneNumberTokenAsync(user, token1, num2));
1608-
IdentityResultAssert.VerifyLogMessage(manager.Logger, $"VerifyUserTokenAsync() failed with purpose: ChangePhoneNumber:111-123-4567 for user {await manager.GetUserIdAsync(user)}.");
1626+
IdentityResultAssert.VerifyLogMessage(manager.Logger, $"VerifyChangePhoneNumberTokenAsync() failed for user {await manager.GetUserIdAsync(user)}.");
16091627
}
16101628

16111629
/// <summary>

src/Microsoft.Extensions.Identity.Core/UserManager.cs

Lines changed: 15 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1579,10 +1579,12 @@ public virtual Task<bool> IsPhoneNumberConfirmedAsync(TUser user)
15791579
/// <returns>
15801580
/// The <see cref="Task"/> that represents the asynchronous operation, containing the telephone change number token.
15811581
/// </returns>
1582-
public virtual Task<string> GenerateChangePhoneNumberTokenAsync(TUser user, string phoneNumber)
1582+
public virtual async Task<string> GenerateChangePhoneNumberTokenAsync(TUser user, string phoneNumber)
15831583
{
15841584
ThrowIfDisposed();
1585-
return GenerateUserTokenAsync(user, Options.Tokens.ChangePhoneNumberTokenProvider, ChangePhoneNumberTokenPurpose + ":" + phoneNumber);
1585+
return Rfc6238AuthenticationService.GenerateCode(
1586+
await CreateSecurityTokenAsync(user), phoneNumber)
1587+
.ToString(CultureInfo.InvariantCulture);
15861588
}
15871589

15881590
/// <summary>
@@ -1596,16 +1598,21 @@ public virtual Task<string> GenerateChangePhoneNumberTokenAsync(TUser user, stri
15961598
/// The <see cref="Task"/> that represents the asynchronous operation, returning true if the <paramref name="token"/>
15971599
/// is valid, otherwise false.
15981600
/// </returns>
1599-
public virtual Task<bool> VerifyChangePhoneNumberTokenAsync(TUser user, string token, string phoneNumber)
1601+
public virtual async Task<bool> VerifyChangePhoneNumberTokenAsync(TUser user, string token, string phoneNumber)
16001602
{
16011603
ThrowIfDisposed();
1602-
if (user == null)
1604+
1605+
var securityToken = await CreateSecurityTokenAsync(user);
1606+
int code;
1607+
if (securityToken != null && Int32.TryParse(token, out code))
16031608
{
1604-
throw new ArgumentNullException(nameof(user));
1609+
if (Rfc6238AuthenticationService.ValidateCode(securityToken, code, phoneNumber))
1610+
{
1611+
return true;
1612+
}
16051613
}
1606-
1607-
// Make sure the token is valid and the stamp matches
1608-
return VerifyUserTokenAsync(user, Options.Tokens.ChangePhoneNumberTokenProvider, ChangePhoneNumberTokenPurpose+":"+ phoneNumber, token);
1614+
Logger.LogWarning(8, "VerifyChangePhoneNumberTokenAsync() failed for user {userId}.", await GetUserIdAsync(user));
1615+
return false;
16091616
}
16101617

16111618
/// <summary>

0 commit comments

Comments
 (0)