SqlRoleProvider.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425
  1. //
  2. // System.Web.Security.SqlRoleProvider
  3. //
  4. // Authors:
  5. // Ben Maurer ([email protected])
  6. // Chris Toshok ([email protected])
  7. //
  8. // (C) 2003 Ben Maurer
  9. // Copyright (c) 2005,2006 Novell, Inc (http://www.novell.com)
  10. //
  11. // Permission is hereby granted, free of charge, to any person obtaining
  12. // a copy of this software and associated documentation files (the
  13. // "Software"), to deal in the Software without restriction, including
  14. // without limitation the rights to use, copy, modify, merge, publish,
  15. // distribute, sublicense, and/or sell copies of the Software, and to
  16. // permit persons to whom the Software is furnished to do so, subject to
  17. // the following conditions:
  18. //
  19. // The above copyright notice and this permission notice shall be
  20. // included in all copies or substantial portions of the Software.
  21. //
  22. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  23. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  24. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  25. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  26. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  27. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  28. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  29. //
  30. #if NET_2_0
  31. using System.Collections;
  32. using System.Collections.Specialized;
  33. using System.Data;
  34. using System.Data.Common;
  35. using System.Configuration;
  36. using System.Configuration.Provider;
  37. using System.Web.Configuration;
  38. namespace System.Web.Security
  39. {
  40. public class SqlRoleProvider : RoleProvider
  41. {
  42. string applicationName;
  43. ConnectionStringSettings connectionString;
  44. DbProviderFactory factory;
  45. DbConnection CreateConnection ()
  46. {
  47. DbConnection connection = factory.CreateConnection ();
  48. connection.ConnectionString = connectionString.ConnectionString;
  49. connection.Open ();
  50. return connection;
  51. }
  52. static void AddParameter (DbCommand command, string parameterName, object parameterValue)
  53. {
  54. AddParameter (command, parameterName, ParameterDirection.Input, parameterValue);
  55. }
  56. static DbParameter AddParameter (DbCommand command, string parameterName, ParameterDirection direction, object parameterValue)
  57. {
  58. DbParameter dbp = command.CreateParameter ();
  59. dbp.ParameterName = parameterName;
  60. dbp.Value = parameterValue;
  61. dbp.Direction = direction;
  62. command.Parameters.Add (dbp);
  63. return dbp;
  64. }
  65. public override void AddUsersToRoles (string [] usernames, string [] rolenames)
  66. {
  67. Hashtable h = new Hashtable ();
  68. foreach (string u in usernames) {
  69. if (u == null)
  70. throw new ArgumentNullException ("null element in usernames array");
  71. if (h.ContainsKey (u))
  72. throw new ArgumentException ("duplicate element in usernames array");
  73. if (u.Length == 0 || u.Length > 256 || u.IndexOf (",") != -1)
  74. throw new ArgumentException ("element in usernames array in illegal format");
  75. h.Add (u, u);
  76. }
  77. h = new Hashtable ();
  78. foreach (string r in rolenames) {
  79. if (r == null)
  80. throw new ArgumentNullException ("null element in rolenames array");
  81. if (h.ContainsKey (r))
  82. throw new ArgumentException ("duplicate element in rolenames array");
  83. if (r.Length == 0 || r.Length > 256 || r.IndexOf (",") != -1)
  84. throw new ArgumentException ("element in rolenames array in illegal format");
  85. h.Add (r, r);
  86. }
  87. using (DbConnection connection = CreateConnection ()) {
  88. /* add the user/role combination to dbo.aspnet_UsersInRoles */
  89. DbCommand command = factory.CreateCommand ();
  90. command.CommandText = @"dbo.aspnet_UsersInRoles_AddUsersToRoles";
  91. command.Connection = connection;
  92. command.CommandType = CommandType.StoredProcedure;
  93. AddParameter (command, "RoleNames", String.Join (",", rolenames));
  94. AddParameter (command, "UserNames", String.Join (",", usernames));
  95. AddParameter (command, "ApplicationName", ApplicationName);
  96. AddParameter (command, "CurrentTimeUtc", DateTime.UtcNow);
  97. DbParameter dbpr = AddParameter (command, null, ParameterDirection.ReturnValue, null);
  98. command.ExecuteNonQuery ();
  99. int returnValue = (int) dbpr.Value;
  100. if (returnValue == 0)
  101. return;
  102. else if (returnValue == 2)
  103. throw new ProviderException ("One or more of the specified user/role names was not found.");
  104. else if (returnValue == 3)
  105. throw new ProviderException ("One or more of the specified user names is already associated with one or more of the specified role names.");
  106. else
  107. throw new ProviderException ("Failed to create new user/role association.");
  108. }
  109. }
  110. public override void CreateRole (string rolename)
  111. {
  112. if (rolename == null)
  113. throw new ArgumentNullException ("rolename");
  114. if (rolename.Length == 0 || rolename.Length > 256 || rolename.IndexOf (",") != -1)
  115. throw new ArgumentException ("rolename is in invalid format");
  116. using (DbConnection connection = CreateConnection ()) {
  117. DbCommand command = factory.CreateCommand ();
  118. command.CommandText = @"dbo.aspnet_Roles_CreateRole";
  119. command.Connection = connection;
  120. command.CommandType = CommandType.StoredProcedure;
  121. AddParameter (command, "ApplicationName", ApplicationName);
  122. AddParameter (command, "RoleName", rolename);
  123. DbParameter dbpr = AddParameter (command, null, ParameterDirection.ReturnValue, null);
  124. command.ExecuteNonQuery ();
  125. int returnValue = (int) dbpr.Value;
  126. if (returnValue == 1)
  127. throw new ProviderException (rolename + " already exists in the database");
  128. else
  129. return;
  130. }
  131. }
  132. public override bool DeleteRole (string rolename, bool throwOnPopulatedRole)
  133. {
  134. if (rolename == null)
  135. throw new ArgumentNullException ("rolename");
  136. if (rolename.Length == 0 || rolename.Length > 256 || rolename.IndexOf (",") != -1)
  137. throw new ArgumentException ("rolename is in invalid format");
  138. using (DbConnection connection = CreateConnection ()) {
  139. DbCommand command = factory.CreateCommand ();
  140. command.CommandText = @"dbo.aspnet_Roles_DeleteRole";
  141. command.Connection = connection;
  142. command.CommandType = CommandType.StoredProcedure;
  143. AddParameter (command, "ApplicationName", ApplicationName);
  144. AddParameter (command, "RoleName", rolename);
  145. AddParameter (command, "DeleteOnlyIfRoleIsEmpty", throwOnPopulatedRole);
  146. DbParameter dbpr = AddParameter (command, null, ParameterDirection.ReturnValue, null);
  147. command.ExecuteNonQuery ();
  148. int returnValue = (int)dbpr.Value;
  149. if (returnValue == 0)
  150. return true;
  151. if (returnValue == 1)
  152. return false; //role does not exists
  153. else if (returnValue == 2 && throwOnPopulatedRole)
  154. throw new ProviderException (rolename + " is not empty");
  155. else
  156. return false;
  157. }
  158. }
  159. public override string [] FindUsersInRole (string roleName, string usernameToMatch)
  160. {
  161. if (roleName == null)
  162. throw new ArgumentNullException ("roleName");
  163. if (usernameToMatch == null)
  164. throw new ArgumentNullException ("usernameToMatch");
  165. if (roleName.Length == 0 || roleName.Length > 256 || roleName.IndexOf (",") != -1)
  166. throw new ArgumentException ("roleName is in invalid format");
  167. if (usernameToMatch.Length == 0 || usernameToMatch.Length > 256)
  168. throw new ArgumentException ("usernameToMatch is in invalid format");
  169. using (DbConnection connection = CreateConnection ()) {
  170. DbCommand command = factory.CreateCommand ();
  171. command.Connection = connection;
  172. command.CommandText = @"dbo.aspnet_UsersInRoles_FindUsersInRole";
  173. command.CommandType = CommandType.StoredProcedure;
  174. AddParameter (command, "ApplicationName", ApplicationName);
  175. AddParameter (command, "RoleName", roleName);
  176. AddParameter (command, "UsernameToMatch", usernameToMatch);
  177. DbDataReader reader = command.ExecuteReader ();
  178. ArrayList userList = new ArrayList ();
  179. while (reader.Read ())
  180. userList.Add (reader.GetString (0));
  181. reader.Close ();
  182. return (string []) userList.ToArray (typeof (string));
  183. }
  184. }
  185. public override string [] GetAllRoles ()
  186. {
  187. using (DbConnection connection = CreateConnection ()) {
  188. DbCommand command = factory.CreateCommand ();
  189. command.CommandText = @"dbo.aspnet_Roles_GetAllRoles";
  190. command.Connection = connection;
  191. command.CommandType = CommandType.StoredProcedure;
  192. AddParameter (command, "ApplicationName", ApplicationName);
  193. DbDataReader reader = command.ExecuteReader ();
  194. ArrayList roleList = new ArrayList ();
  195. while (reader.Read ())
  196. roleList.Add (reader.GetString (0));
  197. reader.Close ();
  198. return (string []) roleList.ToArray (typeof (string));
  199. }
  200. }
  201. public override string [] GetRolesForUser (string username)
  202. {
  203. using (DbConnection connection = CreateConnection ()) {
  204. DbCommand command = factory.CreateCommand ();
  205. command.CommandText = @"dbo.aspnet_UsersInRoles_GetRolesForUser";
  206. command.Connection = connection;
  207. command.CommandType = CommandType.StoredProcedure;
  208. AddParameter (command, "UserName", username);
  209. AddParameter (command, "ApplicationName", ApplicationName);
  210. DbDataReader reader = command.ExecuteReader ();
  211. ArrayList roleList = new ArrayList ();
  212. while (reader.Read ())
  213. roleList.Add (reader.GetString (0));
  214. reader.Close ();
  215. return (string []) roleList.ToArray (typeof (string));
  216. }
  217. }
  218. public override string [] GetUsersInRole (string rolename)
  219. {
  220. using (DbConnection connection = CreateConnection ()) {
  221. DbCommand command = factory.CreateCommand ();
  222. command.CommandText = @"dbo.aspnet_UsersInRoles_GetUsersInRoles";
  223. command.Connection = connection;
  224. command.CommandType = CommandType.StoredProcedure;
  225. AddParameter (command, "RoleName", rolename);
  226. AddParameter (command, "ApplicationName", ApplicationName);
  227. DbDataReader reader = command.ExecuteReader ();
  228. ArrayList userList = new ArrayList ();
  229. while (reader.Read ())
  230. userList.Add (reader.GetString (0));
  231. reader.Close ();
  232. return (string []) userList.ToArray (typeof (string));
  233. }
  234. }
  235. string GetStringConfigValue (NameValueCollection config, string name, string def)
  236. {
  237. string rv = def;
  238. string val = config [name];
  239. if (val != null)
  240. rv = val;
  241. return rv;
  242. }
  243. public override void Initialize (string name, NameValueCollection config)
  244. {
  245. if (config == null)
  246. throw new ArgumentNullException ("config");
  247. base.Initialize (name, config);
  248. applicationName = config ["applicationName"];
  249. string connectionStringName = config ["connectionStringName"];
  250. if (applicationName.Length > 256)
  251. throw new ProviderException ("The ApplicationName attribute must be 256 characters long or less.");
  252. if (connectionStringName == null || connectionStringName.Length == 0)
  253. throw new ProviderException ("The ConnectionStringName attribute must be present and non-zero length.");
  254. // XXX check connectionStringName and commandTimeout
  255. connectionString = WebConfigurationManager.ConnectionStrings [connectionStringName];
  256. if (connectionString == null)
  257. throw new ProviderException (String.Format("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", connectionStringName));
  258. factory = String.IsNullOrEmpty (connectionString.ProviderName) ?
  259. System.Data.SqlClient.SqlClientFactory.Instance :
  260. ProvidersHelper.GetDbProviderFactory (connectionString.ProviderName);
  261. }
  262. public override bool IsUserInRole (string username, string rolename)
  263. {
  264. using (DbConnection connection = CreateConnection ()) {
  265. DbCommand command = factory.CreateCommand ();
  266. command.CommandText = @"dbo.aspnet_UsersInRoles_IsUserInRole";
  267. command.Connection = connection;
  268. command.CommandType = CommandType.StoredProcedure;
  269. AddParameter (command, "RoleName", rolename);
  270. AddParameter (command, "UserName", username);
  271. AddParameter (command, "ApplicationName", ApplicationName);
  272. DbParameter dbpr = AddParameter (command, null, ParameterDirection.ReturnValue, null);
  273. command.ExecuteNonQuery ();
  274. int returnValue = (int) dbpr.Value;
  275. if (returnValue == 1)
  276. return true;
  277. return false;
  278. }
  279. }
  280. public override void RemoveUsersFromRoles (string [] usernames, string [] rolenames)
  281. {
  282. Hashtable h = new Hashtable ();
  283. foreach (string u in usernames) {
  284. if (u == null)
  285. throw new ArgumentNullException ("null element in usernames array");
  286. if (h.ContainsKey (u))
  287. throw new ArgumentException ("duplicate element in usernames array");
  288. if (u.Length == 0 || u.Length > 256 || u.IndexOf (",") != -1)
  289. throw new ArgumentException ("element in usernames array in illegal format");
  290. h.Add (u, u);
  291. }
  292. h = new Hashtable ();
  293. foreach (string r in rolenames) {
  294. if (r == null)
  295. throw new ArgumentNullException ("null element in rolenames array");
  296. if (h.ContainsKey (r))
  297. throw new ArgumentException ("duplicate element in rolenames array");
  298. if (r.Length == 0 || r.Length > 256 || r.IndexOf (",") != -1)
  299. throw new ArgumentException ("element in rolenames array in illegal format");
  300. h.Add (r, r);
  301. }
  302. using (DbConnection connection = CreateConnection ()) {
  303. DbCommand command = factory.CreateCommand ();
  304. command.CommandText = @"dbo.aspnet_UsersInRoles_RemoveUsersFromRoles";
  305. command.Connection = connection;
  306. command.CommandType = CommandType.StoredProcedure;
  307. AddParameter (command, "UserNames", String.Join (",", usernames));
  308. AddParameter (command, "RoleNames", String.Join (",", rolenames));
  309. AddParameter (command, "ApplicationName", ApplicationName);
  310. DbParameter dbpr = AddParameter (command, null, ParameterDirection.ReturnValue, null);
  311. command.ExecuteNonQuery ();
  312. int returnValue = (int) dbpr.Value;
  313. if (returnValue == 0)
  314. return;
  315. else if (returnValue == 1)
  316. throw new ProviderException ("One or more of the specified user names was not found.");
  317. else if (returnValue == 2)
  318. throw new ProviderException ("One or more of the specified role names was not found.");
  319. else if (returnValue == 3)
  320. throw new ProviderException ("One or more of the specified user names is not associated with one or more of the specified role names.");
  321. else
  322. throw new ProviderException ("Failed to remove users from roles");
  323. }
  324. }
  325. public override bool RoleExists (string rolename)
  326. {
  327. using (DbConnection connection = CreateConnection ()) {
  328. DbCommand command = factory.CreateCommand ();
  329. command.CommandText = @"dbo.aspnet_Roles_RoleExists";
  330. command.Connection = connection;
  331. command.CommandType = CommandType.StoredProcedure;
  332. AddParameter (command, "ApplicationName", ApplicationName);
  333. AddParameter (command, "RoleName", rolename);
  334. DbParameter dbpr = AddParameter (command, null, ParameterDirection.ReturnValue, null);
  335. command.ExecuteNonQuery ();
  336. int returnValue = (int) dbpr.Value;
  337. if (returnValue == 1)
  338. return true;
  339. return false;
  340. }
  341. }
  342. public override string ApplicationName
  343. {
  344. get { return applicationName; }
  345. set
  346. {
  347. applicationName = value;
  348. }
  349. }
  350. }
  351. }
  352. #endif