List:Commits« Previous MessageNext Message »
From:rburnett Date:January 31 2008 10:30pm
Subject:Connector/NET commit: r1156 - in trunk/MySql.Web: Providers Providers/Properties Providers/Source Tests
View as plain text  
Added:
   trunk/MySql.Web/Tests/App.config
   trunk/MySql.Web/Tests/ProfileTests.cs
   trunk/MySql.Web/Tests/TestProfile.cs
Modified:
   trunk/MySql.Web/Providers/MySql.Web.csproj
   trunk/MySql.Web/Providers/Properties/schema3.sql
   trunk/MySql.Web/Providers/Source/MembershipProvider.cs
   trunk/MySql.Web/Providers/Source/ProfileProvider.cs
   trunk/MySql.Web/Providers/Source/RoleProvider.cs
   trunk/MySql.Web/Providers/Source/SchemaManager.cs
   trunk/MySql.Web/Tests/BaseTest.cs
   trunk/MySql.Web/Tests/MySql.Web.Tests.csproj
   trunk/MySql.Web/Tests/RoleManagement.cs
   trunk/MySql.Web/Tests/SchemaTests.cs
   trunk/MySql.Web/Tests/UserManagement.cs
Log:
major coding to fix the providers test suite to account for the new schema.  Too many
changes to individually list.  :)

Modified: trunk/MySql.Web/Providers/MySql.Web.csproj
===================================================================
--- trunk/MySql.Web/Providers/MySql.Web.csproj	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Providers/MySql.Web.csproj	2008-01-31 21:30:36 UTC (rev 1156)
@@ -2,7 +2,7 @@
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == ''
">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>9.0.21022</ProductVersion>
+    <ProductVersion>8.0.50727</ProductVersion>
     <SchemaVersion>2.0</SchemaVersion>
     <ProjectGuid>{C28B1166-1380-445D-AEC1-8A18B990DD18}</ProjectGuid>
     <OutputType>Library</OutputType>

Modified: trunk/MySql.Web/Providers/Properties/schema3.sql
===================================================================
--- trunk/MySql.Web/Providers/Properties/schema3.sql	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Providers/Properties/schema3.sql	2008-01-31 21:30:36 UTC (rev 1156)
@@ -16,6 +16,7 @@
           rename to my_aspnet_Membership,
           drop primary key,
           drop column pkid,
+          drop column isonline,
           add column userId INT FIRST,
           add column applicationId INT AFTER userId;
           

Modified: trunk/MySql.Web/Providers/Source/MembershipProvider.cs
===================================================================
--- trunk/MySql.Web/Providers/Source/MembershipProvider.cs	2008-01-31 21:29:20 UTC (rev
1155)
+++ trunk/MySql.Web/Providers/Source/MembershipProvider.cs	2008-01-31 21:30:36 UTC (rev
1156)
@@ -35,6 +35,9 @@
 using System.Web.Security;
 using MySql.Data.MySqlClient;
 using MySql.Web.Properties;
+using MySql.Web.Profile;
+using MySql.Web.Common;
+using System.Transactions;
 
 namespace MySql.Web.Security
 {
@@ -116,13 +119,15 @@
             writeExceptionsToEventLog =
Convert.ToBoolean(GetConfigValue(config["writeExceptionsToEventLog"], "True"));
             string temp_format = config["passwordFormat"];
             if (temp_format == null)
-                temp_format = "Hashed";
+                temp_format = "hashed";
+            else
+                temp_format = temp_format.ToLowerInvariant();
 
-            if (temp_format == "Hashed")
+            if (temp_format == "hashed")
                 passwordFormat = MembershipPasswordFormat.Hashed;
-            else if (temp_format == "Encrypted")
+            else if (temp_format == "encrypted")
                 passwordFormat = MembershipPasswordFormat.Encrypted;
-            else if (temp_format == "Clear")
+            else if (temp_format == "clear")
                 passwordFormat = MembershipPasswordFormat.Clear;
             else
                 throw new ProviderException("Password format not supported.");
@@ -147,8 +152,12 @@
                 // now pre-cache the applicationId
                 using (MySqlConnection conn = new MySqlConnection(connectionString))
                 {
+                    conn.Open();
                     MySqlCommand cmd = new MySqlCommand("SELECT id FROM
my_aspnet_Applications WHERE name=@name", conn);
-                    applicationId = (int)cmd.ExecuteScalar();
+                    cmd.Parameters.AddWithValue("@name", applicationName);
+                    object appId = cmd.ExecuteScalar();
+                    if (appId != null)
+                        applicationId = Convert.ToInt32(appId);
                 }
             }
             catch (Exception ex)
@@ -390,20 +399,21 @@
 
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
 
                     // retrieve the existing key and format for this user
                     string passwordKey;
                     MembershipPasswordFormat passwordFormat;
-                    GetPasswordInfo(conn, username, out passwordKey, out passwordFormat);
-                    int userId = GetUserId(conn, username);
+                    int userId = GetUserId(connection, username);
 
+                    GetPasswordInfo(connection, userId, out passwordKey, out
passwordFormat);
+
                     MySqlCommand cmd = new MySqlCommand(
                         @"UPDATE my_aspnet_Membership
                         SET Password = @pass, LastPasswordChangedDate =
@lastPasswordChangedDate 
-                        WHERE userId=@userId", conn);
+                        WHERE userId=@userId", connection);
                     cmd.Parameters.AddWithValue("@pass", 
                         EncodePassword(newPwd, passwordKey, passwordFormat));
                     cmd.Parameters.AddWithValue("@lastPasswordChangedDate",
DateTime.Now);
@@ -438,21 +448,22 @@
 
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
 
                     string passwordKey;
                     MembershipPasswordFormat passwordFormat;
-                    GetPasswordInfo(conn, username, out passwordKey, out passwordFormat);
+                    int userId = GetUserId(connection, username);
 
-                    int userId = GetUserId(conn, username);
+                    GetPasswordInfo(connection, userId, out passwordKey, out
passwordFormat);
 
+
                     MySqlCommand cmd = new MySqlCommand(
                         @"UPDATE my_aspnet_Membership 
-                        SET PasswordQuestion = @passQuestion, PasswordAnswer =
@passAnswer
-                        WHERE userId=@userId", conn);
-                    cmd.Parameters.AddWithValue("@passQuestion", newPwdQuestion);
+                        SET PasswordQuestion = @passwordQuestion, PasswordAnswer =
@passwordAnswer
+                        WHERE userId=@userId", connection);
+                    cmd.Parameters.AddWithValue("@passwordQuestion", newPwdQuestion);
                     cmd.Parameters.AddWithValue("@passwordAnswer",
                         EncodePassword(newPwdAnswer, passwordKey, passwordFormat));
                     cmd.Parameters.AddWithValue("@userId", userId);
@@ -492,13 +503,13 @@
                 status = MembershipCreateStatus.InvalidPassword;
                 return null;
             }
-            if (RequiresUniqueEmail && GetUserNameByEmail(email) != "")
+            if (RequiresUniqueEmail &&
!String.IsNullOrEmpty(GetUserNameByEmail(email)))
             {
                 status = MembershipCreateStatus.DuplicateEmail;
                 return null;
             }
 
-            // now check to see if that username is already in use.
+            // now check to see if we already have a member by this name
             MembershipUser u = GetUser(username, false);
             if (u != null)
             {
@@ -508,86 +519,68 @@
 
             string passwordKey = GetPasswordKey();
             DateTime createDate = DateTime.Now;
-            if (providerUserKey == null)
+            MySqlTransaction transaction = null;
+
+            using (MySqlConnection connection = new MySqlConnection(connectionString))
             {
-                providerUserKey = Guid.NewGuid();
-            }
-            else
-            {
-                if (!(providerUserKey is Guid))
+                try
                 {
-                    status = MembershipCreateStatus.InvalidProviderUserKey;
-                    return null;
+                    connection.Open();
+                    transaction = connection.BeginTransaction();
+
+                    // either create a new user or fetch the existing user id
+                    int userId = CreateOrFetchUserId(username, false, connection);
+
+                    MySqlCommand cmd = new MySqlCommand(
+                        @"INSERT INTO my_aspnet_Membership 
+                        VALUES(@userId, @email, @comment, @password, @passwordKey, 
+                        @passwordFormat, @passwordQuestion, @passwordAnswer, 
+                        @isApproved, @lastActivityDate, @lastLoginDate,
+                        @lastPasswordChangedDate, @creationDate, 
+                        @isLockedOut, @lastLockedOutDate, @failedPasswordAttemptCount,
+                        @failedPasswordAttemptWindowStart,
@failedPasswordAnswerAttemptCount, 
+                        @failedPasswordAnswerAttemptWindowStart)",
+                        connection);
+                    cmd.Parameters.AddWithValue("@userId", userId);
+                    cmd.Parameters.AddWithValue("@email", email);
+                    cmd.Parameters.AddWithValue("@comment", "");
+                    cmd.Parameters.AddWithValue("@password",
+                        EncodePassword(password, passwordKey, PasswordFormat));
+                    cmd.Parameters.AddWithValue("@passwordKey", passwordKey);
+                    cmd.Parameters.AddWithValue("@passwordFormat", PasswordFormat);
+                    cmd.Parameters.AddWithValue("@passwordQuestion", passwordQuestion);
+                    cmd.Parameters.AddWithValue("@passwordAnswer",
+                        EncodePassword(passwordAnswer, passwordKey, PasswordFormat));
+                    cmd.Parameters.AddWithValue("@isApproved", isApproved);
+                    cmd.Parameters.AddWithValue("@lastActivityDate", createDate);
+                    cmd.Parameters.AddWithValue("@lastLoginDate", createDate);
+                    cmd.Parameters.AddWithValue("@lastPasswordChangedDate", createDate);
+                    cmd.Parameters.AddWithValue("@creationDate", createDate);
+                    cmd.Parameters.AddWithValue("@isLockedOut", false);
+                    cmd.Parameters.AddWithValue("@lastLockedOutDate", createDate);
+                    cmd.Parameters.AddWithValue("@failedPasswordAttemptCount", 0);
+                    cmd.Parameters.AddWithValue("@failedPasswordAttemptWindowStart",
createDate);
+                    cmd.Parameters.AddWithValue("@failedPasswordAnswerAttemptCount", 0);
+                   
cmd.Parameters.AddWithValue("@failedPasswordAnswerAttemptWindowStart", createDate);
+
+                    int recAdded = cmd.ExecuteNonQuery();
+                    if (recAdded > 0)
+                        status = MembershipCreateStatus.Success;
+                    else
+                        status = MembershipCreateStatus.UserRejected;
+                    transaction.Commit();
                 }
-            }
-            MySqlConnection conn = new MySqlConnection(connectionString);
-            MySqlCommand cmd = new MySqlCommand(
-                    @"INSERT INTO mysql_Membership (
-PKID, Username, ApplicationName,
-                    Email, Comment, Password, PasswordKey, PasswordFormat, 
-                    PasswordQuestion, PasswordAnswer, IsApproved, LastActivityDate,
-                    LastPasswordChangedDate, CreationDate, 
-                    IsLockedOut, LastLockedOutDate,  
-                    FailedPasswordAttemptCount, FailedPasswordAttemptWindowStart, 
-                    FailedPasswordAnswerAttemptCount, 
-                    FailedPasswordAnswerAttemptWindowStart)
-                    Values(?PKID, ?Username, ?ApplicationName, ?Email, 
-                     ?Comment, ?Password, ?PasswordKey, ?PasswordFormat, 
-                    ?PasswordQuestion, ?PasswordAnswer, ?IsApproved, ?LastActivityDate,  
-                    ?LastPasswordChangedDate, ?CreationDate, 
-                    ?IsLockedOut, ?LastLockedOutDate, 
-                    ?FailedPasswordAttemptCount,
-                    ?FailedPasswordAttemptWindowStart, 
-                    ?FailedPasswordAnswerAttemptCount, 
-                    ?FailedPasswordAnswerAttemptWindowStart)",
-                    conn);
-            cmd.Parameters.AddWithValue("?PKID", providerUserKey.ToString());
-            cmd.Parameters.AddWithValue("?Username", username);
-            cmd.Parameters.AddWithValue("?ApplicationName", applicationName);
-            cmd.Parameters.AddWithValue("?Email", email);
-            cmd.Parameters.AddWithValue("?Comment", "");
-            cmd.Parameters.AddWithValue("?Password",
-                EncodePassword(password, passwordKey, PasswordFormat));
-            cmd.Parameters.AddWithValue("?PasswordKey", passwordKey);
-            cmd.Parameters.AddWithValue("?PasswordFormat", PasswordFormat);
-            cmd.Parameters.AddWithValue("?PasswordQuestion", passwordQuestion);
-            cmd.Parameters.AddWithValue("?PasswordAnswer",
-                EncodePassword(passwordAnswer, passwordKey, PasswordFormat));
-            cmd.Parameters.AddWithValue("?IsApproved", isApproved);
-            cmd.Parameters.AddWithValue("?LastActivityDate", createDate);
-            cmd.Parameters.AddWithValue("?LastPasswordChangedDate", createDate);
-            cmd.Parameters.AddWithValue("?CreationDate", createDate);
-            cmd.Parameters.AddWithValue("?IsLockedOut", false);
-            cmd.Parameters.AddWithValue("?LastLockedOutDate", createDate);
-            cmd.Parameters.AddWithValue("?FailedPasswordAttemptCount", 0);
-            cmd.Parameters.AddWithValue("?FailedPasswordAttemptWindowStart", createDate);
-            cmd.Parameters.AddWithValue("?FailedPasswordAnswerAttemptCount", 0);
-            cmd.Parameters.AddWithValue("?FailedPasswordAnswerAttemptWindowStart",
createDate);
-            try
-            {
-                conn.Open();
-                int recAdded = cmd.ExecuteNonQuery();
-                if (recAdded > 0)
+                catch (MySqlException e)
                 {
-                    status = MembershipCreateStatus.Success;
+                    if (WriteExceptionsToEventLog)
+                        WriteToEventLog(e, "CreateUser");
+                    status = MembershipCreateStatus.ProviderError;
+                    if (transaction != null)
+                        transaction.Rollback();
+                    return null;
                 }
-                else
-                {
-                    status = MembershipCreateStatus.UserRejected;
-                }
             }
-            catch (MySqlException e)
-            {
-                if (WriteExceptionsToEventLog)
-                {
-                    WriteToEventLog(e, "CreateUser");
-                }
-                status = MembershipCreateStatus.ProviderError;
-            }
-            finally
-            {
-                conn.Close();
-            }
+
             return GetUser(username, false);
         }
 
@@ -664,12 +657,13 @@
 
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
                     MySqlCommand cmd = new MySqlCommand(
-                            @"SELECT Count(*) FROM my_aspnet_Users
-                        WHERE LastActivityDate > @date AND applicationId=@appId",
conn);
+                        @"SELECT COUNT(*) FROM my_aspnet_Membership m JOIN
my_aspnet_Users u
+                        ON m.userId=u.id WHERE m.LastActivityDate > @date AND
u.applicationId=@appId", 
+                        connection);
                     cmd.Parameters.AddWithValue("@date", compareTime);
                     cmd.Parameters.AddWithValue("@appId", applicationId);
                     return Convert.ToInt32(cmd.ExecuteScalar());
