diff --git a/src/Microsoft.AspNet.Identity/UserOptions.cs b/src/Microsoft.AspNet.Identity/UserOptions.cs
index 5b2578aa3b..214d7f9e1e 100644
--- a/src/Microsoft.AspNet.Identity/UserOptions.cs
+++ b/src/Microsoft.AspNet.Identity/UserOptions.cs
@@ -1,20 +1,18 @@
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved.
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+using System.Text.RegularExpressions;
+
namespace Microsoft.AspNet.Identity
{
public class UserOptions
{
public UserOptions()
{
- AllowOnlyAlphanumericNames = true;
//User.RequireUniqueEmail = true; // TODO: app decision?
}
- ///
- /// Only allow [A-Za-z0-9@_] in UserNames
- ///
- public bool AllowOnlyAlphanumericNames { get; set; }
+ public string UserNameValidationRegex { get; set; } = "^[a-zA-Z0-9@_\\.]+$";
///
/// If set, enforces that emails are non empty, valid, and unique
diff --git a/src/Microsoft.AspNet.Identity/UserValidator.cs b/src/Microsoft.AspNet.Identity/UserValidator.cs
index 2fea50531d..749f3a9f3f 100644
--- a/src/Microsoft.AspNet.Identity/UserValidator.cs
+++ b/src/Microsoft.AspNet.Identity/UserValidator.cs
@@ -4,10 +4,10 @@
using System;
using System.Collections.Generic;
using System.Globalization;
-using System.Linq;
#if ASPNET50
using System.Net.Mail;
#endif
+using System.Text.RegularExpressions;
using System.Threading;
using System.Threading.Tasks;
@@ -46,48 +46,6 @@ namespace Microsoft.AspNet.Identity
return errors.Count > 0 ? IdentityResult.Failed(errors.ToArray()) : IdentityResult.Success;
}
- // TODO: Revisit extensibility for Validators
-
- ///
- /// Returns true if the character is a digit between '0' and '9'
- ///
- ///
- ///
- public virtual bool IsDigit(char c)
- {
- return c >= '0' && c <= '9';
- }
-
- ///
- /// Returns true if the character is between 'a' and 'z'
- ///
- ///
- ///
- public virtual bool IsLower(char c)
- {
- return c >= 'a' && c <= 'z';
- }
-
- ///
- /// Returns true if the character is between 'A' and 'Z'
- ///
- ///
- ///
- public virtual bool IsUpper(char c)
- {
- return c >= 'A' && c <= 'Z';
- }
-
- ///
- /// Returns true if the character is upper, lower, a digit, or a common email character [@_.]
- ///
- ///
- ///
- public virtual bool IsAlphaNumeric(char c)
- {
- return IsUpper(c) || IsLower(c) || IsDigit(c) || c == '@' || c == '_' || c == '.';
- }
-
private async Task ValidateUserName(UserManager manager, TUser user, ICollection errors)
{
var userName = await manager.GetUserNameAsync(user);
@@ -95,9 +53,8 @@ namespace Microsoft.AspNet.Identity
{
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.PropertyTooShort, "UserName"));
}
- else if (manager.Options.User.AllowOnlyAlphanumericNames && !userName.All(IsAlphaNumeric))
+ else if (manager.Options.User.UserNameValidationRegex != null && !Regex.IsMatch(userName, manager.Options.User.UserNameValidationRegex))
{
- // If any characters are not letters or digits, its an illegal user name
errors.Add(String.Format(CultureInfo.CurrentCulture, Resources.InvalidUserName, userName));
}
else
diff --git a/src/Microsoft.AspNet.Identity/project.json b/src/Microsoft.AspNet.Identity/project.json
index 6c44cd8eac..68b759996b 100644
--- a/src/Microsoft.AspNet.Identity/project.json
+++ b/src/Microsoft.AspNet.Identity/project.json
@@ -34,6 +34,7 @@
"System.Security.Cryptography.Hashing.Algorithms": "4.0.0.0",
"System.Text.Encoding": "4.0.10.0",
"System.Text.Encoding.Extensions": "4.0.10.0",
+ "System.Text.RegularExpressions": "4.0.0.0",
"System.Threading.Tasks": "4.0.10.0"
}
}
diff --git a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs
index 3eb8ea1aa5..d72a7cc5ff 100644
--- a/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs
+++ b/test/Microsoft.AspNet.Identity.InMemory.Test/InMemoryStoreTest.cs
@@ -27,7 +27,7 @@ namespace Microsoft.AspNet.Identity.InMemory.Test
options.Password.RequireLowercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
- options.User.AllowOnlyAlphanumericNames = false;
+ options.User.UserNameValidationRegex = null;
});
return services.BuildServiceProvider().GetService>();
}
diff --git a/test/Microsoft.AspNet.Identity.SqlServer.InMemory.Test/InMemoryEFUserStoreTest.cs b/test/Microsoft.AspNet.Identity.SqlServer.InMemory.Test/InMemoryEFUserStoreTest.cs
index 70e3d9eaf6..ef93470e05 100644
--- a/test/Microsoft.AspNet.Identity.SqlServer.InMemory.Test/InMemoryEFUserStoreTest.cs
+++ b/test/Microsoft.AspNet.Identity.SqlServer.InMemory.Test/InMemoryEFUserStoreTest.cs
@@ -31,7 +31,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.InMemory.Test
options.Password.RequireLowercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
- options.User.AllowOnlyAlphanumericNames = false;
+ options.User.UserNameValidationRegex = null;
});
return services.BuildServiceProvider().GetService>();
}
diff --git a/test/Microsoft.AspNet.Identity.SqlServer.Test/SqlStoreTestBase.cs b/test/Microsoft.AspNet.Identity.SqlServer.Test/SqlStoreTestBase.cs
index 050c37a069..cdab3b7037 100644
--- a/test/Microsoft.AspNet.Identity.SqlServer.Test/SqlStoreTestBase.cs
+++ b/test/Microsoft.AspNet.Identity.SqlServer.Test/SqlStoreTestBase.cs
@@ -146,7 +146,7 @@ namespace Microsoft.AspNet.Identity.SqlServer.Test
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
options.Password.RequireDigit = false;
- options.User.AllowOnlyAlphanumericNames = false;
+ options.User.UserNameValidationRegex = null;
});
services.SetupOptions(options =>
options.UseSqlServer(ConnectionString));
diff --git a/test/Microsoft.AspNet.Identity.Test/IdentityOptionsTest.cs b/test/Microsoft.AspNet.Identity.Test/IdentityOptionsTest.cs
index 960ed8fbac..3c6b9d66b2 100644
--- a/test/Microsoft.AspNet.Identity.Test/IdentityOptionsTest.cs
+++ b/test/Microsoft.AspNet.Identity.Test/IdentityOptionsTest.cs
@@ -29,7 +29,7 @@ namespace Microsoft.AspNet.Identity.Test
Assert.True(options.Password.RequireUppercase);
Assert.Equal(6, options.Password.RequiredLength);
- Assert.True(options.User.AllowOnlyAlphanumericNames);
+ Assert.Equal("^[a-zA-Z0-9@_\\.]+$", options.User.UserNameValidationRegex);
Assert.False(options.User.RequireUniqueEmail);
Assert.Equal(ClaimTypes.Role, options.ClaimsIdentity.RoleClaimType);
@@ -77,8 +77,7 @@ namespace Microsoft.AspNet.Identity.Test
Assert.Equal(usernameClaimType, options.ClaimsIdentity.UserNameClaimType);
Assert.Equal(securityStampClaimType, options.ClaimsIdentity.SecurityStampClaimType);
Assert.True(options.User.RequireUniqueEmail);
- Assert.True(options.User.AllowOnlyAlphanumericNames);
- Assert.True(options.User.AllowOnlyAlphanumericNames);
+ Assert.Equal("^[a-zA-Z0-9@_\\.]+$", options.User.UserNameValidationRegex);
Assert.False(options.Password.RequireDigit);
Assert.False(options.Password.RequireLowercase);
Assert.False(options.Password.RequireNonLetterOrDigit);
diff --git a/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs b/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs
index a79b8bbf31..793dd36598 100644
--- a/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs
+++ b/test/Microsoft.AspNet.Identity.Test/UserValidatorTest.cs
@@ -76,7 +76,7 @@ namespace Microsoft.AspNet.Identity.Test
{
// Setup
var manager = MockHelpers.TestUserManager(new NoopUserStore());
- manager.Options.User.AllowOnlyAlphanumericNames = false;
+ manager.Options.User.UserNameValidationRegex = null;
var validator = new UserValidator();
var user = new TestUser {UserName = userName};
diff --git a/test/Shared/MockHelpers.cs b/test/Shared/MockHelpers.cs
index c7b09dcc50..89825915c3 100644
--- a/test/Shared/MockHelpers.cs
+++ b/test/Shared/MockHelpers.cs
@@ -24,7 +24,7 @@ namespace Microsoft.AspNet.Identity.Test
options.Password.RequireLowercase = false;
options.Password.RequireNonLetterOrDigit = false;
options.Password.RequireUppercase = false;
- options.User.AllowOnlyAlphanumericNames = false;
+ options.User.UserNameValidationRegex = null;
});
return services.BuildServiceProvider().GetService>();
}
diff --git a/test/Shared/UserManagerTestBase.cs b/test/Shared/UserManagerTestBase.cs
index ab2b45a68e..44e34c0eeb 100644
--- a/test/Shared/UserManagerTestBase.cs
+++ b/test/Shared/UserManagerTestBase.cs
@@ -392,7 +392,7 @@ namespace Microsoft.AspNet.Identity.Test
{
var manager = CreateManager();
manager.Options.User.UseUserNameAsEmail = true;
- manager.Options.User.AllowOnlyAlphanumericNames = false;
+ manager.Options.User.UserNameValidationRegex = null;
var user = CreateTestUser();
var email = user.UserName + "@test.com";
user.UserName = email;