SqlRoleProvider.cs 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436
  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. static DbParameter AddParameter (DbCommand command, string parameterName, ParameterDirection direction, DbType type, object parameterValue)
  66. {
  67. DbParameter dbp = command.CreateParameter ();
  68. dbp.ParameterName = parameterName;
  69. dbp.Value = parameterValue = parameterValue;
  70. dbp.Direction = direction;
  71. dbp.DbType = type;
  72. command.Parameters.Add (dbp);
  73. return dbp;
  74. }
  75. public override void AddUsersToRoles (string [] usernames, string [] rolenames)
  76. {
  77. Hashtable h = new Hashtable ();
  78. foreach (string u in usernames) {
  79. if (u == null)
  80. throw new ArgumentNullException ("null element in usernames array");
  81. if (h.ContainsKey (u))
  82. throw new ArgumentException ("duplicate element in usernames array");
  83. if (u.Length == 0 || u.Length > 256 || u.IndexOf (",") != -1)
  84. throw new ArgumentException ("element in usernames array in illegal format");
  85. h.Add (u, u);
  86. }
  87. h = new Hashtable ();
  88. foreach (string r in rolenames) {
  89. if (r == null)
  90. throw new ArgumentNullException ("null element in rolenames array");
  91. if (h.ContainsKey (r))
  92. throw new ArgumentException ("duplicate element in rolenames array");
  93. if (r.Length == 0 || r.Length > 256 || r.IndexOf (",") != -1)
  94. throw new ArgumentException ("element in rolenames array in illegal format");
  95. h.Add (r, r);
  96. }
  97. using (DbConnection connection = CreateConnection ()) {
  98. /* add the user/role combination to dbo.aspnet_UsersInRoles */
  99. DbCommand command = factory.CreateCommand ();
  100. command.CommandText = @"dbo.aspnet_UsersInRoles_AddUsersToRoles";
  101. command.Connection = connection;
  102. command.CommandType = CommandType.StoredProcedure;
  103. AddParameter (command, "@RoleNames", String.Join (",", rolenames));
  104. AddParameter (command, "@UserNames", String.Join (",", usernames));
  105. AddParameter (command, "@ApplicationName", ApplicationName);
  106. AddParameter (command, "@CurrentTimeUtc", DateTime.UtcNow);
  107. DbParameter dbpr = AddParameter (command, "@ReturnVal", ParameterDirection.ReturnValue, DbType.Int32, null);
  108. command.ExecuteNonQuery ();
  109. int returnValue = (int) dbpr.Value;
  110. if (returnValue == 0)
  111. return;
  112. else if (returnValue == 2)
  113. throw new ProviderException ("One or more of the specified user/role names was not found.");
  114. else if (returnValue == 3)
  115. throw new ProviderException ("One or more of the specified user names is already associated with one or more of the specified role names.");
  116. else
  117. throw new ProviderException ("Failed to create new user/role association.");
  118. }
  119. }
  120. public override void CreateRole (string rolename)
  121. {
  122. if (rolename == null)
  123. throw new ArgumentNullException ("rolename");
  124. if (rolename.Length == 0 || rolename.Length > 256 || rolename.IndexOf (",") != -1)
  125. throw new ArgumentException ("rolename is in invalid format");
  126. using (DbConnection connection = CreateConnection ()) {
  127. DbCommand command = factory.CreateCommand ();
  128. command.CommandText = @"dbo.aspnet_Roles_CreateRole";
  129. command.Connection = connection;
  130. command.CommandType = CommandType.StoredProcedure;
  131. AddParameter (command, "@ApplicationName", ApplicationName);
  132. AddParameter (command, "@RoleName", rolename);
  133. DbParameter dbpr = AddParameter (command, "@ReturnVal", ParameterDirection.ReturnValue, DbType.Int32, null);
  134. command.ExecuteNonQuery ();
  135. int returnValue = (int) dbpr.Value;
  136. if (returnValue == 1)
  137. throw new ProviderException (rolename + " already exists in the database");
  138. else
  139. return;
  140. }
  141. }
  142. public override bool DeleteRole (string rolename, bool throwOnPopulatedRole)
  143. {
  144. if (rolename == null)
  145. throw new ArgumentNullException ("rolename");
  146. if (rolename.Length == 0 || rolename.Length > 256 || rolename.IndexOf (",") != -1)
  147. throw new ArgumentException ("rolename is in invalid format");
  148. using (DbConnection connection = CreateConnection ()) {
  149. DbCommand command = factory.CreateCommand ();
  150. command.CommandText = @"dbo.aspnet_Roles_DeleteRole";
  151. command.Connection = connection;
  152. command.CommandType = CommandType.StoredProcedure;
  153. AddParameter (command, "@ApplicationName", ApplicationName);
  154. AddParameter (command, "@RoleName", rolename);
  155. AddParameter (command, "@DeleteOnlyIfRoleIsEmpty", throwOnPopulatedRole);
  156. DbParameter dbpr = AddParameter (command, "@ReturnVal", ParameterDirection.ReturnValue, DbType.Int32, null);
  157. command.ExecuteNonQuery ();
  158. int returnValue = (int)dbpr.Value;
  159. if (returnValue == 0)
  160. return true;
  161. if (returnValue == 1)
  162. return false; //role does not exists
  163. else if (returnValue == 2 && throwOnPopulatedRole)
  164. throw new ProviderException (rolename + " is not empty");
  165. else
  166. return false;
  167. }
  168. }
  169. public override string [] FindUsersInRole (string roleName, string usernameToMatch)
  170. {
  171. if (roleName == null)
  172. throw new ArgumentNullException ("roleName");
  173. if (usernameToMatch == null)
  174. throw new ArgumentNullException ("usernameToMatch");
  175. if (roleName.Length == 0 || roleName.Length > 256 || roleName.IndexOf (",") != -1)
  176. throw new ArgumentException ("roleName is in invalid format");
  177. if (usernameToMatch.Length == 0 || usernameToMatch.Length > 256)
  178. throw new ArgumentException ("usernameToMatch is in invalid format");
  179. using (DbConnection connection = CreateConnection ()) {
  180. DbCommand command = factory.CreateCommand ();
  181. command.Connection = connection;
  182. command.CommandText = @"dbo.aspnet_UsersInRoles_FindUsersInRole";
  183. command.CommandType = CommandType.StoredProcedure;
  184. AddParameter (command, "@ApplicationName", ApplicationName);
  185. AddParameter (command, "@RoleName", roleName);
  186. AddParameter (command, "@UsernameToMatch", usernameToMatch);
  187. DbDataReader reader = command.ExecuteReader ();
  188. ArrayList userList = new ArrayList ();
  189. while (reader.Read ())
  190. userList.Add (reader.GetString (0));
  191. reader.Close ();
  192. return (string []) userList.ToArray (typeof (string));
  193. }
  194. }
  195. public override string [] GetAllRoles ()
  196. {
  197. using (DbConnection connection = CreateConnection ()) {
  198. DbCommand command = factory.CreateCommand ();
  199. command.CommandText = @"dbo.aspnet_Roles_GetAllRoles";
  200. command.Connection = connection;
  201. command.CommandType = CommandType.StoredProcedure;
  202. AddParameter (command, "@ApplicationName", ApplicationName);
  203. DbDataReader reader = command.ExecuteReader ();
  204. ArrayList roleList = new ArrayList ();
  205. while (reader.Read ())
  206. roleList.Add (reader.GetString (0));
  207. reader.Close ();
  208. return (string []) roleList.ToArray (typeof (string));
  209. }
  210. }
  211. public override string [] GetRolesForUser (string username)
  212. {
  213. using (DbConnection connection = CreateConnection ()) {
  214. DbCommand command = factory.CreateCommand ();
  215. command.CommandText = @"dbo.aspnet_UsersInRoles_GetRolesForUser";
  216. command.Connection = connection;
  217. command.CommandType = CommandType.StoredProcedure;
  218. AddParameter (command, "@UserName", username);
  219. AddParameter (command, "@ApplicationName", ApplicationName);
  220. DbDataReader reader = command.ExecuteReader ();
  221. ArrayList roleList = new ArrayList ();
  222. while (reader.Read ())
  223. roleList.Add (reader.GetString (0));
  224. reader.Close ();
  225. return (string []) roleList.ToArray (typeof (string));
  226. }
  227. }
  228. public override string [] GetUsersInRole (string rolename)
  229. {
  230. using (DbConnection connection = CreateConnection ()) {
  231. DbCommand command = factory.CreateCommand ();
  232. command.CommandText = @"dbo.aspnet_UsersInRoles_GetUsersInRoles";
  233. command.Connection = connection;
  234. command.CommandType = CommandType.StoredProcedure;
  235. AddParameter (command, "@RoleName", rolename);
  236. AddParameter (command, "@ApplicationName", ApplicationName);
  237. DbDataReader reader = command.ExecuteReader ();
  238. ArrayList userList = new ArrayList ();
  239. while (reader.Read ())
  240. userList.Add (reader.GetString (0));
  241. reader.Close ();
  242. return (string []) userList.ToArray (typeof (string));
  243. }
  244. }
  245. // string GetStringConfigValue (NameValueCollection config, string name, string def)
  246. // {
  247. // string rv = def;
  248. // string val = config [name];
  249. // if (val != null)
  250. // rv = val;
  251. // return rv;
  252. // }
  253. public override void Initialize (string name, NameValueCollection config)
  254. {
  255. if (config == null)
  256. throw new ArgumentNullException ("config");
  257. base.Initialize (name, config);
  258. applicationName = config ["applicationName"];
  259. string connectionStringName = config ["connectionStringName"];
  260. if (applicationName.Length > 256)
  261. throw new ProviderException ("The ApplicationName attribute must be 256 characters long or less.");
  262. if (connectionStringName == null || connectionStringName.Length == 0)
  263. throw new ProviderException ("The ConnectionStringName attribute must be present and non-zero length.");
  264. // XXX check connectionStringName and commandTimeout
  265. connectionString = WebConfigurationManager.ConnectionStrings [connectionStringName];
  266. if (connectionString == null)
  267. throw new ProviderException (String.Format("The connection name '{0}' was not found in the applications configuration or the connection string is empty.", connectionStringName));
  268. factory = String.IsNullOrEmpty (connectionString.ProviderName) ?
  269. System.Data.SqlClient.SqlClientFactory.Instance :
  270. ProvidersHelper.GetDbProviderFactory (connectionString.ProviderName);
  271. }
  272. public override bool IsUserInRole (string username, string rolename)
  273. {
  274. using (DbConnection connection = CreateConnection ()) {
  275. DbCommand command = factory.CreateCommand ();
  276. command.CommandText = @"dbo.aspnet_UsersInRoles_IsUserInRole";
  277. command.Connection = connection;
  278. command.CommandType = CommandType.StoredProcedure;
  279. AddParameter (command, "@RoleName", rolename);
  280. AddParameter (command, "@UserName", username);
  281. AddParameter (command, "@ApplicationName", ApplicationName);
  282. DbParameter dbpr = AddParameter (command, "@ReturnVal", ParameterDirection.ReturnValue, DbType.Int32, null);
  283. command.ExecuteNonQuery ();
  284. int returnValue = (int) dbpr.Value;
  285. if (returnValue == 1)
  286. return true;
  287. return false;
  288. }
  289. }
  290. public override void RemoveUsersFromRoles (string [] usernames, string [] rolenames)
  291. {
  292. Hashtable h = new Hashtable ();
  293. foreach (string u in usernames) {
  294. if (u == null)
  295. throw new ArgumentNullException ("null element in usernames array");
  296. if (h.ContainsKey (u))
  297. throw new ArgumentException ("duplicate element in usernames array");
  298. if (u.Length == 0 || u.Length > 256 || u.IndexOf (",") != -1)
  299. throw new ArgumentException ("element in usernames array in illegal format");
  300. h.Add (u, u);
  301. }
  302. h = new Hashtable ();
  303. foreach (string r in rolenames) {
  304. if (r == null)
  305. throw new ArgumentNullException ("null element in rolenames array");
  306. if (h.ContainsKey (r))
  307. throw new ArgumentException ("duplicate element in rolenames array");
  308. if (r.Length == 0 || r.Length > 256 || r.IndexOf (",") != -1)
  309. throw new ArgumentException ("element in rolenames array in illegal format");
  310. h.Add (r, r);
  311. }
  312. using (DbConnection connection = CreateConnection ()) {
  313. DbCommand command = factory.CreateCommand ();
  314. command.CommandText = @"dbo.aspnet_UsersInRoles_RemoveUsersFromRoles";
  315. command.Connection = connection;
  316. command.CommandType = CommandType.StoredProcedure;
  317. AddParameter (command, "@UserNames", String.Join (",", usernames));
  318. AddParameter (command, "@RoleNames", String.Join (",", rolenames));
  319. AddParameter (command, "@ApplicationName", ApplicationName);
  320. DbParameter dbpr = AddParameter (command, "@ReturnVal", ParameterDirection.ReturnValue, DbType.Int32, null);
  321. command.ExecuteNonQuery ();
  322. int returnValue = (int) dbpr.Value;
  323. if (returnValue == 0)
  324. return;
  325. else if (returnValue == 1)
  326. throw new ProviderException ("One or more of the specified user names was not found.");
  327. else if (returnValue == 2)
  328. throw new ProviderException ("One or more of the specified role names was not found.");
  329. else if (returnValue == 3)
  330. throw new ProviderException ("One or more of the specified user names is not associated with one or more of the specified role names.");
  331. else
  332. throw new ProviderException ("Failed to remove users from roles");
  333. }
  334. }
  335. public override bool RoleExists (string rolename)
  336. {
  337. using (DbConnection connection = CreateConnection ()) {
  338. DbCommand command = factory.CreateCommand ();
  339. command.CommandText = @"dbo.aspnet_Roles_RoleExists";
  340. command.Connection = connection;
  341. command.CommandType = CommandType.StoredProcedure;
  342. AddParameter (command, "@ApplicationName", ApplicationName);
  343. AddParameter (command, "@RoleName", rolename);
  344. DbParameter dbpr = AddParameter (command, "@ReturnVal", ParameterDirection.ReturnValue, DbType.Int32, null);
  345. command.ExecuteNonQuery ();
  346. int returnValue = (int) dbpr.Value;
  347. if (returnValue == 1)
  348. return true;
  349. return false;
  350. }
  351. }
  352. public override string ApplicationName
  353. {
  354. get { return applicationName; }
  355. set
  356. {
  357. applicationName = value;
  358. }
  359. }
  360. }
  361. }
  362. #endif