Guest User

Untitled

a guest
Mar 7th, 2018
110
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 24.33 KB | None | 0 0
  1. #region Using
  2.  
  3. using System;
  4. using System.Xml;
  5. using System.Collections.Generic;
  6. using System.Collections.Specialized;
  7. using System.Configuration.Provider;
  8. using System.Web.Security;
  9. using System.Web.Hosting;
  10. using System.Web.Management;
  11. using System.Security.Permissions;
  12. using System.Web;
  13. using System.Text;
  14. using System.Security.Cryptography;
  15. using System.Diagnostics;
  16.  
  17. #endregion
  18.  
  19. namespace BlogEngine.Core.Providers
  20. {
  21. /// <summary>
  22. ///
  23. /// </summary>
  24. public class XmlMembershipProvider : MembershipProvider
  25. {
  26. #region Member variables
  27. private Dictionary<string, MembershipUser> _Users;
  28. private string _XmlFileName;
  29. //variables below are added By Van.
  30. private string pApplicationName;
  31. private bool pEnablePasswordReset;
  32. private bool pEnablePasswordRetrieval;
  33. private bool pRequiresQuestionAndAnswer;
  34. private bool pRequiresUniqueEmail;
  35. private int pMaxInvalidPasswordAttempts;
  36. private int pPasswordAttemptWindow;
  37. private MembershipPasswordFormat pPasswordFormat;
  38. private int pMinRequiredNonAlphanumericCharacters;
  39. private int pMinRequiredPasswordLength;
  40. private string pPasswordStrengthRegularExpression;
  41.  
  42. private int newPasswordLength = 8;
  43. private string eventSource = "XmlMembershipProvider";
  44. private string eventLog = "Application";
  45. private string exceptionMessage = "An exception occurred. Please check the Event Log.";
  46. //
  47. // Used when determining encryption key values.
  48. //
  49. private MachineKeySection machineKey;
  50. //
  51. // If false, exceptions are thrown to the caller. If true,
  52. // exceptions are written to the event log.
  53. //
  54. private bool pWriteExceptionsToEventLog;
  55. #endregion
  56.  
  57. #region Properties
  58.  
  59. // MembershipProvider Properties
  60. /// <summary>
  61. ///
  62. /// </summary>
  63. public override string ApplicationName
  64. {
  65. get { throw new NotSupportedException(); }
  66. set { throw new NotSupportedException(); }
  67. }
  68.  
  69. /// <summary>
  70. ///
  71. /// </summary>
  72. public override bool EnablePasswordRetrieval
  73. {
  74. get { return false; }
  75. }
  76.  
  77. /// <summary>
  78. ///
  79. /// </summary>
  80. public override bool EnablePasswordReset
  81. {
  82. get { return false; }
  83. }
  84.  
  85. /// <summary>
  86. ///
  87. /// </summary>
  88. public override int MaxInvalidPasswordAttempts
  89. {
  90. get { return 5; }
  91. }
  92.  
  93. /// <summary>
  94. ///
  95. /// </summary>
  96. public override int MinRequiredNonAlphanumericCharacters
  97. {
  98. get { return 0; }
  99. }
  100.  
  101. /// <summary>
  102. ///
  103. /// </summary>
  104. public override int MinRequiredPasswordLength
  105. {
  106. get { return 8; }
  107. }
  108.  
  109. /// <summary>
  110. ///
  111. /// </summary>
  112. public override int PasswordAttemptWindow
  113. {
  114. get { throw new NotSupportedException(); }
  115. }
  116.  
  117. /// <summary>
  118. /// Password Format
  119. /// </summary>
  120. public override MembershipPasswordFormat PasswordFormat
  121. {
  122. get { return MembershipPasswordFormat.Hashed; }
  123. }
  124.  
  125. /// <summary>
  126. ///
  127. /// </summary>
  128. public override string PasswordStrengthRegularExpression
  129. {
  130. get { throw new NotSupportedException(); }
  131. }
  132.  
  133. /// <summary>
  134. ///
  135. /// </summary>
  136. public override bool RequiresQuestionAndAnswer
  137. {
  138. get { return false; }
  139. }
  140.  
  141. /// <summary>
  142. ///
  143. /// </summary>
  144. public override bool RequiresUniqueEmail
  145. {
  146. get { return false; }
  147. }
  148.  
  149. #endregion
  150.  
  151. #region Supported methods
  152.  
  153. /// <summary>
  154. ///
  155. /// </summary>
  156. /// <param name="name"></param>
  157. /// <param name="config"></param>
  158. public override void Initialize(string name, NameValueCollection config)
  159. {
  160. if (config == null)
  161. throw new ArgumentNullException("config");
  162.  
  163. if (String.IsNullOrEmpty(name))
  164. name = "XmlMembershipProvider";
  165.  
  166. if (string.IsNullOrEmpty(config["description"]))
  167. {
  168. config.Remove("description");
  169. config.Add("description", "XML membership provider");
  170. }
  171.  
  172. base.Initialize(name, config);
  173.  
  174. //Init member variables
  175. InitMemberVariables(config);
  176.  
  177. // Initialize _XmlFileName and make sure the path
  178. // is app-relative
  179. string path = config["xmlFileName"];
  180.  
  181. if (String.IsNullOrEmpty(path))
  182. path = BlogSettings.Instance.StorageLocation + "Users.xml";
  183.  
  184. if (!VirtualPathUtility.IsAppRelative(path))
  185. throw new ArgumentException
  186. ("xmlFileName must be app-relative");
  187.  
  188. string fullyQualifiedPath = VirtualPathUtility.Combine
  189. (VirtualPathUtility.AppendTrailingSlash
  190. (HttpRuntime.AppDomainAppVirtualPath), path);
  191.  
  192. _XmlFileName = HostingEnvironment.MapPath(fullyQualifiedPath);
  193. config.Remove("xmlFileName");
  194.  
  195. // Make sure we have permission to read the XML data source and
  196. // throw an exception if we don't
  197. FileIOPermission permission = new FileIOPermission(FileIOPermissionAccess.Write, _XmlFileName);
  198. permission.Demand();
  199.  
  200. // Throw an exception if unrecognized attributes remain
  201. if (config.Count > 0)
  202. {
  203. string attr = config.GetKey(0);
  204. if (!String.IsNullOrEmpty(attr))
  205. throw new ProviderException("Unrecognized attribute: " + attr);
  206. }
  207. }
  208.  
  209. /// <summary>
  210. /// Returns true if the username and password match an exsisting user.
  211. /// </summary>
  212. public override bool ValidateUser(string username, string password)
  213. {
  214. if (String.IsNullOrEmpty(username) || String.IsNullOrEmpty(password))
  215. return false;
  216.  
  217. try
  218. {
  219. ReadMembershipDataStore();
  220.  
  221. // Validate the user name and password
  222. MembershipUser user;
  223. string encodePwd;
  224. if (_Users.TryGetValue(username, out user))
  225. {
  226. if (user.Comment == password) // Case-sensitive
  227. {
  228. //user.LastLoginDate = DateTime.Now;
  229. //UpdateUser(user);
  230. return true;
  231. }
  232. }
  233.  
  234. return false;
  235. }
  236. catch (Exception)
  237. {
  238. return false;
  239. }
  240. }
  241.  
  242. /// <summary>
  243. /// Retrieves a user based on his/hers username.
  244. /// the userIsOnline parameter is ignored.
  245. /// </summary>
  246. public override MembershipUser GetUser(string username, bool userIsOnline)
  247. {
  248. if (String.IsNullOrEmpty(username))
  249. return null;
  250.  
  251. ReadMembershipDataStore();
  252.  
  253. // Retrieve the user from the data source
  254. MembershipUser user;
  255. if (_Users.TryGetValue(username, out user))
  256. return user;
  257.  
  258. return null;
  259. }
  260.  
  261. /// <summary>
  262. /// Retrieves a collection of all the users.
  263. /// This implementation ignores pageIndex and pageSize,
  264. /// and it doesn't sort the MembershipUser objects returned.
  265. /// </summary>
  266. public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
  267. {
  268. ReadMembershipDataStore();
  269. MembershipUserCollection users = new MembershipUserCollection();
  270.  
  271. foreach (KeyValuePair<string, MembershipUser> pair in _Users)
  272. {
  273. users.Add(pair.Value);
  274. }
  275.  
  276. totalRecords = users.Count;
  277. return users;
  278. }
  279.  
  280. /// <summary>
  281. /// Changes a users password.
  282. /// </summary>
  283. public override bool ChangePassword(string username, string oldPassword, string newPassword)
  284. {
  285. XmlDocument doc = new XmlDocument();
  286. doc.Load(_XmlFileName);
  287. XmlNodeList nodes = doc.GetElementsByTagName("User");
  288. foreach (XmlNode node in nodes)
  289. {
  290. if (node["UserName"].InnerText.Equals(username, StringComparison.OrdinalIgnoreCase)
  291. || node["Password"].InnerText.Equals(oldPassword, StringComparison.OrdinalIgnoreCase))
  292. {
  293. node["Password"].InnerText = newPassword;
  294. doc.Save(_XmlFileName);
  295. return true;
  296. }
  297. }
  298.  
  299. return false;
  300. }
  301.  
  302. /// <summary>
  303. /// Creates a new user store he/she in the XML file
  304. /// </summary>
  305. public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
  306. {
  307. XmlDocument doc = new XmlDocument();
  308. doc.Load(_XmlFileName);
  309.  
  310. XmlNode xmlUserRoot = doc.CreateElement("User");
  311. XmlNode xmlUserName = doc.CreateElement("UserName");
  312. XmlNode xmlPassword = doc.CreateElement("Password");
  313. XmlNode xmlEmail = doc.CreateElement("Email");
  314. XmlNode xmlLastLoginTime = doc.CreateElement("LastLoginTime");
  315.  
  316. xmlUserName.InnerText = username;
  317. xmlPassword.InnerText = password;
  318. xmlEmail.InnerText = email;
  319. xmlLastLoginTime.InnerText = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");
  320.  
  321. xmlUserRoot.AppendChild(xmlUserName);
  322. xmlUserRoot.AppendChild(xmlPassword);
  323. xmlUserRoot.AppendChild(xmlEmail);
  324. xmlUserRoot.AppendChild(xmlLastLoginTime);
  325.  
  326. doc.SelectSingleNode("Users").AppendChild(xmlUserRoot);
  327. doc.Save(_XmlFileName);
  328.  
  329. status = MembershipCreateStatus.Success;
  330. MembershipUser user = new MembershipUser(Name, username, username, email, passwordQuestion, password, isApproved, false, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.Now, DateTime.MaxValue);
  331. _Users.Add(username, user);
  332. return user;
  333. }
  334.  
  335. /// <summary>
  336. /// Deletes the user from the XML file and
  337. /// removes him/her from the internal cache.
  338. /// </summary>
  339. public override bool DeleteUser(string username, bool deleteAllRelatedData)
  340. {
  341. XmlDocument doc = new XmlDocument();
  342. doc.Load(_XmlFileName);
  343.  
  344. foreach (XmlNode node in doc.GetElementsByTagName("User"))
  345. {
  346. if (node.ChildNodes[0].InnerText.Equals(username, StringComparison.OrdinalIgnoreCase))
  347. {
  348. doc.SelectSingleNode("Users").RemoveChild(node);
  349. doc.Save(_XmlFileName);
  350. _Users.Remove(username);
  351. return true;
  352. }
  353. }
  354.  
  355. return false;
  356. }
  357.  
  358. /// <summary>
  359. /// Get a user based on the username parameter.
  360. /// the userIsOnline parameter is ignored.
  361. /// </summary>
  362. public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
  363. {
  364. XmlDocument doc = new XmlDocument();
  365. doc.Load(_XmlFileName);
  366.  
  367. foreach (XmlNode node in doc.SelectNodes("//User"))
  368. {
  369. if (node.ChildNodes[0].InnerText.Equals(providerUserKey.ToString(), StringComparison.OrdinalIgnoreCase))
  370. {
  371. string userName = node.ChildNodes[0].InnerText;
  372. string password = node.ChildNodes[1].InnerText;
  373. string email = node.ChildNodes[2].InnerText;
  374. DateTime lastLoginTime = DateTime.Parse(node.ChildNodes[3].InnerText);
  375. return new MembershipUser(Name, providerUserKey.ToString(), providerUserKey, email, string.Empty, password, true, false, DateTime.Now, lastLoginTime, DateTime.Now, DateTime.Now, DateTime.MaxValue);
  376. }
  377. }
  378.  
  379. return default(MembershipUser);
  380. }
  381.  
  382. /// <summary>
  383. /// Retrieves a username based on a matching email.
  384. /// </summary>
  385. public override string GetUserNameByEmail(string email)
  386. {
  387. XmlDocument doc = new XmlDocument();
  388. doc.Load(_XmlFileName);
  389.  
  390. foreach (XmlNode node in doc.GetElementsByTagName("User"))
  391. {
  392. if (node.ChildNodes[2].InnerText.Equals(email.Trim(), StringComparison.OrdinalIgnoreCase))
  393. {
  394. return node.ChildNodes[0].InnerText;
  395. }
  396. }
  397.  
  398. return null;
  399. }
  400.  
  401. /// <summary>
  402. /// Updates a user. The username will not be changed.
  403. /// </summary>
  404. public override void UpdateUser(MembershipUser user)
  405. {
  406. XmlDocument doc = new XmlDocument();
  407. doc.Load(_XmlFileName);
  408.  
  409. foreach (XmlNode node in doc.GetElementsByTagName("User"))
  410. {
  411. if (node.ChildNodes[0].InnerText.Equals(user.UserName, StringComparison.OrdinalIgnoreCase))
  412. {
  413. if (user.Comment.Length > 30)
  414. {
  415. node.ChildNodes[1].InnerText = user.Comment;
  416. }
  417. node.ChildNodes[2].InnerText = user.Email;
  418. node.ChildNodes[3].InnerText = user.LastLoginDate.ToString("yyyy-MM-dd HH:mm:ss");
  419. doc.Save(_XmlFileName);
  420. _Users[user.UserName] = user;
  421. }
  422. }
  423. }
  424.  
  425. #endregion
  426.  
  427. #region Helper methods
  428.  
  429. /// <summary>
  430. /// Builds the internal cache of users.
  431. /// </summary>
  432. private void ReadMembershipDataStore()
  433. {
  434. lock (this)
  435. {
  436. if (_Users == null)
  437. {
  438. _Users = new Dictionary<string, MembershipUser>(16, StringComparer.InvariantCultureIgnoreCase);
  439. XmlDocument doc = new XmlDocument();
  440. doc.Load(_XmlFileName);
  441. XmlNodeList nodes = doc.GetElementsByTagName("User");
  442.  
  443. foreach (XmlNode node in nodes)
  444. {
  445. MembershipUser user = new MembershipUser(
  446. Name, // Provider name
  447. node["UserName"].InnerText, // Username
  448. node["UserName"].InnerText, // providerUserKey
  449. node["Email"].InnerText, // Email
  450. String.Empty, // passwordQuestion
  451. node["Password"].InnerText, // Comment
  452. true, // isApproved
  453. false, // isLockedOut
  454. DateTime.Now, // creationDate
  455. DateTime.Parse(node["LastLoginTime"].InnerText), // lastLoginDate
  456. DateTime.Now, // lastActivityDate
  457. DateTime.Now, // lastPasswordChangedDate
  458. new DateTime(1980, 1, 1) // lastLockoutDate
  459. );
  460.  
  461. _Users.Add(user.UserName, user);
  462. }
  463. }
  464. }
  465. }
  466.  
  467. //
  468. // A helper function to retrieve config values from the configuration file.
  469. //
  470. private static string GetConfigValue(string configValue, string defaultValue) {
  471. if (String.IsNullOrEmpty(configValue))
  472. return defaultValue;
  473.  
  474. return configValue;
  475. }
  476. /// <summary>
  477. /// Fill our member variables according to the config file
  478. /// </summary>
  479. /// <param name="config">config</param>
  480. private static void InitMemberVariables(NameValueCollection config) {
  481. pApplicationName = GetConfigValue(config["applicationName"], HostingEnvironment.ApplicationVirtualPath);
  482. pMaxInvalidPasswordAttempts = Convert.ToInt32(GetConfigValue(config["maxInvalidPasswordAttempts"], "5"));
  483. pPasswordAttemptWindow = Convert.ToInt32(GetConfigValue(config["passwordAttemptWindow"], "10"));
  484. pMinRequiredNonAlphanumericCharacters = Convert.ToInt32(GetConfigValue(config["minRequiredNonAlphanumericCharacters"], "1"));
  485. pMinRequiredPasswordLength = Convert.ToInt32(GetConfigValue(config["minRequiredPasswordLength"], "7"));
  486. pPasswordStrengthRegularExpression = Convert.ToString(GetConfigValue(config["passwordStrengthRegularExpression"], ""));
  487. pEnablePasswordReset = Convert.ToBoolean(GetConfigValue(config["enablePasswordReset"], "true"));
  488. pEnablePasswordRetrieval = Convert.ToBoolean(GetConfigValue(config["enablePasswordRetrieval"], "true"));
  489. pRequiresQuestionAndAnswer = Convert.ToBoolean(GetConfigValue(config["requiresQuestionAndAnswer"], "false"));
  490. pRequiresUniqueEmail = Convert.ToBoolean(GetConfigValue(config["requiresUniqueEmail"], "true"));
  491. pWriteExceptionsToEventLog = Convert.ToBoolean(GetConfigValue(config["writeExceptionsToEventLog"], "true"));
  492. string temp_format = config["passwordFormat"];
  493. if (temp_format == null) {
  494. temp_format = "Hashed";
  495. }
  496.  
  497. switch (temp_format) {
  498. case "Hashed":
  499. pPasswordFormat = MembershipPasswordFormat.Hashed;
  500. break;
  501. case "Encrypted":
  502. pPasswordFormat = MembershipPasswordFormat.Encrypted;
  503. break;
  504. case "Clear":
  505. pPasswordFormat = MembershipPasswordFormat.Clear;
  506. break;
  507. default:
  508. throw new ProviderException("Password format not supported.");
  509. }
  510.  
  511. // Get encryption and decryption key information from the configuration.
  512. Configuration cfg =
  513. WebConfigurationManager.OpenWebConfiguration(System.Web.Hosting.HostingEnvironment.ApplicationVirtualPath);
  514. machineKey = (MachineKeySection)cfg.GetSection("system.web/machineKey");
  515.  
  516. if (machineKey.ValidationKey.Contains("AutoGenerate"))
  517. if (PasswordFormat != MembershipPasswordFormat.Clear)
  518. throw new ProviderException("Hashed or Encrypted passwords " +
  519. "are not supported with auto-generated keys.");
  520. }
  521. //
  522. // WriteToEventLog
  523. // A helper function that writes exception detail to the event log. Exceptions
  524. // are written to the event log as a security measure to avoid private database
  525. // details from being returned to the browser. If a method does not return a status
  526. // or boolean indicating the action succeeded or failed, a generic exception is also
  527. // thrown by the caller.
  528. //
  529. private void WriteToEventLog(Exception e, string action) {
  530. EventLog log = new EventLog();
  531. log.Source = eventSource;
  532. log.Log = eventLog;
  533.  
  534. string message = "An exception occurred communicating with the data source.\n\n";
  535. message += "Action: " + action + "\n\n";
  536. message += "Exception: " + e.ToString();
  537.  
  538. log.WriteEntry(message);
  539. }
  540. //
  541. // HexToByte
  542. // Converts a hexadecimal string to a byte array. Used to convert encryption
  543. // key values from the configuration.
  544. //
  545. private byte[] HexToByte(string hexString) {
  546. byte[] returnBytes = new byte[hexString.Length / 2];
  547. for (int i = 0; i < returnBytes.Length; i++)
  548. returnBytes[i] = Convert.ToByte(hexString.Substring(i * 2, 2), 16);
  549. return returnBytes;
  550. }
  551.  
  552. #region Encode And Decode
  553. //
  554. // DecodePassword
  555. // Decrypts or leaves the password clear based on the PasswordFormat.
  556. //
  557. private string DecodePassword(string encodedPassword) {
  558. string password = encodedPassword;
  559.  
  560. switch (PasswordFormat) {
  561. case MembershipPasswordFormat.Clear:
  562. break;
  563. case MembershipPasswordFormat.Encrypted:
  564. password =
  565. Encoding.Unicode.GetString(DecryptPassword(Convert.FromBase64String(password)));
  566. break;
  567. case MembershipPasswordFormat.Hashed:
  568. throw new ProviderException("Cannot decode a hashed password.");
  569. default:
  570. throw new ProviderException("Unsupported password format.");
  571. }
  572.  
  573. return password;
  574. }
  575. //
  576. // EncodePassword
  577. // Encrypts, Hashes, or leaves the password clear based on the PasswordFormat.
  578. //
  579. private string EncodePassword(string password) {
  580. string encodedPassword = password;
  581.  
  582. switch (PasswordFormat) {
  583. case MembershipPasswordFormat.Clear:
  584. break;
  585. case MembershipPasswordFormat.Encrypted:
  586. encodedPassword =
  587. Convert.ToBase64String(EncryptPassword(Encoding.Unicode.GetBytes(password)));
  588. break;
  589. case MembershipPasswordFormat.Hashed:
  590. HMACSHA1 hash = new HMACSHA1();
  591. hash.Key = HexToByte(machineKey.ValidationKey);
  592. encodedPassword =
  593. Convert.ToBase64String(hash.ComputeHash(Encoding.Unicode.GetBytes(password)));
  594. break;
  595. default:
  596. throw new ProviderException("Unsupported password format.");
  597. }
  598.  
  599. return encodedPassword;
  600. }
  601. /// <summary>
  602. /// Encrypts a string using the SHA256 algorithm.
  603. /// </summary>
  604. private static string Encrypt(string plainMessage) {
  605. byte[] data = Encoding.UTF8.GetBytes(plainMessage);
  606. using (HashAlgorithm sha = new SHA256Managed()) {
  607. byte[] encryptedBytes = sha.TransformFinalBlock(data, 0, data.Length);
  608. return Convert.ToBase64String(sha.Hash);
  609. }
  610. }
  611. #endregion
  612.  
  613. //
  614. // CheckPassword
  615. // Compares password values based on the MembershipPasswordFormat.
  616. //
  617. private bool CheckPassword(string password, string dbpassword) {
  618. string pass1 = password;
  619. string pass2 = dbpassword;
  620.  
  621. switch (PasswordFormat) {
  622. case MembershipPasswordFormat.Encrypted:
  623. pass2 = DecodePassword(dbpassword);
  624. break;
  625. case MembershipPasswordFormat.Hashed:
  626. pass1 = EncodePassword(password);
  627. break;
  628. default:
  629. break;
  630. }
  631.  
  632. if (pass1 == pass2) {
  633. return true;
  634. }
  635.  
  636. return false;
  637. }
  638.  
  639. #endregion
  640.  
  641. #region Unsupported methods
  642.  
  643. /// <summary>
  644. ///
  645. /// </summary>
  646. /// <param name="username"></param>
  647. /// <param name="answer"></param>
  648. /// <returns></returns>
  649. public override string ResetPassword(string username, string answer)
  650. {
  651. throw new NotSupportedException();
  652. }
  653.  
  654. /// <summary>
  655. ///
  656. /// </summary>
  657. /// <param name="userName"></param>
  658. /// <returns></returns>
  659. public override bool UnlockUser(string userName)
  660. {
  661. throw new NotSupportedException();
  662. }
  663.  
  664. /// <summary>
  665. ///
  666. /// </summary>
  667. /// <param name="emailToMatch"></param>
  668. /// <param name="pageIndex"></param>
  669. /// <param name="pageSize"></param>
  670. /// <param name="totalRecords"></param>
  671. /// <returns></returns>
  672. public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
  673. {
  674. throw new NotSupportedException();
  675. }
  676.  
  677. /// <summary>
  678. ///
  679. /// </summary>
  680. /// <param name="usernameToMatch"></param>
  681. /// <param name="pageIndex"></param>
  682. /// <param name="pageSize"></param>
  683. /// <param name="totalRecords"></param>
  684. /// <returns></returns>
  685. public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
  686. {
  687. throw new NotSupportedException();
  688. }
  689.  
  690. /// <summary>
  691. ///
  692. /// </summary>
  693. /// <returns></returns>
  694. public override int GetNumberOfUsersOnline()
  695. {
  696. throw new NotSupportedException();
  697. }
  698.  
  699. /// <summary>
  700. ///
  701. /// </summary>
  702. /// <param name="username"></param>
  703. /// <param name="password"></param>
  704. /// <param name="newPasswordQuestion"></param>
  705. /// <param name="newPasswordAnswer"></param>
  706. /// <returns></returns>
  707. public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
  708. {
  709. throw new NotSupportedException();
  710. }
  711.  
  712. /// <summary>
  713. ///
  714. /// </summary>
  715. /// <param name="username"></param>
  716. /// <param name="answer"></param>
  717. /// <returns></returns>
  718. public override string GetPassword(string username, string answer)
  719. {
  720. throw new NotSupportedException();
  721. }
  722.  
  723. #endregion
  724.  
  725. }
  726. }
Add Comment
Please, Sign In to add comment