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 } }