2 // Mainsoft.Web.Security.WPMembershipProvider
\r
5 // Ilya Kharmatsky (ilyak at mainsoft.com)
\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
17 // The above copyright notice and this permission notice shall be
\r
18 // included in all copies or substantial portions of the Software.
\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
32 using System.Collections;
\r
33 using System.Collections.Generic;
\r
36 using System.Web.Security;
\r
41 using com.ibm.portal.um;
\r
43 namespace Mainsoft.Web.Security
\r
46 public class WPMembershipProvider : MembershipProvider
\r
48 private static readonly string PROVIDER_DESCRIPTION = "WebSphere Portal Membership Provider";
\r
49 internal static readonly string PROVIDER_NAME = "WPMembershipProvider";
\r
51 private string applicationName;
\r
54 public override string ApplicationName
\r
60 if (applicationName == null)
\r
61 applicationName = AppDomain.CurrentDomain.FriendlyName;
\r
63 return applicationName;
\r
69 applicationName = value;
\r
74 public override string Description
\r
76 get { return PROVIDER_DESCRIPTION; }
\r
79 public override bool EnablePasswordReset
\r
81 get { return false; }
\r
84 public override bool EnablePasswordRetrieval
\r
86 get { return false; }
\r
90 public override int MaxInvalidPasswordAttempts
\r
92 get { throw new NotImplementedException(); }
\r
96 public override int MinRequiredNonAlphanumericCharacters
\r
98 get { throw new NotImplementedException(); }
\r
102 public override int MinRequiredPasswordLength
\r
104 get { throw new NotImplementedException(); }
\r
107 public override string Name
\r
109 get { return PROVIDER_NAME; }
\r
113 public override int PasswordAttemptWindow
\r
115 get { throw new NotImplementedException("The method or operation is not implemented."); }
\r
119 public override MembershipPasswordFormat PasswordFormat
\r
121 get { throw new NotImplementedException("The method or operation is not implemented."); }
\r
125 public override string PasswordStrengthRegularExpression
\r
127 get { throw new NotImplementedException("The method or operation is not implemented."); }
\r
131 public override bool RequiresQuestionAndAnswer
\r
133 get { throw new NotImplementedException("The method or operation is not implemented."); }
\r
137 public override bool RequiresUniqueEmail
\r
139 get { throw new NotImplementedException("The method or operation is not implemented."); }
\r
145 #region Implemented Methods
\r
146 public override MembershipUserCollection FindUsersByEmail(string emailToMatch, int pageIndex, int pageSize, out int totalRecords)
\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
151 throw new ArgumentException("Argument pageIndex could not be negative", "pageIndex");
\r
153 throw new ArgumentException("Argument pageSize could not be less than one", "pageSize");
\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
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
169 MembershipUserCollection resCollection = new MembershipUserCollection();
\r
170 SliceRange sr = new SliceRange(pageSize, pageIndex);
\r
171 CopyToMembershipUserCollection(principles, resCollection, sr);
\r
173 //Should contain total records recieved.
\r
174 totalRecords = principles.size();
\r
175 return resCollection;
\r
179 public override MembershipUserCollection FindUsersByName(string usernameToMatch, int pageIndex, int pageSize, out int totalRecords)
\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
184 throw new ArgumentException("Argument pageIndex could not be negative", "pageIndex");
\r
186 throw new ArgumentException("Argument pageSize could not be less than one", "pageSize");
\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
192 IPumaServicesProvider pumaServices = PumaServicesProviderFactory.CreateProvider();
\r
194 java.util.List principles =
\r
195 pumaServices.PumaLocator.findUsersByAttribute("uid", usernameToMatch);
\r
197 MembershipUserCollection resCollection = new MembershipUserCollection();
\r
198 SliceRange sr = new SliceRange(pageSize, pageIndex);
\r
200 CopyToMembershipUserCollection(principles, resCollection, sr);
\r
203 //Should contain total records recieved.
\r
204 totalRecords = principles.size();
\r
205 return resCollection;
\r
209 public override MembershipUserCollection GetAllUsers(int pageIndex, int pageSize, out int totalRecords)
\r
212 throw new ArgumentException("Argument pageIndex could not be negative", "pageIndex");
\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
219 IPumaServicesProvider pumaServices = PumaServicesProviderFactory.CreateProvider();
\r
221 java.util.List principles =
\r
222 pumaServices.PumaLocator.findUsersByDefaultAttribute("*");
\r
224 MembershipUserCollection resCollection = new MembershipUserCollection();
\r
225 SliceRange sr = new SliceRange(pageSize, pageIndex);
\r
226 CopyToMembershipUserCollection(principles, resCollection, sr);
\r
229 //Should contain total records recieved.
\r
230 totalRecords = principles.size();
\r
231 return resCollection;
\r
235 //the userIsOnline ignored
\r
236 public override MembershipUser GetUser(string username, bool userIsOnline)
\r
238 if (username.Length > 256)
\r
239 throw new ArgumentException("The username is too long", username);
\r
240 IPumaServicesProvider provider = PumaServicesProviderFactory.CreateProvider();
\r
242 if (username == null || username == String.Empty)
\r
243 return new WPMembershipUser(provider.CurrentUser);
\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
254 * partially implemented :
\r
255 * the userIsOnline - ignored
\r
256 * the providerUserKey - is always considered as a UID
\r
259 public override MembershipUser GetUser(object providerUserKey, bool userIsOnline)
\r
261 if (providerUserKey is string)
\r
262 return GetUser((string)providerUserKey, userIsOnline);
\r
263 throw new NotImplementedException();
\r
266 public override string GetUserNameByEmail(string email)
\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
279 services.GetAttributes((com.ibm.portal.um.User)principles.get(0), "uid");
\r
280 return (string) dic["uid"];
\r
283 #region Helper Methods
\r
284 internal void CopyToMembershipUserCollection(java.util.List principles,
\r
285 MembershipUserCollection resCollection, SliceRange sr)
\r
287 if (sr.start >= principles.size())
\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
294 java.util.Collections.sort(sortedList, WPMembershipUser.UserNameComparator);
\r
296 int sortedListSize = sortedList.size();
\r
298 for (int i = sr.start; i < sortedListSize && i < sr.end; i++)
\r
299 resCollection.Add((MembershipUser)sortedList.get(i));
\r
307 public override bool ChangePassword(string username, string oldPassword, string newPassword)
\r
309 throw new NotImplementedException("The method or operation is not implemented.");
\r
313 public override bool ChangePasswordQuestionAndAnswer(string username, string password, string newPasswordQuestion, string newPasswordAnswer)
\r
315 throw new NotImplementedException("The method or operation is not implemented.");
\r
319 public override MembershipUser CreateUser(string username, string password, string email, string passwordQuestion, string passwordAnswer, bool isApproved, object providerUserKey, out MembershipCreateStatus status)
\r
321 throw new NotImplementedException("The method or operation is not implemented.");
\r
325 public override bool DeleteUser(string username, bool deleteAllRelatedData)
\r
327 throw new NotImplementedException("The method or operation is not implemented.");
\r
331 public override int GetNumberOfUsersOnline()
\r
333 throw new NotImplementedException("The method or operation is not implemented.");
\r
336 public override string GetPassword(string username, string answer)
\r
338 throw new NotImplementedException("The method or operation is not implemented.");
\r
341 public override string ResetPassword(string username, string answer)
\r
343 throw new NotImplementedException("The method or operation is not implemented.");
\r
346 public override bool UnlockUser(string userName)
\r
348 throw new NotImplementedException("The method or operation is not implemented.");
\r
351 public override void UpdateUser(MembershipUser user)
\r
353 throw new NotImplementedException("The method or operation is not implemented.");
\r
356 public override bool ValidateUser(string username, string password)
\r
358 throw new NotImplementedException("The method or operation is not implemented.");
\r
361 #region Helper Classes and Structs
\r
363 internal struct SliceRange
\r
365 internal int start;
\r
368 public SliceRange(int pageSize, int pageIndex)
\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