PageRenderTime 52ms CodeModel.GetById 12ms RepoModel.GetById 0ms app.codeStats 1ms

/mcs/class/System.Web/Test/standalone/sqlmembershipprovider/SqlMembershipProvider.cs

https://github.com/ztfuqingvip/mono
C# | 1795 lines | 1401 code | 311 blank | 83 comment | 234 complexity | f3af92b66ade79609aaf032f0fa6c2b8 MD5 | raw file
Possible License(s): GPL-2.0, Unlicense, MPL-2.0-no-copyleft-exception, CC-BY-SA-3.0

Large files files are truncated, but you can click here to view the full file

  1. //
  2. // System.Web.Security.SqlMembershipProvider
  3. //
  4. // Authors:
  5. // Ben Maurer (bmaurer@users.sourceforge.net)
  6. // Lluis Sanchez Gual (lluis@novell.com)
  7. // Chris Toshok (toshok@ximian.com)
  8. //
  9. // (C) 2003 Ben Maurer
  10. // Copyright (c) 2005,2006 Novell, Inc (http://www.novell.com)
  11. //
  12. // Permission is hereby granted, free of charge, to any person obtaining
  13. // a copy of this software and associated documentation files (the
  14. // "Software"), to deal in the Software without restriction, including
  15. // without limitation the rights to use, copy, modify, merge, publish,
  16. // distribute, sublicense, and/or sell copies of the Software, and to
  17. // permit persons to whom the Software is furnished to do so, subject to
  18. // the following conditions:
  19. //
  20. // The above copyright notice and this permission notice shall be
  21. // included in all copies or substantial portions of the Software.
  22. //
  23. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
  24. // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
  25. // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
  26. // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
  27. // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
  28. // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
  29. // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
  30. //
  31. #if NET_2_0
  32. using System;
  33. using System.Collections;
  34. using System.Collections.Specialized;
  35. using System.Configuration;
  36. using System.Configuration.Provider;
  37. using System.Data;
  38. using System.Data.Common;
  39. using System.Data.SqlClient;
  40. using System.Text;
  41. using System.Web.Configuration;
  42. using System.Security.Cryptography;
  43. using System.Web.Security;
  44. namespace Toshok.Web.Security {
  45. public class SqlMembershipProvider : MembershipProvider {
  46. const int SALT_BYTES = 16;
  47. DateTime DefaultDateTime = new DateTime (1754,1,1);
  48. bool enablePasswordReset;
  49. bool enablePasswordRetrieval;
  50. int maxInvalidPasswordAttempts;
  51. MembershipPasswordFormat passwordFormat;
  52. bool requiresQuestionAndAnswer;
  53. bool requiresUniqueEmail;
  54. int minRequiredNonAlphanumericCharacters;
  55. int minRequiredPasswordLength;
  56. int passwordAttemptWindow;
  57. string passwordStrengthRegularExpression;
  58. TimeSpan userIsOnlineTimeWindow;
  59. ConnectionStringSettings connectionString;
  60. DbProviderFactory factory;
  61. DbConnection connection;
  62. string applicationName;
  63. static object lockobj = new object();
  64. static byte ToHexValue (char c, bool high)
  65. {
  66. byte v;
  67. if (c >= '0' && c <= '9')
  68. v = (byte) (c - '0');
  69. else if (c >= 'a' && c <= 'f')
  70. v = (byte) (c - 'a' + 10);
  71. else if (c >= 'A' && c <= 'F')
  72. v = (byte) (c - 'A' + 10);
  73. else
  74. throw new ArgumentException ("Invalid hex character");
  75. if (high)
  76. v <<= 4;
  77. return v;
  78. }
  79. internal static byte [] GetBytes (string key, int len)
  80. {
  81. byte [] result = new byte [len / 2];
  82. for (int i = 0; i < len; i += 2)
  83. result [i / 2] = (byte) (ToHexValue (key [i], true) + ToHexValue (key [i + 1], false));
  84. return result;
  85. }
  86. SymmetricAlgorithm GetAlg (out byte[] decryptionKey)
  87. {
  88. MachineKeySection section = (MachineKeySection)WebConfigurationManager.GetSection ("system.web/machineKey");
  89. if (section.DecryptionKey.StartsWith ("AutoGenerate"))
  90. throw new ProviderException ("You must explicitly specify a decryption key in the <machineKey> section when using encrypted passwords.");
  91. string alg_type = section.Decryption;
  92. if (alg_type == "Auto")
  93. alg_type = "AES";
  94. SymmetricAlgorithm alg = null;
  95. if (alg_type == "AES")
  96. alg = Rijndael.Create ();
  97. else if (alg_type == "3DES")
  98. alg = TripleDES.Create ();
  99. else
  100. throw new ProviderException (String.Format ("Unsupported decryption attribute '{0}' in <machineKey> configuration section", alg_type));
  101. decryptionKey = GetBytes (section.DecryptionKey, section.DecryptionKey.Length);
  102. return alg;
  103. }
  104. internal string EncodePassword (string password, MembershipPasswordFormat passwordFormat, string salt)
  105. {
  106. byte[] password_bytes;
  107. byte[] salt_bytes;
  108. switch (passwordFormat) {
  109. case MembershipPasswordFormat.Clear:
  110. return password;
  111. case MembershipPasswordFormat.Hashed:
  112. password_bytes = Encoding.Unicode.GetBytes (password);
  113. salt_bytes = Convert.FromBase64String (salt);
  114. byte[] hashBytes = new byte[salt_bytes.Length + password_bytes.Length];
  115. Buffer.BlockCopy (salt_bytes, 0, hashBytes, 0, salt_bytes.Length);
  116. Buffer.BlockCopy (password_bytes, 0, hashBytes, salt_bytes.Length, password_bytes.Length);
  117. MembershipSection section = (MembershipSection)WebConfigurationManager.GetSection ("system.web/membership");
  118. string alg_type = section.HashAlgorithmType;
  119. if (alg_type == "") {
  120. MachineKeySection keysection = (MachineKeySection)WebConfigurationManager.GetSection ("system.web/machineKey");
  121. alg_type = keysection.Validation.ToString ();
  122. }
  123. using (HashAlgorithm hash = HashAlgorithm.Create (alg_type)) {
  124. hash.TransformFinalBlock (hashBytes, 0, hashBytes.Length);
  125. return Convert.ToBase64String (hash.Hash);
  126. }
  127. case MembershipPasswordFormat.Encrypted:
  128. password_bytes = Encoding.Unicode.GetBytes (password);
  129. salt_bytes = Convert.FromBase64String (salt);
  130. byte[] buf = new byte[password_bytes.Length + salt_bytes.Length];
  131. Array.Copy (salt_bytes, 0, buf, 0, salt_bytes.Length);
  132. Array.Copy (password_bytes, 0, buf, salt_bytes.Length, password_bytes.Length);
  133. return Convert.ToBase64String (EncryptPassword (buf));
  134. default:
  135. /* not reached.. */
  136. return null;
  137. }
  138. }
  139. internal string DecodePassword (string password, MembershipPasswordFormat passwordFormat)
  140. {
  141. switch (passwordFormat) {
  142. case MembershipPasswordFormat.Clear:
  143. return password;
  144. case MembershipPasswordFormat.Hashed:
  145. throw new ProviderException ("Hashed passwords cannot be decoded.");
  146. case MembershipPasswordFormat.Encrypted:
  147. return Encoding.Unicode.GetString (DecryptPassword (Convert.FromBase64String (password)));
  148. default:
  149. /* not reached.. */
  150. return null;
  151. }
  152. }
  153. internal static DbProviderFactory GetDbProviderFactory (string providerName)
  154. {
  155. DbProviderFactory f = null;
  156. if (providerName != null && providerName != "") {
  157. try {
  158. f = DbProviderFactories.GetFactory(providerName);
  159. }
  160. catch (Exception e) { Console.WriteLine (e); /* nada */ }
  161. if (f != null)
  162. return f;
  163. }
  164. return SqlClientFactory.Instance;
  165. }
  166. void InitConnection ()
  167. {
  168. if (connection == null) {
  169. lock (lockobj) {
  170. if (connection != null)
  171. return;
  172. factory = GetDbProviderFactory (connectionString.ProviderName);
  173. connection = factory.CreateConnection();
  174. connection.ConnectionString = connectionString.ConnectionString;
  175. connection.Open ();
  176. }
  177. }
  178. }
  179. void AddParameter (DbCommand command, string parameterName, string parameterValue)
  180. {
  181. DbParameter dbp = command.CreateParameter ();
  182. dbp.ParameterName = parameterName;
  183. dbp.Value = parameterValue;
  184. dbp.Direction = ParameterDirection.Input;
  185. command.Parameters.Add (dbp);
  186. }
  187. void CheckParam (string pName, string p, int length)
  188. {
  189. if (p == null)
  190. throw new ArgumentNullException (pName);
  191. if (p.Length == 0 || p.Length > length || p.IndexOf (",") != -1)
  192. throw new ArgumentException (String.Format ("invalid format for {0}", pName));
  193. }
  194. protected override byte[] DecryptPassword (byte[] encodedPassword)
  195. {
  196. byte[] decryptionKey;
  197. SymmetricAlgorithm alg = GetAlg (out decryptionKey);
  198. alg.Key = decryptionKey;
  199. ICryptoTransform decryptor = alg.CreateDecryptor ();
  200. byte[] buf = decryptor.TransformFinalBlock (encodedPassword, 0, encodedPassword.Length);
  201. byte[] rv = new byte[buf.Length - SALT_BYTES];
  202. Array.Copy (buf, 16, rv, 0, buf.Length - 16);
  203. return rv;
  204. }
  205. protected override byte[] EncryptPassword (byte[] password)
  206. {
  207. byte[] decryptionKey;
  208. byte[] iv = new byte[SALT_BYTES];
  209. Array.Copy (password, 0, iv, 0, SALT_BYTES);
  210. Array.Clear (password, 0, SALT_BYTES);
  211. SymmetricAlgorithm alg = GetAlg (out decryptionKey);
  212. ICryptoTransform encryptor = alg.CreateEncryptor (decryptionKey, iv);
  213. return encryptor.TransformFinalBlock (password, 0, password.Length);
  214. }
  215. public override bool ChangePassword (string username, string oldPwd, string newPwd)
  216. {
  217. if (username != null) username = username.Trim ();
  218. if (oldPwd != null) oldPwd = oldPwd.Trim ();
  219. if (newPwd != null) newPwd = newPwd.Trim ();
  220. CheckParam ("username", username, 256);
  221. CheckParam ("oldPwd", oldPwd, 128);
  222. CheckParam ("newPwd", newPwd, 128);
  223. MembershipUser user = GetUser (username, false);
  224. if (user == null) throw new ProviderException ("could not find user in membership database");
  225. if (user.IsLockedOut) throw new MembershipPasswordException ("user is currently locked out");
  226. InitConnection();
  227. DbTransaction trans = connection.BeginTransaction ();
  228. string commandText;
  229. DbCommand command;
  230. try {
  231. MembershipPasswordFormat passwordFormat;
  232. string db_salt;
  233. bool valid = ValidateUsingPassword (trans, username, oldPwd, out passwordFormat, out db_salt);
  234. if (valid) {
  235. EmitValidatingPassword (username, newPwd, false);
  236. string db_password = EncodePassword (newPwd, passwordFormat, db_salt);
  237. DateTime now = DateTime.Now.ToUniversalTime ();
  238. commandText = @"
  239. UPDATE m
  240. SET Password = @Password,
  241. FailedPasswordAttemptCount = 0,
  242. FailedPasswordAttemptWindowStart = @DefaultDateTime,
  243. LastPasswordChangedDate = @Now
  244. FROM dbo.aspnet_Membership m, dbo.aspnet_Users u, dbo.aspnet_Applications a
  245. WHERE m.ApplicationId = a.ApplicationId
  246. AND u.ApplicationId = a.ApplicationId
  247. AND m.UserId = u.UserId
  248. AND u.LoweredUserName = LOWER(@UserName)
  249. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  250. command = factory.CreateCommand ();
  251. command.Transaction = trans;
  252. command.CommandText = commandText;
  253. command.Connection = connection;
  254. command.CommandType = CommandType.Text;
  255. AddParameter (command, "UserName", user.UserName);
  256. AddParameter (command, "Now", now.ToString ());
  257. AddParameter (command, "Password", db_password);
  258. AddParameter (command, "ApplicationName", ApplicationName);
  259. AddParameter (command, "DefaultDateTime", DefaultDateTime.ToString());
  260. if (1 != (int)command.ExecuteNonQuery ())
  261. throw new ProviderException ("failed to update Membership table");
  262. }
  263. trans.Commit ();
  264. return valid;
  265. }
  266. catch (ProviderException) {
  267. trans.Rollback ();
  268. throw;
  269. }
  270. catch (Exception e) {
  271. trans.Rollback ();
  272. throw new ProviderException ("error changing password", e);
  273. }
  274. }
  275. public override bool ChangePasswordQuestionAndAnswer (string username, string password, string newPwdQuestion, string newPwdAnswer)
  276. {
  277. if (username != null) username = username.Trim ();
  278. if (newPwdQuestion != null) newPwdQuestion = newPwdQuestion.Trim ();
  279. if (newPwdAnswer != null) newPwdAnswer = newPwdAnswer.Trim ();
  280. CheckParam ("username", username, 256);
  281. if (RequiresQuestionAndAnswer)
  282. CheckParam ("newPwdQuestion", newPwdQuestion, 128);
  283. if (RequiresQuestionAndAnswer)
  284. CheckParam ("newPwdAnswer", newPwdAnswer, 128);
  285. MembershipUser user = GetUser (username, false);
  286. if (user == null) throw new ProviderException ("could not find user in membership database");
  287. if (user.IsLockedOut) throw new MembershipPasswordException ("user is currently locked out");
  288. InitConnection();
  289. DbTransaction trans = connection.BeginTransaction ();
  290. string commandText;
  291. DbCommand command;
  292. try {
  293. MembershipPasswordFormat passwordFormat;
  294. string db_salt;
  295. bool valid = ValidateUsingPassword (trans, username, password, out passwordFormat, out db_salt);
  296. if (valid) {
  297. string db_passwordAnswer = EncodePassword (newPwdAnswer, passwordFormat, db_salt);
  298. commandText = @"
  299. UPDATE m
  300. SET PasswordQuestion = @PasswordQuestion,
  301. PasswordAnswer = @PasswordAnswer,
  302. FailedPasswordAttemptCount = 0,
  303. FailedPasswordAttemptWindowStart = @DefaultDateTime,
  304. FailedPasswordAnswerAttemptCount = 0,
  305. FailedPasswordAnswerAttemptWindowStart = @DefaultDateTime
  306. FROM dbo.aspnet_Membership m, dbo.aspnet_Users u, dbo.aspnet_Applications a
  307. WHERE m.ApplicationId = a.ApplicationId
  308. AND u.ApplicationId = a.ApplicationId
  309. AND m.UserId = u.UserId
  310. AND u.LoweredUserName = LOWER(@UserName)
  311. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  312. command = factory.CreateCommand ();
  313. command.Transaction = trans;
  314. command.CommandText = commandText;
  315. command.Connection = connection;
  316. command.CommandType = CommandType.Text;
  317. AddParameter (command, "UserName", user.UserName);
  318. AddParameter (command, "PasswordQuestion", newPwdQuestion);
  319. AddParameter (command, "PasswordAnswer", db_passwordAnswer);
  320. AddParameter (command, "ApplicationName", ApplicationName);
  321. AddParameter (command, "DefaultDateTime", DefaultDateTime.ToString());
  322. if (1 != (int)command.ExecuteNonQuery ())
  323. throw new ProviderException ("failed to update Membership table");
  324. }
  325. trans.Commit ();
  326. return valid;
  327. }
  328. catch (ProviderException) {
  329. trans.Rollback ();
  330. throw;
  331. }
  332. catch (Exception e) {
  333. trans.Rollback ();
  334. throw new ProviderException ("error changing password question and answer", e);
  335. }
  336. }
  337. public override MembershipUser CreateUser (string username,
  338. string password,
  339. string email,
  340. string pwdQuestion,
  341. string pwdAnswer,
  342. bool isApproved,
  343. object providerUserKey,
  344. out MembershipCreateStatus status)
  345. {
  346. if (username != null) username = username.Trim ();
  347. if (password != null) password = password.Trim ();
  348. if (email != null) email = email.Trim ();
  349. if (pwdQuestion != null) pwdQuestion = pwdQuestion.Trim ();
  350. if (pwdAnswer != null) pwdAnswer = pwdAnswer.Trim ();
  351. /* some initial validation */
  352. if (username == null || username.Length == 0 || username.Length > 256 || username.IndexOf (",") != -1) {
  353. status = MembershipCreateStatus.InvalidUserName;
  354. return null;
  355. }
  356. if (password == null || password.Length == 0 || password.Length > 128) {
  357. status = MembershipCreateStatus.InvalidPassword;
  358. return null;
  359. }
  360. if (RequiresUniqueEmail && (email == null || email.Length == 0)) {
  361. status = MembershipCreateStatus.InvalidEmail;
  362. return null;
  363. }
  364. if (RequiresQuestionAndAnswer &&
  365. (pwdQuestion == null ||
  366. pwdQuestion.Length == 0 || pwdQuestion.Length > 256)) {
  367. status = MembershipCreateStatus.InvalidQuestion;
  368. return null;
  369. }
  370. if (RequiresQuestionAndAnswer &&
  371. (pwdAnswer == null ||
  372. pwdAnswer.Length == 0 || pwdAnswer.Length > 128)) {
  373. status = MembershipCreateStatus.InvalidAnswer;
  374. return null;
  375. }
  376. if (providerUserKey != null && ! (providerUserKey is Guid)) {
  377. status = MembershipCreateStatus.InvalidProviderUserKey;
  378. return null;
  379. }
  380. /* encode our password/answer using the
  381. * "passwordFormat" configuration option */
  382. string passwordSalt = "";
  383. RandomNumberGenerator rng = RandomNumberGenerator.Create ();
  384. byte[] salt = new byte[SALT_BYTES];
  385. rng.GetBytes (salt);
  386. passwordSalt = Convert.ToBase64String (salt);
  387. password = EncodePassword (password, PasswordFormat, passwordSalt);
  388. if (RequiresQuestionAndAnswer)
  389. pwdAnswer = EncodePassword (pwdAnswer, PasswordFormat, passwordSalt);
  390. /* make sure the hashed/encrypted password and
  391. * answer are still under 128 characters. */
  392. if (password.Length > 128) {
  393. status = MembershipCreateStatus.InvalidPassword;
  394. return null;
  395. }
  396. if (RequiresQuestionAndAnswer) {
  397. if (pwdAnswer.Length > 128) {
  398. status = MembershipCreateStatus.InvalidAnswer;
  399. return null;
  400. }
  401. }
  402. InitConnection();
  403. DbTransaction trans = connection.BeginTransaction ();
  404. string commandText;
  405. DbCommand command;
  406. try {
  407. Guid applicationId;
  408. Guid userId;
  409. /* get the application id since it seems that inside transactions we
  410. can't insert using subqueries.. */
  411. commandText = @"
  412. SELECT ApplicationId
  413. FROM dbo.aspnet_Applications
  414. WHERE dbo.aspnet_Applications.LoweredApplicationName = LOWER(@ApplicationName)
  415. ";
  416. command = factory.CreateCommand ();
  417. command.Transaction = trans;
  418. command.CommandText = commandText;
  419. command.Connection = connection;
  420. command.CommandType = CommandType.Text;
  421. AddParameter (command, "ApplicationName", ApplicationName);
  422. DbDataReader reader = command.ExecuteReader ();
  423. reader.Read ();
  424. applicationId = reader.GetGuid (0);
  425. reader.Close ();
  426. /* check for unique username, email and
  427. * provider user key, if applicable */
  428. commandText = @"
  429. SELECT COUNT(*)
  430. FROM dbo.aspnet_Users u, dbo.aspnet_Applications a
  431. WHERE u.LoweredUserName = LOWER(@UserName)
  432. AND u.ApplicationId = a.ApplicationId
  433. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  434. command = factory.CreateCommand ();
  435. command.Transaction = trans;
  436. command.CommandText = commandText;
  437. command.Connection = connection;
  438. command.CommandType = CommandType.Text;
  439. AddParameter (command, "UserName", username);
  440. AddParameter (command, "ApplicationName", ApplicationName);
  441. if (0 != (int)command.ExecuteScalar()) {
  442. status = MembershipCreateStatus.DuplicateUserName;
  443. trans.Rollback ();
  444. return null;
  445. }
  446. if (requiresUniqueEmail) {
  447. commandText = @"
  448. SELECT COUNT(*)
  449. FROM dbo.aspnet_Membership, dbo.aspnet_Applications
  450. WHERE dbo.aspnet_Membership.Email = @Email
  451. AND dbo.aspnet_Membership.ApplicationId = dbo.aspnet_Applications.ApplicationId
  452. AND dbo.aspnet_Applications.LoweredApplicationName = LOWER(@ApplicationName)";
  453. command = factory.CreateCommand ();
  454. command.Transaction = trans;
  455. command.CommandText = commandText;
  456. command.Connection = connection;
  457. command.CommandType = CommandType.Text;
  458. AddParameter (command, "Email", email);
  459. AddParameter (command, "ApplicationName", ApplicationName);
  460. if (0 != (int)command.ExecuteScalar()) {
  461. status = MembershipCreateStatus.DuplicateEmail;
  462. trans.Rollback ();
  463. return null;
  464. }
  465. }
  466. if (providerUserKey != null) {
  467. commandText = @"
  468. SELECT COUNT(*)
  469. FROM dbo.aspnet_Membership, dbo.aspnet_Applications
  470. WHERE dbo.aspnet_Membership.UserId = @ProviderUserKey
  471. AND dbo.aspnet_Membership.ApplicationId = dbo.aspnet_Applications.ApplicationId
  472. AND dbo.aspnet_Applications.LoweredApplicationName = LOWER(@ApplicationName)";
  473. command = factory.CreateCommand ();
  474. command.Transaction = trans;
  475. command.CommandText = commandText;
  476. command.Connection = connection;
  477. command.CommandType = CommandType.Text;
  478. AddParameter (command, "Email", email);
  479. AddParameter (command, "ApplicationName", ApplicationName);
  480. if (0 != (int)command.ExecuteScalar()) {
  481. status = MembershipCreateStatus.DuplicateProviderUserKey;
  482. trans.Rollback ();
  483. return null;
  484. }
  485. }
  486. /* first into the Users table */
  487. commandText = @"
  488. INSERT into dbo.aspnet_Users (ApplicationId, UserId, UserName, LoweredUserName, LastActivityDate)
  489. VALUES (@ApplicationId, NEWID(), @UserName, LOWER(@UserName), GETDATE())
  490. ";
  491. command = factory.CreateCommand ();
  492. command.Transaction = trans;
  493. command.CommandText = commandText;
  494. command.Connection = connection;
  495. command.CommandType = CommandType.Text;
  496. AddParameter (command, "UserName", username);
  497. AddParameter (command, "ApplicationId", applicationId.ToString());
  498. if (command.ExecuteNonQuery() != 1) {
  499. status = MembershipCreateStatus.UserRejected; /* XXX */
  500. trans.Rollback ();
  501. return null;
  502. }
  503. /* then get the newly created userid */
  504. commandText = @"
  505. SELECT UserId
  506. FROM dbo.aspnet_Users
  507. WHERE dbo.aspnet_Users.LoweredUserName = LOWER(@UserName)
  508. ";
  509. command = factory.CreateCommand ();
  510. command.Transaction = trans;
  511. command.CommandText = commandText;
  512. command.Connection = connection;
  513. command.CommandType = CommandType.Text;
  514. AddParameter (command, "UserName", username);
  515. reader = command.ExecuteReader ();
  516. reader.Read ();
  517. userId = reader.GetGuid (0);
  518. reader.Close ();
  519. /* then insert into the Membership table */
  520. commandText = String.Format (@"
  521. INSERT into dbo.aspnet_Membership
  522. VALUES (@ApplicationId,
  523. @UserId,
  524. @Password, @PasswordFormat, @PasswordSalt,
  525. NULL,
  526. {0}, {1},
  527. {2}, {3},
  528. 0, 0,
  529. GETDATE(), GETDATE(), @DefaultDateTime,
  530. @DefaultDateTime,
  531. 0, @DefaultDateTime, 0, @DefaultDateTime, NULL)",
  532. email == null ? "NULL" : "@Email",
  533. email == null ? "NULL" : "LOWER(@Email)",
  534. pwdQuestion == null ? "NULL" : "@PasswordQuestion",
  535. pwdAnswer == null ? "NULL" : "@PasswordAnswer");
  536. command = factory.CreateCommand ();
  537. command.Transaction = trans;
  538. command.CommandText = commandText;
  539. command.Connection = connection;
  540. command.CommandType = CommandType.Text;
  541. AddParameter (command, "ApplicationId", applicationId.ToString());
  542. AddParameter (command, "UserId", userId.ToString());
  543. if (email != null)
  544. AddParameter (command, "Email", email);
  545. AddParameter (command, "Password", password);
  546. AddParameter (command, "PasswordFormat", ((int)PasswordFormat).ToString());
  547. AddParameter (command, "PasswordSalt", passwordSalt);
  548. if (pwdQuestion != null)
  549. AddParameter (command, "PasswordQuestion", pwdQuestion);
  550. if (pwdAnswer != null)
  551. AddParameter (command, "PasswordAnswer", pwdAnswer);
  552. AddParameter (command, "DefaultDateTime", DefaultDateTime.ToString());
  553. if (command.ExecuteNonQuery() != 1) {
  554. status = MembershipCreateStatus.UserRejected; /* XXX */
  555. return null;
  556. }
  557. trans.Commit ();
  558. status = MembershipCreateStatus.Success;
  559. return GetUser (username, false);
  560. }
  561. catch {
  562. status = MembershipCreateStatus.ProviderError;
  563. trans.Rollback ();
  564. return null;
  565. }
  566. }
  567. public override bool DeleteUser (string username, bool deleteAllRelatedData)
  568. {
  569. CheckParam ("username", username, 256);
  570. if (deleteAllRelatedData) {
  571. /* delete everything from the
  572. * following features as well:
  573. *
  574. * Roles
  575. * Profile
  576. * WebParts Personalization
  577. */
  578. }
  579. DbTransaction trans = connection.BeginTransaction ();
  580. DbCommand command;
  581. string commandText;
  582. InitConnection();
  583. try {
  584. /* delete from the Membership table */
  585. commandText = @"
  586. DELETE dbo.aspnet_Membership
  587. FROM dbo.aspnet_Membership, dbo.aspnet_Users, dbo.aspnet_Applications
  588. WHERE dbo.aspnet_Membership.UserId = dbo.aspnet_Users.UserId
  589. AND dbo.aspnet_Membership.ApplicationId = dbo.aspnet_Applications.ApplicationId
  590. AND dbo.aspnet_Users.LoweredUserName = LOWER (@UserName)
  591. AND dbo.aspnet_Users.ApplicationId = dbo.aspnet_Applications.ApplicationId
  592. AND dbo.aspnet_Applications.LoweredApplicationName = LOWER(@ApplicationName)";
  593. command = factory.CreateCommand ();
  594. command.Transaction = trans;
  595. command.CommandText = commandText;
  596. command.Connection = connection;
  597. command.CommandType = CommandType.Text;
  598. AddParameter (command, "UserName", username);
  599. AddParameter (command, "ApplicationName", ApplicationName);
  600. if (1 != command.ExecuteNonQuery())
  601. throw new ProviderException ("failed to delete from Membership table");
  602. /* delete from the User table */
  603. commandText = @"
  604. DELETE dbo.aspnet_Users
  605. FROM dbo.aspnet_Users, dbo.aspnet_Applications
  606. WHERE dbo.aspnet_Users.LoweredUserName = LOWER (@UserName)
  607. AND dbo.aspnet_Users.ApplicationId = dbo.aspnet_Applications.ApplicationId
  608. AND dbo.aspnet_Applications.LoweredApplicationName = LOWER(@ApplicationName)";
  609. command = factory.CreateCommand ();
  610. command.Transaction = trans;
  611. command.CommandText = commandText;
  612. command.Connection = connection;
  613. command.CommandType = CommandType.Text;
  614. AddParameter (command, "UserName", username);
  615. AddParameter (command, "ApplicationName", ApplicationName);
  616. if (1 != command.ExecuteNonQuery())
  617. throw new ProviderException ("failed to delete from User table");
  618. trans.Commit ();
  619. return true;
  620. }
  621. catch {
  622. trans.Rollback ();
  623. return false;
  624. }
  625. }
  626. public virtual string GeneratePassword ()
  627. {
  628. return Membership.GeneratePassword (minRequiredPasswordLength, minRequiredNonAlphanumericCharacters);
  629. }
  630. public override MembershipUserCollection FindUsersByEmail (string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
  631. {
  632. CheckParam ("emailToMatch", emailToMatch, 256);
  633. if (pageIndex < 0)
  634. throw new ArgumentException ("pageIndex must be >= 0");
  635. if (pageSize < 0)
  636. throw new ArgumentException ("pageSize must be >= 0");
  637. if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
  638. throw new ArgumentException ("pageIndex and pageSize are too large");
  639. string commandText;
  640. InitConnection();
  641. commandText = @"
  642. SELECT u.UserName, m.UserId, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
  643. m.IsLockedOut, m.CreateDate, m.LastLoginDate, u.LastActivityDate,
  644. m.LastPasswordChangedDate, m.LastLockoutDate
  645. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  646. WHERE m.ApplicationId = a.ApplicationId
  647. AND u.ApplicationId = a.ApplicationId
  648. AND m.UserId = u.UserId
  649. AND m.Email LIKE @Email
  650. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  651. DbCommand command = factory.CreateCommand ();
  652. command.CommandText = commandText;
  653. command.Connection = connection;
  654. command.CommandType = CommandType.Text;
  655. AddParameter (command, "Email", emailToMatch);
  656. AddParameter (command, "ApplicationName", ApplicationName);
  657. MembershipUserCollection c = BuildMembershipUserCollection (command, pageIndex, pageSize, out totalRecords);
  658. return c;
  659. }
  660. public override MembershipUserCollection FindUsersByName (string nameToMatch, int pageIndex, int pageSize, out int totalRecords)
  661. {
  662. CheckParam ("nameToMatch", nameToMatch, 256);
  663. if (pageIndex < 0)
  664. throw new ArgumentException ("pageIndex must be >= 0");
  665. if (pageSize < 0)
  666. throw new ArgumentException ("pageSize must be >= 0");
  667. if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
  668. throw new ArgumentException ("pageIndex and pageSize are too large");
  669. string commandText;
  670. InitConnection();
  671. commandText = @"
  672. SELECT u.UserName, m.UserId, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
  673. m.IsLockedOut, m.CreateDate, m.LastLoginDate, u.LastActivityDate,
  674. m.LastPasswordChangedDate, m.LastLockoutDate
  675. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  676. WHERE m.ApplicationId = a.ApplicationId
  677. AND u.ApplicationId = a.ApplicationId
  678. AND m.UserId = u.UserId
  679. AND u.UserName LIKE @UserName
  680. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  681. DbCommand command = factory.CreateCommand ();
  682. command.CommandText = commandText;
  683. command.Connection = connection;
  684. command.CommandType = CommandType.Text;
  685. AddParameter (command, "UserName", nameToMatch);
  686. AddParameter (command, "ApplicationName", ApplicationName);
  687. MembershipUserCollection c = BuildMembershipUserCollection (command, pageIndex, pageSize, out totalRecords);
  688. return c;
  689. }
  690. public override MembershipUserCollection GetAllUsers (int pageIndex, int pageSize, out int totalRecords)
  691. {
  692. if (pageIndex < 0)
  693. throw new ArgumentException ("pageIndex must be >= 0");
  694. if (pageSize < 0)
  695. throw new ArgumentException ("pageSize must be >= 0");
  696. if (pageIndex * pageSize + pageSize - 1 > Int32.MaxValue)
  697. throw new ArgumentException ("pageIndex and pageSize are too large");
  698. string commandText;
  699. InitConnection();
  700. commandText = @"
  701. SELECT u.UserName, m.UserId, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
  702. m.IsLockedOut, m.CreateDate, m.LastLoginDate, u.LastActivityDate,
  703. m.LastPasswordChangedDate, m.LastLockoutDate
  704. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  705. WHERE m.ApplicationId = a.ApplicationId
  706. AND u.ApplicationId = a.ApplicationId
  707. AND m.UserId = u.UserId
  708. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  709. DbCommand command = factory.CreateCommand ();
  710. command.CommandText = commandText;
  711. command.Connection = connection;
  712. command.CommandType = CommandType.Text;
  713. AddParameter (command, "ApplicationName", ApplicationName);
  714. MembershipUserCollection c = BuildMembershipUserCollection (command, pageIndex, pageSize, out totalRecords);
  715. return c;
  716. }
  717. MembershipUserCollection BuildMembershipUserCollection (DbCommand command, int pageIndex, int pageSize, out int totalRecords)
  718. {
  719. DbDataReader reader = null;
  720. try {
  721. int num_read = 0;
  722. int num_added = 0;
  723. int num_to_skip = pageIndex * pageSize;
  724. MembershipUserCollection users = new MembershipUserCollection ();
  725. reader = command.ExecuteReader ();
  726. while (reader.Read()) {
  727. if (num_read >= num_to_skip) {
  728. if (num_added < pageSize) {
  729. users.Add (GetUserFromReader (reader));
  730. num_added ++;
  731. }
  732. num_read ++;
  733. }
  734. }
  735. totalRecords = num_read;
  736. return users;
  737. }
  738. catch {
  739. totalRecords = 0;
  740. return null; /* should we let the exception through? */
  741. }
  742. finally {
  743. if (reader != null)
  744. reader.Close();
  745. }
  746. }
  747. public override int GetNumberOfUsersOnline ()
  748. {
  749. string commandText;
  750. InitConnection();
  751. DateTime now = DateTime.Now.ToUniversalTime ();
  752. commandText = String.Format (@"
  753. SELECT COUNT (*)
  754. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  755. WHERE m.ApplicationId = a.ApplicationId
  756. AND u.ApplicationId = a.ApplicationId
  757. AND m.UserId = u.UserId
  758. AND DATEADD(minute,{0},u.LastActivityDate) >= @Now
  759. AND a.LoweredApplicationName = LOWER(@ApplicationName)",
  760. userIsOnlineTimeWindow.Minutes);
  761. DbCommand command = factory.CreateCommand ();
  762. command.CommandText = commandText;
  763. command.Connection = connection;
  764. command.CommandType = CommandType.Text;
  765. AddParameter (command, "Now", now.ToString ());
  766. AddParameter (command, "ApplicationName", ApplicationName);
  767. try {
  768. return (int)command.ExecuteScalar ();
  769. }
  770. catch (Exception e) {
  771. Console.WriteLine (e);
  772. return -1;
  773. }
  774. }
  775. public override string GetPassword (string username, string answer)
  776. {
  777. if (!enablePasswordRetrieval)
  778. throw new NotSupportedException ("this provider has not been configured to allow the retrieval of passwords");
  779. CheckParam ("username", username, 256);
  780. if (RequiresQuestionAndAnswer)
  781. CheckParam ("answer", answer, 128);
  782. MembershipUser user = GetUser (username, false);
  783. if (user == null) throw new ProviderException ("could not find user in membership database");
  784. if (user.IsLockedOut) throw new MembershipPasswordException ("user is currently locked out");
  785. InitConnection();
  786. DbTransaction trans = connection.BeginTransaction ();
  787. try {
  788. MembershipPasswordFormat passwordFormat;
  789. string salt;
  790. string password = null;
  791. if (ValidateUsingPasswordAnswer (trans, username, answer,
  792. out passwordFormat, out salt)) {
  793. /* if the validation succeeds:
  794. set LastLoginDate to DateTime.Now
  795. set FailedPasswordAnswerAttemptCount to 0
  796. set FailedPasswordAnswerAttemptWindowStart to DefaultDateTime
  797. */
  798. string commandText = @"
  799. SELECT m.Password
  800. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  801. WHERE m.ApplicationId = a.ApplicationId
  802. AND u.ApplicationId = a.ApplicationId
  803. AND m.UserId = u.UserId
  804. AND u.LoweredUserName = LOWER(@UserName)
  805. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  806. DbCommand command = factory.CreateCommand ();
  807. command.Transaction = trans;
  808. command.CommandText = commandText;
  809. command.Connection = connection;
  810. command.CommandType = CommandType.Text;
  811. AddParameter (command, "UserName", username);
  812. AddParameter (command, "ApplicationName", ApplicationName);
  813. DbDataReader reader = command.ExecuteReader ();
  814. reader.Read ();
  815. password = reader.GetString (0);
  816. reader.Close();
  817. password = DecodePassword (password, passwordFormat);
  818. }
  819. else {
  820. throw new MembershipPasswordException ("The password-answer supplied is wrong.");
  821. }
  822. trans.Commit ();
  823. return password;
  824. }
  825. catch (MembershipPasswordException) {
  826. trans.Commit ();
  827. throw;
  828. }
  829. catch {
  830. trans.Rollback ();
  831. throw;
  832. }
  833. }
  834. MembershipUser GetUserFromReader (DbDataReader reader)
  835. {
  836. return new MembershipUser (this.Name, /* XXX is this right? */
  837. reader.GetString (0), /* name */
  838. reader.GetGuid (1), /* providerUserKey */
  839. reader.IsDBNull (2) ? null : reader.GetString (2), /* email */
  840. reader.IsDBNull (3) ? null : reader.GetString (3), /* passwordQuestion */
  841. reader.IsDBNull (4) ? null : reader.GetString (4), /* comment */
  842. reader.GetBoolean (5), /* isApproved */
  843. reader.GetBoolean (6), /* isLockedOut */
  844. reader.GetDateTime (7).ToLocalTime (), /* creationDate */
  845. reader.GetDateTime (8).ToLocalTime (), /* lastLoginDate */
  846. reader.GetDateTime (9).ToLocalTime (), /* lastActivityDate */
  847. reader.GetDateTime (10).ToLocalTime (), /* lastPasswordChangedDate */
  848. reader.GetDateTime (11).ToLocalTime () /* lastLockoutDate */);
  849. }
  850. MembershipUser BuildMembershipUser (DbCommand query, bool userIsOnline)
  851. {
  852. DbDataReader reader = null;
  853. try {
  854. reader = query.ExecuteReader ();
  855. if (!reader.Read ())
  856. return null;
  857. MembershipUser user = GetUserFromReader (reader);
  858. if (user != null && userIsOnline) {
  859. string commandText;
  860. DbCommand command;
  861. commandText = @"
  862. UPDATE dbo.aspnet_Users u, dbo.aspnet_Application a
  863. SET u.LastActivityDate = GETDATE()
  864. WHERE u.ApplicationId = a.ApplicationId
  865. AND u.UserName = @UserName
  866. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  867. command = factory.CreateCommand ();
  868. command.CommandText = commandText;
  869. command.Connection = connection;
  870. command.CommandType = CommandType.Text;
  871. AddParameter (command, "UserName", user.UserName);
  872. AddParameter (command, "ApplicationName", ApplicationName);
  873. command.ExecuteNonQuery();
  874. }
  875. return user;
  876. }
  877. catch {
  878. return null; /* should we let the exception through? */
  879. }
  880. finally {
  881. if (reader != null)
  882. reader.Close ();
  883. }
  884. }
  885. public override MembershipUser GetUser (string username, bool userIsOnline)
  886. {
  887. CheckParam ("username", username, 256);
  888. string commandText;
  889. DbCommand command;
  890. InitConnection();
  891. commandText = @"
  892. SELECT u.UserName, m.UserId, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
  893. m.IsLockedOut, m.CreateDate, m.LastLoginDate, u.LastActivityDate,
  894. m.LastPasswordChangedDate, m.LastLockoutDate
  895. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  896. WHERE m.ApplicationId = a.ApplicationId
  897. AND u.ApplicationId = a.ApplicationId
  898. AND m.UserId = u.UserId
  899. AND u.UserName = @UserName
  900. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  901. command = factory.CreateCommand ();
  902. command.CommandText = commandText;
  903. command.Connection = connection;
  904. command.CommandType = CommandType.Text;
  905. AddParameter (command, "UserName", username);
  906. AddParameter (command, "ApplicationName", ApplicationName);
  907. MembershipUser u = BuildMembershipUser (command, userIsOnline);
  908. return u;
  909. }
  910. public override MembershipUser GetUser (object providerUserKey, bool userIsOnline)
  911. {
  912. string commandText;
  913. DbCommand command;
  914. InitConnection();
  915. commandText = @"
  916. SELECT u.UserName, m.UserId, m.Email, m.PasswordQuestion, m.Comment, m.IsApproved,
  917. m.IsLockedOut, m.CreateDate, m.LastLoginDate, u.LastActivityDate,
  918. m.LastPasswordChangedDate, m.LastLockoutDate
  919. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  920. WHERE m.ApplicationId = a.ApplicationId
  921. AND u.ApplicationId = a.ApplicationId
  922. AND m.UserId = u.UserId
  923. AND u.UserId = @UserKey
  924. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  925. command = factory.CreateCommand ();
  926. command.CommandText = commandText;
  927. command.Connection = connection;
  928. command.CommandType = CommandType.Text;
  929. AddParameter (command, "UserKey", providerUserKey.ToString());
  930. AddParameter (command, "ApplicationName", ApplicationName);
  931. MembershipUser u = BuildMembershipUser (command, userIsOnline);
  932. return u;
  933. }
  934. public override string GetUserNameByEmail (string email)
  935. {
  936. CheckParam ("email", email, 256);
  937. string commandText;
  938. DbCommand command;
  939. InitConnection();
  940. commandText = @"
  941. SELECT u.UserName
  942. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  943. WHERE m.ApplicationId = a.ApplicationId
  944. AND u.ApplicationId = a.ApplicationId
  945. AND m.UserId = u.UserId
  946. AND m.Email = @Email
  947. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  948. command = factory.CreateCommand ();
  949. command.CommandText = commandText;
  950. command.Connection = connection;
  951. command.CommandType = CommandType.Text;
  952. AddParameter (command, "Email", email);
  953. AddParameter (command, "ApplicationName", ApplicationName);
  954. try {
  955. DbDataReader reader = command.ExecuteReader ();
  956. string rv = null;
  957. while (reader.Read())
  958. rv = reader.GetString(0);
  959. reader.Close();
  960. return rv;
  961. }
  962. catch {
  963. return null; /* should we allow the exception through? */
  964. }
  965. }
  966. bool GetBoolConfigValue (NameValueCollection config, string name, bool def)
  967. {
  968. bool rv = def;
  969. string val = config[name];
  970. if (val != null) {
  971. try { rv = Boolean.Parse (val); }
  972. catch (Exception e) {
  973. throw new ProviderException (String.Format ("{0} must be true or false", name), e); }
  974. }
  975. return rv;
  976. }
  977. int GetIntConfigValue (NameValueCollection config, string name, int def)
  978. {
  979. int rv = def;
  980. string val = config[name];
  981. if (val != null) {
  982. try { rv = Int32.Parse (val); }
  983. catch (Exception e) {
  984. throw new ProviderException (String.Format ("{0} must be an integer", name), e); }
  985. }
  986. return rv;
  987. }
  988. int GetEnumConfigValue (NameValueCollection config, string name, Type enumType, int def)
  989. {
  990. int rv = def;
  991. string val = config[name];
  992. if (val != null) {
  993. try { rv = (int)Enum.Parse (enumType, val); }
  994. catch (Exception e) {
  995. throw new ProviderException (String.Format ("{0} must be one of the following values: {1}", name, String.Join (",", Enum.GetNames (enumType))), e); }
  996. }
  997. return rv;
  998. }
  999. string GetStringConfigValue (NameValueCollection config, string name, string def)
  1000. {
  1001. string rv = def;
  1002. string val = config[name];
  1003. if (val != null)
  1004. rv = val;
  1005. return rv;
  1006. }
  1007. void EmitValidatingPassword (string username, string password, bool isNewUser)
  1008. {
  1009. ValidatePasswordEventArgs args = new ValidatePasswordEventArgs (username, password, isNewUser);
  1010. OnValidatingPassword (args);
  1011. /* if we're canceled.. */
  1012. if (args.Cancel) {
  1013. if (args.FailureInformation == null)
  1014. throw new ProviderException ("Password validation canceled");
  1015. else
  1016. throw args.FailureInformation;
  1017. }
  1018. }
  1019. public override void Initialize (string name, NameValueCollection config)
  1020. {
  1021. if (config == null)
  1022. throw new ArgumentNullException ("config");
  1023. base.Initialize (name, config);
  1024. applicationName = GetStringConfigValue (config, "applicationName", "/");
  1025. enablePasswordReset = GetBoolConfigValue (config, "enablePasswordReset", true);
  1026. enablePasswordRetrieval = GetBoolConfigValue (config, "enablePasswordRetrieval", false);
  1027. requiresQuestionAndAnswer = GetBoolConfigValue (config, "requiresQuestionAndAnswer", true);
  1028. requiresUniqueEmail = GetBoolConfigValue (config, "requiresUniqueEmail", false);
  1029. passwordFormat = (MembershipPasswordFormat)GetEnumConfigValue (config, "passwordFormat", typeof (MembershipPasswordFormat),
  1030. (int)MembershipPasswordFormat.Hashed);
  1031. maxInvalidPasswordAttempts = GetIntConfigValue (config, "maxInvalidPasswordAttempts", 5);
  1032. minRequiredPasswordLength = GetIntConfigValue (config, "minRequiredPasswordLength", 7);
  1033. minRequiredNonAlphanumericCharacters = GetIntConfigValue (config, "minRequiredNonAlphanumericCharacters", 1);
  1034. passwordAttemptWindow = GetIntConfigValue (config, "passwordAttemptWindow", 10);
  1035. passwordStrengthRegularExpression = GetStringConfigValue (config, "passwordStrengthRegularExpression", "");
  1036. MembershipSection section = (MembershipSection)WebConfigurationManager.GetSection ("system.web/membership");
  1037. userIsOnlineTimeWindow = section.UserIsOnlineTimeWindow;
  1038. /* we can't support password retrieval with hashed passwords */
  1039. if (passwordFormat == MembershipPasswordFormat.Hashed && enablePasswordRetrieval)
  1040. throw new ProviderException ("password retrieval cannot be used with hashed passwords");
  1041. string connectionStringName = config["connectionStringName"];
  1042. if (applicationName.Length > 256)
  1043. throw new ProviderException ("The ApplicationName attribute must be 256 characters long or less.");
  1044. if (connectionStringName == null || connectionStringName.Length == 0)
  1045. throw new ProviderException ("The ConnectionStringName attribute must be present and non-zero length.");
  1046. connectionString = WebConfigurationManager.ConnectionStrings[connectionStringName];
  1047. }
  1048. public override string ResetPassword (string username, string answer)
  1049. {
  1050. if (!enablePasswordReset)
  1051. throw new NotSupportedException ("this provider has not been configured to allow the resetting of passwords");
  1052. CheckParam ("username", username, 256);
  1053. if (RequiresQuestionAndAnswer)
  1054. CheckParam ("answer", answer, 128);
  1055. MembershipUser user = GetUser (username, false);
  1056. if (user == null) throw new ProviderException ("could not find user in membership database");
  1057. if (user.IsLockedOut) throw new MembershipPasswordException ("user is currently locked out");
  1058. InitConnection();
  1059. string commandText;
  1060. DbCommand command;
  1061. DbTransaction trans = connection.BeginTransaction ();
  1062. try {
  1063. MembershipPasswordFormat db_passwordFormat;
  1064. string db_salt;
  1065. string newPassword = null;
  1066. if (ValidateUsingPasswordAnswer (trans, user.UserName, answer, out db_passwordFormat, out db_salt)) {
  1067. newPassword = GeneratePassword ();
  1068. string db_password;
  1069. EmitValidatingPassword (username, newPassword, false);
  1070. /* otherwise update the user's password in the db */
  1071. db_password = EncodePassword (newPassword, db_passwordFormat, db_salt);
  1072. commandText = @"
  1073. UPDATE m
  1074. SET Password = @Password,
  1075. FailedPasswordAnswerAttemptCount = 0,
  1076. FailedPasswordAnswerAttemptWindowStart = @DefaultDateTime
  1077. FROM dbo.aspnet_Membership m, dbo.aspnet_Users u, dbo.aspnet_Applications a
  1078. WHERE m.ApplicationId = a.ApplicationId
  1079. AND u.ApplicationId = a.ApplicationId
  1080. AND m.UserId = u.UserId
  1081. AND u.LoweredUserName = LOWER(@UserName)
  1082. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  1083. command = factory.CreateCommand ();
  1084. command.Transaction = trans;
  1085. command.CommandText = commandText;
  1086. command.Connection = connection;
  1087. command.CommandType = CommandType.Text;
  1088. AddParameter (command, "UserName", user.UserName);
  1089. AddParameter (command, "Password", db_password);
  1090. AddParameter (command, "ApplicationName", ApplicationName);
  1091. AddParameter (command, "DefaultDateTime", DefaultDateTime.ToString());
  1092. if (1 != (int)command.ExecuteNonQuery ())
  1093. throw new ProviderException ("failed to update Membership table");
  1094. trans.Commit ();
  1095. }
  1096. else {
  1097. throw new MembershipPasswordException ("The password-answer supplied is wrong.");
  1098. }
  1099. return newPassword;
  1100. }
  1101. catch (MembershipPasswordException) {
  1102. trans.Commit ();
  1103. throw;
  1104. }
  1105. catch (ProviderException) {
  1106. trans.Rollback ();
  1107. throw;
  1108. }
  1109. catch (Exception e) {
  1110. trans.Rollback ();
  1111. throw new ProviderException ("Failed to reset password", e);
  1112. }
  1113. }
  1114. public override void UpdateUser (MembershipUser user)
  1115. {
  1116. if (user == null) throw new ArgumentNullException ("user");
  1117. if (user.UserName == null) throw new ArgumentNullException ("user.UserName");
  1118. if (RequiresUniqueEmail && user.Email == null) throw new ArgumentNullException ("user.Email");
  1119. CheckParam ("user.UserName", user.UserName, 256);
  1120. if (user.Email.Length > 256 || (RequiresUniqueEmail && user.Email.Length == 0))
  1121. throw new ArgumentException ("invalid format for user.Email");
  1122. DbTransaction trans = connection.BeginTransaction ();
  1123. string commandText;
  1124. DbCommand command;
  1125. InitConnection();
  1126. try {
  1127. DateTime now = DateTime.Now.ToUniversalTime ();
  1128. commandText = String.Format (@"
  1129. UPDATE m
  1130. SET Email = {0},
  1131. Comment = {1},
  1132. IsApproved = @IsApproved,
  1133. LastLoginDate = @Now
  1134. FROM dbo.aspnet_Membership m, dbo.aspnet_Users u, dbo.aspnet_Applications a
  1135. WHERE m.ApplicationId = a.ApplicationId
  1136. AND u.ApplicationId = a.ApplicationId
  1137. AND m.UserId = u.UserId
  1138. AND u.LoweredUserName = LOWER(@UserName)
  1139. AND a.LoweredApplicationName = LOWER(@ApplicationName)",
  1140. user.Email == null ? "NULL" : "@Email",
  1141. user.Comment == null ? "NULL" : "@Comment");
  1142. command = factory.CreateCommand ();
  1143. command.Transaction = trans;
  1144. command.CommandText = commandText;
  1145. command.Connection = connection;
  1146. command.CommandType = CommandType.Text;
  1147. if (user.Email != null)
  1148. AddParameter (command, "Email", user.Email);
  1149. if (user.Comment != null)
  1150. AddParameter (command, "Comment", user.Comment);
  1151. AddParameter (command, "IsApproved", user.IsApproved.ToString());
  1152. AddParameter (command, "UserName", user.UserName);
  1153. AddParameter (command, "ApplicationName", ApplicationName);
  1154. AddParameter (command, "Now", now.ToString ());
  1155. if (0 == command.ExecuteNonQuery())
  1156. throw new ProviderException ("failed to membership table");
  1157. commandText = @"
  1158. UPDATE dbo.aspnet_Users
  1159. SET LastActivityDate = @Now
  1160. FROM dbo.aspnet_Users u, dbo.aspnet_Applications a
  1161. WHERE a.ApplicationId = a.ApplicationId
  1162. AND u.LoweredUserName = LOWER(@UserName)
  1163. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  1164. command = factory.CreateCommand ();
  1165. command.Transaction = trans;
  1166. command.CommandText = commandText;
  1167. command.Connection = connection;
  1168. command.CommandType = CommandType.Text;
  1169. AddParameter (command, "UserName", user.UserName);
  1170. AddParameter (command, "ApplicationName", ApplicationName);
  1171. AddParameter (command, "Now", now.ToString ());
  1172. if (0 == command.ExecuteNonQuery())
  1173. throw new ProviderException ("failed to user table");
  1174. trans.Commit ();
  1175. }
  1176. catch (ProviderException) {
  1177. trans.Rollback ();
  1178. throw;
  1179. }
  1180. catch (Exception e) {
  1181. trans.Rollback ();
  1182. throw new ProviderException ("failed to update user", e);
  1183. }
  1184. }
  1185. public override bool ValidateUser (string username, string password)
  1186. {
  1187. MembershipUser user = GetUser (username, false);
  1188. /* if the user is locked out, return false immediately */
  1189. if (user.IsLockedOut)
  1190. return false;
  1191. /* if the user is not yet approved, return false */
  1192. if (!user.IsApproved)
  1193. return false;
  1194. EmitValidatingPassword (username, password, false);
  1195. InitConnection();
  1196. DbTransaction trans = connection.BeginTransaction ();
  1197. string commandText;
  1198. DbCommand command;
  1199. try {
  1200. MembershipPasswordFormat passwordFormat;
  1201. string salt;
  1202. bool valid = ValidateUsingPassword (trans, username, password, out passwordFormat, out salt);
  1203. if (valid) {
  1204. DateTime now = DateTime.Now.ToUniversalTime ();
  1205. /* if the validation succeeds:
  1206. set LastLoginDate to DateTime.Now
  1207. set FailedPasswordAttemptCount to 0
  1208. set FailedPasswordAttemptWindow to DefaultDateTime
  1209. set FailedPasswordAnswerAttemptCount to 0
  1210. set FailedPasswordAnswerAttemptWindowStart to DefaultDateTime
  1211. */
  1212. commandText = @"
  1213. UPDATE dbo.aspnet_Membership
  1214. SET LastLoginDate = @Now,
  1215. FailedPasswordAttemptCount = 0,
  1216. FailedPasswordAttemptWindowStart = @DefaultDateTime,
  1217. FailedPasswordAnswerAttemptCount = 0,
  1218. FailedPasswordAnswerAttemptWindowStart = @DefaultDateTime
  1219. FROM dbo.aspnet_Membership m, dbo.aspnet_Applications a, dbo.aspnet_Users u
  1220. WHERE m.ApplicationId = a.ApplicationId
  1221. AND u.ApplicationId = a.ApplicationId
  1222. AND m.UserId = u.UserId
  1223. AND u.LoweredUserName = LOWER(@UserName)
  1224. AND a.LoweredApplicationName = LOWER(@ApplicationName)";
  1225. command = factory.CreateCommand ();
  1226. command.Transaction = trans;
  1227. command.CommandText = commandText;
  1228. command.Connection = connection;
  1229. command.CommandType = CommandType.Text;
  1230. AddParameter (command, "UserName", user.UserName);
  1231. AddParameter (command, "ApplicationName", ApplicationName);
  1232. AddParameter (command, "Now", now.ToString ());
  1233. AddParameter (command, "DefaultDateTime",

Large files files are truncated, but you can click here to view the full file