KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > nightlabs > ipanema > security > User


1 /*
2  * Created on 02.03.2004
3  */

4 package com.nightlabs.ipanema.security;
5
6 import java.io.Serializable JavaDoc;
7 import java.io.UnsupportedEncodingException JavaDoc;
8 import java.security.MessageDigest JavaDoc;
9 import java.security.NoSuchAlgorithmException JavaDoc;
10 import java.util.ArrayList JavaDoc;
11 import java.util.Collection JavaDoc;
12 import java.util.Date JavaDoc;
13 import java.util.HashMap JavaDoc;
14 import java.util.Iterator JavaDoc;
15 import java.util.List JavaDoc;
16 import java.util.Map JavaDoc;
17 import java.util.Random JavaDoc;
18
19 import javax.jdo.PersistenceManager;
20 import javax.jdo.Query;
21 import javax.jdo.spi.PersistenceCapable;
22
23 import org.apache.log4j.Logger;
24
25 import sun.misc.BASE64Encoder;
26
27 import com.nightlabs.ipanema.base.IpanemaBasePrincipal;
28 import com.nightlabs.ipanema.person.Person;
29 import com.nightlabs.ipanema.security.id.UserID;
30 import com.nightlabs.jdo.BaseObjectID;
31
32 /**
33  * @author alex
34  * @author nick
35  * @author marco
36  */

37
38 /**
39  * @jdo.persistence-capable
40  * identity-type = "application"
41  * objectid-class = "com.nightlabs.ipanema.security.id.UserID"
42  * detachable = "true"
43  *
44  * @jdo.inheritance strategy="new-table"
45  *
46  * @jdo.query
47  * name="getUsersByType"
48  * query="SELECT
49  * WHERE this.userType == paramUserType &&
50  * this.userID != paramSystemUserID
51  * PARAMETERS String paramUserType, String paramSystemUserID
52  * IMPORTS import java.lang.String"
53  *
54  * @jdo.fetch-group name="User.person" field-names="person"
55  * @jdo.fetch-group name="User.userRefs" field-names="userRefs"
56  * @jdo.fetch-group name="User.this" fetch-group-names="default" field-names="name, description, person"
57  */

