using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Configuration;
using System.Configuration.Provider;
using System.Data;
using System.Data.SqlClient;
using System.Web.Hosting;
using System.Web.Security;
using Neo.Afx.ComponentModel;
using Neo.Afx.Diagnostics;
namespace Neo.Afx.Security
{
///
/// A custom role provider for use with our custom security API.
///
public class DomainRoleProvider : RoleProvider
{
const string EventSource = "DomainRoleProvider";
const string ExceptionMessage = "An exception occurred. Please check the Event Log.";
const string PrGetAllRoles = "Security.Pr_GetAllRoles";
const string PrGetRolesForUser = "Security.Pr_GetRolesForUser"; // @AppName, @UserName, @AuthMode
const string PrGetUsersInRole = "Security.Pr_GetUsersInRole"; // @AppName, @RoleName, @AuthMode
const string PrIsUserInRole = "Security.Pr_IsUserInRole"; // @AppName, @RoleName, @UserName, @AuthMode
const string PrRoleExists = "Security.Pr_RoleExists"; // @AppName, @RoleName
const string PrFindUsersInRole = "Security.Pr_FindUsersInRole"; // @AppName, @RoleName, @UserName, @AuthMode
string _connectionString;
ConnectionStringSettings _connectionStringSettings;
#region Properties
#region WriteExceptionsToEventLog
///
/// Gets or sets a value indicating whether exceptions are written to the event log.
/// If false, exceptions are thrown to the caller, otherwise exceptions are written to the event log.
///
public bool WriteExceptionsToEventLog
{
get;
set;
}
#endregion
#region ApplicationName
///
/// Gets or sets the name of the application to store and retrieve role information for.
///
public override string ApplicationName
{
get;
set;
}
#endregion
#endregion
#region Non-implemented Methods
///
/// Not implmented
///
/// The usernames.
/// The rolenames.
public override void AddUsersToRoles(string[] usernames, string[] rolenames)
{
}
///
/// Not implmented
///
/// The rolename.
public override void CreateRole(string rolename)
{
}
///
/// Not implmented
///
/// The rolename.
/// true if Throw on populated role; false otherwise.
///
public override bool DeleteRole(string rolename, bool throwOnPopulatedRole)
{
return true;
}
///
/// Not implmented
///
/// The usernames.
/// The rolenames.
public override void RemoveUsersFromRoles(string[] usernames, string[] rolenames)
{
}
#endregion
#region Initialize
///
/// Initializes the provider.
///
/// The friendly name of the provider.
///
/// A collection of the name/value pairs representing
/// the provider-specific attributes specified in the configuration for this provider.
///
/// The name of the provider is null.
///
/// An attempt is made to call Initialize on a provider after the provider has already been initialized.
///
/// The name of the provider has a length of zero.
public override void Initialize(string name, NameValueCollection config)
{
if(config == null)
{
throw new ArgumentNullException("config");
}
if(name.Length == 0)
{
name = "DomainRoleProvider";
}
if(String.IsNullOrEmpty(config["description"]))
{
config.Remove("description");
config.Add("description", "Simple SQL Role provider");
}
// Initialize the abstract base class.
base.Initialize(name, config);
if(config["applicationName"] == null || config["applicationName"].Trim() == "")
{
ApplicationName = HostingEnvironment.ApplicationVirtualPath;
}
else
{
ApplicationName = config["applicationName"];
}
if(config["writeExceptionsToEventLog"] != null)
{
if(config["writeExceptionsToEventLog"].ToUpper() == "TRUE")
{
WriteExceptionsToEventLog = true;
}
}
// Initialize connection.
_connectionStringSettings = ConfigurationManager.ConnectionStrings[config["connectionStringName"]];
if(_connectionStringSettings == null || _connectionStringSettings.ConnectionString.Trim() == "")
{
throw new ProviderException("Connection string cannot be blank.");
}
_connectionString = _connectionStringSettings.ConnectionString;
}
#endregion
#region GetAllRoles
///
/// Gets a list of all the roles.
///
///
/// A string array containing the names of
/// all the roles stored in the data source.
///
public override string[] GetAllRoles()
{
try
{
using(var conn = new SqlConnection(_connectionString))
{
using(var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = PrGetAllRoles;
cmd.Parameters.AddWithValue("@AppName", ApplicationName);
cmd.Connection.Open();
return ToArray(cmd);
}
}
}
catch(SqlException e)
{
if(WriteExceptionsToEventLog)
{
LogUtility.WriteApplicationEventLog(e);
throw new ProviderException(ExceptionMessage);
}
throw;
}
}
#endregion
#region GetRolesForUser
///
/// Gets the roles for the given user.
///
/// The name of the user to be queried.
/// The roles for user.
public override string[] GetRolesForUser(string userName)
{
try
{
using(var conn = new SqlConnection(_connectionString))
{
using(var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = PrGetRolesForUser;
cmd.Parameters.AddWithValue("@AppName", ApplicationName);
cmd.Parameters.AddWithValue("@UserName", userName);
cmd.Parameters.AddWithValue("@AuthMode", DomainAuthenticationProvider.AuthenticationMode.ToString());
cmd.Connection.Open();
return ToArray(cmd);
}
}
}
catch(SqlException e)
{
if(WriteExceptionsToEventLog)
{
LogUtility.WriteApplicationEventLog(e);
throw new ProviderException(ExceptionMessage);
}
throw;
}
}
#endregion
#region GetUsersInRole
///
/// Gets the users in the given role.
///
/// The name of the role to be queried.
/// The users in the given role.
public override string[] GetUsersInRole(string roleName)
{
try
{
using(var conn = new SqlConnection(_connectionString))
{
using(var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = PrGetUsersInRole;
cmd.Parameters.AddWithValue("@AppName", ApplicationName);
cmd.Parameters.AddWithValue("@RoleName", roleName);
cmd.Parameters.AddWithValue("@AuthMode", DomainAuthenticationProvider.AuthenticationMode.ToString());
cmd.Connection.Open();
return ToArray(cmd);
}
}
}
catch(SqlException e)
{
if(WriteExceptionsToEventLog)
{
LogUtility.WriteApplicationEventLog(e);
throw new ProviderException(ExceptionMessage);
}
throw;
}
}
#endregion
#region IsUserInRole
///
/// Determines whether the given user is in the given role.
///
/// The name of the user to be queried.
/// The name of the role to be queried.
///
/// true if the given user is in the given role; false otherwise.
///
public override bool IsUserInRole(string userName, string roleName)
{
bool userIsInRole;
try
{
using(var conn = new SqlConnection(_connectionString))
{
using(var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = PrIsUserInRole;
cmd.Parameters.AddWithValue("@AppName", ApplicationName);
cmd.Parameters.AddWithValue("@RoleName", roleName);
cmd.Parameters.AddWithValue("@UserName", userName);
cmd.Parameters.AddWithValue("@AuthMode", DomainAuthenticationProvider.AuthenticationMode.ToString());
cmd.Connection.Open();
userIsInRole = cmd.ExecuteScalar().ToBoolean();
}
}
}
catch(SqlException e)
{
if(WriteExceptionsToEventLog)
{
LogUtility.WriteApplicationEventLog(e);
throw new ProviderException(ExceptionMessage);
}
throw;
}
return userIsInRole;
}
#endregion
#region RoleExists
///
/// Determines whether the given role exists.
///
/// The name of the role to be queried.
///
/// true if the given role exists; false otherwise.
///
public override bool RoleExists(string roleName)
{
bool exists;
try
{
using(var conn = new SqlConnection(_connectionString))
{
using(var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = PrRoleExists;
cmd.Parameters.AddWithValue("@AppName", ApplicationName);
cmd.Parameters.AddWithValue("@RoleName", roleName);
cmd.Connection.Open();
exists = cmd.ExecuteScalar().ToBoolean();
}
}
}
catch(SqlException e)
{
if(WriteExceptionsToEventLog)
{
LogUtility.WriteApplicationEventLog(e);
throw new ProviderException(ExceptionMessage);
}
throw;
}
return exists;
}
#endregion
#region FindUsersInRole
///
/// Finds the users in the given role.
///
/// The name of the role to be queried.
/// The user names to be matched.
/// The users in the given role.
public override string[] FindUsersInRole(string roleName, string userNameToMatch)
{
try
{
using(var conn = new SqlConnection(_connectionString))
{
using(var cmd = conn.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = PrFindUsersInRole;
cmd.Parameters.AddWithValue("@AppName", ApplicationName);
cmd.Parameters.AddWithValue("@RoleName", roleName);
cmd.Parameters.AddWithValue("@UserName", userNameToMatch);
cmd.Parameters.AddWithValue("@AuthMode", DomainAuthenticationProvider.AuthenticationMode.ToString());
cmd.Connection.Open();
return ToArray(cmd);
}
}
}
catch(SqlException e)
{
if(WriteExceptionsToEventLog)
{
LogUtility.WriteApplicationEventLog(e);
throw new ProviderException(ExceptionMessage);
}
throw;
}
}
#endregion
#region ToArray
static string[] ToArray(SqlCommand cmd)
{
using(var reader = cmd.ExecuteReader(CommandBehavior.CloseConnection))
{
var list = new List();
while(reader.Read())
{
list.Add(reader[0].ToString());
}
return list.ToArray();
}
}
#endregion
}
}