using System; using System.Web.Security; using System.Configuration.Provider; using System.Configuration; using Npgsql; using System.Collections.Generic; using System.Linq; using System.Collections.Specialized; namespace Npgsql.Web { /// /// Npgsql role provider. /// public class NpgsqlRoleProvider: RoleProvider { /// /// The name. /// protected string name = "NpgsqlRoleProvider"; /// /// The name of the connection string. /// protected string connectionStringName = "pgProvider"; /// /// The name of the application. /// protected string applicationName = "/"; /// /// The connection string. /// protected string connectionString = string.Empty; /// /// Initialize the specified iname and config. /// /// Iname. /// Config. public override void Initialize (string iname, NameValueCollection config) { // get the // - application name // - connection string name // - the connection string from its name string cnxName = config ["connectionStringName"]; connectionString = ConfigurationManager.ConnectionStrings [cnxName].ConnectionString; config.Remove ("connectionStringName"); applicationName = config ["applicationName"]; config.Remove ("applicationName"); base.Initialize (iname, config); } /// To be added. /// /// Adds the users to roles. /// /// Usernames. /// Role names. public override void AddUsersToRoles (string[] usernames, string[] roleNames) { if (usernames.Any (x => x == null) || roleNames.Any (x => x == null)) { throw new ArgumentNullException (); } if (usernames.Any (x => x.Trim () == string.Empty) || (roleNames.Any (x => x.Trim () == string.Empty))) { throw new ArgumentException ("One or more of the supplied usernames or role names are empty."); } using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "insert into usersroles (applicationname, username, rolename) values (@appname,@user,@role)"; comm.Parameters.AddWithValue ("appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; NpgsqlParameter pu = comm.Parameters.AddWithValue ("user", NpgsqlTypes.NpgsqlDbType.Varchar, 250); NpgsqlParameter pr = comm.Parameters.AddWithValue ("role", NpgsqlTypes.NpgsqlDbType.Varchar, 250); foreach (string u in usernames) { pu.Value = u; foreach (string r in roleNames) { pr.Value = r; comm.ExecuteNonQuery (); } } } } } /// /// Gets or sets the name of the application. /// /// The name of the application. public override string ApplicationName { get { return applicationName; } set { applicationName = value; } } /// To be added. /// /// Creates the role. /// /// Role name. public override void CreateRole (string roleName) { if (roleName == null) throw new ArgumentNullException (); if (roleName.Trim () == string.Empty) throw new ArgumentException ("A role name cannot be empty."); if (roleName.Contains (",")) throw new ArgumentException ("A role name cannot contain commas. Blame Microsoft for that rule!"); if (roleName.Length > 250) throw new ArgumentException ("The maximum length for a Role name is 250 characters."); using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "insert into roles (rolename, applicationname, comment) values (@rolename, @appname, @comment)"; comm.Parameters.AddWithValue ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; comm.Parameters.AddWithValue ("@comment", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; comm.ExecuteNonQuery (); } } } /// To be added. /// /// Deletes the role. /// /// true, if role was deleted, false otherwise. /// Role name. /// If set to true throw on populated role. public override bool DeleteRole (string roleName, bool throwOnPopulatedRole) { if (roleName == null) throw new ArgumentNullException (); if (roleName.Trim () == string.Empty) throw new ArgumentException ("The specified role name cannot be empty."); if (throwOnPopulatedRole) if (FindUsersInRole (roleName, "").Count () > 0) throw new ProviderException ( string.Format ("The role {0} is populated, we cannot delete it.", roleName)); using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "delete from roles where rolename = @rolename and applicationname = @appname"; comm.Parameters.AddWithValue ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; comm.Parameters.AddWithValue ("@comment", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; comm.ExecuteNonQuery (); } } return true; } /// /// Finds the users in role. /// /// The users in role. /// Role name. /// Username to match. public override string[] FindUsersInRole (string roleName, string usernameToMatch) { return GetUsersInRole (roleName, usernameToMatch); } /// /// Gets the users in role. /// /// The users in role. /// Rolename. /// Username to match. protected string[] GetUsersInRole (string rolename, string usernameToMatch) { if (rolename == null) throw new ArgumentNullException (); if (rolename == string.Empty) throw new ProviderException ("Cannot look for blank role names."); usernameToMatch = usernameToMatch ?? string.Empty; using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "select username from usersroles where applicationname = @appname " + "and rolename = @rolename and username like @username"; comm.Parameters.AddWithValue ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = rolename; comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; comm.Parameters.AddWithValue ("@username", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = usernameToMatch; using (var reader = comm.ExecuteReader()) { var r = new List (); var usernameColumn = reader.GetOrdinal ("username"); while (reader.Read()) { r.Add (reader.GetString (usernameColumn)); } return r.ToArray (); } } } } /// /// Gets all roles. /// /// The all roles. public override string[] GetAllRoles () { using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "select rolename from roles where applicationname = @appname"; comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; using (var reader = comm.ExecuteReader()) { var r = new List (); var rolenameColumn = reader.GetOrdinal ("rolename"); while (reader.Read()) { r.Add (reader.GetString (rolenameColumn)); } return r.ToArray (); } } } } /// /// Gets the roles for user. /// /// The roles for user. /// Username. public override string[] GetRolesForUser (string username) { if (username == null) throw new ArgumentNullException (); if (username.Trim () == string.Empty) throw new ArgumentException ("The specified username cannot be blank."); using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "select rolename from usersroles where applicationname = @appname and username = @username"; comm.Parameters.AddWithValue ("@username", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = username; comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; using (var reader = comm.ExecuteReader()) { var r = new List (); var rolenameColumn = reader.GetOrdinal ("rolename"); while (reader.Read()) { r.Add (reader.GetString (rolenameColumn)); } return r.ToArray (); } } } } /// To be added. /// /// Gets the users in role. /// /// The users in role. /// Role name. public override string[] GetUsersInRole (string roleName) { if (string.IsNullOrEmpty (roleName)) throw new ArgumentException ("The specified role name cannot be blank or null"); using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { // comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "select username from usersroles where applicationname = @appname " + "and rolename = @rolename"; comm.Parameters.AddWithValue ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 255).Value = roleName; comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 255).Value = applicationName; using (var reader = comm.ExecuteReader()) { var r = new List (); var usernameColumn = reader.GetOrdinal ("username"); while (reader.Read()) { r.Add (reader.GetString (usernameColumn)); } return r.ToArray (); } } } } /// To be added. /// /// Determines whether this instance is user in role the specified username roleName. /// /// true if this instance is user in role the specified username roleName; otherwise, false. /// Username. /// Role name. public override bool IsUserInRole (string username, string roleName) { if (username == null || roleName == null) throw new ArgumentNullException (); if (username.Trim () == string.Empty) throw new ArgumentException ("The specified username cannot be blank."); if (roleName.Trim () == string.Empty) throw new ArgumentException ("The specified role name cannot be blank."); using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { // comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "select count(*)>0 from usersroles where applicationname = @appname " + "and username = @username and rolename = @rolename"; comm.Parameters.AddWithValue ("@username", username); comm.Parameters.AddWithValue ("@rolename", roleName); comm.Parameters.AddWithValue ("@appname", applicationName); var retval = (bool)comm.ExecuteScalar (); return retval; } } } /// To be added. /// /// Removes the users from roles. /// /// Usernames. /// Role names. public override void RemoveUsersFromRoles (string[] usernames, string[] roleNames) { if (usernames.Any (x => x == null) || roleNames.Any (x => x == null)) { throw new ArgumentNullException (); } if (usernames.Any (x => x.Trim () == string.Empty) || (roleNames.Any (x => x.Trim () == string.Empty))) { throw new ArgumentException ("One or more of the supplied usernames or role names are empty."); } using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = conn.CreateCommand()) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "delete from usersroles where applicationname = @appname and " + "username = @username and rolename = @rolename"; NpgsqlParameter pu = comm.Parameters.AddWithValue ("@username", NpgsqlTypes.NpgsqlDbType.Varchar, 250); NpgsqlParameter pr = comm.Parameters.AddWithValue ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250); comm.Parameters.AddWithValue ("@appname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; foreach (string rolename in roleNames) { pr.Value = rolename; foreach (string username in usernames) { pu.Value = username; comm.ExecuteNonQuery (); } } } } } /// Tests if a given role name exists. /// /// Tests if a given role name exists. /// /// true, if exists was roled, false otherwise. /// Role name. public override bool RoleExists (string roleName) { using (var conn = new NpgsqlConnection(connectionString)) { conn.Open (); using (var comm = new NpgsqlCommand("role_exists", conn)) { comm.CommandType = System.Data.CommandType.Text; comm.CommandText = "select Count(*)>0 from roles where applicationname = @applicationname and rolename = @rolename"; comm.Parameters.AddWithValue ("@rolename", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = roleName; comm.Parameters.AddWithValue ("@applicationname", NpgsqlTypes.NpgsqlDbType.Varchar, 250).Value = applicationName; var retval = (bool)comm.ExecuteScalar (); return retval; } } } /// /// Gets the name of this provider, /// should correspond to the item key /// in the configuration collection of providers. /// /// The name. public override string Name { get { return name; } } /// /// Gets the description for this provider. /// /// The description. public override string Description { get { return "PostgreSQL ASP.Net Role Provider class"; } } } }