2 // System.Web.Security.Membership
5 // Ben Maurer (bmaurer@users.sourceforge.net)
6 // Lluis Sanchez Gual (lluis@novell.com)
9 // (C) 2005 Novell, inc.
13 // Permission is hereby granted, free of charge, to any person obtaining
14 // a copy of this software and associated documentation files (the
15 // "Software"), to deal in the Software without restriction, including
16 // without limitation the rights to use, copy, modify, merge, publish,
17 // distribute, sublicense, and/or sell copies of the Software, and to
18 // permit persons to whom the Software is furnished to do so, subject to
19 // the following conditions:
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
24 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
25 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
26 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
27 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
28 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
29 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
30 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 using System.Collections;
35 using System.Collections.Specialized;
37 using System.Web.Configuration;
38 using System.Configuration;
39 using System.Security.Cryptography;
41 namespace System.Web.Security
43 public static class Membership
46 const string Membership_providers = "Membership.providers";
47 static MembershipProviderCollection providers {
49 object o = AppDomain.CurrentDomain.GetData (Membership_providers);
51 lock (AppDomain.CurrentDomain) {
52 o = AppDomain.CurrentDomain.GetData (Membership_providers);
54 MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
55 MembershipProviderCollection local_providers = new MembershipProviderCollection ();
56 ProvidersHelper.InstantiateProviders (section.Providers, local_providers, typeof (MembershipProvider));
57 AppDomain.CurrentDomain.SetData (Membership_providers, local_providers);
63 return (MembershipProviderCollection) o;
66 static MembershipProvider provider {
68 MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
69 MembershipProvider p = providers [section.DefaultProvider];
71 throw new ConfigurationErrorsException ("Default Membership Provider could not be found: Cannot instantiate provider: '" + section.DefaultProvider + "'.");
75 static int onlineTimeWindow {
77 MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
78 return (int) section.UserIsOnlineTimeWindow.TotalMinutes;
81 static string hashAlgorithmType {
83 MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
84 string ret = section.HashAlgorithmType;
86 if (ret == String.Empty) {
87 MachineKeySection mks = WebConfigurationManager.GetSection ("system.web/machineKey") as MachineKeySection;
88 return mks.Validation;
96 static MembershipProviderCollection providers;
97 static MembershipProvider provider;
98 static int onlineTimeWindow;
99 static string hashAlgorithmType;
103 MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
105 providers = new MembershipProviderCollection ();
107 ProvidersHelper.InstantiateProviders (section.Providers, providers, typeof (MembershipProvider));
109 provider = providers[section.DefaultProvider];
111 onlineTimeWindow = (int) section.UserIsOnlineTimeWindow.TotalMinutes;
112 hashAlgorithmType = section.HashAlgorithmType;
113 if (String.IsNullOrEmpty (hashAlgorithmType)) {
114 MachineKeySection mks = WebConfigurationManager.GetSection ("system.web/machineKey") as MachineKeySection;
115 MachineKeyValidationConverter cvt = new MachineKeyValidationConverter ();
116 hashAlgorithmType = cvt.ConvertTo (null, null, mks.Validation, typeof (string)) as string;
119 if (String.IsNullOrEmpty (hashAlgorithmType))
120 hashAlgorithmType = "SHA1";
124 public static MembershipUser CreateUser (string username, string password)
126 return CreateUser (username, password, null);
129 public static MembershipUser CreateUser (string username, string password, string email)
131 MembershipCreateStatus status;
132 MembershipUser usr = CreateUser (username, password, email, null, null, true, out status);
134 throw new MembershipCreateUserException (status);
139 public static MembershipUser CreateUser (string username, string password, string email, string pwdQuestion, string pwdAnswer, bool isApproved, out MembershipCreateStatus status)
141 return CreateUser (username, password, email, pwdQuestion, pwdAnswer, isApproved, null, out status);
144 public static MembershipUser CreateUser (string username, string password, string email, string pwdQuestion, string pwdAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
146 if (String.IsNullOrEmpty (username)) {
147 status = MembershipCreateStatus.InvalidUserName;
151 if (String.IsNullOrEmpty (password)) {
152 status = MembershipCreateStatus.InvalidPassword;
156 return Provider.CreateUser (username, password, email, pwdQuestion, pwdAnswer, isApproved, providerUserKey, out status);
159 public static bool DeleteUser (string username)
161 return Provider.DeleteUser (username, true);
164 public static bool DeleteUser (string username, bool deleteAllRelatedData)
166 return Provider.DeleteUser (username, deleteAllRelatedData);
169 public static string GeneratePassword (int length, int numberOfNonAlphanumericCharacters)
171 RandomNumberGenerator rng = RandomNumberGenerator.Create ();
172 byte[] pass_bytes = new byte[length];
174 int num_nonalpha = 0;
176 rng.GetBytes (pass_bytes);
178 for (i = 0; i < length; i ++) {
179 /* convert the random bytes to ascii values 33-126 */
180 pass_bytes[i] = (byte)(pass_bytes[i] % 93 + 33);
182 /* and count the number of
183 * non-alphanumeric characters we have
185 if ((pass_bytes[i] >= 33 && pass_bytes[i] <= 47)
186 || (pass_bytes[i] >= 58 && pass_bytes[i] <= 64)
187 || (pass_bytes[i] >= 91 && pass_bytes[i] <= 96)
188 || (pass_bytes[i] >= 123 && pass_bytes[i] <= 126))
191 /* get rid of any quotes in the
192 * password, just in case they cause
194 if (pass_bytes[i] == 34 || pass_bytes[i] == 39)
196 else if (pass_bytes[i] == 96)
200 if (num_nonalpha < numberOfNonAlphanumericCharacters) {
201 /* loop over the array, converting the
202 * least number of alphanumeric
203 * characters to non-alpha */
204 for (i = 0; i < length; i ++) {
205 if (num_nonalpha == numberOfNonAlphanumericCharacters)
207 if (pass_bytes[i] >= 48 && pass_bytes[i] <= 57) {
208 pass_bytes[i] = (byte)(pass_bytes[i] - 48 + 33);
211 else if (pass_bytes[i] >= 65 && pass_bytes[i] <= 90) {
212 pass_bytes[i] = (byte)((pass_bytes[i] - 65) % 13 + 33);
215 else if (pass_bytes[i] >= 97 && pass_bytes[i] <= 122) {
216 pass_bytes[i] = (byte)((pass_bytes[i] - 97) % 13 + 33);
220 /* and make sure we don't end up with quote characters */
221 if (pass_bytes[i] == 34 || pass_bytes[i] == 39)
223 else if (pass_bytes[i] == 96)
228 return Encoding.ASCII.GetString (pass_bytes);
231 public static MembershipUserCollection GetAllUsers ()
234 return GetAllUsers (0, int.MaxValue, out total);
237 public static MembershipUserCollection GetAllUsers (int pageIndex, int pageSize, out int totalRecords)
239 return Provider.GetAllUsers (pageIndex, pageSize, out totalRecords);
242 public static int GetNumberOfUsersOnline ()
244 return Provider.GetNumberOfUsersOnline ();
247 public static MembershipUser GetUser ()
249 return GetUser (HttpContext.Current.User.Identity.Name, true);
252 public static MembershipUser GetUser (bool userIsOnline)
254 return GetUser (HttpContext.Current.User.Identity.Name, userIsOnline);
257 public static MembershipUser GetUser (string username)
259 return GetUser (username, false);
262 public static MembershipUser GetUser (string username, bool userIsOnline)
264 return Provider.GetUser (username, userIsOnline);
267 public static MembershipUser GetUser (object providerUserKey)
269 return GetUser (providerUserKey, false);
272 public static MembershipUser GetUser (object providerUserKey, bool userIsOnline)
274 return Provider.GetUser (providerUserKey, userIsOnline);
277 public static string GetUserNameByEmail (string email)
279 return Provider.GetUserNameByEmail (email);
282 public static void UpdateUser (MembershipUser user)
284 Provider.UpdateUser (user);
287 public static bool ValidateUser (string username, string password)
289 return Provider.ValidateUser (username, password);
292 public static MembershipUserCollection FindUsersByEmail (string emailToMatch)
295 return Provider.FindUsersByEmail (emailToMatch, 0, int.MaxValue, out totalRecords);
298 public static MembershipUserCollection FindUsersByEmail (string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
300 return Provider.FindUsersByEmail (emailToMatch, pageIndex, pageSize, out totalRecords);
303 public static MembershipUserCollection FindUsersByName (string nameToMatch)
306 return Provider.FindUsersByName (nameToMatch, 0, int.MaxValue, out totalRecords);
309 public static MembershipUserCollection FindUsersByName (string nameToMatch, int pageIndex, int pageSize, out int totalRecords)
311 return Provider.FindUsersByName (nameToMatch, pageIndex, pageSize, out totalRecords);
314 public static string ApplicationName {
315 get { return Provider.ApplicationName; }
316 set { Provider.ApplicationName = value; }
319 public static bool EnablePasswordReset {
320 get { return Provider.EnablePasswordReset; }
323 public static bool EnablePasswordRetrieval {
324 get { return Provider.EnablePasswordRetrieval; }
327 public static string HashAlgorithmType {
328 get { return hashAlgorithmType; }
331 public static bool RequiresQuestionAndAnswer {
332 get { return Provider.RequiresQuestionAndAnswer; }
335 public static int MaxInvalidPasswordAttempts {
336 get { return Provider.MaxInvalidPasswordAttempts; }
339 public static int MinRequiredNonAlphanumericCharacters {
340 get { return Provider.MinRequiredNonAlphanumericCharacters; }
343 public static int MinRequiredPasswordLength {
344 get { return Provider.MinRequiredPasswordLength; }
347 public static int PasswordAttemptWindow {
348 get { return Provider.PasswordAttemptWindow; }
351 public static string PasswordStrengthRegularExpression {
352 get { return Provider.PasswordStrengthRegularExpression; }
355 public static MembershipProvider Provider {
356 get { return provider; }
359 public static MembershipProviderCollection Providers {
360 get { return providers; }
363 public static int UserIsOnlineTimeWindow {
364 get { return onlineTimeWindow; }
367 public static event MembershipValidatePasswordEventHandler ValidatingPassword {
368 add { Provider.ValidatingPassword += value; }
369 remove { Provider.ValidatingPassword -= value; }