df01e16c3f4121441e2deb3fea87d6e523a169ef
[mono.git] / mcs / class / Mainsoft.Web / Mainsoft.Web.J2EE.WAS / Mainsoft.Web.Security / WPMembershipProvider.cs
1 //\r
2 // Mainsoft.Web.Security.WPMembershipProvider\r
3 //\r
4 // Authors:\r
5 //      Ilya Kharmatsky (ilyak at mainsoft.com)\r
6 //\r
7 // (C) 2007 Mainsoft\r
8 //\r
9 // Permission is hereby granted, free of charge, to any person obtaining\r
10 // a copy of this software and associated documentation files (the\r
11 // "Software"), to deal in the Software without restriction, including\r
12 // without limitation the rights to use, copy, modify, merge, publish,\r
13 // distribute, sublicense, and/or sell copies of the Software, and to\r
14 // permit persons to whom the Software is furnished to do so, subject to\r
15 // the following conditions:\r
16 // \r
17 // The above copyright notice and this permission notice shall be\r
18 // included in all copies or substantial portions of the Software.\r
19 // \r
20 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,\r
21 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\r
22 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND\r
23 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE\r
24 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION\r
25 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION\r
26 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.\r
27 //\r
28 \r
29 #if NET_2_0\r
30 \r
31 using System;\r
32 using System.Collections;\r
33 using System.Collections.Generic;\r
34 using System.Text;\r
35 using System.Web;\r
36 using System.Web.Security;\r
37 \r
38 \r
39 using java.util;\r
40 \r
41 using com.ibm.portal.um;\r
42 \r
43 namespace Mainsoft.Web.Security\r
44 {\r
45 \r
46     public class WPMembershipProvider : MembershipProvider\r
47     {\r
48         private static readonly string PROVIDER_DESCRIPTION = "WebSphere Portal Membership Provider";\r
49         internal static readonly string PROVIDER_NAME = "WPMembershipProvider";\r
50 \r
51         private string applicationName;\r
52 \r
53         #region Properties\r
54         public override string ApplicationName\r
55         {\r
56             get\r
57             {\r
58                 lock (this)\r
59                 {\r
60                     if (applicationName == null)\r
61                         applicationName = AppDomain.CurrentDomain.FriendlyName;\r
62                 }\r
63                 return applicationName;\r
64             }\r
65             set\r
66             {\r
67                 lock (this)\r
68                 {\r
69                     applicationName = value;\r
70                 }\r
71             }\r
72         }\r
73 \r
74         public override string Description \r
75         {\r
76             get { return PROVIDER_DESCRIPTION; }\r
77         }\r
78 \r
79         public override bool EnablePasswordReset\r
80         {\r
81             get { return false; }\r
82         }\r
83 \r
84         public override bool EnablePasswordRetrieval\r
85         {\r
86             get { return false; }\r
87         }\r
88 \r
89         [MonoTODO]\r
90         public override int MaxInvalidPasswordAttempts\r
91         {\r
92             get { throw new NotImplementedException(); }\r
93         }\r
94 \r
95         [MonoTODO]\r
96         public override int MinRequiredNonAlphanumericCharacters\r
97         {\r
98             get { throw new NotImplementedException(); }\r
99         }\r
100 \r
101         [MonoTODO]\r
102         public override int MinRequiredPasswordLength\r
103         {\r
104             get { throw new NotImplementedException(); }\r
105         }\r
106 \r
107         public override string Name\r
108         {\r
109             get { return PROVIDER_NAME; }\r
110         }\r
111 \r
112         [MonoTODO]\r
113         public override int PasswordAttemptWindow\r
114         {\r
115             get { throw new NotImplementedException("The method or operation is not implemented."); }\r
116         }\r
117 \r
118         [MonoTODO]\r
119         public override MembershipPasswordFormat PasswordFormat\r
120         {\r
121             get { throw new NotImplementedException("The method or operation is not implemented."); }\r
122         }\r
123 \r
124         [MonoTODO]\r
125         public override string PasswordStrengthRegularExpression\r
126         {\r
127             get { throw new NotImplementedException("The method or operation is not implemented."); }\r
128         }\r
129 \r
130         [MonoTODO]\r
131         public override bool RequiresQuestionAndAnswer\r
132         {\r
133             get { throw new NotImplementedException("The method or operation is not implemented."); }\r
134         }\r
135 \r
136         [MonoTODO]\r
137         public override bool RequiresUniqueEmail\r
138         {\r
139             get { throw new NotImplementedException("The method or operation is not implemented."); }\r
140         }\r
141 \r
142 \r
143         #endregion\r
144 \r
145         #region Implemented Methods\r
146         public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)\r
147         {\r
148             if (emailToMatch == null || emailToMatch.Length > 256) // TODO check if the string could be null, if yes replace it with "*" for any email\r
149                 throw new ArgumentException("Argument emailToMatch either null or length > 256", "emailToMatch");\r
150             if (pageIndex < 0)\r
151                 throw new ArgumentException("Argument pageIndex could not be negative", "pageIndex");\r
152             if (pageSize < 1)\r
153                 throw new ArgumentException("Argument pageSize could not be less than one", "pageSize");\r
154 \r
155             long upperBound = (long)pageIndex * pageSize + pageSize - 1;\r
156             if (upperBound > Int32.MaxValue)\r
157                 throw new ArgumentException("The pageSize and pageIndex produce too long number");\r
158 \r
159 \r
160             IPumaServicesProvider pumaServices = PumaServicesProviderFactory.CreateProvider();\r
161             //Will get the list of : List<com.ibm.portal.um.User> - which should be translated to\r
162             //System.Web.Security.MembershipUser instances...\r
163             //TODO: The attribute "ibm-primaryEmail" is hardcoded right now - should be updated\r
164             //to be configurable.\r
165             java.util.List principles = \r
166                 pumaServices.PumaLocator.findUsersByAttribute("ibm-primaryEmail", emailToMatch);\r
167 \r
168 \r
169             MembershipUserCollection resCollection = new MembershipUserCollection();\r
170             SliceRange sr = new SliceRange(pageSize, pageIndex);\r
171             CopyToMembershipUserCollection(principles, resCollection, sr);\r
172 \r
173             //Should contain total records recieved.\r
174             totalRecords = principles.size();\r
175             return resCollection;\r
176 \r
177         }\r
178 \r
179         public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)\r
180         {\r
181             if (usernameToMatch == null || usernameToMatch.Trim().Length == 0 || usernameToMatch.Trim().Length > 256)\r
182                 throw new ArgumentException("Wrong username given as a parameter - could not be null or empty string and could not have more than 255 characters", usernameToMatch);\r
183             if (pageIndex < 0)\r
184                 throw new ArgumentException("Argument pageIndex could not be negative", "pageIndex");\r
185             if (pageSize < 1)\r
186                 throw new ArgumentException("Argument pageSize could not be less than one", "pageSize");\r
187 \r
188             long upperBound = (long)pageIndex * pageSize + pageSize - 1;\r
189             if (upperBound > Int32.MaxValue)\r
190                 throw new ArgumentException("The pageSize and pageIndex produce too long number");\r
191 \r
192             IPumaServicesProvider pumaServices = PumaServicesProviderFactory.CreateProvider();\r
193 \r
194             java.util.List principles =\r
195                pumaServices.PumaLocator.findUsersByAttribute("uid", usernameToMatch);\r
196 \r
197             MembershipUserCollection resCollection = new MembershipUserCollection();\r
198             SliceRange sr = new SliceRange(pageSize, pageIndex);\r
199 \r
200             CopyToMembershipUserCollection(principles, resCollection, sr);\r
201             \r
202 \r
203             //Should contain total records recieved.\r
204             totalRecords = principles.size();\r
205             return resCollection;\r
206 \r
207         }\r
208 \r
209         public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)\r
210         {\r
211             if (pageIndex < 0)\r
212                 throw new ArgumentException("Argument pageIndex could not be negative", "pageIndex");\r
213             if (pageSize < 1)\r
214                 throw new ArgumentException("Argument pageSize could not be less than one", "pageSize");\r
215             long upperBound = (long)pageIndex * pageSize + pageSize - 1;\r
216             if (upperBound > Int32.MaxValue)\r
217                 throw new ArgumentException("The pageSize and pageIndex produce too long number");\r
218 \r
219             IPumaServicesProvider pumaServices = PumaServicesProviderFactory.CreateProvider();\r
220 \r
221             java.util.List principles =\r
222                pumaServices.PumaLocator.findUsersByDefaultAttribute("*");\r
223 \r
224             MembershipUserCollection resCollection = new MembershipUserCollection();\r
225             SliceRange sr = new SliceRange(pageSize, pageIndex);\r
226             CopyToMembershipUserCollection(principles, resCollection, sr);\r
227             \r
228 \r
229             //Should contain total records recieved.\r
230             totalRecords = principles.size();\r
231             return resCollection;\r
232 \r
233         }\r
234 \r
235         //the userIsOnline ignored\r
236         public override MembershipUser GetUser(string username, bool userIsOnline)\r
237         {\r
238             if (username.Length > 256)\r
239                 throw new ArgumentException("The username is too long", username);\r
240             IPumaServicesProvider provider = PumaServicesProviderFactory.CreateProvider();\r
241             \r
242             if (username == null || username == String.Empty)\r
243                 return new WPMembershipUser(provider.CurrentUser);\r
244 \r
245             java.util.List principles =  provider.PumaLocator.findUsersByAttribute("uid", username);\r
246             MembershipUser result = null;\r
247             if (principles.size() > 0)\r
248                 result = new WPMembershipUser((com.ibm.portal.um.User)principles.get(0));\r
249 \r
250             return result;\r
251 \r
252         }\r
253         /* \r
254          * partially implemented :\r
255          * the userIsOnline - ignored\r
256          * the providerUserKey - is always considered as a UID\r
257          * \r
258          */\r
259         public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)\r
260         {\r
261             if (providerUserKey is string)\r
262                 return GetUser((string)providerUserKey, userIsOnline);\r
263             throw new NotImplementedException();\r
264         }\r
265 \r
266         public override string GetUserNameByEmail(string email)\r
267         {\r
268             //TODO check if email is NULL or empty - what is .Net beh.?\r
269             if (email == null || email.Trim().Length == 0 || email.Trim().Length > 256)\r
270                 throw new ArgumentException("wrong format of parameter", "email");\r
271             IPumaServicesProvider services = PumaServicesProviderFactory.CreateProvider();\r
272             java.util.List principles =\r
273                 services.PumaLocator.findUsersByAttribute("ibm-primaryEmail", email);\r
274             if (principles.size() == 0)\r
275                 return null;\r
276 \r
277 \r
278             IDictionary dic = \r
279                 services.GetAttributes((com.ibm.portal.um.User)principles.get(0), "uid");\r
280             return (string) dic["uid"];\r
281         }\r
282 \r
283         #region Helper Methods\r
284         internal void CopyToMembershipUserCollection(java.util.List principles,\r
285             MembershipUserCollection resCollection, SliceRange sr)\r
286         {            \r
287             if (sr.start >= principles.size())\r
288                 return;\r
289          \r
290             java.util.ArrayList sortedList = new java.util.ArrayList(principles.size());\r
291             for (java.util.Iterator iter = principles.iterator(); iter.hasNext(); )\r
292                 sortedList.add(new WPMembershipUser((User)iter.next()));\r
293             \r
294             java.util.Collections.sort(sortedList, WPMembershipUser.UserNameComparator);\r
295 \r
296             int sortedListSize = sortedList.size();\r
297             \r
298             for (int i = sr.start; i < sortedListSize && i < sr.end; i++)\r
299                 resCollection.Add((MembershipUser)sortedList.get(i));\r
300             \r
301         }\r
302         #endregion\r
303 \r
304         #endregion\r
305 \r
306         [MonoTODO]\r
307         public override bool ChangePassword(string username, string oldPassword, string newPassword)\r
308         {\r
309             throw new NotImplementedException("The method or operation is not implemented.");\r
310         }\r
311 \r
312         [MonoTODO]\r
313         public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)\r
314         {\r
315             throw new NotImplementedException("The method or operation is not implemented.");\r
316         }\r
317 \r
318         [MonoTODO]\r
319         public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)\r
320         {\r
321             throw new NotImplementedException("The method or operation is not implemented.");\r
322         }\r
323 \r
324         [MonoTODO]\r
325         public override bool DeleteUser(string username, bool deleteAllRelatedData)\r
326         {\r
327             throw new NotImplementedException("The method or operation is not implemented.");\r
328         }       \r
329 \r
330        \r
331         public override int GetNumberOfUsersOnline()\r
332         {\r
333             throw new NotImplementedException("The method or operation is not implemented.");\r
334         }\r
335 \r
336         public override string GetPassword(string username, string answer)\r
337         {\r
338             throw new NotImplementedException("The method or operation is not implemented.");\r
339         }\r
340 \r
341         public override string ResetPassword(string username, string answer)\r
342         {\r
343             throw new NotImplementedException("The method or operation is not implemented.");\r
344         }\r
345 \r
346         public override bool UnlockUser(string userName)\r
347         {\r
348             throw new NotImplementedException("The method or operation is not implemented.");\r
349         }\r
350 \r
351         public override void UpdateUser(MembershipUser user)\r
352         {\r
353             throw new NotImplementedException("The method or operation is not implemented.");\r
354         }\r
355 \r
356         public override bool ValidateUser(string username, string password)\r
357         {\r
358             throw new NotImplementedException("The method or operation is not implemented.");\r
359         }\r
360 \r
361         #region Helper Classes and Structs\r
362 \r
363         internal struct SliceRange\r
364         {\r
365             internal int start;\r
366             internal int end;\r
367 \r
368             public SliceRange(int pageSize, int pageIndex)\r
369             {\r
370                 switch (pageIndex)\r
371                 {\r
372                     case 0: start = 0; end = pageSize; break;\r
373                     case 1: start = pageSize; end = 2 * pageSize; break;\r
374                     default: start = (pageIndex - 1) * pageSize; end = pageIndex * pageSize; break;\r
375                 }\r
376 \r
377             }\r
378         }\r
379 \r
380         #endregion\r
381     }\r
382 }\r
383 #endif\r