Merge pull request #4453 from lambdageek/bug-49721
[mono.git] / mcs / class / System.Web / System.Web.Security / Membership.cs
1 //
2 // System.Web.Security.Membership
3 //
4 // Authors:
5 //      Ben Maurer (bmaurer@users.sourceforge.net)
6 //      Lluis Sanchez Gual (lluis@novell.com)
7 //
8 // (C) 2003 Ben Maurer
9 // (C) 2005 Novell, inc.
10 //
11
12 //
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:
20 // 
21 // The above copyright notice and this permission notice shall be
22 // included in all copies or substantial portions of the Software.
23 // 
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.
31 //
32
33 using System.Collections;
34 using System.Collections.Specialized;
35 using System.Text;
36 using System.Web.Configuration;
37 using System.Configuration;
38 using System.Security.Cryptography;
39
40 namespace System.Web.Security
41 {
42         public static class Membership
43         {
44                 static MembershipProviderCollection providers;
45                 static MembershipProvider provider;
46                 static int onlineTimeWindow;
47                 static string hashAlgorithmType;
48                 
49                 static Membership ()
50                 {
51                         MembershipSection section = (MembershipSection) WebConfigurationManager.GetSection ("system.web/membership");
52
53                         providers = new MembershipProviderCollection ();
54
55                         ProvidersHelper.InstantiateProviders (section.Providers, providers, typeof (MembershipProvider));
56
57                         provider = providers[section.DefaultProvider];
58
59                         onlineTimeWindow = (int) section.UserIsOnlineTimeWindow.TotalMinutes;
60                         hashAlgorithmType = section.HashAlgorithmType;
61                         if (String.IsNullOrEmpty (hashAlgorithmType)) {
62                                 MachineKeySection mks = WebConfigurationManager.GetSection ("system.web/machineKey") as MachineKeySection;
63                                 MachineKeyValidationConverter cvt = new MachineKeyValidationConverter ();
64                                 hashAlgorithmType = cvt.ConvertTo (null, null, mks.Validation, typeof (string)) as string;
65                         }
66                         
67                         if (String.IsNullOrEmpty (hashAlgorithmType))
68                                 hashAlgorithmType = "SHA1";
69                 }
70
71                 public static MembershipUser CreateUser (string username, string password)
72                 {
73                         return CreateUser (username, password, null);
74                 }
75                 
76                 public static MembershipUser CreateUser (string username, string password, string email)
77                 {
78                         MembershipCreateStatus status;
79                         MembershipUser usr = CreateUser (username, password, email, null, null, true, out status);
80                         if (usr == null)
81                                 throw new MembershipCreateUserException (status);
82                         
83                         return usr;
84                 }
85                 
86                 public static MembershipUser CreateUser (string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, out MembershipCreateStatus status)
87                 {
88                         return CreateUser (username, password, email, passwordQuestion, passwordAnswer, isApproved, null, out status);
89                 }
90                 
91                 public static MembershipUser CreateUser (string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
92                 {
93                         if (String.IsNullOrEmpty (username)) {
94                                 status = MembershipCreateStatus.InvalidUserName;
95                                 return null;
96                         }
97
98                         if (String.IsNullOrEmpty (password)) {
99                                 status = MembershipCreateStatus.InvalidPassword;
100                                 return null;
101                         }
102
103                         return Provider.CreateUser (username, password, email, passwordQuestion, passwordAnswer, isApproved, providerUserKey, out status);
104                 }
105                 
106                 public static bool DeleteUser (string username)
107                 {
108                         return Provider.DeleteUser (username, true);
109                 }
110                 
111                 public static bool DeleteUser (string username, bool deleteAllRelatedData)
112                 {
113                         return Provider.DeleteUser (username, deleteAllRelatedData);
114                 }
115                 
116                 public static string GeneratePassword (int length, int numberOfNonAlphanumericCharacters)
117                 {
118                         RandomNumberGenerator rng = RandomNumberGenerator.Create ();
119                         byte[] pass_bytes = new byte[length];
120                         int i;
121                         int num_nonalpha = 0;
122
123                         rng.GetBytes (pass_bytes);
124                         
125                         for (i = 0; i < length; i ++) {
126                                 /* convert the random bytes to ascii values 33-126 */
127                                 pass_bytes[i] = (byte)(pass_bytes[i] % 93 + 33);
128
129                                 /* and count the number of
130                                  * non-alphanumeric characters we have
131                                  * as we go */
132                                 if ((pass_bytes[i] >= 33 && pass_bytes[i] <= 47)
133                                     || (pass_bytes[i] >= 58 && pass_bytes[i] <= 64)
134                                     || (pass_bytes[i] >= 91 && pass_bytes[i] <= 96)
135                                     || (pass_bytes[i] >= 123 && pass_bytes[i] <= 126))
136                                         num_nonalpha++;
137
138                                 /* get rid of any quotes in the
139                                  * password, just in case they cause
140                                  * problems */
141                                 if (pass_bytes[i] == 34 || pass_bytes[i] == 39)
142                                         pass_bytes[i] ++;
143                                 else if (pass_bytes[i] == 96)
144                                         pass_bytes[i] --;
145                         }
146
147                         if (num_nonalpha < numberOfNonAlphanumericCharacters) {
148                                 /* loop over the array, converting the
149                                  * least number of alphanumeric
150                                  * characters to non-alpha */
151                                 for (i = 0; i < length; i ++) {
152                                         if (num_nonalpha == numberOfNonAlphanumericCharacters)
153                                                 break;
154                                         if (pass_bytes[i] >= 48 && pass_bytes[i] <= 57) {
155                                                 pass_bytes[i] = (byte)(pass_bytes[i] - 48 + 33);
156                                                 num_nonalpha++;
157                                         }
158                                         else if (pass_bytes[i] >= 65 && pass_bytes[i] <= 90) {
159                                                 pass_bytes[i] = (byte)((pass_bytes[i] - 65) % 13 + 33);
160                                                 num_nonalpha++;
161                                         }
162                                         else if (pass_bytes[i] >= 97 && pass_bytes[i] <= 122) {
163                                                 pass_bytes[i] = (byte)((pass_bytes[i] - 97) % 13 + 33);
164                                                 num_nonalpha++;
165                                         }
166
167                                         /* and make sure we don't end up with quote characters */
168                                         if (pass_bytes[i] == 34 || pass_bytes[i] == 39)
169                                                 pass_bytes[i]++;
170                                         else if (pass_bytes[i] == 96)
171                                                 pass_bytes[i] --;
172                                 }
173                         }
174
175                         return Encoding.ASCII.GetString (pass_bytes);
176                 }
177                 
178                 public static MembershipUserCollection GetAllUsers ()
179                 {
180                         int total;
181                         return GetAllUsers (0, int.MaxValue, out total);
182                 }
183                 
184                 public static MembershipUserCollection GetAllUsers (int pageIndex, int pageSize, out int totalRecords)
185                 {
186                         return Provider.GetAllUsers (pageIndex, pageSize, out totalRecords);
187                 }
188                 
189                 public static int GetNumberOfUsersOnline ()
190                 {
191                         return Provider.GetNumberOfUsersOnline ();
192                 }
193                 
194                 public static MembershipUser GetUser ()
195                 {
196                         return GetUser (HttpContext.Current.User.Identity.Name, true);
197                 }
198                 
199                 public static MembershipUser GetUser (bool userIsOnline)
200                 {
201                         return GetUser (HttpContext.Current.User.Identity.Name, userIsOnline);
202                 }
203                 
204                 public static MembershipUser GetUser (string username)
205                 {
206                         return GetUser (username, false);
207                 }
208                 
209                 public static MembershipUser GetUser (string username, bool userIsOnline)
210                 {
211                         return Provider.GetUser (username, userIsOnline);
212                 }
213                 
214                 public static MembershipUser GetUser (object providerUserKey)
215                 {
216                         return GetUser (providerUserKey, false);
217                 }
218                 
219                 public static MembershipUser GetUser (object providerUserKey, bool userIsOnline)
220                 {
221                         return Provider.GetUser (providerUserKey, userIsOnline);
222                 }
223                 
224                 public static string GetUserNameByEmail (string emailToMatch)
225                 {
226                         return Provider.GetUserNameByEmail (emailToMatch);
227                 }
228                 
229                 public static void UpdateUser (MembershipUser user)
230                 {
231                         Provider.UpdateUser (user);
232                 }
233                 
234                 public static bool ValidateUser (string username, string password)
235                 {
236                         return Provider.ValidateUser (username, password);
237                 }
238                 
239                 public static MembershipUserCollection FindUsersByEmail (string emailToMatch)
240                 {
241                         int totalRecords;
242                         return Provider.FindUsersByEmail (emailToMatch, 0, int.MaxValue, out totalRecords);
243                 }
244                 
245                 public static MembershipUserCollection FindUsersByEmail (string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
246                 {
247                         return Provider.FindUsersByEmail (emailToMatch, pageIndex, pageSize, out totalRecords);
248                 }
249                 
250                 public static MembershipUserCollection FindUsersByName (string usernameToMatch)
251                 {
252                         int totalRecords;
253                         return Provider.FindUsersByName (usernameToMatch, 0, int.MaxValue, out totalRecords);
254                 }
255                 
256                 public static MembershipUserCollection FindUsersByName (string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
257                 {
258                         return Provider.FindUsersByName (usernameToMatch, pageIndex, pageSize, out totalRecords);
259                 }
260
261                 public static string ApplicationName {
262                         get { return Provider.ApplicationName; }
263                         set { Provider.ApplicationName = value; }
264                 }
265                 
266                 public static bool EnablePasswordReset {
267                         get { return Provider.EnablePasswordReset; }
268                 }
269                 
270                 public static bool EnablePasswordRetrieval {
271                         get { return Provider.EnablePasswordRetrieval; }
272                 }
273
274                 public static string HashAlgorithmType {
275                         get { return hashAlgorithmType; }
276                 }
277
278                 public static bool RequiresQuestionAndAnswer {
279                         get { return Provider.RequiresQuestionAndAnswer; }
280                 }
281                 
282                 public static int MaxInvalidPasswordAttempts {
283                         get { return Provider.MaxInvalidPasswordAttempts; }
284                 }
285                 
286                 public static int MinRequiredNonAlphanumericCharacters {
287                         get { return Provider.MinRequiredNonAlphanumericCharacters; }
288                 }
289                 
290                 public static int MinRequiredPasswordLength {
291                         get { return Provider.MinRequiredPasswordLength; }
292                 }
293                 
294                 public static int PasswordAttemptWindow {
295                         get { return Provider.PasswordAttemptWindow; }
296                 }
297                 
298                 public static string PasswordStrengthRegularExpression {
299                         get { return Provider.PasswordStrengthRegularExpression; }
300                 }
301                                 
302                 public static MembershipProvider Provider {
303                         get { return provider; }
304                 }
305                 
306                 public static MembershipProviderCollection Providers {
307                         get { return providers; }
308                 }
309                 
310                 public static int UserIsOnlineTimeWindow {
311                         get { return onlineTimeWindow; }
312                 }
313                 
314                 public static event MembershipValidatePasswordEventHandler ValidatingPassword {
315                         add { Provider.ValidatingPassword += value; }
316                         remove { Provider.ValidatingPassword -= value; }
317                 }
318         }
319 }
320