Fix for codeplex-1357
This change allows users to configure the casing behavior of simple membership provider. The simple membership provider will by default generate a database query that normalizes the case of usernames on the database side. This comes with the side effect of obviating any index that the user may have configured for the user name column. The fix is to make this behavior configurable. With the new option, it will be possible to turn off casing normalization, and allow the database to handle it specific to its collation.
This commit is contained in:
Родитель
679d450616
Коммит
256968e02c
|
@ -157,7 +157,7 @@ namespace WebMatrix.WebData
|
||||||
get { return "webpages_OAuthMembership"; }
|
get { return "webpages_OAuthMembership"; }
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static string OAuthTokenTableName
|
internal static string OAuthTokenTableName
|
||||||
{
|
{
|
||||||
get { return "webpages_OAuthToken"; }
|
get { return "webpages_OAuthToken"; }
|
||||||
}
|
}
|
||||||
|
@ -187,6 +187,8 @@ namespace WebMatrix.WebData
|
||||||
// REVIEW: we could get this from the primary key of UserTable in the future
|
// REVIEW: we could get this from the primary key of UserTable in the future
|
||||||
public string UserIdColumn { get; set; }
|
public string UserIdColumn { get; set; }
|
||||||
|
|
||||||
|
public SimpleMembershipProviderCasingBehavior CasingBehavior { get; set; }
|
||||||
|
|
||||||
internal DatabaseConnectionInfo ConnectionInfo { get; set; }
|
internal DatabaseConnectionInfo ConnectionInfo { get; set; }
|
||||||
internal bool InitializeCalled { get; set; }
|
internal bool InitializeCalled { get; set; }
|
||||||
|
|
||||||
|
@ -297,15 +299,42 @@ namespace WebMatrix.WebData
|
||||||
VerifyInitialized();
|
VerifyInitialized();
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
return GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
return GetUserId(db, userName);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static int GetUserId(IDatabase db, string userTableName, string userNameColumn, string userIdColumn, string userName)
|
private int GetUserId(IDatabase db, string userName)
|
||||||
{
|
{
|
||||||
// Casing is normalized in Sql to allow the database to normalize username according to its collation. The common issue
|
return GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, CasingBehavior, userName);
|
||||||
// that can occur here is the 'Turkish i problem', where the uppercase of 'i' is not 'I' in Turkish.
|
}
|
||||||
var result = db.QueryValue(@"SELECT " + userIdColumn + " FROM " + userTableName + " WHERE (UPPER(" + userNameColumn + ") = UPPER(@0))", userName);
|
|
||||||
|
internal static int GetUserId(
|
||||||
|
IDatabase db,
|
||||||
|
string userTableName,
|
||||||
|
string userNameColumn,
|
||||||
|
string userIdColumn,
|
||||||
|
SimpleMembershipProviderCasingBehavior casingBehavior,
|
||||||
|
string userName)
|
||||||
|
{
|
||||||
|
dynamic result;
|
||||||
|
if (casingBehavior == SimpleMembershipProviderCasingBehavior.NormalizeCasing)
|
||||||
|
{
|
||||||
|
// Casing is normalized in Sql to allow the database to normalize username according to its collation. The common issue
|
||||||
|
// that can occur here is the 'Turkish i problem', where the uppercase of 'i' is not 'I' in Turkish.
|
||||||
|
result = db.QueryValue(@"SELECT " + userIdColumn + " FROM " + userTableName + " WHERE (UPPER(" + userNameColumn + ") = UPPER(@0))", userName);
|
||||||
|
}
|
||||||
|
else if (casingBehavior == SimpleMembershipProviderCasingBehavior.RelyOnDatabaseCollation)
|
||||||
|
{
|
||||||
|
// When this option is supplied we assume the database has been configured with an appropriate casing, and don't normalize
|
||||||
|
// the user name. This is performant but requires appropriate configuration on the database.
|
||||||
|
result = db.QueryValue(@"SELECT " + userIdColumn + " FROM " + userTableName + " WHERE (" + userNameColumn + " = @0)", userName);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Debug.Fail("Unexpected enum value");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
if (result != null)
|
if (result != null)
|
||||||
{
|
{
|
||||||
return (int)result;
|
return (int)result;
|
||||||
|
@ -429,7 +458,7 @@ namespace WebMatrix.WebData
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
// Step 1: Check if the user exists in the Users table
|
// Step 1: Check if the user exists in the Users table
|
||||||
int uid = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int uid = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, CasingBehavior, userName);
|
||||||
if (uid == -1)
|
if (uid == -1)
|
||||||
{
|
{
|
||||||
// User not found
|
// User not found
|
||||||
|
@ -476,7 +505,7 @@ namespace WebMatrix.WebData
|
||||||
private void CreateUserRow(IDatabase db, string userName, IDictionary<string, object> values)
|
private void CreateUserRow(IDatabase db, string userName, IDictionary<string, object> values)
|
||||||
{
|
{
|
||||||
// Make sure user doesn't exist
|
// Make sure user doesn't exist
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int userId = GetUserId(db, userName);
|
||||||
if (userId != -1)
|
if (userId != -1)
|
||||||
{
|
{
|
||||||
throw new MembershipCreateUserException(MembershipCreateStatus.DuplicateUserName);
|
throw new MembershipCreateUserException(MembershipCreateStatus.DuplicateUserName);
|
||||||
|
@ -575,7 +604,7 @@ namespace WebMatrix.WebData
|
||||||
|
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
|
int userId = GetUserId(db, username);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
return false; // User not found
|
return false; // User not found
|
||||||
|
@ -622,7 +651,7 @@ namespace WebMatrix.WebData
|
||||||
// Due to a bug in v1, GetUser allows passing null / empty values.
|
// Due to a bug in v1, GetUser allows passing null / empty values.
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
|
int userId = GetUserId(db, username);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
return null; // User not found
|
return null; // User not found
|
||||||
|
@ -649,7 +678,7 @@ namespace WebMatrix.WebData
|
||||||
|
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int userId = GetUserId(db, userName);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
return false; // User not found
|
return false; // User not found
|
||||||
|
@ -670,7 +699,7 @@ namespace WebMatrix.WebData
|
||||||
|
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
|
int userId = GetUserId(db, username);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
return false; // User not found
|
return false; // User not found
|
||||||
|
@ -746,7 +775,7 @@ namespace WebMatrix.WebData
|
||||||
{
|
{
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int userId = GetUserId(db, userName);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
||||||
|
@ -761,7 +790,7 @@ namespace WebMatrix.WebData
|
||||||
{
|
{
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int userId = GetUserId(db, userName);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
||||||
|
@ -781,7 +810,7 @@ namespace WebMatrix.WebData
|
||||||
{
|
{
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int userId = GetUserId(db, userName);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
||||||
|
@ -801,7 +830,7 @@ namespace WebMatrix.WebData
|
||||||
{
|
{
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, userName);
|
int userId = GetUserId(db, userName);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, userName));
|
||||||
|
@ -852,7 +881,7 @@ namespace WebMatrix.WebData
|
||||||
// Ensures the user exists in the accounts table
|
// Ensures the user exists in the accounts table
|
||||||
private int VerifyUserNameHasConfirmedAccount(IDatabase db, string username, bool throwException)
|
private int VerifyUserNameHasConfirmedAccount(IDatabase db, string username, bool throwException)
|
||||||
{
|
{
|
||||||
int userId = GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
|
int userId = GetUserId(db, username);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
if (throwException)
|
if (throwException)
|
||||||
|
@ -1004,7 +1033,7 @@ namespace WebMatrix.WebData
|
||||||
// GetUser will fail with an exception if the user table isn't set up properly
|
// GetUser will fail with an exception if the user table isn't set up properly
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, "z");
|
GetUserId(db, "z");
|
||||||
}
|
}
|
||||||
catch (Exception e)
|
catch (Exception e)
|
||||||
{
|
{
|
||||||
|
@ -1255,7 +1284,7 @@ namespace WebMatrix.WebData
|
||||||
{
|
{
|
||||||
dynamic id = db.QueryValue(@"SELECT UserId FROM [" + MembershipTableName + "] WHERE UserId=@0", userId);
|
dynamic id = db.QueryValue(@"SELECT UserId FROM [" + MembershipTableName + "] WHERE UserId=@0", userId);
|
||||||
return id != null;
|
return id != null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -0,0 +1,32 @@
|
||||||
|
// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
namespace WebMatrix.WebData
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Configures the behavior of SimpleMembershipProvider for the casing of user name queries.
|
||||||
|
/// </summary>
|
||||||
|
public enum SimpleMembershipProviderCasingBehavior
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Uses the SQL Upper function to normalize the casing of user names for a case-insensitive comparion.
|
||||||
|
/// This is the default value.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This option uses the SQL Upper function to perform case-normalization. This guarantees that the
|
||||||
|
/// the user name is searched case-insensitively, but can have a performance impact when a large number
|
||||||
|
/// of users exist.
|
||||||
|
/// </remarks>
|
||||||
|
NormalizeCasing,
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Relies on the database's configured collation to normalize casing for the comparison of user names. User
|
||||||
|
/// names are provided to the database exactly as entered by the user.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This option relies on the configured collection of database table for user names to perform a correct comparison.
|
||||||
|
/// This is guaranteed to be correct for the chosen collation and performant. Only choose this option if the table storing
|
||||||
|
/// user names is configured with the desired collation.
|
||||||
|
/// </remarks>
|
||||||
|
RelyOnDatabaseCollation,
|
||||||
|
}
|
||||||
|
}
|
|
@ -74,6 +74,8 @@ namespace WebMatrix.WebData
|
||||||
// REVIEW: we could get this from the primary key of UserTable in the future
|
// REVIEW: we could get this from the primary key of UserTable in the future
|
||||||
public string UserIdColumn { get; set; }
|
public string UserIdColumn { get; set; }
|
||||||
|
|
||||||
|
public SimpleMembershipProviderCasingBehavior CasingBehavior { get; set; }
|
||||||
|
|
||||||
internal DatabaseConnectionInfo ConnectionInfo { get; set; }
|
internal DatabaseConnectionInfo ConnectionInfo { get; set; }
|
||||||
internal bool InitializeCalled { get; set; }
|
internal bool InitializeCalled { get; set; }
|
||||||
|
|
||||||
|
@ -142,7 +144,7 @@ namespace WebMatrix.WebData
|
||||||
List<int> userIds = new List<int>(usernames.Length);
|
List<int> userIds = new List<int>(usernames.Length);
|
||||||
foreach (string username in usernames)
|
foreach (string username in usernames)
|
||||||
{
|
{
|
||||||
int id = SimpleMembershipProvider.GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
|
int id = SimpleMembershipProvider.GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, CasingBehavior, username);
|
||||||
if (id == -1)
|
if (id == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, username));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, username));
|
||||||
|
@ -307,7 +309,7 @@ namespace WebMatrix.WebData
|
||||||
}
|
}
|
||||||
using (var db = ConnectToDatabase())
|
using (var db = ConnectToDatabase())
|
||||||
{
|
{
|
||||||
int userId = SimpleMembershipProvider.GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, username);
|
int userId = SimpleMembershipProvider.GetUserId(db, SafeUserTableName, SafeUserNameColumn, SafeUserIdColumn, CasingBehavior, username);
|
||||||
if (userId == -1)
|
if (userId == -1)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, username));
|
throw new InvalidOperationException(String.Format(CultureInfo.CurrentCulture, WebDataResources.Security_NoUserFound, username));
|
||||||
|
|
|
@ -50,6 +50,7 @@
|
||||||
<DependentUpon>WebDataResources.resx</DependentUpon>
|
<DependentUpon>WebDataResources.resx</DependentUpon>
|
||||||
</Compile>
|
</Compile>
|
||||||
<Compile Include="SimpleMembershipProvider.cs" />
|
<Compile Include="SimpleMembershipProvider.cs" />
|
||||||
|
<Compile Include="SimpleMembershipProviderCasingBehavior.cs" />
|
||||||
<Compile Include="SimpleRoleProvider.cs" />
|
<Compile Include="SimpleRoleProvider.cs" />
|
||||||
<Compile Include="WebSecurity.cs" />
|
<Compile Include="WebSecurity.cs" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
|
@ -102,42 +102,99 @@ namespace WebMatrix.WebData
|
||||||
|
|
||||||
public static void InitializeDatabaseConnection(string connectionStringName, string userTableName, string userIdColumn, string userNameColumn, bool autoCreateTables)
|
public static void InitializeDatabaseConnection(string connectionStringName, string userTableName, string userIdColumn, string userNameColumn, bool autoCreateTables)
|
||||||
{
|
{
|
||||||
DatabaseConnectionInfo connect = new DatabaseConnectionInfo();
|
InitializeDatabaseConnection(
|
||||||
connect.ConnectionStringName = connectionStringName;
|
connectionStringName,
|
||||||
InitializeProviders(connect, userTableName, userIdColumn, userNameColumn, autoCreateTables);
|
userTableName,
|
||||||
|
userIdColumn,
|
||||||
|
userNameColumn,
|
||||||
|
autoCreateTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior.NormalizeCasing);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void InitializeDatabaseConnection(string connectionString, string providerName, string userTableName, string userIdColumn, string userNameColumn, bool autoCreateTables)
|
public static void InitializeDatabaseConnection(
|
||||||
|
string connectionStringName,
|
||||||
|
string userTableName,
|
||||||
|
string userIdColumn,
|
||||||
|
string userNameColumn,
|
||||||
|
bool autoCreateTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior casingBehavior)
|
||||||
|
{
|
||||||
|
DatabaseConnectionInfo connect = new DatabaseConnectionInfo();
|
||||||
|
connect.ConnectionStringName = connectionStringName;
|
||||||
|
InitializeProviders(connect, userTableName, userIdColumn, userNameColumn, autoCreateTables, casingBehavior);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializeDatabaseConnection(
|
||||||
|
string connectionString,
|
||||||
|
string providerName,
|
||||||
|
string userTableName,
|
||||||
|
string userIdColumn,
|
||||||
|
string userNameColumn,
|
||||||
|
bool autoCreateTables)
|
||||||
|
{
|
||||||
|
InitializeDatabaseConnection(
|
||||||
|
connectionString,
|
||||||
|
providerName,
|
||||||
|
userTableName,
|
||||||
|
userIdColumn,
|
||||||
|
userNameColumn,
|
||||||
|
autoCreateTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior.NormalizeCasing);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void InitializeDatabaseConnection(
|
||||||
|
string connectionString,
|
||||||
|
string providerName,
|
||||||
|
string userTableName,
|
||||||
|
string userIdColumn,
|
||||||
|
string userNameColumn,
|
||||||
|
bool autoCreateTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior casingBehavior)
|
||||||
{
|
{
|
||||||
DatabaseConnectionInfo connect = new DatabaseConnectionInfo();
|
DatabaseConnectionInfo connect = new DatabaseConnectionInfo();
|
||||||
connect.ConnectionString = connectionString;
|
connect.ConnectionString = connectionString;
|
||||||
connect.ProviderName = providerName;
|
connect.ProviderName = providerName;
|
||||||
InitializeProviders(connect, userTableName, userIdColumn, userNameColumn, autoCreateTables);
|
InitializeProviders(connect, userTableName, userIdColumn, userNameColumn, autoCreateTables, casingBehavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void InitializeProviders(DatabaseConnectionInfo connect, string userTableName, string userIdColumn, string userNameColumn, bool autoCreateTables)
|
private static void InitializeProviders(
|
||||||
|
DatabaseConnectionInfo connect,
|
||||||
|
string userTableName,
|
||||||
|
string userIdColumn,
|
||||||
|
string userNameColumn,
|
||||||
|
bool autoCreateTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior casingBehavior)
|
||||||
{
|
{
|
||||||
SimpleMembershipProvider simpleMembership = Membership.Provider as SimpleMembershipProvider;
|
SimpleMembershipProvider simpleMembership = Membership.Provider as SimpleMembershipProvider;
|
||||||
if (simpleMembership != null)
|
if (simpleMembership != null)
|
||||||
{
|
{
|
||||||
InitializeMembershipProvider(simpleMembership, connect, userTableName, userIdColumn, userNameColumn, autoCreateTables);
|
InitializeMembershipProvider(simpleMembership, connect, userTableName, userIdColumn, userNameColumn, autoCreateTables, casingBehavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
SimpleRoleProvider simpleRoles = Roles.Provider as SimpleRoleProvider;
|
SimpleRoleProvider simpleRoles = Roles.Provider as SimpleRoleProvider;
|
||||||
if (simpleRoles != null)
|
if (simpleRoles != null)
|
||||||
{
|
{
|
||||||
InitializeRoleProvider(simpleRoles, connect, userTableName, userIdColumn, userNameColumn, autoCreateTables);
|
InitializeRoleProvider(simpleRoles, connect, userTableName, userIdColumn, userNameColumn, autoCreateTables, casingBehavior);
|
||||||
}
|
}
|
||||||
|
|
||||||
Initialized = true;
|
Initialized = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InitializeMembershipProvider(SimpleMembershipProvider simpleMembership, DatabaseConnectionInfo connect, string userTableName, string userIdColumn, string userNameColumn, bool createTables)
|
internal static void InitializeMembershipProvider(
|
||||||
|
SimpleMembershipProvider simpleMembership,
|
||||||
|
DatabaseConnectionInfo connect,
|
||||||
|
string userTableName,
|
||||||
|
string userIdColumn,
|
||||||
|
string userNameColumn,
|
||||||
|
bool createTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior casingBehavior)
|
||||||
{
|
{
|
||||||
if (simpleMembership.InitializeCalled)
|
if (simpleMembership.InitializeCalled)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(WebDataResources.Security_InitializeAlreadyCalled);
|
throw new InvalidOperationException(WebDataResources.Security_InitializeAlreadyCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simpleMembership.CasingBehavior = casingBehavior;
|
||||||
simpleMembership.ConnectionInfo = connect;
|
simpleMembership.ConnectionInfo = connect;
|
||||||
simpleMembership.UserIdColumn = userIdColumn;
|
simpleMembership.UserIdColumn = userIdColumn;
|
||||||
simpleMembership.UserNameColumn = userNameColumn;
|
simpleMembership.UserNameColumn = userNameColumn;
|
||||||
|
@ -154,16 +211,26 @@ namespace WebMatrix.WebData
|
||||||
simpleMembership.InitializeCalled = true;
|
simpleMembership.InitializeCalled = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
internal static void InitializeRoleProvider(SimpleRoleProvider simpleRoles, DatabaseConnectionInfo connect, string userTableName, string userIdColumn, string userNameColumn, bool createTables)
|
internal static void InitializeRoleProvider(
|
||||||
|
SimpleRoleProvider simpleRoles,
|
||||||
|
DatabaseConnectionInfo connect,
|
||||||
|
string userTableName,
|
||||||
|
string userIdColumn,
|
||||||
|
string userNameColumn,
|
||||||
|
bool createTables,
|
||||||
|
SimpleMembershipProviderCasingBehavior casingBehavior)
|
||||||
{
|
{
|
||||||
if (simpleRoles.InitializeCalled)
|
if (simpleRoles.InitializeCalled)
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException(WebDataResources.Security_InitializeAlreadyCalled);
|
throw new InvalidOperationException(WebDataResources.Security_InitializeAlreadyCalled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
simpleRoles.CasingBehavior = casingBehavior;
|
||||||
simpleRoles.ConnectionInfo = connect;
|
simpleRoles.ConnectionInfo = connect;
|
||||||
simpleRoles.UserTableName = userTableName;
|
simpleRoles.UserTableName = userTableName;
|
||||||
simpleRoles.UserIdColumn = userIdColumn;
|
simpleRoles.UserIdColumn = userIdColumn;
|
||||||
simpleRoles.UserNameColumn = userNameColumn;
|
simpleRoles.UserNameColumn = userNameColumn;
|
||||||
|
|
||||||
if (createTables)
|
if (createTables)
|
||||||
{
|
{
|
||||||
simpleRoles.CreateTablesIfNeeded();
|
simpleRoles.CreateTablesIfNeeded();
|
||||||
|
|
|
@ -170,6 +170,48 @@ namespace WebMatrix.WebData.Test
|
||||||
Assert.Equal("fGH_eKcjvW__P-5BOEW1AA2", result);
|
Assert.Equal("fGH_eKcjvW__P-5BOEW1AA2", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetUserId_WithCaseNormalization()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var database = new Mock<MockDatabase>(MockBehavior.Strict);
|
||||||
|
var expectedQuery = @"SELECT userId FROM users WHERE (UPPER(userName) = UPPER(@0))";
|
||||||
|
database.Setup(d => d.QueryValue(expectedQuery, "zeke")).Returns(999);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = SimpleMembershipProvider.GetUserId(
|
||||||
|
database.Object,
|
||||||
|
"users",
|
||||||
|
"userName",
|
||||||
|
"userId",
|
||||||
|
SimpleMembershipProviderCasingBehavior.NormalizeCasing,
|
||||||
|
"zeke");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal<int>(999, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Fact]
|
||||||
|
public void GetUserId_WithoutCaseNormalization()
|
||||||
|
{
|
||||||
|
// Arrange
|
||||||
|
var database = new Mock<MockDatabase>(MockBehavior.Strict);
|
||||||
|
var expectedQuery = @"SELECT userId FROM users WHERE (userName = @0)";
|
||||||
|
database.Setup(d => d.QueryValue(expectedQuery, "zeke")).Returns(999);
|
||||||
|
|
||||||
|
// Act
|
||||||
|
var result = SimpleMembershipProvider.GetUserId(
|
||||||
|
database.Object,
|
||||||
|
"users",
|
||||||
|
"userName",
|
||||||
|
"userId",
|
||||||
|
SimpleMembershipProviderCasingBehavior.RelyOnDatabaseCollation,
|
||||||
|
"zeke");
|
||||||
|
|
||||||
|
// Assert
|
||||||
|
Assert.Equal<int>(999, result);
|
||||||
|
}
|
||||||
|
|
||||||
private static DynamicRecord GetRecord(int userId, string confirmationToken)
|
private static DynamicRecord GetRecord(int userId, string confirmationToken)
|
||||||
{
|
{
|
||||||
var data = new Mock<IDataRecord>(MockBehavior.Strict);
|
var data = new Mock<IDataRecord>(MockBehavior.Strict);
|
||||||
|
|
Загрузка…
Ссылка в новой задаче