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>
34 using System.Data.Common;
35 using System.Collections.Generic;
36 using System.Collections.Specialized;
37 using System.Diagnostics;
39 using System.Configuration;
40 using System.Configuration.Provider;
41 using System.Web.Hosting;
42 using System.Web.Security;
44 using Mono.Data.Sqlite;
46 namespace System.Web.Security
48 internal class SqliteRoleProvider : RoleProvider
50 private const string m_RolesTableName = "Roles";
51 private const string m_UserInRolesTableName = "UsersInRoles";
52 private string m_ConnectionString = string.Empty;
54 DbParameter AddParameter (DbCommand command, string parameterName)
56 return AddParameter (command, parameterName, null);
59 DbParameter AddParameter (DbCommand command, string parameterName, object parameterValue)
61 return AddParameter (command, parameterName, ParameterDirection.Input, parameterValue);
64 DbParameter AddParameter (DbCommand command, string parameterName, ParameterDirection direction, object parameterValue)
66 DbParameter dbp = command.CreateParameter ();
67 dbp.ParameterName = parameterName;
68 dbp.Value = parameterValue;
69 dbp.Direction = direction;
70 command.Parameters.Add (dbp);
74 DbParameter AddParameter (DbCommand command, string parameterName, ParameterDirection direction, DbType type, object parameterValue)
76 DbParameter dbp = command.CreateParameter ();
77 dbp.ParameterName = parameterName;
78 dbp.Value = parameterValue;
79 dbp.Direction = direction;
81 command.Parameters.Add (dbp);
86 /// System.Configuration.Provider.ProviderBase.Initialize Method
88 public override void Initialize(string name, NameValueCollection config)
90 // Initialize values from web.config.
92 throw new ArgumentNullException("Config", Properties.Resources.ErrArgumentNull);
94 if (string.IsNullOrEmpty(name))
95 name = Properties.Resources.RoleProviderDefaultName;
97 if (string.IsNullOrEmpty(config["description"]))
99 config.Remove("description");
100 config.Add("description", Properties.Resources.RoleProviderDefaultDescription);
103 // Initialize the abstract base class.
104 base.Initialize(name, config);
106 m_ApplicationName = GetConfigValue(config["applicationName"], HostingEnvironment.ApplicationVirtualPath);
108 // Get connection string.
109 string connStrName = config["connectionStringName"];
111 if (string.IsNullOrEmpty(connStrName))
113 throw new ArgumentOutOfRangeException("ConnectionStringName", Properties.Resources.ErrArgumentNullOrEmpty);
117 ConnectionStringSettings ConnectionStringSettings = ConfigurationManager.ConnectionStrings[connStrName];
119 if (ConnectionStringSettings == null || string.IsNullOrEmpty(ConnectionStringSettings.ConnectionString.Trim()))
121 throw new ProviderException(Properties.Resources.ErrConnectionStringNullOrEmpty);
124 m_ConnectionString = ConnectionStringSettings.ConnectionString;
129 /// System.Web.Security.RoleProvider properties.
131 #region System.Web.Security.RoleProvider properties
132 private string m_ApplicationName = string.Empty;
134 public override string ApplicationName
136 get { return m_ApplicationName; }
137 set { m_ApplicationName = value; }
142 /// System.Web.Security.RoleProvider methods.
144 #region System.Web.Security.RoleProvider methods
147 /// RoleProvider.AddUsersToRoles
149 public override void AddUsersToRoles(string[] userNames, string[] roleNames)
151 foreach (string rolename in roleNames)
153 if (!RoleExists(rolename))
155 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, rolename));
159 foreach (string username in userNames)
161 foreach (string rolename in roleNames)
163 if (IsUserInRole(username, rolename))
165 throw new ProviderException(string.Format(Properties.Resources.ErrUserAlreadyInRole, username, rolename));
170 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
172 using (SqliteCommand dbCommand = dbConn.CreateCommand())
174 dbCommand.CommandText = string.Format("INSERT INTO \"{0}\" (\"Username\", \"Rolename\", \"ApplicationName\") Values (@Username, @Rolename, @ApplicationName)", m_UserInRolesTableName);
176 AddParameter (dbCommand, "@Username");
177 AddParameter (dbCommand, "@Rolename");
178 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
180 SqliteTransaction dbTrans = null;
187 using (dbTrans = dbConn.BeginTransaction())
189 foreach (string username in userNames)
191 foreach (string rolename in roleNames)
193 dbCommand.Parameters["@Username"].Value = username;
194 dbCommand.Parameters["@Rolename"].Value = rolename;
195 dbCommand.ExecuteNonQuery();
198 // Attempt to commit the transaction
202 catch (SqliteException e)
204 Trace.WriteLine(e.ToString());
208 // Attempt to roll back the transaction
209 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
212 catch (SqliteException re)
215 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
216 Trace.WriteLine(re.ToString());
219 throw new ProviderException(Properties.Resources.ErrOperationAborted);
231 /// RoleProvider.CreateRole
233 public override void CreateRole(string roleName)
235 if (RoleExists(roleName))
237 throw new ProviderException(string.Format(Properties.Resources.ErrRoleAlreadyExist, roleName));
240 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
242 using (SqliteCommand dbCommand = dbConn.CreateCommand())
244 dbCommand.CommandText = string.Format("INSERT INTO \"{0}\" (\"Rolename\", \"ApplicationName\") Values (@Rolename, @ApplicationName)", m_RolesTableName);
246 AddParameter (dbCommand, "@Rolename", roleName);
247 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
254 dbCommand.ExecuteNonQuery();
256 catch (SqliteException e)
258 Trace.WriteLine(e.ToString());
259 throw new ProviderException(Properties.Resources.ErrOperationAborted);
271 /// RoleProvider.DeleteRole
273 public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
275 if (!RoleExists(roleName))
277 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, roleName));
280 if (throwOnPopulatedRole && GetUsersInRole(roleName).Length > 0)
282 throw new ProviderException(Properties.Resources.ErrCantDeletePopulatedRole);
285 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
287 using (SqliteCommand dbCommand = dbConn.CreateCommand())
289 dbCommand.CommandText = string.Format("DELETE FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_RolesTableName);
291 AddParameter (dbCommand, "@Rolename", roleName);
292 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
294 SqliteTransaction dbTrans = null;
301 using (dbTrans = dbConn.BeginTransaction())
303 dbCommand.ExecuteNonQuery();
305 // Attempt to commit the transaction
309 catch (SqliteException e)
311 Trace.WriteLine(e.ToString());
315 // Attempt to roll back the transaction
316 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
319 catch (SqliteException re)
322 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
323 Trace.WriteLine(re.ToString());
326 throw new ProviderException(Properties.Resources.ErrOperationAborted);
340 /// RoleProvider.FindUsersInRole
342 public override string[] FindUsersInRole(string roleName, string usernameToMatch)
344 List<string> userList = new List<string>();
346 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
348 using (SqliteCommand dbCommand = dbConn.CreateCommand())
350 dbCommand.CommandText = string.Format("SELECT \"Username\" FROM \"{0}\" WHERE \"Username\" LIKE @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName ORDER BY \"Username\" ASC", m_UserInRolesTableName);
352 AddParameter (dbCommand, "@Username", usernameToMatch);
353 AddParameter (dbCommand, "@Rolename", roleName);
354 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
361 using (SqliteDataReader reader = dbCommand.ExecuteReader())
365 while (reader.Read())
367 userList.Add(reader.GetString(0));
372 catch (SqliteException e)
374 Trace.WriteLine(e.ToString());
375 throw new ProviderException(Properties.Resources.ErrOperationAborted);
385 return userList.ToArray();
389 /// RoleProvider.GetAllRoles
391 public override string[] GetAllRoles()
393 List<string> rolesList = new List<string>();
395 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
397 using (SqliteCommand dbCommand = dbConn.CreateCommand())
399 dbCommand.CommandText = string.Format("SELECT \"Rolename\" FROM \"{0}\" WHERE \"ApplicationName\" = @ApplicationName ORDER BY \"Rolename\" ASC", m_RolesTableName);
401 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
408 using (SqliteDataReader reader = dbCommand.ExecuteReader())
410 while (reader.Read())
412 rolesList.Add(reader.GetString(0));
416 catch (SqliteException e)
418 Trace.WriteLine(e.ToString());
419 throw new ProviderException(Properties.Resources.ErrOperationAborted);
429 return rolesList.ToArray();
433 /// RoleProvider.GetRolesForUser
435 public override string[] GetRolesForUser(string username)
437 List<string> rolesList = new List<string>();
439 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
441 using (SqliteCommand dbCommand = dbConn.CreateCommand())
443 dbCommand.CommandText = string.Format("SELECT \"Rolename\" FROM \"{0}\" WHERE \"Username\" = @Username AND \"ApplicationName\" = @ApplicationName ORDER BY \"Rolename\" ASC", m_UserInRolesTableName);
445 AddParameter (dbCommand, "@Username", username);
446 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
453 using (SqliteDataReader reader = dbCommand.ExecuteReader())
457 while (reader.Read())
459 rolesList.Add(reader.GetString(0));
464 catch (SqliteException e)
466 Trace.WriteLine(e.ToString());
467 throw new ProviderException(Properties.Resources.ErrOperationAborted);
477 return rolesList.ToArray();
481 /// RoleProvider.GetUsersInRole
483 public override string[] GetUsersInRole(string roleName)
485 List<string> userList = new List<string>();
487 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
489 using (SqliteCommand dbCommand = dbConn.CreateCommand())
491 dbCommand.CommandText = string.Format("SELECT \"Username\" FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName ORDER BY \"Username\" ASC", m_UserInRolesTableName);
493 AddParameter (dbCommand, "@Rolename", roleName);
494 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
501 using (SqliteDataReader reader = dbCommand.ExecuteReader())
505 while (reader.Read())
507 userList.Add(reader.GetString(0));
512 catch (SqliteException e)
514 Trace.WriteLine(e.ToString());
515 throw new ProviderException(Properties.Resources.ErrOperationAborted);
525 return userList.ToArray();
529 /// RoleProvider.IsUserInRole
531 public override bool IsUserInRole(string userName, string roleName)
533 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
535 using (SqliteCommand dbCommand = dbConn.CreateCommand())
537 dbCommand.CommandText = string.Format("SELECT COUNT(*) FROM \"{0}\" WHERE \"Username\" = @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_UserInRolesTableName);
539 AddParameter (dbCommand, "@Username", userName);
540 AddParameter (dbCommand, "@Rolename", roleName);
541 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
549 Int32.TryParse(dbCommand.ExecuteScalar().ToString(), out numRecs);
554 catch (SqliteException e)
556 Trace.WriteLine(e.ToString());
557 throw new ProviderException(Properties.Resources.ErrOperationAborted);
571 /// RoleProvider.RemoveUsersFromRoles
573 public override void RemoveUsersFromRoles(string[] userNames, string[] roleNames)
575 foreach (string rolename in roleNames)
577 if (!RoleExists(rolename))
579 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, rolename));
583 foreach (string username in userNames)
585 foreach (string rolename in roleNames)
587 if (!IsUserInRole(username, rolename))
589 throw new ProviderException(string.Format(Properties.Resources.ErrUserIsNotInRole, username, rolename));
594 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
596 using (SqliteCommand dbCommand = dbConn.CreateCommand())
598 dbCommand.CommandText = string.Format("DELETE FROM \"{0}\" WHERE \"Username\" = @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_UserInRolesTableName);
600 AddParameter (dbCommand, "@Username");
601 AddParameter (dbCommand, "@Rolename");
602 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
604 SqliteTransaction dbTrans = null;
611 using (dbTrans = dbConn.BeginTransaction())
613 foreach (string username in userNames)
615 foreach (string rolename in roleNames)
617 dbCommand.Parameters["@Username"].Value = username;
618 dbCommand.Parameters["@Rolename"].Value = rolename;
619 dbCommand.ExecuteNonQuery();
622 // Attempt to commit the transaction
626 catch (SqliteException e)
628 Trace.WriteLine(e.ToString());
632 // Attempt to roll back the transaction
633 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
636 catch (SqliteException re)
639 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
640 Trace.WriteLine(re.ToString());
643 throw new ProviderException(Properties.Resources.ErrOperationAborted);
655 /// RoleProvider.RoleExists
657 public override bool RoleExists(string roleName)
659 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
661 using (SqliteCommand dbCommand = dbConn.CreateCommand())
663 dbCommand.CommandText = string.Format("SELECT COUNT(*) FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_RolesTableName);
665 AddParameter (dbCommand, "@Rolename", roleName);
666 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
674 Int32.TryParse(dbCommand.ExecuteScalar().ToString(), out numRecs);
679 catch (SqliteException e)
681 Trace.WriteLine(e.ToString());
682 throw new ProviderException(Properties.Resources.ErrOperationAborted);
696 #region private methods
698 /// A helper function to retrieve config values from the configuration file.
700 /// <param name="configValue"></param>
701 /// <param name="defaultValue"></param>
702 /// <returns></returns>
703 private string GetConfigValue(string configValue, string defaultValue)
705 if (string.IsNullOrEmpty(configValue))