@@ -693,22 +687,22 @@
         /// </returns>
         public override string GetPassword(string username, string answer)
         {
-            if (!(EnablePasswordRetrieval))
+            if (!EnablePasswordRetrieval)
                 throw new ProviderException("Password Retrieval Not Enabled.");
 
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
 
-                    int userId = GetUserId(conn, username);
+                    int userId = GetUserId(connection, username);
                     if (-1 == userId)
                         throw new ProviderException("Username not found.");
 
                     string sql = @"SELECT password, passwordAnswer, passwordKey,
passwordFormat, 
                     isLockedOut FROM my_aspnet_Membership WHERE userId=@userId";
-                    MySqlCommand cmd = new MySqlCommand(sql, conn);
+                    MySqlCommand cmd = new MySqlCommand(sql, connection);
                     cmd.Parameters.AddWithValue("@userId", userId);
 
                     using (MySqlDataReader reader =
cmd.ExecuteReader(CommandBehavior.SingleRow))
@@ -726,7 +720,7 @@
                         if (RequiresQuestionAndAnswer &&
                             !(CheckPassword(answer, passwordAnswer, passwordKey,
format)))
                         {
-                            UpdateFailureCount(username, "passwordAnswer");
+                            UpdateFailureCount(userId, "passwordAnswer", connection);
                             throw new MembershipPasswordException("Incorrect password
answer.");
                         }
                         if (PasswordFormat == MembershipPasswordFormat.Encrypted)
@@ -757,36 +751,21 @@
         {
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
 
-                    int userId = GetUserId(conn, username);
+                    int userId = GetUserId(connection, username);
                     if (-1 == userId) return null;
 
-                    string sql = @"SELECT * FROM my_aspnet_Membership WHERE
userId=@userId";
-                    MySqlCommand cmd = new MySqlCommand(sql, conn);
-                    cmd.Parameters.AddWithValue("@userId", userId);
-                    MembershipUser user;
-                    using (MySqlDataReader reader = cmd.ExecuteReader())
-                    {
-                        user = GetUserFromReader(reader);
-                    }
-                    if (userIsOnline)
-                    {
-                        cmd.CommandText =
-                            @"UPDATE my_aspnet_Users SET LastActivityDate = @date WHERE
id=@userId";
-                        cmd.Parameters.AddWithValue("@date", DateTime.Now);
-                        cmd.ExecuteNonQuery();
-                    }
-                    return user;
+                    return GetUser(userId, userIsOnline);
                 }
             }
             catch (MySqlException e)
             {
                 if (WriteExceptionsToEventLog)
                     WriteToEventLog(e, "GetUser(String, Boolean)");
-                throw new ProviderException(exceptionMessage);
+                throw new ProviderException(exceptionMessage, e);
             }
         }
 
@@ -802,29 +781,39 @@
         {
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (TransactionScope scope = new TransactionScope())
                 {
-                    conn.Open();
+                    using (MySqlConnection connection = new
MySqlConnection(connectionString))
+                    {
+                        connection.Open();
 
-                    MySqlCommand cmd = new MySqlCommand(
-                        @"SELECT * FROM my_aspnet_Membership WHERE userId=@userId",
conn);
-                    cmd.Parameters.AddWithValue("@userId", providerUserKey);
+                        MySqlCommand cmd = new MySqlCommand("", connection);
+                        cmd.Parameters.AddWithValue("@userId", providerUserKey);
 
-                    MembershipUser user;
-                    using (MySqlDataReader reader = cmd.ExecuteReader())
-                    {
-                        if (!reader.Read()) return null;
-                        user = GetUserFromReader(reader);
-                    }
+                        if (userIsOnline)
+                        {
+                            cmd.CommandText =
+                                @"UPDATE my_aspnet_Users SET LastActivityDate = @date
WHERE id=@userId";
+                            cmd.Parameters.AddWithValue("@date", DateTime.Now);
+                            cmd.ExecuteNonQuery();
 
-                    if (userIsOnline)
-                    {
-                        cmd.CommandText =
-                            @"UPDATE my_aspnet_Users SET LastActivityDate = @date WHERE
id=@userId";
-                        cmd.Parameters.AddWithValue("@date", DateTime.Now);
-                        cmd.ExecuteNonQuery();
+                            cmd.CommandText = "UPDATE my_aspnet_Membership SET
LastActivityDate=@date WHERE userId=@userId";
+                            cmd.ExecuteNonQuery();
+                        }
+
+                        cmd.CommandText = @"SELECT m.*,u.name 
+                        FROM my_aspnet_Membership m JOIN my_aspnet_Users u ON
m.userId=u.id 
+                        WHERE u.id=@userId";
+
+                        MembershipUser user;
+                        using (MySqlDataReader reader = cmd.ExecuteReader())
+                        {
+                            if (!reader.Read()) return null;
+                            user = GetUserFromReader(reader);
+                        }
+
+                        return user;
                     }
-                    return user;
                 }
             }
             catch (MySqlException e)
@@ -858,7 +847,7 @@
                         WHERE userId=@userId";
 
                     MySqlCommand cmd = new MySqlCommand(sql, conn);
-                    cmd.Parameters.AddWithValue("@LastLockedOutDate", DateTime.Now);
+                    cmd.Parameters.AddWithValue("@lastDate", DateTime.Now);
                     cmd.Parameters.AddWithValue("@userId", userId);
                     return cmd.ExecuteNonQuery() > 0;
                 }
