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 const string m_RolesTableName = "Roles";
51 const string m_UserInRolesTableName = "UsersInRoles";
52 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);
75 /// System.Configuration.Provider.ProviderBase.Initialize Method
77 public override void Initialize(string name, NameValueCollection config)
79 // Initialize values from web.config.
81 throw new ArgumentNullException("Config", Properties.Resources.ErrArgumentNull);
83 if (string.IsNullOrEmpty(name))
84 name = Properties.Resources.RoleProviderDefaultName;
86 if (string.IsNullOrEmpty(config["description"]))
88 config.Remove("description");
89 config.Add("description", Properties.Resources.RoleProviderDefaultDescription);
92 // Initialize the abstract base class.
93 base.Initialize(name, config);
95 m_ApplicationName = GetConfigValue(config["applicationName"], HostingEnvironment.ApplicationVirtualPath);
97 // Get connection string.
98 string connStrName = config["connectionStringName"];
100 if (string.IsNullOrEmpty(connStrName))
102 throw new ArgumentOutOfRangeException("ConnectionStringName", Properties.Resources.ErrArgumentNullOrEmpty);
106 ConnectionStringSettings ConnectionStringSettings = ConfigurationManager.ConnectionStrings[connStrName];
108 if (ConnectionStringSettings == null || string.IsNullOrEmpty(ConnectionStringSettings.ConnectionString.Trim()))
110 throw new ProviderException(Properties.Resources.ErrConnectionStringNullOrEmpty);
113 m_ConnectionString = ConnectionStringSettings.ConnectionString;
118 /// System.Web.Security.RoleProvider properties.
120 #region System.Web.Security.RoleProvider properties
121 string m_ApplicationName = string.Empty;
123 public override string ApplicationName
125 get { return m_ApplicationName; }
126 set { m_ApplicationName = value; }
131 /// System.Web.Security.RoleProvider methods.
133 #region System.Web.Security.RoleProvider methods
136 /// RoleProvider.AddUsersToRoles
138 public override void AddUsersToRoles(string[] userNames, string[] roleNames)
140 foreach (string rolename in roleNames)
142 if (!RoleExists(rolename))
144 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, rolename));
148 foreach (string username in userNames)
150 foreach (string rolename in roleNames)
152 if (IsUserInRole(username, rolename))
154 throw new ProviderException(string.Format(Properties.Resources.ErrUserAlreadyInRole, username, rolename));
159 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
161 using (SqliteCommand dbCommand = dbConn.CreateCommand())
163 dbCommand.CommandText = string.Format("INSERT INTO \"{0}\" (\"Username\", \"Rolename\", \"ApplicationName\") Values (@Username, @Rolename, @ApplicationName)", m_UserInRolesTableName);
165 AddParameter (dbCommand, "@Username");
166 AddParameter (dbCommand, "@Rolename");
167 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
169 SqliteTransaction dbTrans = null;
176 using (dbTrans = dbConn.BeginTransaction())
178 foreach (string username in userNames)
180 foreach (string rolename in roleNames)
182 dbCommand.Parameters["@Username"].Value = username;
183 dbCommand.Parameters["@Rolename"].Value = rolename;
184 dbCommand.ExecuteNonQuery();
187 // Attempt to commit the transaction
191 catch (SqliteException e)
193 Trace.WriteLine(e.ToString());
197 // Attempt to roll back the transaction
198 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
201 catch (SqliteException re)
204 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
205 Trace.WriteLine(re.ToString());
208 throw new ProviderException(Properties.Resources.ErrOperationAborted);
220 /// RoleProvider.CreateRole
222 public override void CreateRole(string roleName)
224 if (RoleExists(roleName))
226 throw new ProviderException(string.Format(Properties.Resources.ErrRoleAlreadyExist, roleName));
229 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
231 using (SqliteCommand dbCommand = dbConn.CreateCommand())
233 dbCommand.CommandText = string.Format("INSERT INTO \"{0}\" (\"Rolename\", \"ApplicationName\") Values (@Rolename, @ApplicationName)", m_RolesTableName);
235 AddParameter (dbCommand, "@Rolename", roleName);
236 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
243 dbCommand.ExecuteNonQuery();
245 catch (SqliteException e)
247 Trace.WriteLine(e.ToString());
248 throw new ProviderException(Properties.Resources.ErrOperationAborted);
260 /// RoleProvider.DeleteRole
262 public override bool DeleteRole(string roleName, bool throwOnPopulatedRole)
264 if (!RoleExists(roleName))
266 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, roleName));
269 if (throwOnPopulatedRole && GetUsersInRole(roleName).Length > 0)
271 throw new ProviderException(Properties.Resources.ErrCantDeletePopulatedRole);
274 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
276 using (SqliteCommand dbCommand = dbConn.CreateCommand())
278 dbCommand.CommandText = string.Format("DELETE FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_RolesTableName);
280 AddParameter (dbCommand, "@Rolename", roleName);
281 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
283 SqliteTransaction dbTrans = null;
290 using (dbTrans = dbConn.BeginTransaction())
292 dbCommand.ExecuteNonQuery();
294 // Attempt to commit the transaction
298 catch (SqliteException e)
300 Trace.WriteLine(e.ToString());
304 // Attempt to roll back the transaction
305 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
308 catch (SqliteException re)
311 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
312 Trace.WriteLine(re.ToString());
315 throw new ProviderException(Properties.Resources.ErrOperationAborted);
329 /// RoleProvider.FindUsersInRole
331 public override string[] FindUsersInRole(string roleName, string usernameToMatch)
333 List<string> userList = new List<string>();
335 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
337 using (SqliteCommand dbCommand = dbConn.CreateCommand())
339 dbCommand.CommandText = string.Format("SELECT \"Username\" FROM \"{0}\" WHERE \"Username\" LIKE @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName ORDER BY \"Username\" ASC", m_UserInRolesTableName);
341 AddParameter (dbCommand, "@Username", usernameToMatch);
342 AddParameter (dbCommand, "@Rolename", roleName);
343 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
350 using (SqliteDataReader reader = dbCommand.ExecuteReader())
354 while (reader.Read())
356 userList.Add(reader.GetString(0));
361 catch (SqliteException e)
363 Trace.WriteLine(e.ToString());
364 throw new ProviderException(Properties.Resources.ErrOperationAborted);
374 return userList.ToArray();
378 /// RoleProvider.GetAllRoles
380 public override string[] GetAllRoles()
382 List<string> rolesList = new List<string>();
384 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
386 using (SqliteCommand dbCommand = dbConn.CreateCommand())
388 dbCommand.CommandText = string.Format("SELECT \"Rolename\" FROM \"{0}\" WHERE \"ApplicationName\" = @ApplicationName ORDER BY \"Rolename\" ASC", m_RolesTableName);
390 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
397 using (SqliteDataReader reader = dbCommand.ExecuteReader())
399 while (reader.Read())
401 rolesList.Add(reader.GetString(0));
405 catch (SqliteException e)
407 Trace.WriteLine(e.ToString());
408 throw new ProviderException(Properties.Resources.ErrOperationAborted);
418 return rolesList.ToArray();
422 /// RoleProvider.GetRolesForUser
424 public override string[] GetRolesForUser(string username)
426 List<string> rolesList = new List<string>();
428 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
430 using (SqliteCommand dbCommand = dbConn.CreateCommand())
432 dbCommand.CommandText = string.Format("SELECT \"Rolename\" FROM \"{0}\" WHERE \"Username\" = @Username AND \"ApplicationName\" = @ApplicationName ORDER BY \"Rolename\" ASC", m_UserInRolesTableName);
434 AddParameter (dbCommand, "@Username", username);
435 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
442 using (SqliteDataReader reader = dbCommand.ExecuteReader())
446 while (reader.Read())
448 rolesList.Add(reader.GetString(0));
453 catch (SqliteException e)
455 Trace.WriteLine(e.ToString());
456 throw new ProviderException(Properties.Resources.ErrOperationAborted);
466 return rolesList.ToArray();
470 /// RoleProvider.GetUsersInRole
472 public override string[] GetUsersInRole(string roleName)
474 List<string> userList = new List<string>();
476 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
478 using (SqliteCommand dbCommand = dbConn.CreateCommand())
480 dbCommand.CommandText = string.Format("SELECT \"Username\" FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName ORDER BY \"Username\" ASC", m_UserInRolesTableName);
482 AddParameter (dbCommand, "@Rolename", roleName);
483 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
490 using (SqliteDataReader reader = dbCommand.ExecuteReader())
494 while (reader.Read())
496 userList.Add(reader.GetString(0));
501 catch (SqliteException e)
503 Trace.WriteLine(e.ToString());
504 throw new ProviderException(Properties.Resources.ErrOperationAborted);
514 return userList.ToArray();
518 /// RoleProvider.IsUserInRole
520 public override bool IsUserInRole(string userName, string roleName)
522 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
524 using (SqliteCommand dbCommand = dbConn.CreateCommand())
526 dbCommand.CommandText = string.Format("SELECT COUNT(*) FROM \"{0}\" WHERE \"Username\" = @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_UserInRolesTableName);
528 AddParameter (dbCommand, "@Username", userName);
529 AddParameter (dbCommand, "@Rolename", roleName);
530 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
538 Int32.TryParse(dbCommand.ExecuteScalar().ToString(), out numRecs);
543 catch (SqliteException e)
545 Trace.WriteLine(e.ToString());
546 throw new ProviderException(Properties.Resources.ErrOperationAborted);
560 /// RoleProvider.RemoveUsersFromRoles
562 public override void RemoveUsersFromRoles(string[] userNames, string[] roleNames)
564 foreach (string rolename in roleNames)
566 if (!RoleExists(rolename))
568 throw new ProviderException(string.Format(Properties.Resources.ErrRoleNotExist, rolename));
572 foreach (string username in userNames)
574 foreach (string rolename in roleNames)
576 if (!IsUserInRole(username, rolename))
578 throw new ProviderException(string.Format(Properties.Resources.ErrUserIsNotInRole, username, rolename));
583 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
585 using (SqliteCommand dbCommand = dbConn.CreateCommand())
587 dbCommand.CommandText = string.Format("DELETE FROM \"{0}\" WHERE \"Username\" = @Username AND \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_UserInRolesTableName);
589 AddParameter (dbCommand, "@Username");
590 AddParameter (dbCommand, "@Rolename");
591 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
593 SqliteTransaction dbTrans = null;
600 using (dbTrans = dbConn.BeginTransaction())
602 foreach (string username in userNames)
604 foreach (string rolename in roleNames)
606 dbCommand.Parameters["@Username"].Value = username;
607 dbCommand.Parameters["@Rolename"].Value = rolename;
608 dbCommand.ExecuteNonQuery();
611 // Attempt to commit the transaction
615 catch (SqliteException e)
617 Trace.WriteLine(e.ToString());
621 // Attempt to roll back the transaction
622 Trace.WriteLine(Properties.Resources.LogRollbackAttempt);
625 catch (SqliteException re)
628 Trace.WriteLine(Properties.Resources.ErrRollbackFailed);
629 Trace.WriteLine(re.ToString());
632 throw new ProviderException(Properties.Resources.ErrOperationAborted);
644 /// RoleProvider.RoleExists
646 public override bool RoleExists(string roleName)
648 using (SqliteConnection dbConn = new SqliteConnection(m_ConnectionString))
650 using (SqliteCommand dbCommand = dbConn.CreateCommand())
652 dbCommand.CommandText = string.Format("SELECT COUNT(*) FROM \"{0}\" WHERE \"Rolename\" = @Rolename AND \"ApplicationName\" = @ApplicationName", m_RolesTableName);
654 AddParameter (dbCommand, "@Rolename", roleName);
655 AddParameter (dbCommand, "@ApplicationName", m_ApplicationName);
663 Int32.TryParse(dbCommand.ExecuteScalar().ToString(), out numRecs);
668 catch (SqliteException e)
670 Trace.WriteLine(e.ToString());
671 throw new ProviderException(Properties.Resources.ErrOperationAborted);
685 #region private methods
687 /// A helper function to retrieve config values from the configuration file.
689 /// <param name="configValue"></param>
690 /// <param name="defaultValue"></param>
691 /// <returns></returns>
692 string GetConfigValue(string configValue, string defaultValue)
694 if (string.IsNullOrEmpty(configValue))