mirror of
https://bitbucket.org/anguist/ntpa
synced 2026-09-30 22:28:28 +00:00
519 lines
18 KiB
C#
519 lines
18 KiB
C#
// Copyright © 2014, 2015 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
|
|
|
|
using MySql.Web.Common;
|
|
using MySql.Web.General;
|
|
using MySql.Web.Properties;
|
|
using System;
|
|
using System.Collections.Generic;
|
|
using System.Configuration;
|
|
using System.Configuration.Provider;
|
|
using System.Linq;
|
|
using System.Resources;
|
|
using System.Text;
|
|
using System.Threading.Tasks;
|
|
using System.Web.Hosting;
|
|
using System.Web.Security;
|
|
using WebMatrix.WebData;
|
|
|
|
namespace MySql.Web.Security
|
|
{
|
|
public class MySqlSimpleRoleProvider : SimpleRoleProvider
|
|
{
|
|
#region Private
|
|
private readonly RoleProvider _prevProvider;
|
|
|
|
Application _app;
|
|
bool _enablePwdReset;
|
|
bool _enablePwdRetrival;
|
|
int _maxPwdAttempts;
|
|
int _minReqNonAlphanumericalChars;
|
|
int _minReqPwdLength;
|
|
int _pwdAttemptWindow;
|
|
MembershipPasswordFormat _pwdFormat;
|
|
string _pwdStrenghtRegex;
|
|
bool _reqQuestionAnswer;
|
|
bool _reqUniqueEmail;
|
|
string _connString;
|
|
string _userTableName;
|
|
string _userIdColumn;
|
|
string _userNameColumn;
|
|
bool _autoGenerateTables;
|
|
private readonly string _rolesTable = "webpages_Roles";
|
|
private readonly string _userInRolesTable = "webpages_UsersInRoles";
|
|
private static string GetConfigValue(string configVal, string defaultVal)
|
|
{
|
|
return !string.IsNullOrEmpty(configVal) ? configVal : defaultVal;
|
|
}
|
|
|
|
private void NotInitializedException()
|
|
{
|
|
throw new Exception(Resources.SimpleMembershipNotInitialized);
|
|
}
|
|
|
|
#endregion
|
|
public MySqlSimpleRoleProvider()
|
|
: this(null)
|
|
{ }
|
|
|
|
public MySqlSimpleRoleProvider(RoleProvider previousProvider)
|
|
{
|
|
_prevProvider = previousProvider;
|
|
}
|
|
|
|
public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
|
|
{
|
|
if (config == null)
|
|
{
|
|
throw new ArgumentNullException("config");
|
|
}
|
|
if (string.IsNullOrEmpty(name))
|
|
{
|
|
name = "MySqlExtendedMembershipProvider";
|
|
}
|
|
if (string.IsNullOrEmpty(config["description"]))
|
|
{
|
|
config.Remove("description");
|
|
config.Add("description", string.Format("MySql Default {0} Description", name));
|
|
}
|
|
|
|
base.Initialize(name, config);
|
|
|
|
var appName = GetConfigValue(config["applicationName"], HostingEnvironment.SiteName);
|
|
_maxPwdAttempts = Int32.Parse(GetConfigValue(config["maxInvalidPasswordAttempts"], "5"));
|
|
_pwdAttemptWindow = Int32.Parse(GetConfigValue(config["passwordAttemptWindow"], "10"));
|
|
_minReqNonAlphanumericalChars = Int32.Parse(GetConfigValue(config["minRequiredNonalphanumericCharacters"], "1"));
|
|
_minReqPwdLength = Int32.Parse(GetConfigValue(config["minRequiredPasswordLength"], "7"));
|
|
_pwdStrenghtRegex = GetConfigValue(config["passwordStrengthRegularExpression"], "");
|
|
_enablePwdReset = bool.Parse(GetConfigValue(config["enablePasswordReset"], "True"));
|
|
_enablePwdRetrival = bool.Parse(GetConfigValue(config["enablePasswordRetrieval"], "False"));
|
|
_reqQuestionAnswer = bool.Parse(GetConfigValue(config["requiresQuestionAndAnswer"], "False"));
|
|
_reqUniqueEmail = bool.Parse(GetConfigValue(config["requiresUniqueEmail"], "True"));
|
|
|
|
var pwdFormat = !string.IsNullOrEmpty(config["passwordFormat"]) ? config["passwordFormat"].ToString().ToLowerInvariant() : "hashed";
|
|
|
|
switch (pwdFormat)
|
|
{
|
|
case "hashed":
|
|
_pwdFormat = MembershipPasswordFormat.Hashed;
|
|
break;
|
|
case "encrypted":
|
|
_pwdFormat = MembershipPasswordFormat.Encrypted;
|
|
break;
|
|
case "clear":
|
|
_pwdFormat = MembershipPasswordFormat.Clear;
|
|
break;
|
|
default:
|
|
throw new ProviderException(Resources.PasswordFormatNotSupported);
|
|
}
|
|
|
|
if (_pwdFormat == MembershipPasswordFormat.Hashed)
|
|
{
|
|
if (_enablePwdRetrival)
|
|
throw new ProviderException(Resources.CannotRetrieveHashedPasswords);
|
|
}
|
|
|
|
_app = new Application(appName, base.Description);
|
|
ConnectionStringSettings connStrSettings = ConfigurationManager.ConnectionStrings[config["connectionStringName"]];
|
|
_connString = connStrSettings != null ? connStrSettings.ConnectionString.Trim() : "";
|
|
if (string.IsNullOrEmpty(_connString)) return;
|
|
|
|
UserTableName = GetConfigValue(config["userTableName"], "");
|
|
UserIdColumn = GetConfigValue(config["userIdColumn"], "");
|
|
UserNameColumn = GetConfigValue(config["userNameColumn"], "");
|
|
_autoGenerateTables = bool.Parse(GetConfigValue(config["autoGenerateTables"], "True"));
|
|
if (_autoGenerateTables)
|
|
CreateTables();
|
|
|
|
Initialized = true;
|
|
}
|
|
|
|
public override void AddUsersToRoles(string[] usernames, string[] roleNames)
|
|
{
|
|
if (!Initialized)
|
|
{
|
|
_prevProvider.AddUsersToRoles(usernames, roleNames);
|
|
}
|
|
else
|
|
{
|
|
if (usernames.Where(username => string.IsNullOrEmpty(username)).Count() > 0 || usernames.Where(username => string.IsNullOrEmpty(username)).Count() > 0)
|
|
throw new ArgumentException(Resources.InvalidArrayValue);
|
|
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
foreach (var userid in GetUsersId(usernames))
|
|
{
|
|
foreach (var roleid in GetRolesId(roleNames))
|
|
{
|
|
if (userid > 0 && roleid > 0)
|
|
{
|
|
dbConn.ExecuteNonQuery(string.Format("insert into {0} (userid, roleid) values(?,?);", _userInRolesTable), userid, roleid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override void CreateRole(string roleName)
|
|
{
|
|
if (!Initialized)
|
|
{
|
|
_prevProvider.CreateRole(roleName);
|
|
}
|
|
else
|
|
{
|
|
if (string.IsNullOrEmpty(roleName))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("roleName");
|
|
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
int roleid = GetRoleId(roleName);
|
|
if (roleid != 0)
|
|
{
|
|
throw new InvalidOperationException(string.Format(Resources.RoleAlreadyExists, roleName));
|
|
}
|
|
if (dbConn.ExecuteNonQuery(string.Format("insert into {0} (rolename) values(?);", _rolesTable), roleName) <= 0)
|
|
{
|
|
throw new ProviderException(string.Format(Resources.CreateRoleFailed, roleName));
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
|
|
{
|
|
if (!Initialized)
|
|
{
|
|
return _prevProvider.DeleteRole(roleName, throwOnPopulatedRole);
|
|
}
|
|
if (string.IsNullOrEmpty(roleName))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("roleName");
|
|
|
|
int roleid = GetRoleId(roleName);
|
|
if (roleid <= 0)
|
|
{
|
|
return false;
|
|
}
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
if (throwOnPopulatedRole)
|
|
{
|
|
if (IsRoleInUse(roleid))
|
|
throw new InvalidOperationException(string.Format(Resources.RoleInUse, roleName));
|
|
}
|
|
else
|
|
{
|
|
dbConn.ExecuteNonQuery(string.Format("delete from {0} where roleid=?;", _userInRolesTable), roleid);
|
|
}
|
|
return dbConn.ExecuteNonQuery(string.Format("delete from {0} where roleid=?;", _rolesTable), roleid) > 0;
|
|
}
|
|
}
|
|
|
|
public override string[] FindUsersInRole(string roleName, string usernameToMatch)
|
|
{
|
|
if (!Initialized)
|
|
{
|
|
return _prevProvider.FindUsersInRole(roleName, usernameToMatch);
|
|
}
|
|
if (string.IsNullOrEmpty(roleName))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("roleName");
|
|
if (string.IsNullOrEmpty(usernameToMatch))
|
|
return GetUsersInRole(roleName);
|
|
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
var usersName = dbConn.ExecuteQuery(string.Format("select ut.{0} from {1} as rt join {2} as urt on rt.roleid=urt.roleid join {3} as ut on rt.userid=ut.{4} where rt.rolename=? and ut.name like '%?%'", UserNameColumn, _rolesTable, _userInRolesTable, UserTableName, UserIdColumn), roleName, usernameToMatch);
|
|
if (usersName.Count() > 0)
|
|
return usersName.Select(username => username[0].ToString()).ToArray();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override string[] GetAllRoles()
|
|
{
|
|
if (!Initialized)
|
|
return _prevProvider.GetAllRoles();
|
|
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
var roles = dbConn.ExecuteQuery(string.Format("select rolename from {0};", _rolesTable));
|
|
if (roles.Count() > 0)
|
|
return roles.Select(role => role[0].ToString()).ToArray();
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override string[] GetRolesForUser(string username)
|
|
{
|
|
if (!Initialized)
|
|
return _prevProvider.GetRolesForUser(username);
|
|
if (string.IsNullOrEmpty(username))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("username");
|
|
|
|
string connString = GetConnectionString();
|
|
int userid = MySqlSimpleMembershipProvider.GetUserId(username, connString, UserTableName, UserIdColumn, UserNameColumn);
|
|
if (userid > 0)
|
|
{
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(connString))
|
|
{
|
|
var roles = dbConn.ExecuteQuery(string.Format("select rt.rolename from {0} as urt join {1} as rt on urt.roleid = rt.roleid where urt.userid=?;", _userInRolesTable, _rolesTable), userid);
|
|
if (roles.Count() > 0)
|
|
return roles.Select(role => role[0].ToString()).ToArray();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override string[] GetUsersInRole(string roleName)
|
|
{
|
|
if (!Initialized)
|
|
return _prevProvider.GetUsersInRole(roleName);
|
|
if (string.IsNullOrEmpty(roleName))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("roleName");
|
|
|
|
int roleid = GetRoleId(roleName);
|
|
if (roleid > 0)
|
|
{
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
var users = dbConn.ExecuteQuery(string.Format("select ut.{0} from {1} as urt join {2} as ut on urt.userid = ut.{3} where urt.roleid=?;", UserNameColumn, _userInRolesTable, UserTableName, UserIdColumn), roleid);
|
|
if (users.Count() > 0)
|
|
return users.Select(role => role[0].ToString()).ToArray();
|
|
}
|
|
}
|
|
return null;
|
|
}
|
|
|
|
public override bool IsUserInRole(string username, string roleName)
|
|
{
|
|
if (!Initialized)
|
|
return _prevProvider.IsUserInRole(username, roleName);
|
|
string connString = GetConnectionString();
|
|
if (string.IsNullOrEmpty(username))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("username");
|
|
if (string.IsNullOrEmpty(roleName))
|
|
MySqlSimpleMembershipProvider.NullArgumentException("roleName");
|
|
int userid = MySqlSimpleMembershipProvider.GetUserId(username, connString, UserTableName, UserIdColumn, UserNameColumn);
|
|
int roleid = GetRoleId(roleName);
|
|
if (userid <= 0 || roleid <= 0)
|
|
return false;
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(connString))
|
|
{
|
|
return (dbConn.ExecuteQuery(string.Format("select count(userid) from {0} where userid=? and roleid=?;", _userInRolesTable), userid, roleid)).Count() > 0;
|
|
}
|
|
}
|
|
|
|
public override void RemoveUsersFromRoles(string[] usernames, string[] roleNames)
|
|
{
|
|
if (!Initialized)
|
|
_prevProvider.RemoveUsersFromRoles(usernames, roleNames);
|
|
else
|
|
{
|
|
if (usernames.Where(username => string.IsNullOrEmpty(username)).Count() > 0 || usernames.Where(username => string.IsNullOrEmpty(username)).Count() > 0)
|
|
throw new ArgumentException(Resources.InvalidArrayValue);
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
foreach (var userid in GetUsersId(usernames))
|
|
{
|
|
foreach (var roleid in GetRolesId(roleNames))
|
|
{
|
|
if (userid > 0 && roleid > 0)
|
|
{
|
|
dbConn.ExecuteNonQuery(string.Format("delete from {0} where userid=? and roleid=?;", _userInRolesTable), userid, roleid);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public override bool RoleExists(string roleName)
|
|
{
|
|
if (!Initialized)
|
|
return _prevProvider.RoleExists(roleName);
|
|
return (GetRoleId(roleName) > 0);
|
|
}
|
|
|
|
#region Properties
|
|
|
|
public override string ApplicationName
|
|
{
|
|
get
|
|
{
|
|
if (Initialized)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
else
|
|
{
|
|
return _prevProvider.ApplicationName;
|
|
}
|
|
}
|
|
set
|
|
{
|
|
if (Initialized)
|
|
{
|
|
throw new NotSupportedException();
|
|
}
|
|
else
|
|
{
|
|
_prevProvider.ApplicationName = value;
|
|
}
|
|
}
|
|
}
|
|
|
|
public string ConnectionString
|
|
{ get; set; }
|
|
|
|
public string ConnectionStringName
|
|
{ get; set; }
|
|
|
|
public string UserTableName
|
|
{
|
|
get
|
|
{
|
|
if (string.IsNullOrEmpty(_userTableName))
|
|
throw new InvalidOperationException(Resources.UserTableNameNotInitilized);
|
|
|
|
return _userTableName;
|
|
}
|
|
internal set
|
|
{
|
|
_userTableName = value;
|
|
}
|
|
}
|
|
|
|
public string UserIdColumn
|
|
{
|
|
get
|
|
{
|
|
if (string.IsNullOrEmpty(_userIdColumn))
|
|
throw new InvalidOperationException(Resources.UserIdColumnNotInitialized);
|
|
|
|
return _userIdColumn;
|
|
}
|
|
internal set
|
|
{
|
|
_userIdColumn = value;
|
|
}
|
|
}
|
|
|
|
public string UserNameColumn
|
|
{
|
|
get
|
|
{
|
|
if (string.IsNullOrEmpty(_userNameColumn))
|
|
throw new InvalidOperationException(Resources.UserNameColumnNotInitialized);
|
|
|
|
return _userNameColumn;
|
|
}
|
|
internal set
|
|
{
|
|
_userNameColumn = value;
|
|
}
|
|
}
|
|
|
|
#endregion
|
|
|
|
#region Private_Internal
|
|
internal bool Initialized
|
|
{
|
|
get;
|
|
set;
|
|
}
|
|
|
|
internal void CreateTables()
|
|
{
|
|
var connString = GetConnectionString();
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(connString))
|
|
{
|
|
//create schema
|
|
ResourceManager r = new ResourceManager("MySql.Web.Properties.Resources", typeof(SchemaManager).Assembly);
|
|
string schema = r.GetString("schema11");
|
|
dbConn.ExecuteNonQuery(schema);
|
|
}
|
|
}
|
|
|
|
private string GetConnectionString()
|
|
{
|
|
if (!string.IsNullOrEmpty(ConnectionString))
|
|
return ConnectionString;
|
|
else
|
|
{
|
|
ConnectionStringSettings connString = ConfigurationManager.ConnectionStrings[ConnectionStringName];
|
|
if (connString != null)
|
|
return connString.ConnectionString;
|
|
}
|
|
|
|
if (!string.IsNullOrEmpty(_connString))
|
|
return _connString;
|
|
throw new InvalidOperationException(Resources.NoConnString);
|
|
}
|
|
|
|
private IEnumerable<int> GetUsersId(string[] usersName)
|
|
{
|
|
foreach (string userName in usersName)
|
|
{
|
|
yield return MySqlSimpleMembershipProvider.GetUserId(userName, GetConnectionString(), UserTableName, UserIdColumn, UserNameColumn);
|
|
}
|
|
}
|
|
|
|
private IEnumerable<int> GetRolesId(string[] roles)
|
|
{
|
|
foreach (string role in roles)
|
|
{
|
|
yield return GetRoleId(role);
|
|
}
|
|
}
|
|
|
|
internal int GetRoleId(string role)
|
|
{
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
var roleid = dbConn.ExecuteQuerySingleRecord(string.Format("select roleid from {0} where rolename=?;", _rolesTable), role);
|
|
if (roleid != null)
|
|
return (int)role[0];
|
|
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
private bool UserHasRole(int userid, int roleid)
|
|
{
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
return (dbConn.ExecuteQuery(string.Format("select count(*) from {0} where userid=? and roleid=?;", _userInRolesTable), userid, roleid).Count() > 0);
|
|
}
|
|
}
|
|
|
|
private bool IsRoleInUse(int roleid)
|
|
{
|
|
using (MySqlDatabaseWrapper dbConn = new MySqlDatabaseWrapper(GetConnectionString()))
|
|
{
|
|
return (dbConn.ExecuteQuery(string.Format("select count(*) from {0} where roleid=?;", _userInRolesTable), roleid).Count() > 0);
|
|
}
|
|
}
|
|
#endregion
|
|
}
|
|
}
|