KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > services > dbobj > DefaultUserInfo


1 /* ====================================================================
2  * The Jcorporate Apache Style Software License, Version 1.2 05-07-2002
3  *
4  * Copyright (c) 1995-2002 Jcorporate Ltd. All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  * notice, this list of conditions and the following disclaimer.
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in
15  * the documentation and/or other materials provided with the
16  * distribution.
17  *
18  * 3. The end-user documentation included with the redistribution,
19  * if any, must include the following acknowledgment:
20  * "This product includes software developed by Jcorporate Ltd.
21  * (http://www.jcorporate.com/)."
22  * Alternately, this acknowledgment may appear in the software itself,
23  * if and wherever such third-party acknowledgments normally appear.
24  *
25  * 4. "Jcorporate" and product names such as "Expresso" must
26  * not be used to endorse or promote products derived from this
27  * software without prior written permission. For written permission,
28  * please contact info@jcorporate.com.
29  *
30  * 5. Products derived from this software may not be called "Expresso",
31  * or other Jcorporate product names; nor may "Expresso" or other
32  * Jcorporate product names appear in their name, without prior
33  * written permission of Jcorporate Ltd.
34  *
35  * 6. No product derived from this software may compete in the same
36  * market space, i.e. framework, without prior written permission
37  * of Jcorporate Ltd. For written permission, please contact
38  * partners@jcorporate.com.
39  *
40  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED
41  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
42  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
43  * DISCLAIMED. IN NO EVENT SHALL JCORPORATE LTD OR ITS CONTRIBUTORS
44  * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
45  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
46  * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
47  * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
48  * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
49  * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
50  * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * ====================================================================
53  *
54  * This software consists of voluntary contributions made by many
55  * individuals on behalf of the Jcorporate Ltd. Contributions back
56  * to the project(s) are encouraged when you make modifications.
57  * Please send them to support@jcorporate.com. For more information
58  * on Jcorporate Ltd. and its products, please see
59  * <http://www.jcorporate.com/>.
60  *
61  * Portions of this software are based upon other open source
62  * products and are subject to their respective licenses.
63  */

64
65 package com.jcorporate.expresso.services.dbobj;
66
67 import com.jcorporate.expresso.core.cache.Cache;
68 import com.jcorporate.expresso.core.cache.CacheException;
69 import com.jcorporate.expresso.core.cache.CacheManager;
70 import com.jcorporate.expresso.core.cache.CacheSystem;
71 import com.jcorporate.expresso.core.cache.CachedObject;
72 import com.jcorporate.expresso.core.controller.ControllerRequest;
73 import com.jcorporate.expresso.core.db.DBConnection;
74 import com.jcorporate.expresso.core.db.DBException;
75 import com.jcorporate.expresso.core.dbobj.DBField;
76 import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
77 import com.jcorporate.expresso.core.dbobj.ValidValue;
78 import com.jcorporate.expresso.core.logging.LogException;
79 import com.jcorporate.expresso.core.misc.Base64;
80 import com.jcorporate.expresso.core.misc.ConfigManager;
81 import com.jcorporate.expresso.core.misc.ConfigurationException;
82 import com.jcorporate.expresso.core.misc.DateTime;
83 import com.jcorporate.expresso.core.misc.EMailSender;
84 import com.jcorporate.expresso.core.misc.EventHandler;
85 import com.jcorporate.expresso.core.misc.StringUtil;
86 import com.jcorporate.expresso.core.security.CryptoManager;
87 import com.jcorporate.expresso.core.security.User;
88 import com.jcorporate.expresso.core.security.UserInfo;
89 import com.jcorporate.expresso.kernel.exception.ChainedException;
90 import com.jcorporate.expresso.kernel.util.FastStringBuffer;
91 import org.apache.log4j.Logger;
92
93 import java.util.Date JavaDoc;
94 import java.util.Enumeration JavaDoc;
95 import java.util.Hashtable JavaDoc;
96 import java.util.Iterator JavaDoc;
97 import java.util.Vector JavaDoc;
98
99
100 /**
101  * Default implementation of the UserInfo object. This is the class that comes
102  * for managing users and security with Expresso.
103  *
104  * @author Michael Nash, adapted Larry Hamel, CodeGuild
105  */