@@ -913,36 +902,38 @@
         {
             if (!(EnablePasswordReset))
                 throw new NotSupportedException("Password Reset is not enabled.");
-            if (answer == null && RequiresQuestionAndAnswer)
-            {
-                UpdateFailureCount(username, "passwordAnswer");
-                throw new ProviderException("Password answer required for password
Reset.");
-            }
 
-            string newPassword = Membership.GeneratePassword(newPasswordLength,
MinRequiredNonAlphanumericCharacters);
-            ValidatePasswordEventArgs Args = new ValidatePasswordEventArgs(username,
newPassword, true);
-            OnValidatingPassword(Args);
-            if (Args.Cancel)
-            {
-                if (!(Args.FailureInformation == null))
-                    throw Args.FailureInformation;
-                else
-                    throw new MembershipPasswordException("Reset password canceled due to
password validation failure.");
-            }
-
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
 
-                    int userId = GetUserId(conn, username);
+                    // fetch the userid first
+                    int userId = GetUserId(connection, username);
                     if (-1 == userId)
                         throw new ProviderException("Username not found.");
 
+                    if (answer == null && RequiresQuestionAndAnswer)
+                    {
+                        UpdateFailureCount(userId, "passwordAnswer", connection);
+                        throw new ProviderException("Password answer required for
password Reset.");
+                    }
+
+                    string newPassword = Membership.GeneratePassword(newPasswordLength,
MinRequiredNonAlphanumericCharacters);
+                    ValidatePasswordEventArgs Args = new
ValidatePasswordEventArgs(username, newPassword, true);
+                    OnValidatingPassword(Args);
+                    if (Args.Cancel)
+                    {
+                        if (!(Args.FailureInformation == null))
+                            throw Args.FailureInformation;
+                        else
+                            throw new MembershipPasswordException("Reset password
canceled due to password validation failure.");
+                    }
+
                     MySqlCommand cmd = new MySqlCommand(@"SELECT passwordAnswer, 
                     passwordKey, passwordFormat, IsLockedOut 
-                    FROM my_aspnet_Membership WHERE userId=@userId", conn);
+                    FROM my_aspnet_Membership WHERE userId=@userId", connection);
                     cmd.Parameters.AddWithValue("@userId", userId);
 
                     string passwordKey = String.Empty;
@@ -961,7 +952,7 @@
                         if (RequiresQuestionAndAnswer &&
                             !CheckPassword(answer, passwordAnswer, passwordKey, format))
                         {
-                            UpdateFailureCount(username, "passwordAnswer");
+                            UpdateFailureCount(userId, "passwordAnswer", connection);
                             throw new MembershipPasswordException("Incorrect password
answer.");
                         }
                     }
@@ -1006,7 +997,8 @@
 
                     string sql = @"UPDATE my_aspnet_Membership m, my_aspnet_Users u 
                         SET m.email=@email, m.comment=@comment, m.isApproved=@isApproved,
-                        m.lastLoginDate=@lastLoginDate,
u.lastActivityDate=@lastActivityDate
+                        m.lastLoginDate=@lastLoginDate,
u.lastActivityDate=@lastActivityDate,
+                        m.lastActivityDate=@lastActivityDate
                         WHERE m.userId=u.id AND u.name LIKE @name AND
u.applicationId=@appId";
                     MySqlCommand cmd = new MySqlCommand(sql, conn);
                     cmd.Parameters.AddWithValue("@Email", user.Email);
@@ -1040,18 +1032,18 @@
             bool isValid = false;
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
-                    conn.Open();
+                    connection.Open();
 
                     // first get the user id.  If that is -1, then the user doesn't exist
                     // so we just return false since we can't bump any counters
-                    int userId = GetUserId(conn, username);
+                    int userId = GetUserId(connection, username);
                     if (-1 == userId) return false;
 
-                    string sql = @"SELECT password, passwordKey, passwordFormat,
isApproved 
-                            FROM my_aspnet_Membership WHERE userId=@userId";
-                    MySqlCommand cmd = new MySqlCommand(sql, conn);
+                    string sql = @"SELECT password, passwordKey, passwordFormat,
isApproved,
+                            islockedout FROM my_aspnet_Membership WHERE userId=@userId";
+                    MySqlCommand cmd = new MySqlCommand(sql, connection);
                     cmd.Parameters.AddWithValue("@userId", userId);
                     cmd.Parameters.AddWithValue("@appId", applicationId);
 
@@ -1069,15 +1061,18 @@
                         reader.Close();
 
                         if (!CheckPassword(password, pwd, passwordKey, format))
-                            UpdateFailureCount(username, "password");
+                            UpdateFailureCount(userId, "password", connection);
                         else if (isApproved)
                         {
                             isValid = true;
+                            DateTime currentDate = DateTime.Now;
                             MySqlCommand updateCmd = new MySqlCommand(
                                 @"UPDATE my_aspnet_Membership m, my_aspnet_Users u 
-                                SET m.LastLoginDate = @lastLoginDate, u.lastActivityDate
= @date 
-                                WHERE m.userid=@userid AND u.id=@userid", conn);
-                            updateCmd.Parameters.AddWithValue("@lastLoginDate",
DateTime.Now);
+                                SET m.LastLoginDate = @lastLoginDate, u.lastActivityDate
= @date,
+                                m.lastActivityDate=@date 
+                                WHERE m.userid=@userid AND u.id=@userid", connection);
+                            updateCmd.Parameters.AddWithValue("@lastLoginDate",
currentDate);
+                            updateCmd.Parameters.AddWithValue("@date", currentDate);
                             updateCmd.Parameters.AddWithValue("@userid", userId);
                             updateCmd.Parameters.AddWithValue("@appId", applicationId);
                             updateCmd.ExecuteNonQuery();
@@ -1132,7 +1127,9 @@
 
         private int GetUserId(MySqlConnection connection, string username)
         {
-            MySqlCommand cmd = new MySqlCommand("SELECT id FROM my_aspnet_Users WHERE
name LIKE @name", connection);
+            MySqlCommand cmd = new MySqlCommand(
+                "SELECT id FROM my_aspnet_Users WHERE name LIKE @name", connection);
+            cmd.Parameters.AddWithValue("@name", username);
             object id = cmd.ExecuteScalar();
             if (id == null) return -1;
             return (int)id;
@@ -1152,36 +1149,34 @@
 
         private MembershipUser GetUserFromReader(MySqlDataReader reader)
         {
-            object providerUserKey = reader.GetValue(0);
-            string username = reader.GetString(1);
+            object providerUserKey = reader.GetInt32("userId");
+            string username = reader.GetString("name");
 
             string email = null;
-            if (!reader.IsDBNull(2))
-                email = reader.GetString(2);
+            if (!reader.IsDBNull(reader.GetOrdinal("email")))
+                email = reader.GetString("email");
 
             string passwordQuestion = "";
-            if (!(reader.GetValue(3) == DBNull.Value))
-                passwordQuestion = reader.GetString(3);
+            if (!(reader.GetValue(reader.GetOrdinal("passwordQuestion")) ==
DBNull.Value))
+                passwordQuestion = reader.GetString("passwordQuestion");
 
             string comment = "";
-            if (!(reader.GetValue(4) == DBNull.Value))
-                comment = reader.GetString(4);
+            if (!(reader.GetValue(reader.GetOrdinal("comment")) == DBNull.Value))
+                comment = reader.GetString("comment");
 
-            bool isApproved = reader.GetBoolean(5);
-            bool isLockedOut = reader.GetBoolean(6);
-            DateTime creationDate = reader.GetDateTime(7);
+            bool isApproved = reader.GetBoolean("isApproved");
+            bool isLockedOut = reader.GetBoolean("isLockedOut");
+            DateTime creationDate = reader.GetDateTime("creationDate");
             DateTime lastLoginDate = new DateTime();
-            if (!(reader.GetValue(8) == DBNull.Value))
-            {
-                lastLoginDate = reader.GetDateTime(8);
-            }
-            DateTime lastActivityDate = reader.GetDateTime(9);
-            DateTime lastPasswordChangedDate = reader.GetDateTime(10);
+            if (!(reader.GetValue(reader.GetOrdinal("lastLoginDate")) == DBNull.Value))
+                lastLoginDate = reader.GetDateTime("lastLoginDate");
+
+            DateTime lastActivityDate = reader.GetDateTime("lastActivityDate");
+            DateTime lastPasswordChangedDate =
reader.GetDateTime("lastPasswordChangedDate");
             DateTime lastLockedOutDate = new DateTime();
-            if (!(reader.GetValue(11) == DBNull.Value))
-            {
-                lastLockedOutDate = reader.GetDateTime(11);
-            }
+            if (!(reader.GetValue(reader.GetOrdinal("lastLockedoutDate")) ==
DBNull.Value))
+                lastLockedOutDate = reader.GetDateTime("lastLockedoutDate");
+
             MembershipUser u =
                 new MembershipUser(Name, username, providerUserKey, email,
passwordQuestion, comment, isApproved,
                                    isLockedOut, creationDate, lastLoginDate,
lastActivityDate, lastPasswordChangedDate,
@@ -1242,27 +1237,24 @@
             }
         }
 
-        private void UpdateFailureCount(string username, string failureType)
+        private void UpdateFailureCount(int userId, string failureType, MySqlConnection
connection)
         {
-            MySqlConnection conn = new MySqlConnection(connectionString);
-            MySqlCommand cmd =
-                new MySqlCommand(
-                    @"SELECT FailedPasswordAttemptCount, 
+            MySqlCommand cmd = new MySqlCommand(
+                @"SELECT FailedPasswordAttemptCount, 
                 FailedPasswordAttemptWindowStart, FailedPasswordAnswerAttemptCount, 
-                FailedPasswordAnswerAttemptWindowStart FROM mysql_Membership 
-                WHERE Username = ?Username AND ApplicationName = ?ApplicationName",
-                    conn);
-            cmd.Parameters.Add("?Username", MySqlDbType.VarChar, 255).Value = username;
-            cmd.Parameters.Add("?ApplicationName", MySqlDbType.VarChar, 255).Value =
applicationName;
-            MySqlDataReader reader = null;
+                FailedPasswordAnswerAttemptWindowStart FROM my_aspnet_Membership 
+                WHERE userId=@userId", connection);
+            cmd.Parameters.AddWithValue("@userId", userId);
+
             DateTime windowStart = new DateTime();
             int failureCount = 0;
             try
             {
-                conn.Open();
-                reader = cmd.ExecuteReader(CommandBehavior.SingleRow);
-                if (reader.HasRows)
+                using (MySqlDataReader reader =
cmd.ExecuteReader(CommandBehavior.SingleRow))
                 {
+                    if (!reader.HasRows)
+                        throw new ProviderException("Unable to update failure count. 
Membership database may be corrupt.");
+
                     reader.Read();
                     if (failureType == "password")
                     {
@@ -1275,35 +1267,32 @@
                         windowStart = reader.GetDateTime(3);
                     }
                 }
-                reader.Close();
+
                 DateTime windowEnd = windowStart.AddMinutes(PasswordAttemptWindow);
                 if (failureCount == 0 || DateTime.Now > windowEnd)
                 {
                     if (failureType == "password")
                     {
                         cmd.CommandText =
-                            @"UPDATE mysql_Membership 
-                            SET FailedPasswordAttemptCount = ?Count, 
-                            FailedPasswordAttemptWindowStart = ?WindowStart 
-                            WHERE Username = ?Username AND ApplicationName =
?ApplicationName";
+                            @"UPDATE my_aspnet_Membership 
+                            SET FailedPasswordAttemptCount = @count, 
+                            FailedPasswordAttemptWindowStart = @windowStart 
+                            WHERE userId=@userId";
                     }
                     if (failureType == "passwordAnswer")
                     {
                         cmd.CommandText =
-                            @"UPDATE mysql_Membership 
-                            SET FailedPasswordAnswerAttemptCount = ?Count, 
-                            FailedPasswordAnswerAttemptWindowStart = ?WindowStart 
-                            WHERE Username = ?Username AND ApplicationName =
?ApplicationName";
+                            @"UPDATE my_aspnet_Membership 
+                            SET FailedPasswordAnswerAttemptCount = @count, 
+                            FailedPasswordAnswerAttemptWindowStart = @windowStart 
+                            WHERE userId = @userId";
                     }
                     cmd.Parameters.Clear();
-                    cmd.Parameters.Add("?Count", MySqlDbType.Int32).Value = 1;
-                    cmd.Parameters.Add("?WindowStart", MySqlDbType.DateTime).Value =
DateTime.Now;
-                    cmd.Parameters.Add("?Username", MySqlDbType.VarChar, 255).Value =
username;
-                    cmd.Parameters.Add("?ApplicationName", MySqlDbType.VarChar,
255).Value = applicationName;
+                    cmd.Parameters.AddWithValue("@count", 1);
+                    cmd.Parameters.AddWithValue("@windowStart", DateTime.Now);
+                    cmd.Parameters.AddWithValue("@userId", userId);
                     if (cmd.ExecuteNonQuery() < 0)
-                    {
                         throw new ProviderException("Unable to update failure count and
window start.");
-                    }
                 }
                 else
                 {
@@ -1311,66 +1300,44 @@
                     if (failureCount >= MaxInvalidPasswordAttempts)
                     {
                         cmd.CommandText =
-                            @"UPDATE mysql_Membership SET IsLockedOut = ?IsLockedOut, 
-                            LastLockedOutDate = ?LastLockedOutDate WHERE Username =
?Username AND 
-                            ApplicationName = ?ApplicationName";
+                            @"UPDATE my_aspnet_Membership SET IsLockedOut = @isLockedOut,

+                            LastLockedOutDate = @lastLockedOutDate WHERE userId=@userId";
                         cmd.Parameters.Clear();
-                        cmd.Parameters.Add("?IsLockedOut", MySqlDbType.Bit).Value = true;
-                        cmd.Parameters.Add("?LastLockedOutDate",
MySqlDbType.DateTime).Value = DateTime.Now;
-                        cmd.Parameters.Add("?Username", MySqlDbType.VarChar, 255).Value =
username;
-                        cmd.Parameters.Add("?ApplicationName", MySqlDbType.VarChar,
255).Value = applicationName;
+                        cmd.Parameters.AddWithValue("@isLockedOut", true);
+                        cmd.Parameters.AddWithValue("@lastLockedOutDate", DateTime.Now);
+                        cmd.Parameters.AddWithValue("@userId", userId);
                         if (cmd.ExecuteNonQuery() < 0)
-                        {
                             throw new ProviderException("Unable to lock out user.");
-                        }
                     }
                     else
                     {
                         if (failureType == "password")
                         {
                             cmd.CommandText =
-                                @"UPDATE mysql_Membership 
-                                SET FailedPasswordAttemptCount = ?Count WHERE Username =
?Username 
-                                AND ApplicationName = ?ApplicationName";
+                                @"UPDATE my_aspnet_Membership 
+                                SET FailedPasswordAttemptCount = @count WHERE
userId=@userId";
                         }
                         if (failureType == "passwordAnswer")
                         {
                             cmd.CommandText =
-                                @"UPDATE mysql_Membership 
-                                SET FailedPasswordAnswerAttemptCount = ?Count 
-                                WHERE Username = ?Username AND ApplicationName =
?ApplicationName";
+                                @"UPDATE my_aspnet_Membership 
+                                SET FailedPasswordAnswerAttemptCount = @count 
+                                WHERE userId=@userId";
                         }
                         cmd.Parameters.Clear();
-                        cmd.Parameters.Add("?Count", MySqlDbType.Int32).Value =
failureCount;
-                        cmd.Parameters.Add("?Username", MySqlDbType.VarChar, 255).Value =
username;
-                        cmd.Parameters.Add("?ApplicationName", MySqlDbType.VarChar,
255).Value = applicationName;
+                        cmd.Parameters.AddWithValue("@count", failureCount);
+                        cmd.Parameters.AddWithValue("@userId", userId);
                         if (cmd.ExecuteNonQuery() < 0)
-                        {
                             throw new ProviderException("Unable to update failure
count.");
-                        }
                     }
                 }
             }
             catch (MySqlException e)
             {
                 if (WriteExceptionsToEventLog)
-                {
                     WriteToEventLog(e, "UpdateFailureCount");
-                    throw new ProviderException(exceptionMessage);
-                }
-                else
-                {
-                    throw;
-                }
+                throw new ProviderException(exceptionMessage, e);
             }
-            finally
-            {
-                if (!(reader == null))
-                {
-                    reader.Close();
-                }
-                conn.Close();
-            }
         }
 
         private bool CheckPassword(string password, string dbpassword,
@@ -1380,14 +1347,13 @@
             return password == dbpassword;
         }
 
-        private void GetPasswordInfo(MySqlConnection connection, string username,
+        private void GetPasswordInfo(MySqlConnection connection, int userId,
             out string passwordKey, out MembershipPasswordFormat passwordFormat)
         {
             MySqlCommand cmd = new MySqlCommand(
-                @"SELECT PasswordKey, PasswordFormat FROM mysql_Membership WHERE
-                  Username = ?Username AND ApplicationName = ?ApplicationName",
connection);
-            cmd.Parameters.AddWithValue("?Username", username);
-            cmd.Parameters.AddWithValue("?ApplicationName", applicationName);
+                @"SELECT PasswordKey, PasswordFormat FROM my_aspnet_Membership WHERE
+                  userId=@userId", connection);
+            cmd.Parameters.AddWithValue("@userId", userId);
             using (MySqlDataReader reader = cmd.ExecuteReader())
             {
                 reader.Read();
@@ -1403,13 +1369,14 @@
             MembershipUserCollection users = new MembershipUserCollection();
             try
             {
-                using (MySqlConnection conn = new MySqlConnection(connectionString))
+                using (MySqlConnection connection = new
MySqlConnection(connectionString))
                 {
+                    connection.Open();
                     MySqlCommand cmd = new MySqlCommand();
-                    cmd.Connection = conn;
+                    cmd.Connection = connection;
 
-                    string sql = @"SELECT u.*,m.* FROM my_aspnet_Users u
-                        JOIN my_aspnet_Membership m ON m.usrId=u.id 
+                    string sql = @"SELECT SQL_CALC_FOUND_ROWS u.name,m.* FROM
my_aspnet_Users u
+                        JOIN my_aspnet_Membership m ON m.userId=u.id 
                         WHERE u.applicationId=@appId";
 
                     if (username != null)
@@ -1422,8 +1389,9 @@
                         sql += " AND m.email LIKE @email";
                         cmd.Parameters.AddWithValue("@email", email);
                     }
-                    sql += "ORDER BY u.id ASC LIMIT {0},{1}";
+                    sql += " ORDER BY u.id ASC LIMIT {0},{1}";
                     cmd.CommandText = String.Format(sql, pageIndex * pageSize, pageSize);
+                    cmd.Parameters.AddWithValue("@appId", applicationId);
                     using (MySqlDataReader reader = cmd.ExecuteReader())
                     {
                         while (reader.Read())
@@ -1443,6 +1411,23 @@
             }
         }
 
+        private int CreateOrFetchUserId(string username, bool p, MySqlConnection
connection)
+        {
+            MySqlCommand cmd = new MySqlCommand("SELECT id FROM my_aspnet_Users WHERE
name=@name", connection);
+            cmd.Parameters.AddWithValue("@name", username);
+            object id = cmd.ExecuteScalar();
+            if (id == null)
+            {
+                cmd.CommandText = "INSERT INTO my_aspnet_Users VALUES (NULL, @appId,
@name, 0, NOW())";
+                cmd.Parameters.AddWithValue("@appId", applicationId);
+                cmd.ExecuteNonQuery();
+
+                cmd.CommandText = "SELECT LAST_INSERT_ID()";
+            }
+            id = cmd.ExecuteScalar();
+            return Convert.ToInt32(id);
+        }
+
         #endregion
     }
 }
\ No newline at end of file

Modified: trunk/MySql.Web/Providers/Source/ProfileProvider.cs
===================================================================
--- trunk/MySql.Web/Providers/Source/ProfileProvider.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Providers/Source/ProfileProvider.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -35,10 +35,16 @@
 using System.Data;
 using System.IO;
 using System.Globalization;
+using System.Transactions;
+using System.Web.Security;
+using MySql.Web.Common;
 
-namespace MySql.Web.Security
+namespace MySql.Web.Profile
 {
-    class MySQLProfileProvider : ProfileProvider
+    /// <summary>
+    /// 
+    /// </summary>
+    public class MySQLProfileProvider : ProfileProvider
     {
         private string applicationName;
         private string connectionString;
@@ -46,8 +52,17 @@
 
         #region Abstract Members
 
+        /// <summary>
+        /// Initializes the provider.
+        /// </summary>
+        /// <param name="name">The friendly name of the provider.</param>
+        /// <param name="config">A collection of the name/value pairs representing
the provider-specific attributes specified in the configuration for this
provider.</param>
+        /// <exception cref="T:System.ArgumentNullException">The name of the
provider is null.</exception>
+        /// <exception cref="T:System.ArgumentException">The name of the provider
has a length of zero.</exception>
+        /// <exception cref="T:System.InvalidOperationException">An attempt is made
to call <see
cref="M:System.Configuration.Provider.ProviderBase.Initialize(System.String,System.Collections.Specialized.NameValueCollection)"/>
on a provider after the provider has already been initialized.</exception>
         public override void Initialize(string name, NameValueCollection config)
         {
+            applicationId = -1;
             if (config == null)
                 throw new ArgumentNullException("config");
 
@@ -78,8 +93,12 @@
                 // now pre-cache the applicationId
                 using (MySqlConnection conn = new MySqlConnection(connectionString))
                 {
+                    conn.Open();
                     MySqlCommand cmd = new MySqlCommand("SELECT id FROM
my_aspnet_Applications WHERE name=@name", conn);
-                    applicationId = (int)cmd.ExecuteScalar();
+                    cmd.Parameters.AddWithValue("@name", applicationName);
+                    object appIdValue = cmd.ExecuteScalar();
+                    if (appIdValue != null)
+                        applicationId = Convert.ToInt32(appIdValue);
                 }
             }
             catch (Exception ex)
@@ -397,7 +416,7 @@
             {
                 MySqlConnection c = new MySqlConnection(connectionString);
                 MySqlCommand cmd = new MySqlCommand(@"SELECT * FROM my_aspnet_Profiles p
-                JOIN my_aspnet_Users u ON u.userId = p.userId
+                JOIN my_aspnet_Users u ON u.id = p.userId
                 WHERE u.applicationId = @appId AND u.name = @name", c);
                 cmd.Parameters.AddWithValue("@appId", applicationId);
                 cmd.Parameters.AddWithValue("@name", username);
@@ -405,7 +424,8 @@
                 DataTable dt = new DataTable();
                 da.Fill(dt);
 
-                DecodeProfileData(dt.Rows[0], values);
+                if (dt.Rows.Count > 0)
+                    DecodeProfileData(dt.Rows[0], values);
                 return values;
             }
             catch (Exception ex)
@@ -432,23 +452,29 @@
             // save the encoded profile data to the database
             try
             {
-                MySqlConnection c = new MySqlConnection(connectionString);
-                MySqlCommand cmd = new MySqlCommand(@"SELECT id FROM my_aspnet_Users
-                WHERE applicationId = @appId AND name = @name", c);
-                cmd.Parameters.AddWithValue("@appId", applicationId);
-                cmd.Parameters.AddWithValue("@name", username);
-                int userId = (int)cmd.ExecuteScalar();
+                using (TransactionScope ts = new TransactionScope())
+                {
+                    using (MySqlConnection connection = new
MySqlConnection(connectionString))
+                    {
+                        connection.Open();
+                        int userId = CreateOrFetchUserId(connection, username,
isAuthenticated);
 
-                cmd.CommandText = @"INSERT INTO my_aspnet_Profiles (userId, index,
stringData, binaryData) 
-                    VALUES (@userId, @index, @stringData, @binaryData) ON DUPLICATE KEY
UPDATE";
-                cmd.Parameters.Clear();
-                cmd.Parameters.AddWithValue("@userId", userId);
-                cmd.Parameters.AddWithValue("@index", index);
-                cmd.Parameters.AddWithValue("@stringData", stringData);
-                cmd.Parameters.AddWithValue("@binaryData", binaryData);
-                count = cmd.ExecuteNonQuery();
-                if (count != 1)
-                    throw new Exception("Profile update operation affected zero rows.");
+                        MySqlCommand cmd = new MySqlCommand(
+                            @"INSERT INTO my_aspnet_Profiles  
+                            VALUES (@userId, @index, @stringData, @binaryData, NULL) ON
DUPLICATE KEY UPDATE
+                            valueindex=VALUES(valueindex), stringdata=VALUES(stringdata),
+                            binarydata=VALUES(binarydata)", connection);
+                        cmd.Parameters.Clear();
+                        cmd.Parameters.AddWithValue("@userId", userId);
+                        cmd.Parameters.AddWithValue("@index", index);
+                        cmd.Parameters.AddWithValue("@stringData", stringData);
+                        cmd.Parameters.AddWithValue("@binaryData", binaryData);
+                        count = cmd.ExecuteNonQuery();
+                        if (count != 1)
+                            throw new Exception("Profile update operation affected zero
rows.");
+                        ts.Complete();
+                    }
+                }
             }
             catch (Exception ex)
             {
@@ -460,15 +486,67 @@
 
         internal static void DeleteUserData(MySqlConnection connection, int userId)
         {
-            MySqlCommand cmd = new MySqlCommand("DELETE FROM my_aspnet_Profiles WHERE
userId=@userId", connection);
+            MySqlCommand cmd = new MySqlCommand(
+                "DELETE FROM my_aspnet_Profiles WHERE userId=@userId", connection);
+            cmd.Parameters.AddWithValue("@userId", userId);
             cmd.ExecuteNonQuery();
         }
 
         #region Private Methods
 
+        /// <summary>
+        /// It is assumed that this method is called from within a transaction or
+        /// a transactionscope
+        /// </summary>
+        /// <param name="connection"></param>
+        /// <param name="username"></param>
+        /// <param name="authenticated"></param>
+        /// <returns></returns>
+        private int CreateOrFetchUserId(MySqlConnection connection, string username, bool
authenticated)
+        {
+            // first attempt to fetch an existing user id
+            MySqlCommand cmd = new MySqlCommand(@"SELECT id FROM my_aspnet_Users
+                WHERE applicationId = @appId AND name = @name", connection);
+            cmd.Parameters.AddWithValue("@appId", applicationId);
+            cmd.Parameters.AddWithValue("@name", username);
+            object userId = cmd.ExecuteScalar();
+            if (userId != null) return (int)userId;
+
+            // the user doesn't exist so we have to create one
+            int appId = CreateOrFetchApplicationId(connection);
+
+            cmd.CommandText = @"INSERT INTO my_aspnet_Users VALUES (NULL, @appId, @name,
@isAnon, Now())";
+            cmd.Parameters[0].Value = appId;
+            cmd.Parameters.AddWithValue("@isAnon", !authenticated);
+            int recordsAffected = cmd.ExecuteNonQuery();
+            if (recordsAffected != 1)
+                throw new ProviderException("Unable to create use for profile.");
+
+            cmd.CommandText = "SELECT LAST_INSERT_ID()";
+            return Convert.ToInt32(cmd.ExecuteScalar());
+        }
+
+        private int CreateOrFetchApplicationId(MySqlConnection connection)
+        {
+            if (applicationId != -1)
+                return applicationId;
+            MySqlCommand cmd = new MySqlCommand(
+                @"INSERT INTO my_aspnet_Applications VALUES (NULL, @appName, @appDesc)",
+                connection);
+            cmd.Parameters.AddWithValue("@appName", applicationName);
+            cmd.Parameters.AddWithValue("@appDesc", base.Description);
+            int recordsAffected = cmd.ExecuteNonQuery();
+            if (recordsAffected != 1)
+                throw new ProviderException("Unable to create application for profile.");
+
+            cmd.CommandText = "SELECT LAST_INSERT_ID()";
+            applicationId = Convert.ToInt32(cmd.ExecuteScalar());
+            return applicationId;
+        }
+
         private void DecodeProfileData(DataRow profileRow,
SettingsPropertyValueCollection values)
         {
-            string indexData = (string)profileRow["index"];
+            string indexData = (string)profileRow["valueindex"];
             string stringData = (string)profileRow["stringData"];
             byte[] binaryData = (byte[])profileRow["binaryData"];
 
@@ -536,18 +614,19 @@
                     !isAuthenticated) continue;
 
                 count++;
+                object propValue = value.SerializedValue;
                 if ((value.Deserialized && value.PropertyValue == null) ||
                     value.SerializedValue == null)
                     indexBuilder.AppendFormat("{0}//0/-1:", value.Name);
-                else if (value.PropertyValue is string)
+                else if (propValue is string)
                 {
                     indexBuilder.AppendFormat("{0}/0/{1}/{2}:", value.Name,
-                        stringDataBuilder.Length, (value.PropertyValue as
string).Length);
-                    stringDataBuilder.Append(value.PropertyValue);
+                        stringDataBuilder.Length, (propValue as string).Length);
+                    stringDataBuilder.Append(propValue);
                 }
                 else
                 {
-                    byte[] binaryValue = (byte[])value.PropertyValue;
+                    byte[] binaryValue = (byte[])propValue;
                     indexBuilder.AppendFormat("{0}/1/{1}/{2}:", value.Name,
                         binaryBuilder.Position, binaryValue.Length);
                     binaryBuilder.Write(binaryValue, 0, binaryValue.Length);

Modified: trunk/MySql.Web/Providers/Source/RoleProvider.cs
===================================================================
--- trunk/MySql.Web/Providers/Source/RoleProvider.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Providers/Source/RoleProvider.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -32,6 +32,7 @@
 using MySql.Data.MySqlClient;
 using System.Transactions;
 using System.Collections.Generic;
+using MySql.Web.Common;
 
 namespace MySql.Web.Security
 {
@@ -507,7 +508,9 @@
 
         internal static void DeleteUserData(MySqlConnection connection, int userId)
         {
-            MySqlCommand cmd = new MySqlCommand("DELETE FROM my_aspnet_UsersInRoles WHERE
userId=@userId", connection);
+            MySqlCommand cmd = new MySqlCommand(
+                "DELETE FROM my_aspnet_UsersInRoles WHERE userId=@userId", connection);
+            cmd.Parameters.AddWithValue("@userId", userId);
             cmd.ExecuteNonQuery();
         }
 

Modified: trunk/MySql.Web/Providers/Source/SchemaManager.cs
===================================================================
--- trunk/MySql.Web/Providers/Source/SchemaManager.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Providers/Source/SchemaManager.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -30,7 +30,7 @@
 using System.Resources;
 using System.IO;
 
-namespace MySql.Web.Security
+namespace MySql.Web.Common
 {
     /// <summary>
     /// 
@@ -50,21 +50,42 @@
 
         internal static void CheckSchema(string connectionString, NameValueCollection
config)
         {
-            // make sure the user doesn't use autogenerateschema any longer
-            foreach (string key in config.AllKeys)
-                if (key.ToLowerInvariant() == "autogenerateschema")
-                    throw new ProviderException(
-                        "AutoGenerateSchema is not a valid configuration option.");
-
             try
             {
                 int ver = GetSchemaVersion(connectionString);
                 if (ver == Version) return;
+
+                if (config["autogenerateschema"] == "true")
+                    UpgradeToCurrent(connectionString, ver);
+                else
+                    throw new ProviderException("Unable to initialize provider.  Missing
or incorrect schema.");
+
             }
-            catch (Exception) { }
+            catch (Exception ex)
+            {
+                throw new ProviderException("Error during provider initialization.", ex);
+            }
+        }
 
-            throw new ProviderException(
-                "Unable to initialize provider.  Possibly missing or incorrect schema
version.");
+        private static void UpgradeToCurrent(string connectionString, int version)
+        {
+            ResourceManager r = new ResourceManager("MySql.Web.Properties.Resources", 
+                typeof(SchemaManager).Assembly);
+
+            if (version == Version) return;
+
+            using (MySqlConnection connection = new MySqlConnection(connectionString))
+            {
+                connection.Open();
+
+                for (int ver = version + 1; ver <= Version; ver++)
+                {
+                    string schema = r.GetString(String.Format("schema{0}", ver));
+                    MySqlScript script = new MySqlScript(connection);
+                    script.Query = schema;
+                    script.Execute();
+                }
+            }
         }
 
         private static int GetSchemaVersion(string connectionString)
@@ -80,10 +101,14 @@
                 if (dt.Rows.Count == 1)
                     return Convert.ToInt32(dt.Rows[0]["TABLE_COMMENT"]);
 
+                restrictions[2] = "my_aspnet_schemaversion";
+                dt = conn.GetSchema("Tables", restrictions);
+                if (dt.Rows.Count == 0) return 0;
+
                 MySqlCommand cmd = new MySqlCommand("SELECT * FROM
my_aspnet_SchemaVersion", conn);
                 object ver = cmd.ExecuteScalar();
                 if (ver == null)
-                    return 0;
+                    throw new ProviderException("Schema corrupt");
                 return (int)ver;
             }
         }

Added: trunk/MySql.Web/Tests/App.config
===================================================================
--- trunk/MySql.Web/Tests/App.config	                        (rev 0)
+++ trunk/MySql.Web/Tests/App.config	2008-01-31 21:30:36 UTC (rev 1156)
@@ -0,0 +1,21 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<configuration>
+  <system.web>
+    <profile defaultProvider="MySqlProfileProvider">
+      <providers>
+        <clear/>
+        <add name="MySqlProfileProvider" connectionStringName="LocalMySqlServer" 
+             applicationName="/" type="MySql.Web.Profile.MySQLProfileProvider, mysql.web,
Version=5.2.0.0, Culture=neutral, PublicKeyToken=c5687fc88969c44d"/>
+      </providers>
+      <properties>
+        <add name="Name"/>
+        <add name="FavoriteColors"
type="System.Collections.Specialized.StringCollection, system, Version=2.0.0.0,
Culture=neutral, PublicKeyToken=b77a5c561934e089" serializeAs ="Xml"/>
+        <add name="Weight" type="System.Int32"/>
+				<add name="BirthDate" type="System.DateTime"/>
+        <add name="HasDefault" type="System.String" defaultValue="mydefault"/>
+        <add name="ReadOnly" type="System.Int32" readOnly ="true"/>
+        <!--<add name="StudentInfo" type="StudentInfo"
serializeAs="Binary"/>-->
+      </properties>
+    </profile>
+  </system.web>
+</configuration>

Modified: trunk/MySql.Web/Tests/BaseTest.cs
===================================================================
--- trunk/MySql.Web/Tests/BaseTest.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Tests/BaseTest.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -32,8 +32,11 @@
 using System.Collections.Specialized;
 using System.Diagnostics;
 using MySql.Data.MySqlClient.Tests;
+using System.Resources;
+using MySql.Web.Common;
+using MySql.Web.Security;
 
-namespace MySql.Web.Security.Tests
+namespace MySql.Web.Tests
 {
     public class BaseWebTest : BaseTest
     {
@@ -78,6 +81,32 @@
         public override void FixtureSetup()
         {
             base.FixtureSetup();
+            for (int ver = 1; ver <= SchemaManager.Version; ver++)
+                LoadSchema(ver);
         }
+
+        public override void Setup()
+        {
+           base.Setup();
+           execSQL("TRUNCATE TABLE my_aspnet_Applications");
+           execSQL("TRUNCATE TABLE my_aspnet_Membership");
+           execSQL("TRUNCATE TABLE my_aspnet_Profiles");
+           execSQL("TRUNCATE TABLE my_aspnet_Roles");
+           execSQL("TRUNCATE TABLE my_aspnet_Users");
+           execSQL("TRUNCATE TABLE my_aspnet_UsersInRoles");
+       }
+
+        protected void LoadSchema(int version)
+        {
+            if (version < 1) return;
+
+            MySQLMembershipProvider provider = new MySQLMembershipProvider();
+
+            ResourceManager r = new ResourceManager("MySql.Web.Properties.Resources",
typeof(MySQLMembershipProvider).Assembly);
+            string schema = r.GetString(String.Format("schema{0}", version));
+            MySqlScript script = new MySqlScript(conn);
+            script.Query = schema;
+            script.Execute();
+        }
     }
 }

Modified: trunk/MySql.Web/Tests/MySql.Web.Tests.csproj
===================================================================
--- trunk/MySql.Web/Tests/MySql.Web.Tests.csproj	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Tests/MySql.Web.Tests.csproj	2008-01-31 21:30:36 UTC (rev 1156)
@@ -42,9 +42,11 @@
   </ItemGroup>
   <ItemGroup>
     <Compile Include="BaseTest.cs" />
+    <Compile Include="ProfileTests.cs" />
     <Compile Include="RoleManagement.cs" />
     <Compile Include="SchemaTests.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
+    <Compile Include="TestProfile.cs" />
     <Compile Include="UserManagement.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -61,6 +63,9 @@
       <Name>MySql.Web</Name>
     </ProjectReference>
   </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config" />
+  </ItemGroup>
   <Import Project="$(MSBuildBinPath)\Microsoft.CSharp.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and
uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.

Added: trunk/MySql.Web/Tests/ProfileTests.cs
===================================================================
--- trunk/MySql.Web/Tests/ProfileTests.cs	                        (rev 0)
+++ trunk/MySql.Web/Tests/ProfileTests.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -0,0 +1,201 @@
+// Copyright (C) 2007 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL 
+// as it is applied to this software. View the full text of the 
+// exception in file EXCEPTIONS in the directory of this software 
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+
+//  This code was contributed by Sean Wright (srwright@stripped) on 2007-01-12
+//  The copyright was assigned and transferred under the terms of
+//  the MySQL Contributor License Agreement (CLA)
+
+using NUnit.Framework;
+using System.Web.Security;
+using System.Collections.Specialized;
+using System.Data;
+using System;
+using System.Configuration.Provider;
+using System.Configuration;
+using MySql.Web.Profile;
+using System.Web.Profile;
+
+namespace MySql.Web.Tests
+{
+    [TestFixture]
+    public class ProfileTests : BaseWebTest
+    {
+        private MySQLProfileProvider InitProfileProvider()
+        {
+            MySQLProfileProvider p = new MySQLProfileProvider();
+            NameValueCollection config = new NameValueCollection();
+            config.Add("connectionStringName", "LocalMySqlServer");
+            config.Add("applicationName", "/");
+            p.Initialize(null, config);
+            return p;
+        }
+
+        [Test]
+        public void SettingValuesCreatesAnAppAndUserId()
+        {
+            // make sure there are no apps currently
+            DataTable dt = FillTable("SELECT * FROM my_aspnet_applications");
+            Assert.AreEqual(0, dt.Rows.Count);
+
+            MySQLProfileProvider provider = InitProfileProvider();
+            SettingsContext ctx = new SettingsContext();
+            ctx.Add("IsAuthenticated", false);
+            ctx.Add("UserName", "user1");
+
+            SettingsPropertyValueCollection values = new
SettingsPropertyValueCollection();
+            SettingsProperty property1 = new SettingsProperty("color");
+            property1.PropertyType = typeof(string);
+            property1.Attributes["AllowAnonymous"] = true;
+            SettingsPropertyValue value = new SettingsPropertyValue(property1);
+            value.PropertyValue = "blue";
+            values.Add(value);
+
+            provider.SetPropertyValues(ctx, values);
+
+            dt = FillTable("SELECT * FROM my_aspnet_applications");
+            Assert.AreEqual(1, dt.Rows.Count);
+            dt = FillTable("SELECT * FROM my_aspnet_users");
+            Assert.AreEqual(1, dt.Rows.Count);
+            dt = FillTable("SELECT * FROM my_aspnet_profiles");
+            Assert.AreEqual(1, dt.Rows.Count);
+        }
+
+        [Test]
+        public void AnonymousUserSettingNonAnonymousProperties()
+        {
+            // make sure there are no apps currently
+            DataTable dt = FillTable("SELECT * FROM my_aspnet_applications");
+            Assert.AreEqual(0, dt.Rows.Count);
+
+            MySQLProfileProvider provider = InitProfileProvider();
+            SettingsContext ctx = new SettingsContext();
+            ctx.Add("IsAuthenticated", false);
+            ctx.Add("UserName", "user1");
+
+            SettingsPropertyValueCollection values = new
SettingsPropertyValueCollection();
+            SettingsProperty property1 = new SettingsProperty("color");
+            property1.PropertyType = typeof(string);
+            property1.Attributes["AllowAnonymous"] = false;
+            SettingsPropertyValue value = new SettingsPropertyValue(property1);
+            value.PropertyValue = "blue";
+            values.Add(value);
+
+            provider.SetPropertyValues(ctx, values);
+
+            dt = FillTable("SELECT * FROM my_aspnet_applications");
+            Assert.AreEqual(0, dt.Rows.Count);
+            dt = FillTable("SELECT * FROM my_aspnet_users");
+            Assert.AreEqual(0, dt.Rows.Count);
+            dt = FillTable("SELECT * FROM my_aspnet_profiles");
+            Assert.AreEqual(0, dt.Rows.Count);
+        }
+
+        [Test]
+        public void StringCollectionAsProperty()
+        {
+            // make sure there are no apps currently
+            DataTable dt = FillTable("SELECT * FROM my_aspnet_applications");
+            Assert.AreEqual(0, dt.Rows.Count);
+
+            ProfileBase profile = ProfileBase.Create("foo", true);
+            StringCollection colors = new StringCollection();
+            colors.Add("red");
+            colors.Add("green");
+            colors.Add("blue");
+            profile["FavoriteColors"] = colors;
+            profile.Save();
+
+            dt = FillTable("SELECT * FROM my_aspnet_applications");
+            Assert.AreEqual(1, dt.Rows.Count);
+            dt = FillTable("SELECT * FROM my_aspnet_users");
+            Assert.AreEqual(1, dt.Rows.Count);
+            dt = FillTable("SELECT * FROM my_aspnet_profiles");
+            Assert.AreEqual(1, dt.Rows.Count);
+
+            // now retrieve them
+            SettingsPropertyCollection getProps = new SettingsPropertyCollection();
+            SettingsProperty getProp1 = new SettingsProperty("FavoriteColors");
+            getProp1.PropertyType = typeof(StringCollection);
+            getProp1.SerializeAs = SettingsSerializeAs.Xml;
+            getProps.Add(getProp1);
+
+            MySQLProfileProvider provider = InitProfileProvider();
+            SettingsContext ctx = new SettingsContext();
+            ctx.Add("IsAuthenticated", true);
+            ctx.Add("UserName", "foo");
+            SettingsPropertyValueCollection getValues = provider.GetPropertyValues(ctx,
getProps);
+            Assert.AreEqual(1, getValues.Count);
+            SettingsPropertyValue getValue1 = getValues["FavoriteColors"];
+            StringCollection outValue = (StringCollection)getValue1.PropertyValue;
+            Assert.AreEqual(3, outValue.Count);
+            Assert.AreEqual("red", outValue[0]);
+            Assert.AreEqual("green", outValue[1]);
+            Assert.AreEqual("blue", outValue[2]);
+        }
+
+        [Test]
+        public void AuthenticatedDateTime()
+        {
+            ProfileBase profile = ProfileBase.Create("foo", true);
+            DateTime date = DateTime.Now;
+            profile["BirthDate"] = date;
+            profile.Save();
+
+            SettingsPropertyCollection getProps = new SettingsPropertyCollection();
+            SettingsProperty getProp1 = new SettingsProperty("BirthDate");
+            getProp1.PropertyType = typeof(DateTime);
+            getProp1.SerializeAs = SettingsSerializeAs.Xml;
+            getProps.Add(getProp1);
+
+            MySQLProfileProvider provider = InitProfileProvider();
+            SettingsContext ctx = new SettingsContext();
+            ctx.Add("IsAuthenticated", true);
+            ctx.Add("UserName", "foo");
+
+            SettingsPropertyValueCollection getValues = provider.GetPropertyValues(ctx,
getProps);
+            Assert.AreEqual(1, getValues.Count);
+            SettingsPropertyValue getValue1 = getValues["BirthDate"];
+            Assert.AreEqual(date, getValue1.PropertyValue);
+        }
+
+        [Test]
+        public void AuthenticatedStringProperty()
+        {
+            ProfileBase profile = ProfileBase.Create("foo", true);
+            profile["Name"] = "Fred Flintstone";
+            profile.Save();
+
+            SettingsPropertyCollection getProps = new SettingsPropertyCollection();
+            SettingsProperty getProp1 = new SettingsProperty("Name");
+            getProp1.PropertyType = typeof(String);
+            getProps.Add(getProp1);
+
+            MySQLProfileProvider provider = InitProfileProvider();
+            SettingsContext ctx = new SettingsContext();
+            ctx.Add("IsAuthenticated", true);
+            ctx.Add("UserName", "foo");
+
+            SettingsPropertyValueCollection getValues = provider.GetPropertyValues(ctx,
getProps);
+            Assert.AreEqual(1, getValues.Count);
+            SettingsPropertyValue getValue1 = getValues["Name"];
+            Assert.AreEqual("Fred Flintstone", getValue1.PropertyValue);
+        }
+    }
+}

Modified: trunk/MySql.Web/Tests/RoleManagement.cs
===================================================================
--- trunk/MySql.Web/Tests/RoleManagement.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Tests/RoleManagement.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -28,8 +28,9 @@
 using System.Data;
 using System;
 using System.Configuration.Provider;
+using MySql.Web.Security;
 
-namespace MySql.Web.Security.Tests
+namespace MySql.Web.Tests
 {
     [TestFixture]
     public class RoleManagement : BaseWebTest

Modified: trunk/MySql.Web/Tests/SchemaTests.cs
===================================================================
--- trunk/MySql.Web/Tests/SchemaTests.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Tests/SchemaTests.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -32,7 +32,7 @@
 using System.IO;
 using System.Configuration.Provider;
 
-namespace MySql.Web.Security.Tests
+namespace MySql.Web.Tests
 {
     [TestFixture]
     public class SchemaTests : BaseWebTest
@@ -129,19 +129,6 @@
             }
         }
 
-        private void LoadSchema(int version)
-        {
-            if (version < 1) return;
-
-            MySQLMembershipProvider provider = new MySQLMembershipProvider();
-
-            ResourceManager r = new ResourceManager("MySql.Web.Properties.Resources",
typeof(MySQLMembershipProvider).Assembly);
-            string schema = r.GetString(String.Format("schema{0}", version));
-            MySqlScript script = new MySqlScript(conn);
-            script.Query = schema;
-            script.Execute();
-        }
-
         [Test]
         public void CurrentSchema()
         {

Added: trunk/MySql.Web/Tests/TestProfile.cs
===================================================================
--- trunk/MySql.Web/Tests/TestProfile.cs	                        (rev 0)
+++ trunk/MySql.Web/Tests/TestProfile.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -0,0 +1,66 @@
+// Copyright (C) 2007 MySQL AB
+//
+// This program is free software; you can redistribute it and/or modify
+// it under the terms of the GNU General Public License version 2 as published by
+// the Free Software Foundation
+//
+// There are special exceptions to the terms and conditions of the GPL 
+// as it is applied to this software. View the full text of the 
+// exception in file EXCEPTIONS in the directory of this software 
+// distribution.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA 
+
+//  This code was contributed by Sean Wright (srwright@stripped) on 2007-01-12
+//  The copyright was assigned and transferred under the terms of
+//  the MySQL Contributor License Agreement (CLA)
+
+using System;
+using System.Collections.Generic;
+using System.Text;
+using System.Web.Profile;
+using System.Web.Security;
+
+namespace MySql.Web.Tests
+{
+    public class TestProfile : ProfileBase
+    {
+        public static TestProfile GetUserProfile(string username, bool auth)
+        {
+            return Create(username, auth) as TestProfile;
+        }
+
+        public static TestProfile GetUserProfile(bool auth) 
+        {
+            return Create(Membership.GetUser().UserName, auth) as TestProfile; 
+        }
+
+        [SettingsAllowAnonymous(false)]
+        public string Description 
+        { 
+            get { return base["Description"] as string; } 
+            set { base["Description"] = value; } 
+        }
+
+        [SettingsAllowAnonymous(false)]
+        public string Location 
+        { 
+            get { return base["Location"] as string; } 
+            set { base["Location"] = value; } 
+        }
+
+        [SettingsAllowAnonymous(false)]
+        public string FavoriteMovie 
+        { 
+            get { return base["FavoriteMovie"] as string; } 
+            set { base["FavoriteMovie"] = value; } 
+        }
+    } 
+}

Modified: trunk/MySql.Web/Tests/UserManagement.cs
===================================================================
--- trunk/MySql.Web/Tests/UserManagement.cs	2008-01-31 21:29:20 UTC (rev 1155)
+++ trunk/MySql.Web/Tests/UserManagement.cs	2008-01-31 21:30:36 UTC (rev 1156)
@@ -28,8 +28,9 @@
 using System.Data;
 using System;
 using System.Configuration.Provider;
+using MySql.Web.Security;
 
-namespace MySql.Web.Security.Tests
+namespace MySql.Web.Tests
 {
     [TestFixture]
     public class UserManagement : BaseWebTest
@@ -134,17 +135,28 @@
         }
 
         [Test]
+        public void FindUsersByEmail()
+        {
+            CreateUserWithHashedPassword();
+
+            int records;
+            MembershipUserCollection users = provider.FindUsersByEmail("foo@stripped", 0,
10, out records);
+            Assert.AreEqual(1, records);
+            Assert.AreEqual("foo", users["foo"].UserName);
+        }
+
+        [Test]
         public void TestCreateUserOverrides()
         {
             try
             {
 				// we have to initialize the provider so the db will exist
-				provider = new MySQLMembershipProvider();
+/*				provider = new MySQLMembershipProvider();
 				NameValueCollection config = new NameValueCollection();
 				config.Add("connectionStringName", "LocalMySqlServer");
 				config.Add("applicationName", "/");
 				provider.Initialize(null, config);
-				
+*/				
 				Membership.CreateUser("foo", "bar");
                 int records;
                 MembershipUserCollection users = Membership.FindUsersByName("F%", 0, 10,
out records);
@@ -165,57 +177,225 @@
         [Test]
         public void NumberOfUsersOnline()
         {
-            Assert.Fail();
+            int numOnline = Membership.GetNumberOfUsersOnline();
+            Assert.AreEqual(0, numOnline);
+
+            Membership.CreateUser("foo", "bar");
+            Membership.CreateUser("foo2", "bar");
+
+            numOnline = Membership.GetNumberOfUsersOnline();
+            Assert.AreEqual(2, numOnline);
         }
 
         [Test]
         public void UnlockUser()
         {
-            Assert.Fail();
+            Membership.CreateUser("foo", "bar");
+            Assert.IsFalse(Membership.ValidateUser("foo", "bar2"));
+            Assert.IsFalse(Membership.ValidateUser("foo", "bar3"));
+            Assert.IsFalse(Membership.ValidateUser("foo", "bar3"));
+            Assert.IsFalse(Membership.ValidateUser("foo", "bar3"));
+            Assert.IsFalse(Membership.ValidateUser("foo", "bar3"));
+
+            // the user should be locked now so the right password should fail
+            Assert.IsFalse(Membership.ValidateUser("foo", "bar"));
+
+            MembershipUser user = Membership.GetUser("foo");
+            Assert.IsTrue(user.IsLockedOut);
+
+            Assert.IsTrue(user.UnlockUser());
+            user = Membership.GetUser("foo");
+            Assert.IsFalse(user.IsLockedOut);
+
+            Assert.IsTrue(Membership.ValidateUser("foo", "bar"));
         }
 
         [Test]
         public void GetUsernameByEmail()
         {
-            Assert.Fail();
+            Membership.CreateUser("foo", "bar", "foo@stripped");
+            string username = Membership.GetUserNameByEmail("foo@stripped");
+            Assert.AreEqual("foo", username);
+
+            username = Membership.GetUserNameByEmail("foo@stripped");
+            Assert.IsNull(username);
+
+            username = Membership.GetUserNameByEmail("  foo@stripped   ");
+            Assert.AreEqual("foo", username);
         }
 
         [Test]
         public void UpdateUser()
         {
-            Assert.Fail();
+            MembershipCreateStatus status;
+            Membership.CreateUser("foo", "bar", "foo@stripped", "color", "blue", true, out
status);
+            Assert.AreEqual(MembershipCreateStatus.Success, status);
+
+            MembershipUser user = Membership.GetUser("foo");
+
+            user.Comment = "my comment";
+            user.Email = "my email";
+            user.IsApproved = false;
+            user.LastActivityDate = new DateTime(2008, 1, 1);
+            user.LastLoginDate = new DateTime(2008, 2, 1);
+            Membership.UpdateUser(user);
+
+            MembershipUser newUser = Membership.GetUser("foo");
+            Assert.AreEqual(user.Comment, newUser.Comment);
+            Assert.AreEqual(user.Email, newUser.Email);
+            Assert.AreEqual(user.IsApproved, newUser.IsApproved);
+            Assert.AreEqual(user.LastActivityDate, newUser.LastActivityDate);
+            Assert.AreEqual(user.LastLoginDate, newUser.LastLoginDate);
         }
 
+        private void ChangePasswordQAHelper(MembershipUser user, string pw, string newQ,
string newA)
+        {
+            try
+            {
+                user.ChangePasswordQuestionAndAnswer(pw, newQ, newA);
+                Assert.Fail("This should not work.");
+            }
+            catch (ArgumentNullException ane)
+            {
+                Assert.AreEqual("password", ane.ParamName);
+            }
+            catch (ArgumentException)
+            {
+                Assert.IsNotNull(pw);
+            }
+        }
+
         [Test]
         public void ChangePasswordQuestionAndAnswer()
         {
-            Assert.Fail();
+            MembershipCreateStatus status;
+            Membership.CreateUser("foo", "bar", "foo@stripped", "color", "blue", true, out
status);
+            Assert.AreEqual(MembershipCreateStatus.Success, status);
+
+            MembershipUser user = Membership.GetUser("foo");
+            ChangePasswordQAHelper(user, "", "newQ", "newA");
+            ChangePasswordQAHelper(user, "bar", "", "newA");
+            ChangePasswordQAHelper(user, "bar", "newQ", "");
+            ChangePasswordQAHelper(user, null, "newQ", "newA");
+
+            bool result = user.ChangePasswordQuestionAndAnswer("bar", "newQ", "newA");
+            Assert.IsTrue(result);
+
+            user = Membership.GetUser("foo");
+            Assert.AreEqual("newQ", user.PasswordQuestion);
         }
 
         [Test]
         public void GetAllUsers()
         {
-            Assert.Fail();
+            // first create a bunch of users
+            for (int i=0; i < 100; i++)
+                Membership.CreateUser(String.Format("foo{0}", i), "bar");
+
+            MembershipUserCollection users = Membership.GetAllUsers();
+            Assert.AreEqual(100, users.Count);
+            int index = 0;
+            foreach (MembershipUser user in users)
+                Assert.AreEqual(String.Format("foo{0}", index++), user.UserName);
+
+            int total;
+            users = Membership.GetAllUsers(2, 10, out total);
+            Assert.AreEqual(10, users.Count);
+            Assert.AreEqual(100, total);
+            index = 0;
+            foreach (MembershipUser user in users)
+                Assert.AreEqual(String.Format("foo2{0}", index++), user.UserName);
         }
 
+        private void GetPasswordHelper(bool requireQA, bool enablePasswordRetrieval,
string answer)
+        {
+            MembershipCreateStatus status;
+            provider = new MySQLMembershipProvider();
+            NameValueCollection config = new NameValueCollection();
+            config.Add("connectionStringName", "LocalMySqlServer");
+            config.Add("requiresQuestionAndAnswer", requireQA ? "true" : "false");
+            config.Add("enablePasswordRetrieval", enablePasswordRetrieval ? "true" :
"false");
+            config.Add("passwordFormat", "clear");
+            config.Add("applicationName", "/");
+            provider.Initialize(null, config);
+
+            provider.CreateUser("foo", "bar", "foo@stripped", "color", "blue", true, null,
out status);
+
+            try
+            {
+                string password = provider.GetPassword("foo", answer);
+                if (!enablePasswordRetrieval)
+                    Assert.Fail("This should have thrown an exception");
+                Assert.AreEqual("bar", password);
+            }
+            catch (ProviderException)
+            {
+                if (requireQA && answer != null)
+                    Assert.Fail("This should not have thrown an exception");
+            }
+        }
+
         [Test]
         public void GetPassword()
         {
-            Assert.Fail();
+            GetPasswordHelper(false, false, null);
+            GetPasswordHelper(false, true, null);
+            GetPasswordHelper(true, true, null);
+            GetPasswordHelper(true, true, "blue");
         }
 
         [Test]
         public void GetUser()
         {
-            // both variants
-            Assert.Fail();
+            Membership.CreateUser("foo", "bar");
+            MembershipUser user = Membership.GetUser(1);
+            Assert.AreEqual("foo", user.UserName);
+
+            // now move the activity date back outside the login
+            // window
+            user.LastActivityDate = new DateTime(2008, 1, 1);
+            Membership.UpdateUser(user);
+
+            user = Membership.GetUser("foo");
+            Assert.IsFalse(user.IsOnline);
+
+            user = Membership.GetUser("foo", true);
+            Assert.IsTrue(user.IsOnline);
+
+            // now move the activity date back outside the login
+            // window again
+            user.LastActivityDate = new DateTime(2008, 1, 1);
+            Membership.UpdateUser(user);
+
+            user = Membership.GetUser(1);
+            Assert.IsFalse(user.IsOnline);
+
+            user = Membership.GetUser(1, true);
+            Assert.IsTrue(user.IsOnline);
         }
 
         [Test]
         public void FindUsers()
         {
-            // all variants
-            Assert.Fail();
+            for (int i=0; i < 100; i++)
+                Membership.CreateUser(String.Format("boo{0}", i), "bar");
+            for (int i=0; i < 100; i++)
+                Membership.CreateUser(String.Format("foo{0}", i), "bar");
+            for (int i=0; i < 100; i++)
+                Membership.CreateUser(String.Format("schmoo{0}", i), "bar");
+
+
+            MembershipUserCollection users = Membership.FindUsersByName("fo%");
+            Assert.AreEqual(100, users.Count);
+
+            int total;
+            users = Membership.FindUsersByName("fo%", 2, 10, out total);
+            Assert.AreEqual(10, users.Count);
+            Assert.AreEqual(100, total);
+            int index = 0;
+            foreach (MembershipUser user in users)
+                Assert.AreEqual(String.Format("foo2{0}", index++), user.UserName);
+
         }
     }
 }

Thread
Connector/NET commit: r1156 - in trunk/MySql.Web: Providers Providers/Properties Providers/Source Testsrburnett31 Jan