58 public class User implements Serializable JavaDoc //, InstanceCallbacks
59
{
60     public static Logger LOGGER = Logger.getLogger(User.class);
61     
62     public static final String JavaDoc FETCH_GROUP_PERSON = "User.person";
63     public static final String JavaDoc FETCH_GROUP_USERREFS = "User.userRefs";
64     public static final String JavaDoc FETCH_GROUP_THIS_USER = "User.this";
65     
66     public static final String JavaDoc QUERY_GET_USERS_BY_TYPE = "getUsersByType";
67
68     /**
69      * The user <tt>_Other_</tt> is used to assign rolegroups within
70      * an <tt>Authority</tt> to all users that are not registered within
71      * this <tt>Authority</tt>.
72      * <p>
73      * The user <tt>_Other_</tt> has no password assigned. This means,
74      * it is a kind of pseudo user who
75      * never logs into the system and never performs any action.
76      */

77     public static String JavaDoc OTHER_USERID = "_Other_";
78
79     /**
80      * The user <tt>_System_</tt> represents the system itself. For
81      * example the initialization of datastores is done by this user.
82      * Because it does not have a password, noone can login as <tt>_System_</tt>.
83      * To allow the system itself to internally authenticate as this
84      * user, the <tt>IpanemaServerManager</tt> and the <tt>IpanemaServerLoginModule</tt>
85      * have a mechanism to create a temporary session password for this
86      * user.
87      * <p>
88      * This user has all access rights! Including <tt>_ServerAdmin_</tt> and all
89      * the roles that are registered in the datastore.
90      */

91     public static String JavaDoc SYSTEM_USERID = "_System_";
92
93     /**
94      * @jdo.field
95      * persistence-modifier="transactional"
96      * default-fetch-group="false"
97      */

98     public boolean passwdChanged = false;
99     
100     public static User getUser(PersistenceManager pm, IpanemaBasePrincipal principal) {
101         return getUser(pm, principal.getOrganisationID(), principal.getUserID());
102     }
103     
104     public static User getUser(PersistenceManager pm, String JavaDoc organisationID, String JavaDoc userID)
105     {
106         pm.getExtent(User.class);
107         return (User) pm.getObjectById(UserID.create(organisationID, userID), true);
108     }
109
110     /**
111      * This is the organisationID to which the user belongs. Within one organisation,
112      * all the users have their organisation's ID stored here, thus it's the same
113      * value for all of them. Even if the User object represents another organisation,
114      * this member is the organisationID to which the user logs in.
115      *
116      * @jdo.field primary-key="true"
117      * @jdo.column length="100"
118      */

119     private String JavaDoc organisationID;
120
121     /**
122      * @jdo.field primary-key="true"
123      * @jdo.column length="100"
124      */

125     private String JavaDoc userID;
126
127     public static final String JavaDoc USERTYPE_USER = "User";
128     public static final String JavaDoc USERTYPE_ORGANISATION = "Organisation";
129     public static final String JavaDoc USERTYPE_USERGROUP = "UserGroup";
130
131     public static final String JavaDoc USERID_PREFIX_TYPE_ORGANISATION = "$"; // "@";
132
public static final String JavaDoc USERID_PREFIX_TYPE_USERGROUP = "!";
133     /**
134      * @jdo.field persistence-modifier="persistent"
135      * @jdo.column length="100"
136      */

137     private String JavaDoc userType;
138
139     /**
140      * @jdo.field persistence-modifier="persistent"
141      * @jdo.column length="255"
142      */

143     private String JavaDoc name;
144     
145     /**
146      * @jdo.field persistence-modifier="persistent"
147      * @jdo.column length="255"
148      */

149     private String JavaDoc description;
150
151     /**
152      * @jdo.field persistence-modifier="persistent"
153      * @jdo.column length="255"
154      */

155     private String JavaDoc password;
156     
157     /**
158      * key: String userID (UserGroup extends User, thus userGroupID = userID)<br/>
159      * value: UserGroup userGroup
160      * <br/><br/>
161      * UserGroup (m) - (n) User
162      *
163      * @jdo.field
164      * persistence-modifier="persistent"
165      * collection-type="map"
166      * key-type="java.lang.String"
167      * value-type="UserGroup"
168      *
169      * @jdo.join
170      */

171     private Map JavaDoc userGroups = new HashMap JavaDoc();
172
173     /**
174      * key: String authorityID<br/>
175      * value: UserRef userRef
176      * <br/><br/>
177      * User (1) - (n) UserRef
178      *
179      * @jdo.field
180      * persistence-modifier="persistent"
181      * collection-type="map"
182      * key-type="java.lang.String"
183      * value-type="UserRef"
184      * mapped-by="user"
185      *
186      * @jdo.map-vendor-extension vendor-name="jpox" key="key-field" value="authorityID"
187      */

188     private Map JavaDoc userRefs = new HashMap JavaDoc();
189
190
191     /**
192      * @jdo.field persistence-modifier="persistent" load-fetch-group="all"
193      */

194     private Person person = null;
195
196     /**
197      * @jdo.field persistence-modifier="persistent"
198      */

199     private Date JavaDoc changeDT;
200
201
202     public User() {}
203     
204     public User(String JavaDoc _userID)
205     {
206         this(null, _userID);
207     }
208
209     public User(String JavaDoc _organisationID, String JavaDoc _userID)
210     {
211 // if (_organisationID == null)
212
// throw new NullPointerException("organisationID must not be null!");
213

214         if (_userID == null)
215             throw new NullPointerException JavaDoc("userID must not be null!");
216
217         if (!BaseObjectID.isValidIDString(_userID))
218             throw new IllegalArgumentException JavaDoc("userID \""+_userID+"\" is not a valid id!");
219
220         this.organisationID = _organisationID;
221         this.userID = _userID;
222         if (userID.startsWith(USERID_PREFIX_TYPE_ORGANISATION))
223             this.userType = USERTYPE_ORGANISATION;
224         else if (userID.startsWith(USERID_PREFIX_TYPE_USERGROUP))
225             this.userType = USERTYPE_USERGROUP;
226         else
227             this.userType = USERTYPE_USER;
228         changeDT = new Date JavaDoc();
229     }
230
231
232     /**
233      * @return Returns the organisationID.
234      */

235     public String JavaDoc getOrganisationID() {
236         return organisationID;
237     }
238     
239     protected void setOrganisationID(String JavaDoc _organisationID) {
240         this.organisationID = _organisationID;
241     }
242
243     /**
244      * @return Returns the userID.
245      */

246     public String JavaDoc getUserID()
247     {
248         return userID;
249     }
250
251     protected void setUserID(String JavaDoc _userID)
252     {
253         this.userID = _userID;
254     }
255
256     /**
257      * @return Returns the userType.
258      */

259     public String JavaDoc getUserType() {
260         return userType;
261     }
262     
263     /**
264      * @return Returns the description.
265      */

266     public String JavaDoc getDescription() {
267         return description;
268     }
269     /**
270      * @param description The description to set.
271      */

272     public void setDescription(String JavaDoc description) {
273         this.description = description;
274         changeDT = new Date JavaDoc();
275     }
276     /**
277      * @return Returns the name.
278      */

279     public String JavaDoc getName() {
280         return name;
281     }
282     /**
283      * @param name The name to set.
284      */

285     public void setName(String JavaDoc name) {
286         this.name = name;
287         changeDT = new Date JavaDoc();
288     }
289
290     /**
291      * @return Returns the password.
292      */

293     public String JavaDoc getPassword()
294     {
295         return password;
296     }
297
298     /**
299      * @param password The password in NOT encrypted form to set.
300      * @throws SecurityException
301      */

302     public void setPasswordPlain(String JavaDoc password) throws SecurityException JavaDoc
303     {
304         setPassword(encryptPassword(password));
305     }
306
307     /**
308      * @param password The password in ENCRYPTED form to set.
309      */

310     public void setPassword(String JavaDoc password)
311     {
312       passwdChanged = true;
313       this.password = password;
314       changeDT = new Date JavaDoc();
315     }
316
317
318     /**
319      * @return Returns the person.
320      */

321     public Person getPerson() {
322         return person;
323     }
324     /**
325      * @param person The person to set.
326      */

327     public void setPerson(Person person) {
328         this.person = person;
329         if (person != null) {
330             // TODO: Here we should set the name of the user to sth. like
331
// "{Company}: {Name}, {FirstName}" from person data.
332
}
333         changeDT = new Date JavaDoc();
334     }
335
336     /**
337      * @return Returns the changeDT.
338      */

339     public Date JavaDoc getChangeDT() {
340         return changeDT;
341     }
342     
343     /**
344      * This method checks, whether a plain password matches the password set
345      * for this user. Therefore, it encrypts the plain password and checks equality
346      * of the hashes.
347      * @param plainPassword
348      * @return True if the password matches, false otherwise.
349      */

350     public boolean checkPassword(String JavaDoc plainPassword)
351         throws SecurityException JavaDoc
352     {
353         if (plainPassword == null)
354             throw new NullPointerException JavaDoc("plainPassword must not be null!");
355         
356         return encryptPassword(plainPassword).equals(getPassword());
357     }
358
359
360     public static final int INCLUDE_NONE = 0;
361     public static final int INCLUDE_PERSON = 0x1;
362     public static final int INCLUDE_USERGROUPS = 0x2;
363     public static final int INCLUDE_ALL = Integer.MAX_VALUE;
364
365     public void makeTransient(int includeMask)
366     {
367         PersistenceManager pm = ((PersistenceCapable)this).jdoGetPersistenceManager();
368         if (pm == null)
369             return;
370
371         pm.retrieve(this);
372         
373         Map JavaDoc tmpUserGroups = new HashMap JavaDoc();
374         if ((includeMask & INCLUDE_USERGROUPS) != 0) {
375             for (Iterator JavaDoc it = userGroups.values().iterator(); it.hasNext(); ) {
376                 UserGroup userGroup = (UserGroup)it.next();
377                 userGroup.makeTransient(UserGroup.INCLUDE_NONE);
378                 tmpUserGroups.put(userGroup.getUserID(), userGroup);
379             }
380         }
381
382         pm.makeTransient(this);
383
384         this.userGroups = tmpUserGroups;
385     }
386
387     protected transient String JavaDoc login = null;
388     /**
389      * This method returns the login of this user in the form {userID}@{organisationID}.
390      * The login is the system wide unique identifier for a user.
391      *
392      * @return Returns the login as {userID}@{organisationID}
393      */

394     public String JavaDoc getLogin()
395     {
396         if (login == null) {
397             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
398             sb.append(getUserID());
399             sb.append('@');
400             sb.append(getOrganisationID());
401             login = sb.toString();
402         }
403         return login;
404     }
405     
406     
407     public Collection JavaDoc getUserRefs()
408     {
409         return userRefs.values();
410     }
411
412
413     protected void _addUserRef(UserRef userRef)
414     {
415         if (userRef == null)
416             throw new NullPointerException JavaDoc("userRef must not be null!");
417
418         if (!this.userID.equals(userRef.getUserID()))
419             throw new IllegalArgumentException JavaDoc("userRef.userID invalid!");
420
421         userRefs.put(userRef.getAuthorityID(), userRef);
422     }
423     
424     protected void _removeUserRef(String JavaDoc authorityID)
425     {
426         userRefs.remove(authorityID);
427     }
428     
429     public UserRef getUserRef(String JavaDoc authorityID)
430     {
431         return (UserRef)userRefs.get(authorityID);
432     }
433
434     protected void _addUserGroup(UserGroup userGroup)
435     {
436         if (userGroup == null)
437             throw new NullPointerException JavaDoc("userGroup must not be null!");
438
439         userGroups.put(userGroup.getUserID(), userGroup);
440     }
441
442     /**
443      * @param userGroupID Because UserGroup extends User, the userGroupID is the userID.
444      */

445     protected void _removeUserGroup(String JavaDoc userGroupID)
446     {
447         userGroups.remove(userGroupID);
448     }
449
450     public boolean isUserGroupsEmpty()
451     {
452         return userGroups.isEmpty();
453     }
454
455     public Collection JavaDoc getUserGroups()
456     {
457         return userGroups.values();
458     }
459
460     /**
461      * @param userGroupID Because UserGroup extends User, the userGroupID is the userID.
462      */

463     public UserGroup getUserGroup(String JavaDoc userGroupID)
464     {
465         return (UserGroup)userGroups.get(userGroupID);
466     }
467     
468
469     protected transient String JavaDoc thisString = null;
470     public String JavaDoc toString()
471     {
472         if (thisString == null) {
473             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
474             sb.append(this.getClass().getName());
475             sb.append('{');
476 // sb.append(getUserID());
477
// sb.append('@');
478
// sb.append(getOrganisationID());
479
sb.append(getLogin()); // because the login is created in jdoPostLoad anyway.
480
sb.append('}');
481             thisString = sb.toString();
482         }
483         return thisString;
484     }
485
486     /**
487      * @see java.lang.Object#equals(java.lang.Object)
488      */

489     public boolean equals(Object JavaDoc obj) {
490         if (obj == this)
491             return true;
492
493         if (!(obj instanceof User))
494             return false;
495
496         User other = (User)obj;
497         return
498             this.getOrganisationID().equals(other.getOrganisationID())
499             &&
500             this.getUserID().equals(other.getUserID());
501     }
502
503     /**
504      * @see java.lang.Object#hashCode()
505      */

506     public int hashCode() {
507         return this.getOrganisationID().hashCode() ^ this.getUserID().hashCode();
508     }
509
510 // public static final String USERTYPE_ORGANISATION = "organisation";
511
// public static final String USERTYPE_USER = "user";
512
//
513
// public static final String USERID_PREFIX_TYPE_ORGANISATION = "@";
514
// public String getUserType()
515
// {
516
// if (userID.startsWith(USERID_PREFIX_TYPE_ORGANISATION))
517
// return USERTYPE_ORGANISATION;
518
// else
519
// return USERTYPE_USER;
520
// }
521

522
523 // /**
524
// * @see javax.jdo.InstanceCallbacks#jdoPostLoad()
525
// */
526
// public void jdoPostLoad() {
527
// // noop
528
// }
529
// /**
530
// * @see javax.jdo.InstanceCallbacks#jdoPreStore()
531
// */
532
// public void jdoPreStore() {
533
// // noop
534
// }
535
// /**
536
// * @see javax.jdo.InstanceCallbacks#jdoPreClear()
537
// */
538
// public void jdoPreClear() {
539
// // noop
540
// }
541
// /**
542
// * @see javax.jdo.InstanceCallbacks#jdoPreDelete()
543
// */
544
// public void jdoPreDelete() {
545
// // noop
546
// }
547

548     /**
549      * This method generates a random password.
550      *
551      * @param minLen The minimum length (included).
552      * @param maxLen The maximum length (included).
553      * @return
554      */

555     public static String JavaDoc generatePassword(int minLen, int maxLen)
556     {
557         Random JavaDoc random = new Random JavaDoc();
558         int len = minLen + random.nextInt(maxLen - minLen + 1);
559         StringBuffer JavaDoc pw = new StringBuffer JavaDoc();
560         for (int i = 0; i < len; ++i) {
561             int v = random.nextInt(126 - 40) + 40; // generate a number in [40..125]
562
pw.append((char)v);
563         }
564         return pw.toString();
565     }
566
567     public static String JavaDoc encryptPassword(String JavaDoc password)
568     throws SecurityException JavaDoc
569     {
570       if(password == null)
571         return null;
572       
573         MessageDigest JavaDoc md = null;
574         try {
575             md = MessageDigest.getInstance("SHA");
576             md.update(password.getBytes("UTF-8"));
577         } catch(NoSuchAlgorithmException JavaDoc e) {
578             throw new SecurityException JavaDoc(e);
579         } catch(UnsupportedEncodingException JavaDoc e) {
580             throw new SecurityException JavaDoc(e);
581         }
582         byte raw[] = md.digest();
583         return (new BASE64Encoder()).encode(raw);
584     }
585     
586     public static UserSearchResult searchUsers (
587             PersistenceManager pm,
588             String JavaDoc userType,
589             String JavaDoc searchStr, boolean exact, int itemsPerPage, int pageIndex, int userIncludeMask)
590         throws SecurityException JavaDoc
591     {
592         try {
593             if ("".equals(searchStr))
594                 searchStr = null;
595             
596             if (itemsPerPage <= 0) {
597                 itemsPerPage = Integer.MAX_VALUE;
598                 pageIndex = 0;
599             }
600             
601             if (pageIndex < 0)
602                 pageIndex = 0;
603             
604             Query query = pm.newQuery(pm.getExtent(User.class, true));
605             query.declareImports("import java.lang.String");
606             query.declareParameters("String userType, String searchStr");
607             StringBuffer JavaDoc filter = new StringBuffer JavaDoc();
608             if (userType != null)
609                 filter.append("this.userType == userType");
610
611             if (userType != null && searchStr != null)
612                 filter.append(" && ");
613             
614             if (searchStr != null) {
615                 searchStr = searchStr.toLowerCase();
616                 if (exact)
617                     filter.append("this.userID.toLowerCase() == searchStr");
618                 else
619                     filter.append("this.userID.toLowerCase().indexOf(searchStr) >= 0");
620             }
621             query.setFilter(filter.toString());
622             query.setOrdering("this.organisationID ascending, this.userID ascending");
623             Collection JavaDoc c = (Collection JavaDoc)query.execute(userType, searchStr);
624             int itemsFound = c.size();
625             Iterator JavaDoc it = c.iterator();
626             List JavaDoc items = new ArrayList JavaDoc();
627             int idx = 0;
628             int firstIdx = 0; int lastIdx = Integer.MAX_VALUE;
629             if (pageIndex >= 0)
630                 firstIdx = itemsPerPage * pageIndex;
631             lastIdx = firstIdx + itemsPerPage - 1;
632
633             while (it.hasNext()) {
634                 User user = (User)it.next();
635                 if (idx >= firstIdx)
636                     items.add(user);
637
638                 ++idx;
639                 if (idx > lastIdx)
640                     break;
641             } // while (it.hasNext()) {
642
return new UserSearchResult(itemsFound, itemsPerPage, pageIndex, items);
643         } catch (Exception JavaDoc x) {
644             throw new SecurityException JavaDoc(x);
645         }
646     }
647     
648     /**
649      * Returns all users of the given type exluding the user with the given
650      * systemUserID
651      *
652      * @param pm PersistenceManager to use
653      * @param userType The userType to search for
654      * @param systemUserID The userID to exclude
655      * @return All users of the given type exluding the user with the given systemUserID
656      */

657     public static Collection JavaDoc getUsersByType(PersistenceManager pm, String JavaDoc userType, String JavaDoc systemUserID) {
658         Query q = pm.newNamedQuery(User.class, QUERY_GET_USERS_BY_TYPE);
659         return (Collection JavaDoc)q.execute(userType, systemUserID);
660     }
661
662 }
663
Popular Tags