2 // $Id: PgRoleProvider.cs 12 2007-10-17 17:22:43Z dna $
4 // Permission is hereby granted, free of charge, to any person obtaining
5 // a copy of this software and associated documentation files (the
6 // "Software"), to deal in the Software without restriction, including
7 // without limitation the rights to use, copy, modify, merge, publish,
8 // distribute, sublicense, and/or sell copies of the Software, and to
9 // permit persons to whom the Software is furnished to do so, subject to
10 // the following conditions:
12 // The above copyright notice and this permission notice shall be
13 // included in all copies or substantial portions of the Software.
15 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
23 // Copyright © 2006, 2007 Nauck IT KG http://www.nauck-it.de
26 // Daniel Nauck <d.nauck(at)nauck-it.de>
28 // Adapted to Sqlite by Marek Habersack <mhabersack@novell.com>
33 using System.Data.Common;
34 using System.Collections.Generic;
35 using System.Collections.Specialized;
36 using System.Diagnostics;
38 using System.Configuration;
39 using System.Configuration.Provider;
40 using System.Web.Hosting;
41 using System.Web.Security;
43 using Mono.Data.Sqlite;
45 namespace System.Web.Security
47 internal class SqliteRoleProvider : RoleProvider
49 const string m_RolesTableName = "Roles";
50 const string m_UserInRolesTableName = "UsersInRoles";
51 string m_ConnectionString = string.Empty;
53 DbParameter AddParameter (DbCommand command, string parameterName)
55 return AddParameter (command, parameterName, null);
58 DbParameter AddParameter (DbCommand command, string parameterName, object parameterValue)
60 return AddParameter (command, parameterName, ParameterDirection.Input, parameterValue);
63 DbParameter AddParameter (DbCommand command, string parameterName, ParameterDirection direction, object parameterValue)
65 DbParameter dbp = command.CreateParameter ();
66 dbp.ParameterName = parameterName;
67 dbp.Value = parameterValue;
68 dbp.Direction = direction;
69 command.Parameters.Add (dbp);
74 /// System.Configuration.Provider.ProviderBase.Initialize Method
76 public override void Initialize(string name, NameValueCollection config)
78 // Initialize values from web.config.
80 throw new ArgumentNullException("Config", Properties.Resources.ErrArgumentNull);
82 if (string.IsNullOrEmpty(name))
83 name = Properties.Resources.RoleProviderDefaultName;
85 if (string.IsNullOrEmpty(config["description"]))
87 config.Remove("description");
88 config.Add("description", Properties.Resources.RoleProviderDefaultDescription);
91 // Initialize the abstract base class.
92 base.Initialize(name, config);
94 m_ApplicationName = GetConfigValue(config["applicationName"], HostingEnvironment.ApplicationVirtualPath);
96 // Get connection string.
97 string connStrName = config["connectionStringName"];
99 if (string.IsNullOrEmpty(connStrName))
101 throw new ArgumentOutOfRangeException("ConnectionStringName", Properties.Resources.ErrArgumentNullOrEmpty);
105 ConnectionStringSettings ConnectionStringSettings = ConfigurationManager.ConnectionStrings[connStrName];
107 if (ConnectionStringSettings == null || string.IsNullOrEmpty(ConnectionStringSettings.ConnectionString.Trim()))
109 throw new ProviderException(Properties.Resources.ErrConnectionStringNullOrEmpty);
112 m_ConnectionString = ConnectionStringSettings.ConnectionString;
117 /// System.Web.Security.RoleProvider properties.
119 #region System.Web.Security.RoleProvider properties
120 string m_ApplicationName = string.Empty;
122 public override string ApplicationName
124 get { return m_ApplicationName; }
125 set { m_ApplicationName = value; }
130 /// System.Web.Security.RoleProvider methods.
132 #region System.Web.Security.RoleProvider methods
135 /// RoleProvider.AddUsersToRoles
137 public override void AddUsersToRoles(string[] userNames, string[] roleNames)
139 foreach (string rolename in roleNames)
141 if (!RoleExists(rolename))
143 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, rolename));
147 foreach (string username in userNames)
149 foreach (string rolename in roleNames)
151 if (IsUserInRole(username, rolename))
153 throw new ProviderException(string.Format(Properties.Resources.ErrUserAlreadyInRole, username, rolename));
158 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
160 using (SqliteCommand dbCommand = dbConn.CreateCommand())
162 dbCommand.CommandText = string.Format("INSERT INTO \"{0}\" (\"Username\", \"Rolename\", \"ApplicationName\") Values (@Username, @Rolename, @ApplicationName)", m_UserInRolesTableName);
164 AddParameter (dbCommand, "@Username");
165 AddParameter (dbCommand, "@Rolename");
166 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
168 SqliteTransaction dbTrans = null;
175 using (dbTrans = dbConn.BeginTransaction())
177 foreach (string username in userNames)
179 foreach (string rolename in roleNames)
181 dbCommand.Parameters["@Username"].Value = username;
182 dbCommand.Parameters["@Rolename"].Value = rolename;
183 dbCommand.ExecuteNonQuery();
186 // Attempt to commit the transaction
190 catch (SqliteException e)
192 Trace.WriteLine(e.ToString());
196 // Attempt to roll back the transaction
197 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
200 catch (SqliteException re)
203 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
204 Trace.WriteLine(re.ToString());
207 throw new ProviderException(Properties.Resources.ErrOperationAborted);
219 /// RoleProvider.CreateRole
221 public override void CreateRole(string roleName)
223 if (RoleExists(roleName))
225 throw new ProviderException(string.Format(Properties.Resources.ErrRoleAlreadyExist, roleName));
228 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
230 using (SqliteCommand dbCommand = dbConn.CreateCommand())
232 dbCommand.CommandText = string.Format("INSERT INTO \"{0}\" (\"Rolename\", \"ApplicationName\") Values (@Rolename, @ApplicationName)", m_RolesTableName);
234 AddParameter (dbCommand, "@Rolename", roleName);
235 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
242 dbCommand.ExecuteNonQuery();
244 catch (SqliteException e)
246 Trace.WriteLine(e.ToString());
247 throw new ProviderException(Properties.Resources.ErrOperationAborted);
259 /// RoleProvider.DeleteRole
261 public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
263 if (!RoleExists(roleName))
265 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, roleName));
268 if (throwOnPopulatedRole && GetUsersInRole(roleName).Length > 0)
270 throw new ProviderException(Properties.Resources.ErrCantDeletePopulatedRole);
273 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
275 using (SqliteCommand dbCommand = dbConn.CreateCommand())
277 dbCommand.CommandText = string.Format("DELETE FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_RolesTableName);
279 AddParameter (dbCommand, "@Rolename", roleName);
280 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
282 SqliteTransaction dbTrans = null;
289 using (dbTrans = dbConn.BeginTransaction())
291 dbCommand.ExecuteNonQuery();
293 // Attempt to commit the transaction
297 catch (SqliteException e)
299 Trace.WriteLine(e.ToString());
303 // Attempt to roll back the transaction
304 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
307 catch (SqliteException re)
310 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
311 Trace.WriteLine(re.ToString());
314 throw new ProviderException(Properties.Resources.ErrOperationAborted);
328 /// RoleProvider.FindUsersInRole
330 public override string[] FindUsersInRole(string roleName, string usernameToMatch)
332 List<string> userList = new List<string>();
334 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
336 using (SqliteCommand dbCommand = dbConn.CreateCommand())
338 dbCommand.CommandText = string.Format("SELECT \"Username\" FROM \"{0}\" WHERE \"Username\" LIKE @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName ORDER BY \"Username\" ASC", m_UserInRolesTableName);
340 AddParameter (dbCommand, "@Username", usernameToMatch);
341 AddParameter (dbCommand, "@Rolename", roleName);
342 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
349 using (SqliteDataReader reader = dbCommand.ExecuteReader())
353 while (reader.Read())
355 userList.Add(reader.GetString(0));
360 catch (SqliteException e)
362 Trace.WriteLine(e.ToString());
363 throw new ProviderException(Properties.Resources.ErrOperationAborted);
373 return userList.ToArray();
377 /// RoleProvider.GetAllRoles
379 public override string[] GetAllRoles()
381 List<string> rolesList = new List<string>();
383 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
385 using (SqliteCommand dbCommand = dbConn.CreateCommand())
387 dbCommand.CommandText = string.Format("SELECT \"Rolename\" FROM \"{0}\" WHERE \"ApplicationName\" = @ApplicationName ORDER BY \"Rolename\" ASC", m_RolesTableName);
389 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
396 using (SqliteDataReader reader = dbCommand.ExecuteReader())
398 while (reader.Read())
400 rolesList.Add(reader.GetString(0));
404 catch (SqliteException e)
406 Trace.WriteLine(e.ToString());
407 throw new ProviderException(Properties.Resources.ErrOperationAborted);
417 return rolesList.ToArray();
421 /// RoleProvider.GetRolesForUser
423 public override string[] GetRolesForUser(string username)
425 List<string> rolesList = new List<string>();
427 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
429 using (SqliteCommand dbCommand = dbConn.CreateCommand())
431 dbCommand.CommandText = string.Format("SELECT \"Rolename\" FROM \"{0}\" WHERE \"Username\" = @Username AND \"ApplicationName\" = @ApplicationName ORDER BY \"Rolename\" ASC", m_UserInRolesTableName);
433 AddParameter (dbCommand, "@Username", username);
434 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
441 using (SqliteDataReader reader = dbCommand.ExecuteReader())
445 while (reader.Read())
447 rolesList.Add(reader.GetString(0));
452 catch (SqliteException e)
454 Trace.WriteLine(e.ToString());
455 throw new ProviderException(Properties.Resources.ErrOperationAborted);
465 return rolesList.ToArray();
469 /// RoleProvider.GetUsersInRole
471 public override string[] GetUsersInRole(string roleName)
473 List<string> userList = new List<string>();
475 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
477 using (SqliteCommand dbCommand = dbConn.CreateCommand())
479 dbCommand.CommandText = string.Format("SELECT \"Username\" FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName ORDER BY \"Username\" ASC", m_UserInRolesTableName);
481 AddParameter (dbCommand, "@Rolename", roleName);
482 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
489 using (SqliteDataReader reader = dbCommand.ExecuteReader())
493 while (reader.Read())
495 userList.Add(reader.GetString(0));
500 catch (SqliteException e)
502 Trace.WriteLine(e.ToString());
503 throw new ProviderException(Properties.Resources.ErrOperationAborted);
513 return userList.ToArray();
517 /// RoleProvider.IsUserInRole
519 public override bool IsUserInRole(string userName, string roleName)
521 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
523 using (SqliteCommand dbCommand = dbConn.CreateCommand())
525 dbCommand.CommandText = string.Format("SELECT COUNT(*) FROM \"{0}\" WHERE \"Username\" = @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_UserInRolesTableName);
527 AddParameter (dbCommand, "@Username", userName);
528 AddParameter (dbCommand, "@Rolename", roleName);
529 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
537 Int32.TryParse(dbCommand.ExecuteScalar().ToString(), out numRecs);
542 catch (SqliteException e)
544 Trace.WriteLine(e.ToString());
545 throw new ProviderException(Properties.Resources.ErrOperationAborted);
559 /// RoleProvider.RemoveUsersFromRoles
561 public override void RemoveUsersFromRoles(string[] userNames, string[] roleNames)
563 foreach (string rolename in roleNames)
565 if (!RoleExists(rolename))
567 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, rolename));
571 foreach (string username in userNames)
573 foreach (string rolename in roleNames)
575 if (!IsUserInRole(username, rolename))
577 throw new ProviderException(string.Format(Properties.Resources.ErrUserIsNotInRole, username, rolename));
582 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
584 using (SqliteCommand dbCommand = dbConn.CreateCommand())
586 dbCommand.CommandText = string.Format("DELETE FROM \"{0}\" WHERE \"Username\" = @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_UserInRolesTableName);
588 AddParameter (dbCommand, "@Username");
589 AddParameter (dbCommand, "@Rolename");
590 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
592 SqliteTransaction dbTrans = null;
599 using (dbTrans = dbConn.BeginTransaction())
601 foreach (string username in userNames)
603 foreach (string rolename in roleNames)
605 dbCommand.Parameters["@Username"].Value = username;
606 dbCommand.Parameters["@Rolename"].Value = rolename;
607 dbCommand.ExecuteNonQuery();
610 // Attempt to commit the transaction
614 catch (SqliteException e)
616 Trace.WriteLine(e.ToString());
620 // Attempt to roll back the transaction
621 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
624 catch (SqliteException re)
627 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
628 Trace.WriteLine(re.ToString());
631 throw new ProviderException(Properties.Resources.ErrOperationAborted);
643 /// RoleProvider.RoleExists
645 public override bool RoleExists(string roleName)
647 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
649 using (SqliteCommand dbCommand = dbConn.CreateCommand())
651 dbCommand.CommandText = string.Format("SELECT COUNT(*) FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_RolesTableName);
653 AddParameter (dbCommand, "@Rolename", roleName);
654 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
662 Int32.TryParse(dbCommand.ExecuteScalar().ToString(), out numRecs);
667 catch (SqliteException e)
669 Trace.WriteLine(e.ToString());
670 throw new ProviderException(Properties.Resources.ErrOperationAborted);
684 #region private methods
686 /// A helper function to retrieve config values from the configuration file.
688 /// <param name="configValue"></param>
689 /// <param name="defaultValue"></param>
690 /// <returns></returns>
691 string GetConfigValue(string configValue, string defaultValue)
693 if (string.IsNullOrEmpty(configValue))