mirror of
https://bitbucket.org/anguist/ntpa
synced 2026-10-01 07:08:04 +00:00
676 lines
28 KiB
C#
676 lines
28 KiB
C#
// Copyright © 2004, 2011, Oracle and/or its affiliates. All rights reserved.
|
|
//
|
|
// MySQL Connector/NET is licensed under the terms of the GPLv2
|
|
// <http://www.gnu.org/licenses/old-licenses/gpl-2.0.html>, like most
|
|
// MySQL Connectors. There are special exceptions to the terms and
|
|
// conditions of the GPLv2 as it is applied to this software, see the
|
|
// FLOSS License Exception
|
|
// <http://www.mysql.com/about/legal/licensing/foss-exception.html>.
|
|
//
|
|
// This program is free software; you can redistribute it and/or modify
|
|
// it under the terms of the GNU General Public License as published
|
|
// by the Free Software Foundation; version 2 of the License.
|
|
//
|
|
// 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.,
|
|
// 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
|
|
|
// This code was contributed by Sean Wright (srwright@alcor.concordia.ca) on 2007-01-12
|
|
// The copyright was assigned and transferred under the terms of
|
|
// the MySQL Contributor License Agreement (CLA)
|
|
|
|
using System;
|
|
using System.Web.Profile;
|
|
using System.Configuration;
|
|
using System.Collections.Specialized;
|
|
using System.Web.Hosting;
|
|
using MySql.Data.MySqlClient;
|
|
using System.Configuration.Provider;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Text;
|
|
using System.Data;
|
|
using System.IO;
|
|
using System.Globalization;
|
|
using System.Web.Security;
|
|
using MySql.Web.Common;
|
|
using MySql.Web.Properties;
|
|
using MySql.Web.General;
|
|
|
|
namespace MySql.Web.Profile
|
|
{
|
|
/// <summary>
|
|
///
|
|
/// </summary>
|
|
public class MySQLProfileProvider : ProfileProvider
|
|
{
|
|
private string connectionString;
|
|
private Application app;
|
|
|
|
#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)
|
|
{
|
|
if (config == null)
|
|
throw new ArgumentNullException("config");
|
|
|
|
if (name == null || name.Length == 0)
|
|
name = "MySQLProfileProvider";
|
|
|
|
if (string.IsNullOrEmpty(config["description"]))
|
|
{
|
|
config.Remove("description");
|
|
config.Add("description", "MySQL Profile provider");
|
|
}
|
|
base.Initialize(name, config);
|
|
|
|
try
|
|
{
|
|
string applicationName = GetConfigValue(config["applicationName"], HostingEnvironment.ApplicationVirtualPath);
|
|
|
|
connectionString = "";
|
|
ConnectionStringSettings ConnectionStringSettings = ConfigurationManager.ConnectionStrings[
|
|
config["connectionStringName"]];
|
|
if (ConnectionStringSettings != null)
|
|
connectionString = ConnectionStringSettings.ConnectionString.Trim();
|
|
|
|
if (String.IsNullOrEmpty(connectionString)) return;
|
|
|
|
// make sure our schema is up to date
|
|
SchemaManager.CheckSchema(connectionString, config);
|
|
|
|
app = new Application(applicationName, base.Description);
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new ProviderException(Resources.ErrorInitProfileProvider, ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, deletes all user-profile data
|
|
/// for profiles in which the last activity date occurred before the
|
|
/// specified date.
|
|
/// </summary>
|
|
/// <param name="authenticationOption">One of the
|
|
/// <see cref="T:System.Web.Profile.ProfileAuthenticationOption"/>
|
|
/// values, specifying whether anonymous, authenticated, or both
|
|
/// types of profiles are deleted.</param>
|
|
/// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime"/>
|
|
/// that identifies which user profiles are considered inactive. If the
|
|
/// <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate"/>
|
|
/// value of a user profile occurs on or before this date and time, the
|
|
/// profile is considered inactive.</param>
|
|
/// <returns>
|
|
/// The number of profiles deleted from the data source.
|
|
/// </returns>
|
|
public override int DeleteInactiveProfiles(
|
|
ProfileAuthenticationOption authenticationOption,
|
|
DateTime userInactiveSinceDate)
|
|
{
|
|
using (MySqlConnection c = new MySqlConnection(connectionString))
|
|
{
|
|
c.Open();
|
|
|
|
MySqlCommand queryCmd = new MySqlCommand(
|
|
@"SELECT * FROM my_aspnet_users
|
|
WHERE applicationId=@appId AND
|
|
lastActivityDate < @lastActivityDate",
|
|
c);
|
|
queryCmd.Parameters.AddWithValue("@appId", app.FetchId(c));
|
|
queryCmd.Parameters.AddWithValue("@lastActivityDate", userInactiveSinceDate);
|
|
if (authenticationOption == ProfileAuthenticationOption.Anonymous)
|
|
queryCmd.CommandText += " AND isAnonymous = 1";
|
|
else if (authenticationOption == ProfileAuthenticationOption.Authenticated)
|
|
queryCmd.CommandText += " AND isAnonymous = 0";
|
|
|
|
MySqlCommand deleteCmd = new MySqlCommand(
|
|
"DELETE FROM my_aspnet_profiles WHERE userId = @userId", c);
|
|
deleteCmd.Parameters.Add("@userId", MySqlDbType.UInt64);
|
|
|
|
List<ulong> uidList = new List<ulong>();
|
|
using (MySqlDataReader reader = queryCmd.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
uidList.Add(reader.GetUInt64("userId"));
|
|
}
|
|
|
|
int count = 0;
|
|
foreach (ulong uid in uidList)
|
|
{
|
|
deleteCmd.Parameters[0].Value = uid;
|
|
count += deleteCmd.ExecuteNonQuery();
|
|
}
|
|
return count;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, deletes profile properties
|
|
/// and information for profiles that match the supplied list of user names.
|
|
/// </summary>
|
|
/// <param name="usernames">A string array of user names for
|
|
/// profiles to be deleted.</param>
|
|
/// <returns>
|
|
/// The number of profiles deleted from the data source.
|
|
/// </returns>
|
|
public override int DeleteProfiles(string[] usernames)
|
|
{
|
|
using (MySqlConnection c = new MySqlConnection(connectionString))
|
|
{
|
|
c.Open();
|
|
|
|
MySqlCommand queryCmd = new MySqlCommand(
|
|
@"SELECT * FROM my_aspnet_users
|
|
WHERE applicationId=@appId AND name = @name", c);
|
|
queryCmd.Parameters.AddWithValue("@appId", app.FetchId(c));
|
|
queryCmd.Parameters.Add("@name", MySqlDbType.VarChar);
|
|
|
|
MySqlCommand deleteCmd = new MySqlCommand(
|
|
"DELETE FROM my_aspnet_profiles WHERE userId = @userId", c);
|
|
deleteCmd.Parameters.Add("@userId", MySqlDbType.Int32);
|
|
|
|
int count = 0;
|
|
foreach (string name in usernames)
|
|
{
|
|
queryCmd.Parameters[1].Value = name;
|
|
int uid = (int)queryCmd.ExecuteScalar();
|
|
|
|
deleteCmd.Parameters[0].Value = uid;
|
|
count += deleteCmd.ExecuteNonQuery();
|
|
}
|
|
return count;
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, deletes profile properties
|
|
/// and information for the supplied list of profiles.
|
|
/// </summary>
|
|
/// <param name="profiles">A
|
|
/// <see cref="T:System.Web.Profile.ProfileInfoCollection"/> of
|
|
/// information about profiles that are to be deleted.</param>
|
|
/// <returns>
|
|
/// The number of profiles deleted from the data source.
|
|
/// </returns>
|
|
public override int DeleteProfiles(ProfileInfoCollection profiles)
|
|
{
|
|
string[] s = new string[profiles.Count];
|
|
|
|
int i = 0;
|
|
foreach (ProfileInfo p in profiles)
|
|
s[i++] = p.UserName;
|
|
return DeleteProfiles(s);
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, retrieves profile information
|
|
/// for profiles in which the last activity date occurred on or before
|
|
/// the specified date and the user name matches the specified user name.
|
|
/// </summary>
|
|
/// <param name="authenticationOption">One of the
|
|
/// <see cref="T:System.Web.Profile.ProfileAuthenticationOption"/> values,
|
|
/// specifying whether anonymous, authenticated, or both types of profiles
|
|
/// are returned.</param>
|
|
/// <param name="usernameToMatch">The user name to search for.</param>
|
|
/// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime"/>
|
|
/// that identifies which user profiles are considered inactive. If the
|
|
/// <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate"/> value
|
|
/// of a user profile occurs on or before this date and time, the profile
|
|
/// is considered inactive.</param>
|
|
/// <param name="pageIndex">The index of the page of results to return.</param>
|
|
/// <param name="pageSize">The size of the page of results to return.</param>
|
|
/// <param name="totalRecords">When this method returns, contains the total
|
|
/// number of profiles.</param>
|
|
/// <returns>
|
|
/// A <see cref="T:System.Web.Profile.ProfileInfoCollection"/> containing
|
|
/// user profile information for inactive profiles where the user name
|
|
/// matches the supplied <paramref name="usernameToMatch"/> parameter.
|
|
/// </returns>
|
|
public override ProfileInfoCollection FindInactiveProfilesByUserName(
|
|
ProfileAuthenticationOption authenticationOption,
|
|
string usernameToMatch, DateTime userInactiveSinceDate,
|
|
int pageIndex, int pageSize, out int totalRecords)
|
|
{
|
|
return GetProfiles(authenticationOption, usernameToMatch,
|
|
userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, retrieves profile information
|
|
/// for profiles in which the user name matches the specified user names.
|
|
/// </summary>
|
|
/// <param name="authenticationOption">One of the
|
|
/// <see cref="T:System.Web.Profile.ProfileAuthenticationOption"/> values,
|
|
/// specifying whether anonymous, authenticated, or both types of profiles
|
|
/// are returned.</param>
|
|
/// <param name="usernameToMatch">The user name to search for.</param>
|
|
/// <param name="pageIndex">The index of the page of results to return.</param>
|
|
/// <param name="pageSize">The size of the page of results to return.</param>
|
|
/// <param name="totalRecords">When this method returns, contains the total
|
|
/// number of profiles.</param>
|
|
/// <returns>
|
|
/// A <see cref="T:System.Web.Profile.ProfileInfoCollection"/> containing
|
|
/// user-profile information for profiles where the user name matches the
|
|
/// supplied <paramref name="usernameToMatch"/> parameter.
|
|
/// </returns>
|
|
public override ProfileInfoCollection FindProfilesByUserName(
|
|
ProfileAuthenticationOption authenticationOption,
|
|
string usernameToMatch, int pageIndex, int pageSize,
|
|
out int totalRecords)
|
|
{
|
|
return GetProfiles(authenticationOption, usernameToMatch,
|
|
DateTime.MinValue, pageIndex, pageSize, out totalRecords);
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, retrieves user-profile data
|
|
/// from the data source for profiles in which the last activity date
|
|
/// occurred on or before the specified date.
|
|
/// </summary>
|
|
/// <param name="authenticationOption">One of the
|
|
/// <see cref="T:System.Web.Profile.ProfileAuthenticationOption"/> values,
|
|
/// specifying whether anonymous, authenticated, or both types of profiles
|
|
/// are returned.</param>
|
|
/// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime"/>
|
|
/// that identifies which user profiles are considered inactive. If the
|
|
/// <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate"/> of
|
|
/// a user profile occurs on or before this date and time, the profile is
|
|
/// considered inactive.</param>
|
|
/// <param name="pageIndex">The index of the page of results to return.</param>
|
|
/// <param name="pageSize">The size of the page of results to return.</param>
|
|
/// <param name="totalRecords">When this method returns, contains the
|
|
/// total number of profiles.</param>
|
|
/// <returns>
|
|
/// A <see cref="T:System.Web.Profile.ProfileInfoCollection"/> containing user-profile information about the inactive profiles.
|
|
/// </returns>
|
|
public override ProfileInfoCollection GetAllInactiveProfiles(
|
|
ProfileAuthenticationOption authenticationOption,
|
|
DateTime userInactiveSinceDate, int pageIndex, int pageSize,
|
|
out int totalRecords)
|
|
{
|
|
return GetProfiles(authenticationOption, null,
|
|
userInactiveSinceDate, pageIndex, pageSize, out totalRecords);
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, retrieves user profile data for
|
|
/// all profiles in the data source.
|
|
/// </summary>
|
|
/// <param name="authenticationOption">One of the
|
|
/// <see cref="T:System.Web.Profile.ProfileAuthenticationOption"/> values,
|
|
/// specifying whether anonymous, authenticated, or both types of profiles
|
|
/// are returned.</param>
|
|
/// <param name="pageIndex">The index of the page of results to return.</param>
|
|
/// <param name="pageSize">The size of the page of results to return.</param>
|
|
/// <param name="totalRecords">When this method returns, contains the
|
|
/// total number of profiles.</param>
|
|
/// <returns>
|
|
/// A <see cref="T:System.Web.Profile.ProfileInfoCollection"/> containing
|
|
/// user-profile information for all profiles in the data source.
|
|
/// </returns>
|
|
public override ProfileInfoCollection GetAllProfiles(
|
|
ProfileAuthenticationOption authenticationOption, int pageIndex,
|
|
int pageSize, out int totalRecords)
|
|
{
|
|
return GetProfiles(authenticationOption, null,
|
|
DateTime.MinValue, pageIndex, pageSize, out totalRecords);
|
|
}
|
|
|
|
/// <summary>
|
|
/// When overridden in a derived class, returns the number of profiles
|
|
/// in which the last activity date occurred on or before the specified
|
|
/// date.
|
|
/// </summary>
|
|
/// <param name="authenticationOption">One of the
|
|
/// <see cref="T:System.Web.Profile.ProfileAuthenticationOption"/> values,
|
|
/// specifying whether anonymous, authenticated, or both types of profiles
|
|
/// are returned.</param>
|
|
/// <param name="userInactiveSinceDate">A <see cref="T:System.DateTime"/>
|
|
/// that identifies which user profiles are considered inactive. If the
|
|
/// <see cref="P:System.Web.Profile.ProfileInfo.LastActivityDate"/> of
|
|
/// a user profile occurs on or before this date and time, the profile
|
|
/// is considered inactive.</param>
|
|
/// <returns>
|
|
/// The number of profiles in which the last activity date occurred on
|
|
/// or before the specified date.
|
|
/// </returns>
|
|
public override int GetNumberOfInactiveProfiles(
|
|
ProfileAuthenticationOption authenticationOption,
|
|
DateTime userInactiveSinceDate)
|
|
{
|
|
using (MySqlConnection c = new MySqlConnection(connectionString))
|
|
{
|
|
c.Open();
|
|
|
|
MySqlCommand queryCmd = new MySqlCommand(
|
|
@"SELECT COUNT(*) FROM my_aspnet_users
|
|
WHERE applicationId = @appId AND
|
|
lastActivityDate < @lastActivityDate",
|
|
c);
|
|
queryCmd.Parameters.AddWithValue("@appId", app.FetchId(c));
|
|
queryCmd.Parameters.AddWithValue("@lastActivityDate", userInactiveSinceDate);
|
|
if (authenticationOption == ProfileAuthenticationOption.Anonymous)
|
|
queryCmd.CommandText += " AND isAnonymous = 1";
|
|
else if (authenticationOption == ProfileAuthenticationOption.Authenticated)
|
|
queryCmd.CommandText += " AND isAnonymous = 0";
|
|
return (int)queryCmd.ExecuteScalar();
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Gets or sets the name of the currently running application.
|
|
/// </summary>
|
|
/// <value></value>
|
|
/// <returns>A <see cref="T:System.String"/> that contains the application's shortened name, which does not contain a full path or extension, for example, SimpleAppSettings.</returns>
|
|
public override string ApplicationName
|
|
{
|
|
get { return app.Name; }
|
|
set { app.Name = value; }
|
|
}
|
|
|
|
/// <summary>
|
|
/// Returns the collection of settings property values for the specified application instance and settings property group.
|
|
/// </summary>
|
|
/// <param name="context">A <see cref="T:System.Configuration.SettingsContext"/> describing the current application use.</param>
|
|
/// <param name="collection">A <see cref="T:System.Configuration.SettingsPropertyCollection"/> containing the settings property group whose values are to be retrieved.</param>
|
|
/// <returns>
|
|
/// A <see cref="T:System.Configuration.SettingsPropertyValueCollection"/> containing the values for the specified settings property group.
|
|
/// </returns>
|
|
public override SettingsPropertyValueCollection GetPropertyValues(
|
|
SettingsContext context, SettingsPropertyCollection collection)
|
|
{
|
|
SettingsPropertyValueCollection values = new SettingsPropertyValueCollection();
|
|
|
|
if (collection.Count < 1) return values;
|
|
|
|
string username = (string)context["UserName"];
|
|
|
|
foreach (SettingsProperty property in collection)
|
|
{
|
|
if (property.PropertyType.IsPrimitive || property.PropertyType == typeof(string))
|
|
property.SerializeAs = SettingsSerializeAs.String;
|
|
else
|
|
property.SerializeAs = SettingsSerializeAs.Xml;
|
|
|
|
values.Add(new SettingsPropertyValue(property));
|
|
}
|
|
|
|
if (String.IsNullOrEmpty(username))
|
|
return values;
|
|
|
|
// retrieve encoded profile data from the database
|
|
try
|
|
{
|
|
|
|
using (MySqlConnection c = new MySqlConnection(connectionString))
|
|
{
|
|
c.Open();
|
|
MySqlCommand cmd = new MySqlCommand(
|
|
@"SELECT * FROM my_aspnet_profiles p
|
|
JOIN my_aspnet_users u ON u.id = p.userId
|
|
WHERE u.applicationId = @appId AND u.name = @name", c);
|
|
cmd.Parameters.AddWithValue("@appId", app.FetchId(c));
|
|
cmd.Parameters.AddWithValue("@name", username);
|
|
MySqlDataAdapter da = new MySqlDataAdapter(cmd);
|
|
DataTable dt = new DataTable();
|
|
da.Fill(dt);
|
|
|
|
if (dt.Rows.Count > 0)
|
|
DecodeProfileData(dt.Rows[0], values);
|
|
return values;
|
|
}
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
throw new ProviderException(Resources.UnableToRetrieveProfileData, ex);
|
|
}
|
|
}
|
|
|
|
/// <summary>
|
|
/// Sets the values of the specified group of property settings.
|
|
/// </summary>
|
|
/// <param name="context">A <see cref="T:System.Configuration.SettingsContext"/> describing the current application usage.</param>
|
|
/// <param name="collection">A <see cref="T:System.Configuration.SettingsPropertyValueCollection"/> representing the group of property settings to set.</param>
|
|
public override void SetPropertyValues(
|
|
SettingsContext context, SettingsPropertyValueCollection collection)
|
|
{
|
|
bool isAuthenticated = (bool)context["IsAuthenticated"];
|
|
string username = (string)context["UserName"];
|
|
|
|
if (String.IsNullOrEmpty(username)) return;
|
|
if (collection.Count < 1) return;
|
|
|
|
string index = String.Empty;
|
|
string stringData = String.Empty;
|
|
byte[] binaryData = null;
|
|
int count = EncodeProfileData(collection, isAuthenticated, ref index, ref stringData, ref binaryData);
|
|
if (count < 1) return;
|
|
|
|
MySqlTransaction txn = null;
|
|
// save the encoded profile data to the database
|
|
using (MySqlConnection connection = new MySqlConnection(connectionString))
|
|
{
|
|
try
|
|
{
|
|
connection.Open();
|
|
txn = connection.BeginTransaction();
|
|
|
|
// either create a new user or fetch the existing user id
|
|
long userId = SchemaManager.CreateOrFetchUserId(connection, username,
|
|
app.EnsureId(connection), isAuthenticated);
|
|
|
|
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 == 0)
|
|
throw new Exception(Resources.ProfileUpdateFailed);
|
|
txn.Commit();
|
|
}
|
|
catch (Exception ex)
|
|
{
|
|
if (txn != null)
|
|
txn.Rollback();
|
|
throw new ProviderException(Resources.ProfileUpdateFailed, ex);
|
|
}
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
internal static void DeleteUserData(MySqlConnection connection, int userId)
|
|
{
|
|
MySqlCommand cmd = new MySqlCommand(
|
|
"DELETE FROM my_aspnet_profiles WHERE userId=@userId", connection);
|
|
cmd.Parameters.AddWithValue("@userId", userId);
|
|
cmd.ExecuteNonQuery();
|
|
}
|
|
|
|
#region Private Methods
|
|
|
|
private void DecodeProfileData(DataRow profileRow, SettingsPropertyValueCollection values)
|
|
{
|
|
string indexData = (string)profileRow["valueindex"];
|
|
string stringData = (string)profileRow["stringData"];
|
|
byte[] binaryData = (byte[])profileRow["binaryData"];
|
|
|
|
if (indexData == null) return;
|
|
|
|
string[] indexes = indexData.Split(':');
|
|
|
|
foreach (string index in indexes)
|
|
{
|
|
string[] parts = index.Split('/');
|
|
SettingsPropertyValue value = values[parts[0]];
|
|
if (value == null) continue;
|
|
|
|
int pos = Int32.Parse(parts[2], CultureInfo.InvariantCulture);
|
|
int len = Int32.Parse(parts[3], CultureInfo.InvariantCulture);
|
|
if (len == -1)
|
|
{
|
|
value.PropertyValue = null;
|
|
value.IsDirty = false;
|
|
value.Deserialized = true;
|
|
}
|
|
else if (parts[1].Equals("0"))
|
|
value.SerializedValue = stringData.Substring(pos, len);
|
|
else
|
|
{
|
|
byte[] buf = new byte[len];
|
|
Buffer.BlockCopy(binaryData, pos, buf, 0, len);
|
|
value.SerializedValue = buf;
|
|
}
|
|
}
|
|
}
|
|
|
|
private int EncodeProfileData(SettingsPropertyValueCollection collection, bool isAuthenticated,
|
|
ref string index, ref string stringData, ref byte[] binaryData)
|
|
{
|
|
bool itemsToSave = false;
|
|
|
|
// first we need to determine if there are any items that need saving
|
|
// this is an optimization
|
|
foreach (SettingsPropertyValue value in collection)
|
|
{
|
|
if (!value.IsDirty) continue;
|
|
if (value.Property.Attributes["AllowAnonymous"].Equals(false) &&
|
|
!isAuthenticated) continue;
|
|
itemsToSave = true;
|
|
break;
|
|
}
|
|
if (!itemsToSave) return 0;
|
|
|
|
StringBuilder indexBuilder = new StringBuilder();
|
|
StringBuilder stringDataBuilder = new StringBuilder();
|
|
MemoryStream binaryBuilder = new MemoryStream();
|
|
int count = 0;
|
|
|
|
// ok, we have some values that need to be saved so we go back through
|
|
foreach (SettingsPropertyValue value in collection)
|
|
{
|
|
// if the value has not been written to and is still using the default value
|
|
// no need to save it
|
|
if (value.UsingDefaultValue && !value.IsDirty) continue;
|
|
|
|
// we don't save properties that require the user to be authenticated when the
|
|
// current user is not authenticated.
|
|
if (value.Property.Attributes["AllowAnonymous"].Equals(false) &&
|
|
!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 (propValue is string)
|
|
{
|
|
indexBuilder.AppendFormat("{0}/0/{1}/{2}:", value.Name,
|
|
stringDataBuilder.Length, (propValue as string).Length);
|
|
stringDataBuilder.Append(propValue);
|
|
}
|
|
else
|
|
{
|
|
byte[] binaryValue = (byte[])propValue;
|
|
indexBuilder.AppendFormat("{0}/1/{1}/{2}:", value.Name,
|
|
binaryBuilder.Position, binaryValue.Length);
|
|
binaryBuilder.Write(binaryValue, 0, binaryValue.Length);
|
|
}
|
|
}
|
|
index = indexBuilder.ToString();
|
|
stringData = stringDataBuilder.ToString();
|
|
binaryData = binaryBuilder.ToArray();
|
|
return count;
|
|
}
|
|
|
|
|
|
private ProfileInfoCollection GetProfiles(
|
|
ProfileAuthenticationOption authenticationOption,
|
|
string usernameToMatch, DateTime userInactiveSinceDate,
|
|
int pageIndex, int pageSize, out int totalRecords)
|
|
{
|
|
List<string> whereClauses = new List<string>();
|
|
|
|
using (MySqlConnection c = new MySqlConnection(connectionString))
|
|
{
|
|
c.Open();
|
|
|
|
MySqlCommand cmd = new MySqlCommand(
|
|
@"SELECT p.*, u.name, u.isAnonymous, u.lastActivityDate,
|
|
LENGTH(p.stringdata) + LENGTH(p.binarydata) AS profilesize
|
|
FROM my_aspnet_profiles p
|
|
JOIN my_aspnet_users u ON u.id = p.userId
|
|
WHERE u.applicationId = @appId", c);
|
|
cmd.Parameters.AddWithValue("@appId", app.FetchId(c));
|
|
|
|
if (usernameToMatch != null)
|
|
{
|
|
cmd.CommandText += " AND u.name LIKE @userName";
|
|
cmd.Parameters.AddWithValue("@userName", usernameToMatch);
|
|
}
|
|
if (userInactiveSinceDate != DateTime.MinValue)
|
|
{
|
|
cmd.CommandText += " AND u.lastActivityDate < @lastActivityDate";
|
|
cmd.Parameters.AddWithValue("@lastActivityDate", userInactiveSinceDate);
|
|
}
|
|
if (authenticationOption == ProfileAuthenticationOption.Anonymous)
|
|
cmd.CommandText += " AND u.isAnonymous = 1";
|
|
else if (authenticationOption == ProfileAuthenticationOption.Authenticated)
|
|
cmd.CommandText += " AND u.isAnonymous = 0";
|
|
|
|
cmd.CommandText += String.Format(" LIMIT {0},{1}", pageIndex * pageSize, pageSize);
|
|
|
|
ProfileInfoCollection pic = new ProfileInfoCollection();
|
|
using (MySqlDataReader reader = cmd.ExecuteReader())
|
|
{
|
|
while (reader.Read())
|
|
{
|
|
ProfileInfo pi = new ProfileInfo(
|
|
reader.GetString("name"),
|
|
reader.GetBoolean("isAnonymous"),
|
|
reader.GetDateTime("lastActivityDate"),
|
|
reader.GetDateTime("lastUpdatedDate"),
|
|
reader.GetInt32("profilesize"));
|
|
pic.Add(pi);
|
|
}
|
|
}
|
|
cmd.CommandText = "SELECT FOUND_ROWS()";
|
|
totalRecords = Convert.ToInt32(cmd.ExecuteScalar());
|
|
return pic;
|
|
}
|
|
}
|
|
|
|
private static string GetConfigValue(string configValue, string defaultValue)
|
|
{
|
|
if (string.IsNullOrEmpty(configValue))
|
|
{
|
|
return defaultValue;
|
|
}
|
|
return configValue;
|
|
}
|
|
|
|
#endregion
|
|
|
|
}
|
|
}
|