UseUserNameAsEmail support

When set:
- FindByEmail will use UserName
- SetEmail will set the user name and email
- GetEmail will return user name
- This setting does not impact the Get/Set/FindUserName apis
This commit is contained in:
Hao Kung 2014-08-07 16:37:26 -07:00
parent 7d4aed4e3b
commit 097925a3e4
4 changed files with 107 additions and 8 deletions

View File

@ -487,11 +487,17 @@ namespace Microsoft.AspNet.Identity
{
throw new ArgumentNullException("user");
}
await Store.SetUserNameAsync(user, userName, cancellationToken);
await UpdateNormalizedUserName(user, cancellationToken);
await UpdateUserName(user, userName, cancellationToken);
return await UpdateAsync(user, cancellationToken);
}
private async Task UpdateUserName(TUser user, string userName, CancellationToken cancellationToken)
{
await Store.SetUserNameAsync(user, userName, cancellationToken);
await UpdateNormalizedUserName(user, cancellationToken);
}
/// <summary>
/// Get the user's id
/// </summary>
@ -1124,6 +1130,11 @@ namespace Microsoft.AspNet.Identity
CancellationToken cancellationToken = default(CancellationToken))
{
ThrowIfDisposed();
if (Options.User.UseUserNameAsEmail)
{
return await GetUserNameAsync(user, cancellationToken);
}
var store = GetEmailStore();
if (user == null)
{
@ -1143,6 +1154,12 @@ namespace Microsoft.AspNet.Identity
CancellationToken cancellationToken = default(CancellationToken))
{
ThrowIfDisposed();
if (Options.User.UseUserNameAsEmail)
{
await UpdateUserName(user, email, cancellationToken);
}
var store = GetEmailStore();
if (user == null)
{
@ -1164,6 +1181,11 @@ namespace Microsoft.AspNet.Identity
CancellationToken cancellationToken = default(CancellationToken))
{
ThrowIfDisposed();
if (Options.User.UseUserNameAsEmail)
{
return FindByNameAsync(email, cancellationToken);
}
var store = GetEmailStore();
if (email == null)
{

View File

@ -20,5 +20,10 @@ namespace Microsoft.AspNet.Identity
/// If set, enforces that emails are non empty, valid, and unique
/// </summary>
public bool RequireUniqueEmail { get; set; }
/// <summary>
/// If set, the user name will also be considered the email
/// </summary>
public bool UseUserNameAsEmail { get; set; }
}
}

View File

@ -502,6 +502,24 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test
IdentityResultAssert.IsFailure(result, "A user with that external login already exists.");
}
[Fact]
public async Task UserNameAsEmailTest()
{
var manager = CreateManager();
manager.Options.User.UseUserNameAsEmail = true;
manager.Options.User.AllowOnlyAlphanumericNames = false;
const string email = "email@test.com";
var user = new ApplicationUser { UserName = email };
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
Assert.Equal(user, await manager.FindByEmailAsync(email));
Assert.Equal(email, await manager.GetEmailAsync(user));
const string newEmail = "modified@woot.com";
IdentityResultAssert.IsSuccess(await manager.SetEmailAsync(user, newEmail));
Assert.Equal(newEmail, user.UserName);
Assert.Equal(newEmail, user.Email);
Assert.False(user.EmailConfirmed);
}
// Email tests
[Fact]
public async Task CanFindByEmail()
@ -511,8 +529,7 @@ namespace Microsoft.AspNet.Identity.EntityFramework.Test
var user = new ApplicationUser { Email = email };
IdentityResultAssert.IsSuccess(await manager.CreateAsync(user));
var fetch = await manager.FindByEmailAsync(email);
//Assert.Equal(user, fetch);
Assert.Equal(user.Id, fetch.Id);
Assert.Equal(user, fetch);
}
[Fact]

View File

@ -42,8 +42,6 @@ namespace Microsoft.AspNet.Identity.Test
Assert.NotNull(manager.Options);
}
#if NET45
//TODO: Mock fails in K (this works fine in net45)
[Fact]
public async Task CreateCallsStore()
{
@ -164,6 +162,65 @@ namespace Microsoft.AspNet.Identity.Test
store.VerifyAll();
}
[Fact]
public async Task UseUserNameAsEmailCallsStoreFindByName()
{
// Setup
var store = new Mock<IUserStore<TestUser>>();
var user = new TestUser {UserName="Foo"};
store.Setup(s => s.FindByNameAsync(user.UserName, CancellationToken.None)).Returns(Task.FromResult(user)).Verifiable();
var userManager = MockHelpers.TestUserManager(store.Object);
userManager.Options.User.UseUserNameAsEmail = true;
userManager.UserNameNormalizer = null;
// Act
var result = await userManager.FindByEmailAsync(user.UserName);
// Assert
Assert.Equal(user, result);
store.VerifyAll();
}
[Fact]
public async Task UseUserNameAsEmailReturnsName()
{
// Setup
var store = new Mock<IUserStore<TestUser>>();
var user = new TestUser { UserName = "Foo@email.com" };
store.Setup(s => s.GetUserNameAsync(user, CancellationToken.None)).ReturnsAsync(user.UserName).Verifiable();
var userManager = MockHelpers.TestUserManager(store.Object);
userManager.Options.User.UseUserNameAsEmail = true;
userManager.UserNameNormalizer = null;
// Act
var result = await userManager.GetEmailAsync(user);
// Assert
Assert.Equal(user.UserName, result);
store.VerifyAll();
}
[Fact]
public async Task UseUserNameAsEmailUpdatesNameAndEmail()
{
// Setup
var store = new Mock<IUserEmailStore<TestUser>>();
var user = new TestUser { UserName = "Foo" };
var email = "foo@foo.com";
store.Setup(s => s.SetUserNameAsync(user, email, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
store.Setup(s => s.SetEmailAsync(user, email, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
store.Setup(s => s.SetEmailConfirmedAsync(user, false, CancellationToken.None)).Returns(Task.FromResult(0)).Verifiable();
var userManager = MockHelpers.TestUserManager(store.Object);
userManager.Options.User.UseUserNameAsEmail = true;
userManager.UserNameNormalizer = null;
// Act
IdentityResultAssert.IsSuccess(await userManager.SetEmailAsync(user, email));
// Assert
store.VerifyAll();
}
[Fact]
public async Task AddToRolesCallsStore()
{
@ -275,8 +332,6 @@ namespace Microsoft.AspNet.Identity.Test
store.VerifyAll();
}
#endif
[Fact]
public async Task CheckPasswordWithNullUserReturnsFalse()
{