106 public class DefaultUserInfo
107         extends SecurityDBObject
108         implements UserInfo {
109
110     /**
111      * Debugging information value
112      */

113     public static final String JavaDoc THIS_CLASS = DefaultUserInfo.class.getName();
114
115     /**
116      *
117      */

118     public static final String JavaDoc NAME_2_ID_CACHE_NAME = THIS_CLASS + ".nameToId";
119
120
121     /**
122      * Field name for the user id
123      */

124     public static final String JavaDoc EXPUID = "ExpUid";
125
126     /**
127      * Field name for the login name
128      */

129     public static final String JavaDoc LOGIN = "LoginName";
130
131     /**
132      * Field name for the password
133      */

134     public static final String JavaDoc PASSWORD = "Passwd";
135
136     /**
137      * Field name for user's email
138      */

139     public static final String JavaDoc EMAIL_ADDRESS = "EMail";
140
141     /**
142      * Field name for the registration domain id.
143      */

144     public static final String JavaDoc REGISTRATION_DOMAIN = "RegDomId";
145
146     /**
147      * Field name for account status
148      */

149     public static final String JavaDoc ACCOUNT_STATUS = "AccountStatus";
150
151     /**
152      * Field name for registration complete flag
153      */

154     public static final String JavaDoc IS_REG_COMPLETE = "RegComplete";
155
156     /**
157      * Field name for created date
158      */

159     public static final String JavaDoc CREATED_DATE = "CreateDate";
160
161     /**
162      * Field name for updated date
163      */

164     public static final String JavaDoc UPDATED_DATE = "UpdateDate";
165
166     /**
167      * Field name for validation code
168      */

169     public static final String JavaDoc VALIDATION_CODE = "EmailValCode";
170
171     /**
172      * Field name for full name.
173      */

174     public static final String JavaDoc FULL_NAME = "UserName";
175
176
177     /**
178      * Full name field length
179      */

180     public static final int FULL_NAME_LENGTH = 80;
181
182     /**
183      * Email address length
184      */

185     public static final int EMAIL_ADDRESS_LENGTH = 80;
186
187     /**
188      * Login name length
189      */

190     public static final int LOGIN_LENGTH = 30;
191
192     /**
193      * Password name length
194      */

195     public static final int PASSWORD_LENGTH = 30;
196
197     /**
198      * Validation code length
199      */

200     public static final int VALIDATION_CODE_LENGTH = 30;
201
202     /**
203      * The log4j Logger
204      */

205     private static Logger log = Logger.getLogger(DefaultUserInfo.class);
206
207     /**
208      * constants used to indicate one of two cases: whether checking for unique email/login name during add() or update()
209      */

210     private static final boolean IS_UPDATE = true;
211     private static final boolean IS_ADD = false;
212
213     /**
214      * Sets the uid of the userinfo object
215      *
216      * @param uid the user id to set
217      * @throws DBException upon error
218      */

219     public void setUid(String JavaDoc uid)
220             throws DBException {
221         StringUtil.assertNotBlank(uid, "Can't set a blank UID");
222         setField(EXPUID, uid);
223     } /* setUid(String) */
224
225
226     /**
227      * Sets the uid of the userinfo object
228      *
229      * @param uid the user id to set
230      * @throws DBException upon error
231      */

232     public void setUid(int uid)
233             throws DBException {
234         setField(EXPUID, uid);
235     }
236
237     /**
238      * Default constructor
239      */

240     public DefaultUserInfo()
241             throws DBException {
242     } /* DefaultUserInfo() */
243
244
245     /**
246      * Constructor with UID
247      *
248      * @param uid The User ID of the owner object
249      * @throws DBException upon error
250      */

251     public DefaultUserInfo(int uid)
252             throws DBException {
253         super(uid);
254     }
255
256     /**
257      * constructor for db transactions
258      *
259      * @param localConnection the DB connection which should be used, typically because of an ongoing transaction
260      */

261     public DefaultUserInfo(DBConnection localConnection) throws DBException {
262         if (localConnection != null) {
263             setConnection(localConnection);
264         }
265     }
266
267     /**
268      * For using DBObjects within Controllers. Initializes based upon the current
269      * user and the requested db. [Of course this can be modified later]
270      *
271      * @param request - The controller request handed to you by the framework.
272      */

273     public DefaultUserInfo(ControllerRequest request)
274             throws DBException {
275         super(request);
276     }
277
278     /**
279      * Override of add to check for duplicate emails.
280      *
281      * @throws DBException upon error
282      */

283     public void add()
284             throws DBException {
285
286         checkEmailAddrAlreadyUsed(IS_ADD);
287
288         // At initial login, UserName == LoginName, Registation controllers can later modify this
289
if (getField(FULL_NAME).equals("")) {
290             setField(FULL_NAME, getField(LOGIN));
291         }
292         // If a User is added without a status, we set the AccountStatus to "I"
293
// for security reasons
294
if (getField(ACCOUNT_STATUS).equals("")) {
295             setField(ACCOUNT_STATUS, "I");
296         }
297         // Set the registration domain id
298
if (getRegistrationDomain().equals("")) {
299             setRegistrationDomain("default");
300         }
301
302         RegistrationDomain rd = new RegistrationDomain();
303         rd.setDataContext(getDataContext());
304         rd.setField("Name", getRegistrationDomain());
305
306         if (!rd.find()) {
307             throw new DBException("Registration domain \"" +
308                     getRegistrationDomain() +
309                     "\" has not been defined");
310         }
311
312         setField(REGISTRATION_DOMAIN, rd.getField(REGISTRATION_DOMAIN));
313
314         // Check value of registration valid flag
315
if (getField(IS_REG_COMPLETE).equals("")) {
316             setField(IS_REG_COMPLETE, "N");
317         }
318         // We should always have a CreateDate
319
if (getField(CREATED_DATE).equals("")) {
320             setField(CREATED_DATE, DateTime.getDateTimeForDB(this.getDataContext()));
321         }
322         // We should always have a UpdateDate
323
if (getField(UPDATED_DATE).equals("")) {
324             setField(UPDATED_DATE, getField(CREATED_DATE));
325         }
326
327         super.add();
328
329         User user = new User();
330         user.setDataContext(this.getDataContext());
331         user.addNotify(this);
332
333     } /* add() */
334
335
336     /**
337      * Extends the checkAllRefs method to check for valid Registration Domain Id
338      *
339      * @throws DBException If a referential integrity violation is found
340      */

341     protected void checkAllRefs()
342             throws DBException {
343         checkRef(REGISTRATION_DOMAIN, new RegistrationDomain(),
344                 "Invalid " + getString(getMetaData().getDescription(REGISTRATION_DOMAIN)));
345     } /* checkAllRefs() */
346
347
348     /**
349      * Override of deleteMethod() to notify UserListeners of deltion
350      *
351      * @throws DBException upon error
352      */

353     public void delete()
354             throws DBException {
355
356         // Nobody sets the key field UID...so we cheat here.
357
// Find the field first so the keyfield is set and then do a delete
358
find();
359         User user = new User();
360         user.setDataContext(this.getDataContext());
361         user.deleteNotify(this); //We cannot delete until all listeners have
362
//agreed that this is workable.
363
super.delete();
364
365
366     } /* delete() */
367
368
369     /**
370      * Retrieve the account status of the user
371      *
372      * @return java.lang.String : one of the account status codes
373      * @throws DBException upon error
374      */

375     public String JavaDoc getAccountStatus()
376             throws DBException {
377         return getField(ACCOUNT_STATUS);
378     } /* getAccountStatus() */
379
380
381     /**
382      * Retrieve a list of all users... may get REALLY intensive!
383      *
384      * @return Vector of UserInfo objects
385      * @throws DBException upon database error
386      */

387     public Vector JavaDoc getAllUsers()
388             throws DBException {
389         return new Vector JavaDoc(searchAndRetrieveList(LOGIN));
390     } /* getAllUsers() */
391
392     /**
393      * Get the account creation date
394      *
395      * @return java.lang.String as a date formatted string
396      * @throws DBException upon error
397      */

398     public String JavaDoc getCreateDate()
399             throws DBException {
400         return getField(CREATED_DATE);
401     } /* getCreateDate() */
402
403
404     /**
405      * Retrieve the email address of the account
406      *
407      * @return java.lang.String
408      * @throws DBException upon error
409      */

410     public String JavaDoc getEmail()
411             throws DBException {
412         return getField(EMAIL_ADDRESS);
413     } /* getEmail() */
414
415     /**
416      * Create an email authorization code. Used anymore??
417      *
418      * @return java.lang.String
419      * @throws DBException upon error
420      */

421     public String JavaDoc getEmailAuthCode()
422             throws DBException {
423         Date JavaDoc createDate = getFieldDate(CREATED_DATE);
424         long dateLong = createDate.getTime();
425         long emailAuthCode = Math.round(dateLong * 1.71);
426
427         return Long.toString(emailAuthCode);
428     } /* getEmailAuthCode() */
429
430
431     /**
432      * Retrieve the email validation code
433      *
434      * @return java.lang.String
435      */

436     public String JavaDoc getEmailValCode()
437             throws DBException {
438         return getField(VALIDATION_CODE);
439     } /* getEmailValCode() */
440
441
442     /**
443      * Get the groups that below to this user
444      *
445      * @return Vector of strings
446      * @throws DBException upon database access error
447      */

448     public Vector JavaDoc getGroups()
449             throws DBException {
450
451         //
452
//Attempt Cache retrieval first.
453
//
454
CacheSystem cs = CacheManager.getCacheSystem(this.getDataContext());
455         String JavaDoc cacheName = THIS_CLASS + ".groups";
456         String JavaDoc key = Integer.toString(this.getUid());
457         Cache cache = cs.getCache(cacheName);
458         if (cache == null) {
459             try {
460                 cache = cs.createCache(cacheName, false, 200);
461                 cs.addListener(cacheName,
462                         com.jcorporate.expresso.services.dbobj.GroupMembers.class.getName());
463             } catch (CacheException ex) {
464                 log.error("Error creating cache: " + cacheName);
465             }
466         }
467
468         if (cache != null) {
469             CachedObject c = (CachedObject) cache.getItem(key);
470             if (c != null) {
471                 return (Vector JavaDoc) c.getValue();
472             }
473         }
474
475         Vector JavaDoc myGroups = new Vector JavaDoc(3);
476
477
478         GroupMembers memberList = new GroupMembers();
479         memberList.setDataContext(getDataContext());
480         memberList.setField(GroupMembers.EXPUID, getUid());
481
482
483         if (log.isDebugEnabled()) {
484             log.debug("Getting groups for uid " + getUid() + ", login name " +
485                     getLoginName());
486         }
487         for (Iterator JavaDoc e = memberList.searchAndRetrieveList().iterator();
488              e.hasNext();) {
489             GroupMembers oneMember = null;
490             oneMember = (GroupMembers) e.next();
491             myGroups.addElement(oneMember.getField("GroupName"));
492
493             if (log.isDebugEnabled()) {
494                 log.debug("" + getUid() + " is a Member of group " +
495                         oneMember.getField("GroupName"));
496             }
497         }
498
499         /**
500          * back in the bad old days, we manually added the UserGroup.UNKNOWN_USERS_GROUP so that
501          * it appeared as though everyone was a member of this group. If your app depends on this old
502          * behavior, set the following Setup value to true.
503          String isAddUnknownUsersGroup = Setup.getValueUnrequired(getDataContext(), "AddUnknownUserGroup");
504          if ( StringUtil.toBoolean(isAddUnknownUsersGroup) )
505          myGroups.addElement(UserGroup.UNKNOWN_USERS_GROUP);
506          */

507
508         myGroups.addElement(UserGroup.UNKNOWN_USERS_GROUP);
509
510
511         if (log.isDebugEnabled()) {
512             log.debug("" + getUid() + " is a member of " + myGroups.size() +
513                     " groups");
514         }
515
516         if (cache != null) {
517             CachedObject co = new CachedObject(key, myGroups);
518             try {
519                 cs.addItem(cacheName, co, 1000 * 60 * 10); //10 minute cache;
520
} catch (CacheException ex) {
521                 log.error("Error adding group list to cache", ex);
522             }
523         }
524
525         return myGroups;
526     } /* getGroups() */
527
528
529     /**
530      * get name used for login query that is accompanied by password
531      */

532     public String JavaDoc getLoginName()
533             throws DBException {
534         return getField(LOGIN);
535     } /* getLoginName() */
536
537
538     public String JavaDoc getPassword()
539             throws DBException {
540         return getField(PASSWORD);
541     } /* getPassword() */
542
543
544     public boolean getRegComplete()
545             throws DBException {
546         String JavaDoc statusString = getField(IS_REG_COMPLETE);
547         boolean status = false;
548
549         if (statusString.equals("Y")) {
550             status = true;
551         }
552
553         return status;
554     } /* getRegComplete() */
555
556
557     public String JavaDoc getRegistrationDomain()
558             throws DBException {
559         String JavaDoc domain = "default";
560         RegistrationDomain rd = new RegistrationDomain();
561         rd.setDataContext(getDataContext());
562         rd.setField(REGISTRATION_DOMAIN, getField(REGISTRATION_DOMAIN));
563
564         if (rd.find()) {
565             domain = rd.getField("Name");
566         }
567
568         return domain;
569     } /* getRegistrationDomain() */
570
571
572     public int getUid()
573             throws DBException {
574         return getFieldInt(EXPUID);
575     } /* getUid() */
576
577
578     public String JavaDoc getUpdateDate()
579             throws DBException {
580         return getField(UPDATED_DATE);
581     } /* getUpdateDate() */
582
583
584     /**
585      * get descriptive, full name
586      *
587      * @deprecated Since Expresso 5.5; use getFullName()
588      * instead to avoid confusion with login name
589      */

590     public String JavaDoc getUserName()
591             throws DBException {
592         return getField(FULL_NAME);
593     } /* getUserName() */
594
595     /**
596      * get descriptive, full name (first + last names) of person
597      */

598     public String JavaDoc getFullName()
599             throws DBException {
600         return getField(FULL_NAME);
601     } /* getUserName() */
602
603
604     /**
605      * Get the valid values for various fields on this data object
606      *
607      * @param fieldName The fieldname to retrieve the valid values for.
608      * @return a java.util.Vector of ValidValue objects
609      * @throws com.jcorporate.expresso.core.db.DBException
610      * The exception description.
611      */

612     public synchronized Vector JavaDoc getValidValues(String JavaDoc fieldName)
613             throws DBException {
614         if (ACCOUNT_STATUS.equals(fieldName)) {
615             Vector JavaDoc values = new Vector JavaDoc();
616             values.addElement(new ValidValue("A", "Active"));
617             values.addElement(new ValidValue("I",
618                     "Inactive Until Email Confirmation"));
619             values.addElement(new ValidValue("D", "Disabled"));
620             values.addElement(new ValidValue("W", "Waiting For Approval"));
621             values.addElement(new ValidValue("X",
622                     "Registration Denied By Administrator"));
623
624             return values;
625         } else if (fieldName.equals(IS_REG_COMPLETE)) {
626             Vector JavaDoc rv = new Vector JavaDoc(2);
627             ValidValue rvv = new ValidValue("Y", "Complete");
628             rv.addElement(rvv);
629             rvv = new ValidValue("N", "Incomplete");
630             rv.addElement(rvv);
631
632             return rv;
633         }
634
635         // default for all other fields
636
return super.getValidValues(fieldName);
637     } /* getValidValues(String) */
638
639     public Vector JavaDoc getValues() throws DBException {
640         // FIXME: change the next line!
641
return getValuesDefault(EXPUID, LOGIN);
642     } /* getValues() */
643
644     /**
645      * hashEncodePassword: If passed a plaintext string > 0 bytes, then this
646      * function will SHA1 hash the password, then Base64 encode it and return it
647      * as a string.
648      * <p/>
649      * If the password is zero length, then it will simply return a zero length
650      * string also.
651      *
652      * @param plaintext - the password to process in this manner: <br>
653      * returnValue = Base64(SHA-1(plaintext))
654      * @return a String representing a Base64 encoded Hashed Password
655      */

656     public String JavaDoc hashEncodePassword(String JavaDoc plaintext) throws DBException {
657         if (plaintext == null) {
658             throw new DBException("Password Must not be NULL");
659         }
660         if (plaintext.length() == 0) {
661             return plaintext;
662         }
663         try {
664             return Base64.encode(CryptoManager.getInstance().getStringHash().produceHash(plaintext.getBytes()));
665         } catch (Exception JavaDoc ex) {
666             throw new DBException("Error hashing Password:" +
667                     " You may not have installed the" +
668                     " Cryptography Extensions Properly:", ex);
669         }
670     } /* hashEncodePassword(String) */
671
672
673     /**
674      * Send this user a notification via e-mail.
675      *
676      * @param subject Subject of the e-mail
677      * @param message Message to send in body of e-mail
678      * @throws DBException If the mail message cannot be sent
679      */

680     public void notify(String JavaDoc subject, String JavaDoc message)
681             throws DBException, LogException {
682         log.info("Notifying user " + getField(EXPUID) + " of " + subject);
683
684         String JavaDoc sendToUser = getField(EMAIL_ADDRESS);
685
686         try {
687             EMailSender ems = new EMailSender();
688             ems.setDBName(getDataContext());
689             ems.send(sendToUser, subject, message);
690         } catch (Exception JavaDoc e) {
691             throw new DBException("Uncaught exception sending e-mail", e);
692         }
693     } /* notify(String, String) */
694
695
696     /**
697      * Check if the given number is in the range of letters and
698      * digits that we want to use for generating a password
699      * Previously in com.jcorporate.expresso.ext.servlet.RegisterUser.java
700      *
701      * @param x The byte to check
702      * @return true if it is a printable form
703      */

704     private boolean okNumber(byte x) {
705         if ((x >= 65) && (x <= 90)) {
706             return true;
707         }
708         if ((x >= 48) && (x <= 57)) {
709             return true;
710         }
711         if ((x >= 97) && (x <= 122)) {
712             return true;
713         }
714
715         return false;
716     } /* okNumber(byte) */
717
718     /**
719      * passwordEquals - feed it a password and it will tell you if the hash of it
720      * matches the one on file.
721      * <p/>
722      * Also, for backwards compatability and some other issues, this function
723      * will also accept a plaintext version of the password if it is sitting in
724      * the database. However, if a plaintext match is encountered, then it will
725      * hash the password and re-write itself to the database record.
726      *
727      * @param tryPassword The value the user input for an attempted login.
728      * @return true if the password equals
729      */

730     public boolean passwordEquals(String JavaDoc tryPassword)
731             throws DBException {
732         if (tryPassword == null) {
733             throw new DBException("tryPassword Must not be NULL");
734         }
735
736         String JavaDoc fieldData = getPassword();
737         String JavaDoc trieduser = getLoginName();
738
739         if (log.isDebugEnabled()) {
740             log.debug("Trying user " + trieduser + ", password '" +
741                     tryPassword + "' - field data is '" + fieldData + "'");
742         }
743
744         String JavaDoc triedhash = hashEncodePassword(tryPassword);
745
746         if (log.isDebugEnabled()) {
747             log.debug("Password hashed is " + triedhash + "'");
748         }
749         if (triedhash.equals(fieldData)) {
750             return true;
751         } else {
752             if (log.isDebugEnabled()) {
753                 log.debug("Hash doesn't equal data - trying plaintext");
754             }
755             //The second compare check is to make sure somebody isn't just
756
//replaying a snooped password and attempting to use it against
757
//us. If Password.length() == 28 then it's a hash.
758
if (tryPassword.equals(fieldData) && fieldData.length() < 20) {
759                 if (log.isDebugEnabled()) {
760                     log.debug("Password matches in plain text - hashing & writing to DB");
761                 }
762
763                 setPassword(hashEncodePassword(fieldData));
764                 update();
765
766                 return true;
767             } else {
768
769                 //No Match
770
if (log.isDebugEnabled()) {
771                     log.debug("Password doesn't equal plain text either ('" +
772                             tryPassword + "' <> '" + fieldData +
773                             "') or field data is over 20 characters");
774                 }
775
776                 return false;
777             }
778         }
779     } /* passwordEquals(String) */
780
781
782     /**
783      * Called by the various objects that can log in a user
784      * to do post-login tasks
785      */

786     public void postLogin()
787             throws DBException, LogException {
788         UserGroup oneGroup = new UserGroup(SecuredDBObject.SYSTEM_ACCOUNT);
789         oneGroup.setDataContext(getDataContext());
790
791         String JavaDoc theEvent = null;
792         Hashtable JavaDoc allEvents = new Hashtable JavaDoc(1);
793         String JavaDoc oneGroupName = null;
794
795         for (Enumeration JavaDoc gl = getGroups().elements(); gl.hasMoreElements();) {
796             oneGroupName = (String JavaDoc) gl.nextElement();
797             oneGroup.clear();
798             oneGroup.setField("GroupName", oneGroupName);
799
800             if (oneGroup.find()) {
801                 theEvent = oneGroup.getField("LoginEvent");
802
803                 if (!theEvent.equals("")) {
804                     allEvents.put(theEvent, oneGroup.getField("GroupName"));
805                 }
806             } /* if the group exists */
807
808         } /* for each group user is a member of */
809
810
811         /* if any events need to be triggered... */
812         String JavaDoc theMessage = null;
813
814         if (allEvents.size() > 0) {
815             for (Enumeration JavaDoc el = allEvents.keys(); el.hasMoreElements();) {
816                 theEvent = (String JavaDoc) el.nextElement();
817                 theMessage = ("User " + getLoginName() + " (" +
818                         getFullName() + ") who is a member " +
819                         " of group " +
820                         (String JavaDoc) allEvents.get(theEvent) +
821                         " has just logged in.");
822                 EventHandler.Event(getDataContext(), theEvent, theMessage, true);
823             } /* for each event */
824
825         } /* if any events to be triggered */
826
827     } /* postLogin() */
828
829
830     /**
831      * @return a random generated password
832      */

833     public String JavaDoc randomPassword() {
834         int passwordLength;
835         int iterations = 0;
836
837         //
838
//Read the property value of minimum password length
839
//
840
String JavaDoc propValue = null;
841
842         try {
843             propValue = StringUtil.notNull(ConfigManager.getContext(getDataContext()).getMinPasswordSize());
844         } catch (ConfigurationException ce) {
845             throw new IllegalArgumentException JavaDoc(ce.getMessage());
846         }
847         if (!propValue.equals("")) {
848             try {
849                 passwordLength = Integer.parseInt(propValue, 10);
850             } catch (NumberFormatException JavaDoc ex) {
851
852                 //Bad number
853
passwordLength = 6;
854             }
855         } else {
856             passwordLength = 6;
857         }
858         FastStringBuffer newPassword = new FastStringBuffer(passwordLength);
859
860         /////////////////////////////////
861
//
862
//Now Generate the new password. (Code from servlet.RegisterUser) before)
863
//
864
//Get 400 bytes worth of
865
//Modified: Fill an array of 200 possible numbers. This is our previous max
866
//tries anyway. Then try those in the array. Saves many allocations,
867
//and more importantly, provides a true random number source.
868
byte[] possibleNumbers;
869
870         try {
871             possibleNumbers = CryptoManager.getInstance().getRandomGenerator().getRandomBytes(200);
872         } catch (ChainedException e) {
873             possibleNumbers = new byte[200];
874
875             //If an error occurs, just fill it with Math.random() after logging the
876
//exception.
877
Logger.getLogger("com.jcorporate.expresso.core.security.").error("Random Password", e);
878
879             for (int i = 0; i < 200; i++) {
880                 possibleNumbers[i] = (byte) (Math.random() * 122);
881             }
882         }
883         while ((newPassword.length() < passwordLength) && (iterations < 200)) {
884             iterations++;
885
886             //oneNumber = Math.random() * 122;
887
if (okNumber(possibleNumbers[iterations])) {
888                 newPassword.append((char) possibleNumbers[iterations]);
889             }
890         }
891
892         return newPassword.toString();
893     } /* randomPassword() */
894
895     /**
896      * Sends an Authorization Email to a new User.
897      * The user must click on the link encoded in this email before
898      * his account will be activated.
899      */

900     public void sendAuthEmail()
901             throws DBException {
902         try {
903             String JavaDoc dbContext = getDataContext();
904             String JavaDoc authURL = Setup.getValue(dbContext, "EmailValidateURL");
905             String JavaDoc emailAuthCode = getEmailAuthCode();
906             this.setField(VALIDATION_CODE, emailAuthCode);
907             this.update();
908             authURL = authURL + "?UserName=" + getField(LOGIN) + "&db=" +
909                     getDataContext() + "&EmailAuthCode=" + emailAuthCode;
910
911             String JavaDoc subject = "New Account Validation - Please Respond";
912             FastStringBuffer sb = new FastStringBuffer(512);
913
914             if (!"".equals(getFullName())) {
915                 sb.append("Dear " + getFullName() + ",");
916             }
917
918             sb.append("\n");
919             sb.append("\n");
920             sb.append("Thank you for registering");
921
922             String JavaDoc companyName = Setup.getValue(dbContext, "CompanyName");
923             String JavaDoc homePageURL = Setup.getValue(dbContext, "HomePageURL");
924
925             if (companyName != null && !"".equals(companyName)) {
926                 sb.append(" with " + companyName);
927             }
928             if (homePageURL != null && !"".equals(homePageURL)) {
929                 sb.append(" at " + homePageURL);
930             }
931
932             sb.append("!");
933             sb.append("\n");
934             sb.append("\n");
935             sb.append("Your account has been successfully created. " +
936                     "The final step in the");
937             sb.append("\n");
938             sb.append("registration process is to simply follow the link " +
939                     "below to let us");
940             sb.append("\n");
941             sb.append("know that you received this message. You must follow " +
942                     "the link below");
943             sb.append("\n");
944             sb.append("before your account will be activated.");
945             sb.append("\n");
946             sb.append("\n");
947             sb.append("NOTE: If you did not register, you may safely");
948             sb.append("\n");
949             sb.append("ignore this message.");
950             sb.append("\n");
951             sb.append("\n");
952             sb.append("In many email clients, you may simply click on the " +
953                     "link below to");
954             sb.append("\n");
955             sb.append("complete the registration process. If your email " +
956                     "client does not");
957             sb.append("\n");
958             sb.append("support this, cut-and-paste the link below into your " +
959                     "web browser's");
960             sb.append("\n");
961             sb.append("\"Location\" window:");
962             sb.append("\n");
963             sb.append("\n");
964             sb.append(authURL);
965             sb.append("\n");
966             sb.append("\n");
967
968             if (companyName != null && !"".equals(companyName)) {
969                 sb.append("Thank you from all of us at " + companyName + ".");
970             }
971
972             sb.append("\n");
973
974             if (companyName != null && !"".equals(homePageURL)) {
975                 sb.append(homePageURL);
976             }
977
978             sb.append("\n");
979
980             String JavaDoc message = sb.toString();
981             notify(subject, message);
982         } catch (Exception JavaDoc e) {
983             throw new DBException("Error in sending account verification message to " +
984                     getField(FULL_NAME) + " at " + getField(EMAIL_ADDRESS) + ": " +
985                     e.toString());
986         }
987     } /* sendAuthEmail() */
988
989
990     /**
991      * Send this user an e-mail with file attachments.
992      *
993      * @param subject Subject of the e-mail
994      * @param message Message to send in body of e-mail
995      * @param fileNames of the files to attach
996      * @throws DBException If the mail message cannot be sent
997      */

998     public void sendFileTo(String JavaDoc subject, String JavaDoc message, Vector JavaDoc fileNames)
999             throws DBException, LogException {
1000        log.info("Sending " + fileNames.size() + " files via e-mail to " +
1001                getField(LOGIN));
1002
1003        String JavaDoc sendToUser = getField(EMAIL_ADDRESS);
1004
1005        try { // create some properties and get the default Session
1006
EMailSender ems = new EMailSender();
1007            ems.setDBName(getDataContext());
1008            ems.addFileAttachments(fileNames);
1009            ems.send(sendToUser, subject, message);
1010        } catch (Exception JavaDoc e) {
1011            throw new DBException("Error sending e-mail", e);
1012        }
1013    } /* sendFileTo(String, String, Vector) */
1014
1015
1016    /**
1017     * Once a user has validated his email address through the email validation
1018     * servlet, the user will receive this message giving previously requested
1019     * username/password.
1020     * <p/>
1021     * Creation date: (8/8/00 11:44:26 PM)
1022     * author Adam Rossi, PlatinumSolutions, Inc.
1023     *
1024     * @throws com.jcorporate.expresso.core.db.DBException
1025     * The exception description.
1026     */

1027    public void sendFollowUpEmail()
1028            throws DBException {
1029        try {
1030            String JavaDoc subject = "New Registration Complete - Welcome!";
1031            String JavaDoc dbContext = getDataContext();
1032
1033            // We can't retrieve the passsword in plain text to transmit to the user
1034
// So we just create and set a new passord and send that over.
1035
String JavaDoc password = this.randomPassword();
1036            this.setPassword(password);
1037            this.update();
1038
1039            FastStringBuffer sb = new FastStringBuffer(512);
1040
1041            if (!"".equals(getFullName())) {
1042                sb.append("Dear " + getFullName() + ",");
1043            }
1044
1045            sb.append("\n");
1046            sb.append("\n");
1047            sb.append("Thank you for registering");
1048
1049            String JavaDoc companyName = Setup.getValue(dbContext, "CompanyName");
1050            String JavaDoc homePageURL = Setup.getValue(dbContext, "HomePageURL");
1051
1052            if (companyName != null && !"".equals(companyName)) {
1053                sb.append(" with " + companyName);
1054            }
1055            if (homePageURL != null && !"".equals(homePageURL)) {
1056                sb.append(" at " + homePageURL);
1057            }
1058
1059            sb.append("!");
1060            sb.append("\n");
1061            sb.append("\n");
1062            sb.append("Your account is now active. Below is the information " +
1063                    "you will need to log in.");
1064            sb.append("\n");
1065            sb.append("Please keep this information in a safe place.We hope " +
1066                    "you enjoy the site and");
1067            sb.append("\n");
1068            sb.append("look forward to your participation.");
1069            sb.append("\n");
1070            sb.append("\n");
1071            sb.append("Login Name: " + getLoginName());
1072            sb.append("\n");
1073            sb.append("Password: " + password);
1074            sb.append("\n");
1075            sb.append("\n");
1076
1077            if (companyName != null && !"".equals(companyName)) {
1078                sb.append("Thank you from all of us at " + companyName + ".");
1079            }
1080
1081            sb.append("\n");
1082
1083            if (companyName != null && !"".equals(homePageURL)) {
1084                sb.append(homePageURL);
1085            }
1086
1087            sb.append("\n");
1088
1089            String JavaDoc message = sb.toString();
1090            notify(subject, message);
1091        } catch (Exception JavaDoc e) {
1092            throw new DBException("Error in sending account verification follow up message to " +
1093                    getLoginName() + " at " + getEmail() + ": " +
1094                    e.toString());
1095        }
1096    } /* sendFollowUpEmail() */
1097
1098
1099    public void setAccountStatus(String JavaDoc accountStatus)
1100            throws DBException {
1101        setField(ACCOUNT_STATUS, accountStatus);
1102    } /* setAccountStatus(String) */
1103
1104
1105    public void setEmail(String JavaDoc email)
1106            throws DBException {
1107        setField(EMAIL_ADDRESS, email);
1108    } /* setEmail(String) */
1109
1110
1111    public void setEmailValCode(String JavaDoc code)
1112            throws DBException {
1113        setField(VALIDATION_CODE, code);
1114    } /* setEmailValCode(String) */
1115
1116
1117    public void setLoginName(String JavaDoc loginName)
1118            throws DBException {
1119        setField(LOGIN, loginName);
1120    } /* setLoginName(String) */
1121
1122
1123    public void setPassword(String JavaDoc password)
1124            throws DBException {
1125        setField(PASSWORD, password);
1126    } /* setPassword(String) */
1127
1128
1129    public void setRegComplete(boolean status)
1130            throws DBException {
1131        String JavaDoc statusString = "N";
1132
1133        if (status) {
1134            statusString = "Y";
1135        }
1136
1137        setField(IS_REG_COMPLETE, statusString);
1138    } /* setRegistrationComplete(String) */
1139
1140
1141    public void setRegistrationDomain(String JavaDoc domain)
1142            throws DBException {
1143        RegistrationDomain rd = new RegistrationDomain();
1144        rd.setDataContext(getDataContext());
1145        rd.setField("Name", domain);
1146
1147        if (rd.find()) {
1148            setField(REGISTRATION_DOMAIN, rd.getField(REGISTRATION_DOMAIN));
1149        } else {
1150            throw new DBException("Registration domain \"" + domain +
1151                    "\" has not been defined.");
1152        }
1153    } /* setRegistrationDomain(String) */
1154
1155
1156    /**
1157     * @see com.jcorporate.expresso.core.dbobj.SecuredDBObject#setupFields
1158     */

1159    public void setupFields()
1160            throws DBException {
1161        setTargetTable("USERSTABLE");
1162        setDescription("DBuser");
1163        setCharset("ISO-8859-1");
1164        addField(EXPUID, DBField.AUTOINC_TYPE, 0, false, "userId");
1165        addField(LOGIN, DBField.CHAR_TYPE, LOGIN_LENGTH, false, "userLogin");
1166        addField(PASSWORD, DBField.VARCHAR_TYPE, PASSWORD_LENGTH, true, "password");
1167        addField(EMAIL_ADDRESS, DBField.VARCHAR_TYPE, EMAIL_ADDRESS_LENGTH, false, "email");
1168        addField(REGISTRATION_DOMAIN, DBField.INTEGER_TYPE, 0, false, "RegDomainId");
1169        addField(ACCOUNT_STATUS, DBField.CHAR_TYPE, 1, false, "isActive");
1170        addField(IS_REG_COMPLETE, DBField.CHAR_TYPE, 1, false, "RegComplete");
1171        addField(CREATED_DATE, DBField.DATETIME_TYPE, 0, false, "accountCreation");
1172        addField(UPDATED_DATE, DBField.DATETIME_TYPE, 0, false, "accountUpdate");
1173        addField(VALIDATION_CODE, DBField.VARCHAR_TYPE, VALIDATION_CODE_LENGTH, true, "validationCode");
1174        addField(FULL_NAME, DBField.VARCHAR_TYPE, FULL_NAME_LENGTH, true, "userFullName");
1175
1176        //Set up the string filters.
1177
setStringFilter(LOGIN, "stripFilter");
1178
1179        //Nobody should even put special characters here
1180
setStringFilter(FULL_NAME, "stripFilter");
1181
1182        //Nobody should even put special characters here
1183
setStringFilter(EMAIL_ADDRESS, "stripFilter");
1184
1185        //Nobody should even put special characters here
1186
setStringFilter(PASSWORD, "rawFilter");
1187
1188        //Must all all characters through or Password gets mucked up.
1189
setStringFilter(FULL_NAME, "rawFilter");
1190
1191        //The default for the field anyway, but included for completeness' sake
1192
setStringFilter(VALIDATION_CODE, "stripFilter");
1193
1194        addKey(EXPUID);
1195        setSecret(PASSWORD);
1196        setSecret(VALIDATION_CODE);
1197        setMultiValued(ACCOUNT_STATUS);
1198        setMultiValued(IS_REG_COMPLETE);
1199        setMultiValued(REGISTRATION_DOMAIN);
1200        setLookupObject(REGISTRATION_DOMAIN, RegistrationDomain.class.getName());
1201
1202        setReadOnly(CREATED_DATE);
1203        setReadOnly(UPDATED_DATE);
1204        addIndex("LoginNames", LOGIN, true);
1205        addIndex("EMails", EMAIL_ADDRESS, false);
1206        addIndex("Acct_status_idx", ACCOUNT_STATUS, false);
1207        addDetail(GroupMembers.class.getName(), EXPUID, GroupMembers.EXPUID);
1208    } /* setupFields() */
1209
1210
1211    public void setUserName(String JavaDoc name)
1212            throws DBException {
1213        setField(FULL_NAME, name);
1214    } /* setUserName(String) */
1215
1216
1217    /**
1218     * Override of add to check for duplicate emails, and handle empty fields
1219     *
1220     * @throws DBException upon error
1221     */

1222    public void update()
1223            throws DBException {
1224        setCheckZeroUpdate(false);
1225
1226        checkEmailAddrAlreadyUsed(IS_UPDATE);
1227
1228        if (getField(FULL_NAME).equals("")) {
1229            setField(FULL_NAME, getField(LOGIN));
1230        }
1231        // If a User is added without a status, we set the AccountStatus to "I"
1232
// for security reasons
1233
if (getField(ACCOUNT_STATUS).equals("")) {
1234            setField(ACCOUNT_STATUS, "I");
1235        }
1236        // Set the registration domain id
1237
if (getRegistrationDomain().equals("")) {
1238            setRegistrationDomain("default");
1239        }
1240
1241        RegistrationDomain rd = new RegistrationDomain();
1242        rd.setDataContext(getDataContext());
1243        rd.setField("Name", getRegistrationDomain());
1244
1245        if (!rd.find()) {
1246            throw new DBException("Regsitration domain \"" +
1247                    getRegistrationDomain() +
1248                    "\" has not been defined");
1249        }
1250
1251        setField(REGISTRATION_DOMAIN, rd.getField(REGISTRATION_DOMAIN));
1252
1253        // Check value of registration valid flag
1254
if (getField(IS_REG_COMPLETE).equals("")) {
1255            setField(IS_REG_COMPLETE, "N");
1256        }
1257        // We should always have a CreateDate
1258
if (getField(CREATED_DATE).equals("")) {
1259            setField(CREATED_DATE, DateTime.getDateTimeForDB(this.getDataContext()));
1260        }
1261
1262        // touch update date
1263
setField(UPDATED_DATE, DateTime.getDateTimeForDB(this.getDataContext()));
1264
1265        super.update();
1266
1267
1268        User user = new User();
1269        user.setDataContext(this.getDataContext());
1270        user.updateNotify(this);
1271
1272    }
1273
1274    /**
1275     * Check that another user with same email doesn't exist already
1276     *
1277     * @param isUpdate boolean for true = update case, false = 'add' case
1278     */

1279    private void checkEmailAddrAlreadyUsed(boolean isUpdate) throws DBException {
1280
1281        // If this site uses email as login name, force login name equal to email
1282
boolean useEmailAsLogin = false;
1283
1284        try {
1285            useEmailAsLogin = ConfigManager.getContext(getDataContext()).useEmailAsLogin();
1286        } catch (ConfigurationException ce) {
1287            throw new DBException(ce);
1288        }
1289
1290        if (isUpdate) {
1291            // update case may be shortcircuited, thus requiring no db access
1292
String JavaDoc onlychanged = Setup.getValueUnrequired(getDataContext(), UPDATE_CHANGED_ONLY);
1293            if (StringUtil.toBoolean(onlychanged)) {
1294                // ok, setting says that this app only updates the field which are changed
1295
// if email/login not changed, don't waste time checking for whether they are unique
1296
if (getDataField(EMAIL_ADDRESS).isChanged() || (!useEmailAsLogin && getDataField(LOGIN).isChanged())) {
1297                    // go on through tests below
1298
} else {
1299                    return; // shortcircuit tests--fields haven't changed
1300
}
1301            }
1302        }
1303
1304        if (!getField(EMAIL_ADDRESS).equalsIgnoreCase("none")) {
1305            UserInfo anotherUser = new User().getUserInfo();
1306            anotherUser.setDBName(getDataContext());
1307            anotherUser.setEmail(getField(EMAIL_ADDRESS));
1308
1309            boolean foundEmail = anotherUser.find();
1310            if (foundEmail && isUpdate && (anotherUser.getUid() != getUid())) {
1311                // update case: must also be diff. uid
1312
throw new DBException("Another user with the same email address \"" +
1313                        getField(EMAIL_ADDRESS) + "\" already exists");
1314            } else if (foundEmail && !isUpdate) {
1315                // add case--just finding another with this email is enough to throw
1316
throw new DBException("Another user with the same email address \"" +
1317                        getField(EMAIL_ADDRESS) + "\" already exists");
1318
1319            }
1320        }
1321
1322        if (useEmailAsLogin) {
1323            if (getField(LOGIN).equals("")) {
1324                setField(LOGIN, getField(EMAIL_ADDRESS));
1325            }
1326        } else {
1327
1328            // This site has separate login name, make sure same login name doesn't exist already
1329
UserInfo anotherUser = new User().getUserInfo();
1330            anotherUser.setDBName(getDataContext());
1331            anotherUser.setLoginName(getField(LOGIN));
1332            boolean foundLogin = anotherUser.find();
1333
1334            if (!isUpdate && foundLogin) {
1335                throw new DBException("Another user with the same login \"" +
1336                        getField(LOGIN) +
1337                        "\" already exists");
1338            } else if (isUpdate && foundLogin && (anotherUser.getUid() != getUid())) {
1339                throw new DBException("Another user with the same login \"" +
1340                        getField(LOGIN) +
1341                        "\" already exists");
1342            }
1343        }
1344    }
1345
1346    /**
1347     * Override to provide better performance. We cache recently used LoginNames
1348     * into a cache. If we find the appropriate loginname, then
1349     * we map the uid so that subsequent find() will perform a retrieve() so we can utilize the
1350     * cache instead.
1351     *
1352     * @return true if successfully found the object
1353     * @throws DBException if there's an error performing the find.
1354     */

1355    public boolean find() throws com.jcorporate.expresso.core.db.DBException {
1356
1357        // case where UID is known means no caching
1358
if (this.getField(EXPUID).length() > 0) {
1359            boolean returnValue = super.find();
1360            return returnValue; // used UID so we already hit any dbobject cache during find()
1361
}
1362
1363        // if we have a login name, try to find user from cache
1364
if (getLoginName().length() > 0) {
1365
1366            String JavaDoc keyString = getName2IdCacheKey();
1367            try {
1368                Cache cache = getName2IdCache();
1369                CachedObject c = (CachedObject) cache.getItem(keyString);
1370                if (c != null) {
1371                    Integer JavaDoc cachedUID = (Integer JavaDoc) c.getValue();
1372                    this.setUid(cachedUID.intValue());
1373                    try {
1374                        this.retrieve();
1375
1376                        // success!
1377
return true;
1378                    } catch (com.jcorporate.expresso.core.db.exception.DBRecordNotFoundException e) {
1379                        // log error
1380
log.error("Error retrieving user from uid found in cache", e);
1381                        // and try again below
1382
}
1383                }
1384            } catch (CacheException e) {
1385                log.error("Error retrieving from cache", e);
1386                // and try again below
1387
}
1388        }
1389
1390        // get here (in non-error case) when EXPID unknown, nor was any *cached* login name provided
1391
boolean returnValue = super.find();
1392        if (returnValue) {
1393            cacheUser(); // cache in case we search via loginname later
1394
}
1395        return returnValue;
1396
1397    } /* update() */
1398
1399    private void cacheUser() throws DBException {
1400        String JavaDoc keyString = getName2IdCacheKey();
1401        try {
1402            Cache cache = getName2IdCache();
1403            CachedObject c = (CachedObject) cache.getItem(keyString);
1404            if (c == null) {
1405                CachedObject co = new CachedObject(keyString, new Integer JavaDoc(this.getUid()));
1406                CacheSystem cs = CacheManager.getCacheSystem(this.getDataContext());
1407                cs.addItem(NAME_2_ID_CACHE_NAME, co, 1000 * 60 * 10); //10 minute cache;
1408
}
1409        } catch (CacheException e) {
1410            log.error("Error adding to cache", e);
1411        }
1412    }
1413
1414    /**
1415     * @return cache; never null
1416     */

1417    private Cache getName2IdCache() throws CacheException {
1418        CacheSystem cs = CacheManager.getCacheSystem(this.getDataContext());
1419        Cache cache = cs.getCache(NAME_2_ID_CACHE_NAME);
1420        if (cache == null) {
1421            cache = cs.createCache(NAME_2_ID_CACHE_NAME, false, 20);
1422            cs.addListener(NAME_2_ID_CACHE_NAME, this.getClass().getName());
1423        }
1424        return cache;
1425    }
1426
1427    /**
1428     * @return key made from context + name
1429     * @todo use faststrbuf pool
1430     */

1431    private String JavaDoc getName2IdCacheKey() throws DBException {
1432        FastStringBuffer key = new FastStringBuffer(16);
1433        key.append(this.getDataContext());
1434        key.append(".");
1435        key.append(this.getLoginName());
1436        String JavaDoc keyString = key.toString();
1437        return keyString;
1438    }
1439
1440    /**
1441     * the primary group of this user is appropriate for unix-like purposes,
1442     * such as setting the group for a file permission
1443     *
1444     * @return name of the primary group of this user; null if no group is found
1445     * @throws DBException upon database access error
1446     */

1447    public String JavaDoc getPrimaryGroup()
1448            throws DBException {
1449        return getPrimaryGroup(this);
1450    }
1451
1452    /**
1453     * the primary group of this user is appropriate for unix-like purposes,
1454     * such as setting the group for a file permission
1455     *
1456     * @param user The userInfo object to query
1457     * @return name of the primary group of this user; null if no group is primary
1458     * @throws DBException upon database access error
1459     */

1460    public static String JavaDoc getPrimaryGroup(UserInfo user) throws DBException {
1461        UserGroup primary = null;
1462
1463        UserPreference pref = new UserPreference();
1464        pref.setDataContext(user.getDataContext());
1465        pref.setField(UserPreference.PREF_CODE, UserPreferenceDef.PRIMARY_GROUP_PREF);
1466        pref.setField(UserPreference.CLASS_NAME, UserPreferenceDef.ANY_CLASS);
1467        pref.setField(UserPreference.EXPUID, user.getUid());
1468        if (!pref.find()) {
1469
1470            // if none marked as primary, use first group in membership list
1471
Vector JavaDoc groupNames = user.getGroups();
1472            if (groupNames.size() > 0) {
1473                primary = new UserGroup();
1474                primary.setDataContext(user.getDataContext());
1475                primary.setField(UserGroup.GROUP_NAME_FIELD,
1476                        (String JavaDoc) groupNames.get(0));
1477                if (!primary.find()) {
1478                    primary = null;
1479                }
1480            }
1481        } else {
1482            // have preference; we expect this to be a real group
1483
String JavaDoc primStr = pref.getField(UserPreference.PREF_VALUE);
1484            primary = new UserGroup();
1485            primary.setDataContext(user.getDataContext());
1486            primary.setField(UserGroup.GROUP_NAME_FIELD, primStr);
1487            if (!primary.find()) {
1488                // unexpected
1489
throw new DBException("cannot locate primary group: "
1490                        + primStr + " which is specified for user: "
1491                        + user.getLoginName());
1492            }
1493        }
1494
1495        if (primary == null) {
1496            return null;
1497        } else {
1498            return primary.getField(UserGroup.GROUP_NAME_FIELD);
1499        }
1500    }
1501
1502    /**
1503     * set the primary group of this user. primary group is appropriate for
1504     * unix-like purposes, such as setting the group for a file permission
1505     *
1506     * @param group The UserGroup object to use.
1507     * @throws DBException upon database access error
1508     */

1509    public void setPrimaryGroup(UserGroup group) throws DBException {
1510        UserPreference pref = new UserPreference();
1511        pref.setDataContext(this.getDataContext());
1512        pref.setField(UserPreference.PREF_CODE, UserPreferenceDef.PRIMARY_GROUP_PREF);
1513        pref.setField(UserPreference.CLASS_NAME, UserPreferenceDef.ANY_CLASS);
1514        pref.setField(UserPreference.EXPUID, this.getUid());
1515        pref.setField(UserPreference.PREF_VALUE, group.getGroupName());
1516        pref.addOrUpdate();
1517    }
1518} /* UserDBObj */
1519
Popular Tags