KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jcorporate > expresso > ext > dbobj > SingleDBUserInfo


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.ext.dbobj;
66
67 import com.jcorporate.expresso.core.controller.ControllerRequest;
68 import com.jcorporate.expresso.core.db.DBException;
69 import com.jcorporate.expresso.core.dbobj.SecuredDBObject;
70 import com.jcorporate.expresso.core.dbobj.ValidValue;
71 import com.jcorporate.expresso.core.logging.LogException;
72 import com.jcorporate.expresso.core.misc.Base64;
73 import com.jcorporate.expresso.core.misc.ConfigManager;
74 import com.jcorporate.expresso.core.misc.ConfigurationException;
75 import com.jcorporate.expresso.core.misc.DateTime;
76 import com.jcorporate.expresso.core.misc.EMailSender;
77 import com.jcorporate.expresso.core.misc.EventHandler;
78 import com.jcorporate.expresso.core.misc.StringUtil;
79 import com.jcorporate.expresso.core.security.CryptoManager;
80 import com.jcorporate.expresso.core.security.User;
81 import com.jcorporate.expresso.core.security.UserInfo;
82 import com.jcorporate.expresso.kernel.exception.ChainedException;
83 import com.jcorporate.expresso.services.dbobj.DefaultUserInfo;
84 import com.jcorporate.expresso.services.dbobj.GroupMembers;
85 import com.jcorporate.expresso.services.dbobj.RegistrationDomain;
86 import com.jcorporate.expresso.services.dbobj.Setup;
87 import com.jcorporate.expresso.services.dbobj.UserGroup;
88 import org.apache.log4j.Logger;
89
90 import java.util.Date JavaDoc;
91 import java.util.Enumeration JavaDoc;
92 import java.util.Hashtable JavaDoc;
93 import java.util.Iterator JavaDoc;
94 import java.util.Vector JavaDoc;
95
96
97 /**
98  * @author Michael Nash
99  * @deprecated 10/4/2004 functionality can be handled by DefaultUserInfo with DBOTHERMAP
100  * method to map a table to a context
101  */

102 public class SingleDBUserInfo
103         extends SecuredDBObject
104         implements UserInfo {
105     /**
106      * Field name for full name.
107      */

108     public static final String JavaDoc FULL_NAME = "UserName";
109
110     private static final String JavaDoc thisClass = SingleDBUserInfo.class.getName();
111     private static Logger log = Logger.getLogger(SingleDBUserInfo.class);
112     private boolean noConfig = false;
113     private static String JavaDoc noConfigMessage = "Unable to read userContext custom property - can't use SingleDBUserInfo";
114
115     public void setUid(String JavaDoc uid)
116             throws DBException {
117         StringUtil.assertNotBlank(uid, "Can't set a blank UID");
118         setField("ExpUid", uid);
119     } /* setUid(String) */
120
121
122     public void setUid(int uid)
123             throws DBException {
124         setField("ExpUid", uid);
125     }
126
127     public void setDBName() {
128         setFixedDBName();
129     }
130
131     public String JavaDoc getDataContext() {
132         setFixedDBName();
133
134         return super.getDataContext();
135     }
136
137     public SingleDBUserInfo()
138             throws DBException {
139         super();
140     } /* SingleDBUserInfo() */
141
142     /**
143      * Use over (String) constructor. Initializes the object in the context
144      * of the user who's uid belongs to the parameter.
145      *
146      * @param uid the Uid of the user context
147      * @throws DBException if there's an initialization problem
148      */

149     public SingleDBUserInfo(int uid)
150             throws DBException {
151         super(uid);
152     }
153
154     /**
155      * For using DBObjects within Controllers. Initializes based upon the current
156      * user and the requested db. [Of course this can be modified later]
157      *
158      * @param request - The controller request handed to you by the framework.
159      */

160     public SingleDBUserInfo(ControllerRequest request)
161             throws DBException {
162         super(request);
163     }
164
165     private void setFixedDBName() {
166         try {
167             String JavaDoc newDBName = StringUtil.notNull(ConfigManager.getContext("default").getCustomProperty("userContext"));
168
169             if (newDBName.equals("")) {
170                 noConfig = true;
171
172                 return;
173             }
174
175             super.setDataContext(newDBName);
176         } catch (ConfigurationException ce) {
177             throw new IllegalArgumentException JavaDoc(ce.getMessage());
178         }
179     }
180
181     public void add()
182             throws DBException {
183         setFixedDBName();
184
185         if (noConfig) {
186             throw new DBException(noConfigMessage);
187         }
188
189         // Check that another user with same email doesn't exist already
190
SingleDBUserInfo anotherUser = new SingleDBUserInfo();
191
192         if (!getField("EMail").equalsIgnoreCase("none")) {
193             anotherUser.setDataContext(getDataContext());
194             anotherUser.setEmail(getField("EMail"));
195
196             if (anotherUser.find()) {
197                 throw new DBException("Another user with the same email address \"" +
198                         getField("EMail") + "\" already exists");
199             }
200         }
201
202         // If this site uses email as login name, force login name equal to email
203
boolean useEmailAsLogin = false;
204
205         try {
206             useEmailAsLogin = ConfigManager.getContext(getDataContext()).useEmailAsLogin();
207         } catch (ConfigurationException ce) {
208             throw new DBException(ce);
209         }
210         if (useEmailAsLogin) {
211             if (getField("LoginName").equals("")) {
212                 setField("LoginName", getField("EMail"));
213             }
214         } else {
215
216             // This site has separate login name, make sure same login name doesn't exist already
217
anotherUser.clear();
218             anotherUser.setDataContext(getDataContext());
219             anotherUser.setLoginName(getField("LoginName"));
220
221             if (anotherUser.find()) {
222                 throw new DBException("Another user with the same login \"" +
223                         getField("LoginName") +
224                         "\" already exists");
225             }
226         }
227         // At initial login, UserName == LoginName, Registation controllers can later modify this
228
if (getField("UserName").equals("")) {
229             setField("UserName", getField("LoginName"));
230         }
231         // If a User is added without a status, we set the AccountStatus to "I"
232
// for security reasons
233
if (getField("AccountStatus").equals("")) {
234             setField("AccountStatus", "I");
235         }
236         // Set the registration domain id
237
if (getRegistrationDomain().equals("")) {
238             setRegistrationDomain("default");
239         }
240
241         RegistrationDomain rd = new RegistrationDomain();
242         rd.setDataContext(getDataContext());
243         rd.setField("Name", getRegistrationDomain());
244
245         if (!rd.find()) {
246             throw new DBException("Registration domain \"" +
247                     getRegistrationDomain() +
248                     "\" has not been defined");
249         }
250
251         setField("RegDomId", rd.getField("RegDomId"));
252
253         // Check value of registration valid flag
254
if (getField("RegComplete").equals("")) {
255             setField("RegComplete", "N");
256         }
257         // We should always have a CreateDate
258
if (getField("CreateDate").equals("")) {
259             setField("CreateDate", DateTime.getDateTimeForDB(this.getDataContext()));
260         }
261         // We should always have a UpdateDate
262
if (getField("UpdateDate").equals("")) {
263             setField("UpdateDate", getField("CreateDate"));
264         }
265
266         super.add();
267         User user = new User();
268         user.setDataContext(this.getDataContext());
269         user.addNotify(this);
270     } /* add() */
271
272
273     /**
274      * Extends the checkAllRefs method to check for valid Registration Domain Id
275      *
276      * @throws DBException If a referential integrity violation is found
277      */

278     protected void checkAllRefs()
279             throws DBException {
280         checkRef("RegDomId", new RegistrationDomain(),
281                 "Invalid " + getString(getMetaData().getDescription("RegDomId")));
282     } /* checkAllRefs() */
283
284
285     public void delete()
286             throws DBException {
287         if (noConfig) {
288             throw new DBException(noConfigMessage);
289         }
290
291         User user = new User();
292         user.setDataContext(this.getDataContext());
293         user.deleteNotify(this);
294
295         super.delete();
296
297     } /* delete() */
298
299
300     public String JavaDoc getAccountStatus()
301             throws DBException {
302         return getField("AccountStatus");
303     } /* getAccountStatus() */
304
305
306     public Vector JavaDoc getAllUsers()
307             throws DBException {
308         return new Vector JavaDoc(searchAndRetrieveList("LoginName"));
309     } /* getAllUsers() */
310
311
312     public String JavaDoc getCreateDate()
313             throws DBException {
314         return getField("CreateDate");
315     } /* getCreateDate() */
316
317
318     public String JavaDoc getEmail()
319             throws DBException {
320         return getField("EMail");
321     } /* getEmail() */
322
323
324     public String JavaDoc getEmailAuthCode()
325             throws DBException {
326         Date JavaDoc createDate = getFieldDate("CreateDate");
327         long dateLong = createDate.getTime();
328         long emailAuthCode = Math.round(dateLong * 1.71);
329
330         return Long.toString(emailAuthCode);
331     } /* getEmailAuthCode() */
332
333
334     public String JavaDoc getEmailValCode()
335             throws DBException {
336         return getField("EmailValCode");
337     } /* getEmailValCode() */
338
339
340     public Vector JavaDoc getGroups()
341             throws DBException {
342         Vector JavaDoc myGroups = new Vector JavaDoc(1);
343         GroupMembers memberList = new GroupMembers();
344         memberList.setDataContext(getDataContext());
345
346         GroupMembers oneMember = null;
347         memberList.setField("ExpUid", getUid());
348
349         if (log.isDebugEnabled()) {
350             log.debug("Getting groups for uid " + getUid() + ", login name " +
351                     getLoginName());
352         }
353         for (Iterator JavaDoc e = memberList.searchAndRetrieveList().iterator();
354              e.hasNext();) {
355             oneMember = (GroupMembers) e.next();
356             myGroups.addElement(oneMember.getField("GroupName"));
357
358             if (log.isDebugEnabled()) {
359                 log.debug("" + getUid() + " is a Member of group " +
360                         oneMember.getField("GroupName"));
361             }
362         }
363
364         /**
365          * back in the bad old days, we manually added the UserGroup.UNKNOWN_USERS_GROUP so that
366          * it appeared as though everyone was a member of this group. If your app depends on this old
367          * behavior, set the following Setup value to true.
368          String isAddUnknownUsersGroup = Setup.getValueUnrequired(getDataContext(), "AddUnknownUserGroup");
369          if (StringUtil.toBoolean(isAddUnknownUsersGroup))
370          myGroups.addElement(UserGroup.UNKNOWN_USERS_GROUP);
371          */

372
373         myGroups.addElement(UserGroup.UNKNOWN_USERS_GROUP);
374
375
376         if (log.isDebugEnabled()) {
377             log.debug("" + getUid() + " is a member of " + myGroups.size() +
378                     " groups");
379         }
380
381         return myGroups;
382     } /* getGroups() */
383
384
385     public String JavaDoc getLoginName()
386             throws DBException {
387         return getField("LoginName");
388     } /* getLoginName() */
389
390
391     public String JavaDoc getPassword()
392             throws DBException {
393         return getField("Passwd");
394     } /* getPassword() */
395
396
397     public boolean getRegComplete()
398             throws DBException {
399         String JavaDoc statusString = getField("RegComplete");
400         boolean status = false;
401
402         if (statusString.equals("Y")) {
403             status = true;
404         }
405
406         return status;
407     } /* getRegComplete() */
408
409
410     public String JavaDoc getRegistrationDomain()
411             throws DBException {
412         String JavaDoc domain = "default";
413         RegistrationDomain rd = new RegistrationDomain();
414         rd.setDataContext(getDataContext());
415         rd.setField("RegDomId", getField("RegDomId"));
416
417         if (rd.find()) {
418             domain = rd.getField("Name");
419         }
420
421         return domain;
422     } /* getRegistrationDomain() */
423
424
425     public int getUid()
426             throws DBException {
427         return getFieldInt("ExpUid");
428     } /* getUid() */
429
430
431     public String JavaDoc getUpdateDate()
432             throws DBException {
433         return getField("UpdateDate");
434     } /* getUpdateDate() */
435
436
437     /**
438      * get descriptive, full name
439      *
440      * @deprecated Since Expresso 5.5; use getFullName()
441      * instead to avoid confusion with login name
442      */

443     public String JavaDoc getUserName()
444             throws DBException {
445         return getField("UserName");
446     } /* getUserName() */
447
448     /**
449      * get descriptive, full name
450      */

451     public String JavaDoc getFullName()
452             throws DBException {
453         return getField(FULL_NAME);
454     } /* getUserName() */
455
456
457     /**
458      * @param fieldName The name of the field to get the valid values for
459      * @return java.util.Vector of ValidValue objects
460      * @throws com.jcorporate.expresso.core.db.DBException
461      * The exception description.
462      */

463     public synchronized Vector JavaDoc getValidValues(String JavaDoc fieldName)
464             throws DBException {
465
466         if ("AccountStatus".equals(fieldName)) {
467             Vector JavaDoc values = new Vector JavaDoc();
468             values.addElement(new ValidValue("A", "Active"));
469             values.addElement(new ValidValue("I",
470                     "Inactive Until Email Confirmation"));
471             values.addElement(new ValidValue("D", "Disabled"));
472             values.addElement(new ValidValue("W", "Waiting For Approval"));
473             values.addElement(new ValidValue("X",
474                     "Registration Denied By Administrator"));
475
476             return values;
477         } else if (fieldName.equals("RegComplete")) {
478             Vector JavaDoc rv = new Vector JavaDoc(2);
479             ValidValue rvv = new ValidValue("Y", "Complete");
480             rv.addElement(rvv);
481             rvv = new ValidValue("N", "Incomplete");
482             rv.addElement(rvv);
483
484             return rv;
485         }
486
487         return super.getValidValues(fieldName);
488     } /* getValidValues(String) */
489
490
491     /**
492      * hashEncodePassword: If passed a plaintext string > 0 bytes, then this
493      * function will SHA1 hash the password, then Base64 encode it and return it
494      * as a string.
495      * <p/>
496      * If the password is zero length, then it will simply return a zero length
497      * string also.
498      *
499      * @param plaintext - the password to process in this manner: <br>
500      * returnValue = Base64(SHA-1(plaintext))
501      * @return Base64-hash encoded password
502      */

503     public String JavaDoc hashEncodePassword(String JavaDoc plaintext) throws DBException {
504         String JavaDoc myName = (thisClass + "hashEncodePassword()");
505
506         if (plaintext == null) {
507             throw new DBException(myName + ": Password Must not be NULL");
508         }
509         if (plaintext.length() == 0) {
510             return plaintext;
511         }
512         try {
513             return Base64.encode(CryptoManager.getInstance().getStringHash().produceHash(plaintext.getBytes()));
514         } catch (Exception JavaDoc ex) {
515             throw new DBException(myName + ":Error hashing Password:" +
516                     " You may not have installed the" +
517                     " Cryptography Extensions Properly:", ex);
518         }
519     } /* hashEncodePassword(String) */
520
521
522     /**
523      * Send this user a notification via e-mail.
524      *
525      * @param subject Subject of the e-mail
526      * @param message Message to send in body of e-mail
527      * @throws DBException If the mail message cannot be sent
528      */

529     public void notify(String JavaDoc subject, String JavaDoc message)
530             throws DBException, LogException {
531         if (noConfig) {
532             throw new DBException(noConfigMessage);
533         }
534
535         String JavaDoc myName = (thisClass + "notify(String, String)");
536         log.info("Notifying user " + getField("ExpUid") + " of " + subject);
537
538         String JavaDoc sendToUser = getField("EMail");
539
540         try {
541             EMailSender ems = new EMailSender();
542             ems.setDBName(getDataContext());
543             ems.send(sendToUser, subject, message);
544         } catch (Exception JavaDoc e) {
545             throw new DBException(myName +
546                     ":Uncaught exception sending e-mail", e);
547         }
548     } /* notify(String, String) */
549
550
551     /**
552      * Check if the given number is in the range of letters and
553      * digits that we want to use for generating a password
554      * Previously in com.jcorporate.expresso.ext.servlet.RegisterUser.java
555      *
556      * @param x The byte to check if printable
557      * @return true if it is a printable ASCII character
558      */

559     private boolean okNumber(byte x) {
560         if ((x >= 65) && (x <= 90)) {
561             return true;
562         }
563         if ((x >= 48) && (x <= 57)) {
564             return true;
565         }
566         if ((x >= 97) && (x <= 122)) {
567             return true;
568         }
569
570         return false;
571     } /* okNumber(byte) */
572
573     /**
574      * passwordEquals - feed it a password and it will tell you if the hash of it
575      * matches the one on file.
576      * <p/>
577      * Also, for backwards compatability and some other issues, this function
578      * will also accept a plaintext version of the password if it is sitting in
579      * the database. However, if a plaintext match is encountered, then it will
580      * hash the password and re-write itself to the database record.
581      *
582      * @param tryPassword The value the user input for an attempted login.
583      * @return true if the compared password equals
584      */

585     public boolean passwordEquals(String JavaDoc tryPassword)
586             throws DBException {
587
588         if (tryPassword == null) {
589             throw new DBException(thisClass + ":tryPassword Must not be NULL");
590         }
591
592         String JavaDoc fieldData = getPassword();
593         String JavaDoc trieduser = getLoginName();
594
595         if (log.isDebugEnabled()) {
596             log.debug("Trying user " + trieduser + ", password '" +
597                     tryPassword + "' - field data is '" + fieldData + "'");
598         }
599
600         String JavaDoc triedhash = hashEncodePassword(tryPassword);
601
602         if (log.isDebugEnabled()) {
603             log.debug("Password hashed is " + triedhash + "'");
604         }
605         if (triedhash.equals(fieldData)) {
606             return true;
607         } else {
608             if (log.isDebugEnabled()) {
609                 log.debug("Hash doesn't equal data - trying plaintext");
610             }
611             //The second compare check is to make sure somebody isn't just
612
//replaying a snooped password and attempting to use it against
613
//us. If Password.length() == 28 then it's a hash.
614
if (tryPassword.equals(fieldData) && fieldData.length() < 20) {
615                 if (log.isDebugEnabled()) {
616                     log.debug("Password matches in plain text - hashing & writing to DB");
617                 }
618
619                 setPassword(hashEncodePassword(fieldData));
620                 update();
621
622                 return true;
623             } else {
624
625                 //No Match
626
if (log.isDebugEnabled()) {
627                     log.debug("Password doesn't equal plain text either ('" +
628                             tryPassword + "' <> '" + fieldData +
629                             "') or field data is over 20 characters");
630                 }
631
632                 return false;
633             }
634         }
635     } /* passwordEquals(String) */
636
637
638     /**
639      * Called by the various objects that can log in a user
640      * to do post-login tasks
641      */

642     public void postLogin()
643             throws DBException, LogException {
644         UserGroup oneGroup = new UserGroup(SecuredDBObject.SYSTEM_ACCOUNT);
645         oneGroup.setDataContext(getDataContext());
646
647         String JavaDoc theEvent = null;
648         Hashtable JavaDoc allEvents = new Hashtable JavaDoc(1);
649         String JavaDoc oneGroupName = null;
650
651         for (Enumeration JavaDoc gl = getGroups().elements(); gl.hasMoreElements();) {
652             oneGroupName = (String JavaDoc) gl.nextElement();
653             oneGroup.clear();
654             oneGroup.setField("GroupName", oneGroupName);
655
656             if (oneGroup.find()) {
657                 theEvent = oneGroup.getField("LoginEvent");
658
659                 if (!theEvent.equals("")) {
660                     allEvents.put(theEvent, oneGroup.getField("GroupName"));
661                 }
662             } /* if the group exists */
663
664         } /* for each group user is a member of */
665
666
667         /* if any events need to be triggered... */
668         String JavaDoc theMessage = null;
669
670         if (allEvents.size() > 0) {
671             for (Enumeration JavaDoc el = allEvents.keys(); el.hasMoreElements();) {
672                 theEvent = (String JavaDoc) el.nextElement();
673                 theMessage = ("User " + getLoginName() + " (" +
674                         getFullName() + ") who is a member " +
675                         " of group " +
676                         (String JavaDoc) allEvents.get(theEvent) +
677                         " has just logged in.");
678                 EventHandler.Event(getDataContext(), theEvent, theMessage, true);
679             } /* for each event */
680
681         } /* if any events to be triggered */
682
683     } /* postLogin() */
684
685
686     /**
687      * @return a new random generated password
688      */

689     public String JavaDoc randomPassword() {
690         int passwordLength;
691         StringBuffer JavaDoc newPassword = new StringBuffer JavaDoc("");
692         int iterations = 0;
693
694         //
695
//Read the property value of minimum password length
696
//
697
String JavaDoc propValue = null;
698
699         try {
700             propValue = StringUtil.notNull(ConfigManager.getContext(getDataContext()).getMinPasswordSize());
701         } catch (ConfigurationException ce) {
702             throw new IllegalArgumentException JavaDoc(ce.getMessage());
703         }
704         if (!propValue.equals("")) {
705             try {
706                 passwordLength = Integer.parseInt(propValue, 10);
707             } catch (NumberFormatException JavaDoc ex) {
708
709                 //Bad number
710
passwordLength = 6;
711             }
712         } else {
713             passwordLength = 6;
714         }
715
716         /////////////////////////////////
717
//
718
//Now Generate the new password. (Code from servlet.RegisterUser) before)
719
//
720
//Get 400 bytes worth of
721
//Modified: Fill an array of 200 possible numbers. This is our previous max
722
//tries anyway. Then try those in the array. Saves many allocations,
723
//and more importantly, provides a true random number source.
724
byte[] possibleNumbers;
725
726         try {
727             possibleNumbers = CryptoManager.getInstance().getRandomGenerator().getRandomBytes(200);
728         } catch (ChainedException e) {
729             possibleNumbers = new byte[200];
730
731             //If an error occurs, just fill it with Math.random() after logging the
732
//exception.
733
Logger.getLogger("com.jcorporate.expresso.core.security.").error("Random Password", e);
734
735             for (int i = 0; i < 200; i++) {
736                 possibleNumbers[i] = (byte) (Math.random() * 122);
737             }
738         }
739         while ((newPassword.length() < passwordLength) && (iterations < 200)) {
740             iterations++;
741
742             //oneNumber = Math.random() * 122;
743
if (okNumber(possibleNumbers[iterations])) {
744                 newPassword.append((char) possibleNumbers[iterations]);
745             }
746         }
747
748         return newPassword.toString();
749     } /* randomPassword() */
750
751     /**
752      * Sends an Authorization Email to a new User.
753      * The user must click on the link encoded in this email before
754      * his account will be activated.
755      */

756     public void sendAuthEmail()
757             throws DBException {
758         try {
759             String JavaDoc dbContext = getDataContext();
760             String JavaDoc authURL = Setup.getValue(dbContext, "EmailValidateURL");
761             String JavaDoc emailAuthCode = getEmailAuthCode();
762             this.setField("EmailValCode", emailAuthCode);
763             this.update();
764             authURL = authURL + "?UserName=" + getField("LoginName") + "&db=" +
765                     getDataContext() + "&EmailAuthCode=" + emailAuthCode;
766
767             String JavaDoc subject = "New Account Validation - Please Respond";
768             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
769
770             if (!"".equals(getFullName())) {
771                 sb.append("Dear " + getFullName() + ",");
772             }
773
774             sb.append("\n");
775             sb.append("\n");
776             sb.append("Thank you for registering");
777
778             String JavaDoc companyName = Setup.getValue(dbContext, "CompanyName");
779             String JavaDoc homePageURL = Setup.getValue(dbContext, "HomePageURL");
780
781             if (companyName != null && !"".equals(companyName)) {
782                 sb.append(" with " + companyName);
783             }
784             if (homePageURL != null && !"".equals(homePageURL)) {
785                 sb.append(" at " + homePageURL);
786             }
787
788             sb.append("!");
789             sb.append("\n");
790             sb.append("\n");
791             sb.append("Your account has been successfully created. " +
792                     "The final step in the");
793             sb.append("\n");
794             sb.append("registration process is to simply follow the link " +
795                     "below to let us");
796             sb.append("\n");
797             sb.append("know that you received this message. You must follow " +
798                     "the link below");
799             sb.append("\n");
800             sb.append("before your account will be activated.");
801             sb.append("\n");
802             sb.append("\n");
803             sb.append("NOTE: If you did not register, you may safely");
804             sb.append("\n");
805             sb.append("ignore this message.");
806             sb.append("\n");
807             sb.append("\n");
808             sb.append("In many email clients, you may simply click on the " +
809                     "link below to");
810             sb.append("\n");
811             sb.append("complete the registration process. If your email " +
812                     "client does not");
813             sb.append("\n");
814             sb.append("support this, cut-and-paste the link below into your " +
815                     "web browser's");
816             sb.append("\n");
817             sb.append("\"Location\" window:");
818             sb.append("\n");
819             sb.append("\n");
820             sb.append(authURL);
821             sb.append("\n");
822             sb.append("\n");
823
824             if (companyName != null && !"".equals(companyName)) {
825                 sb.append("Thank you from all of us at " + companyName + ".");
826             }
827
828             sb.append("\n");
829
830             if (companyName != null && !"".equals(homePageURL)) {
831                 sb.append(homePageURL);
832             }
833
834             sb.append("\n");
835
836             String JavaDoc message = sb.toString();
837             notify(subject, message);
838         } catch (Exception JavaDoc e) {
839             throw new DBException("Error in sending account verification message to " +
840                     getField("UserName") + " at " + getField("EMail") + ": " +
841                     e.toString());
842         }
843     } /* sendAuthEmail() */
844
845
846     /**
847      * Send this user an e-mail with file attachments.
848      *
849      * @param subject Subject of the e-mail
850      * @param message Message to send in body of e-mail
851      * @param fileNames of the files to attach
852      * @throws DBException If the mail message cannot be sent
853      */

854     public void sendFileTo(String JavaDoc subject, String JavaDoc message, Vector JavaDoc fileNames)
855             throws DBException, LogException {
856         String JavaDoc myName = (thisClass +
857                 "sendFileTo(String, String, String)");
858         log.info("Sending " + fileNames.size() + " files via e-mail to " +
859                 getField("LoginName"));
860
861         String JavaDoc sendToUser = getField("EMail");
862
863         try { // create some properties and get the default Session
864
EMailSender ems = new EMailSender();
865             ems.setDBName(getDataContext());
866             ems.addFileAttachments(fileNames);
867             ems.send(sendToUser, subject, message);
868         } catch (Exception JavaDoc e) {
869             throw new DBException(myName + ":Error sending e-mail", e);
870         }
871     } /* sendFileTo(String, String, Vector) */
872
873
874     /**
875      * Once a user has validated his email address through the email validation
876      * servlet, the user will receive this message giving previously requested
877      * username/password.
878      * <p/>
879      * Creation date: (8/8/00 11:44:26 PM)
880      * author: Adam Rossi, PlatinumSolutions, Inc.
881      *
882      * @throws com.jcorporate.expresso.core.db.DBException
883      * The exception description.
884      */

885     public void sendFollowUpEmail()
886             throws DBException {
887         try {
888             String JavaDoc subject = "New Registration Complete - Welcome!";
889             String JavaDoc dbContext = getDataContext();
890
891             // We can't retrieve the passsword in plain text to transmit to the user
892
// So we just create and set a new passord and send that over.
893
String JavaDoc password = this.randomPassword();
894             this.setPassword(password);
895             this.update();
896
897             StringBuffer JavaDoc sb = new StringBuffer JavaDoc();
898
899             if (!"".equals(getFullName())) {
900                 sb.append("Dear " + getFullName() + ",");
901             }
902
903             sb.append("\n");
904             sb.append("\n");
905             sb.append("Thank you for registering");
906
907             String JavaDoc companyName = Setup.getValue(dbContext, "CompanyName");
908             String JavaDoc homePageURL = Setup.getValue(dbContext, "HomePageURL");
909
910             if (companyName != null && !"".equals(companyName)) {
911                 sb.append(" with " + companyName);
912             }
913             if (homePageURL != null && !"".equals(homePageURL)) {
914                 sb.append(" at " + homePageURL);
915             }
916
917             sb.append("!");
918             sb.append("\n");
919             sb.append("\n");
920             sb.append("Your account is now active. Below is the information " +
921                     "you will need to log in.");
922             sb.append("\n");
923             sb.append("Please keep this information in a safe place.We hope " +
924                     "you enjoy the site and");
925             sb.append("\n");
926             sb.append("look forward to your participation.");
927             sb.append("\n");
928             sb.append("\n");
929             sb.append("Login Name: " + getLoginName());
930             sb.append("\n");
931             sb.append("Password: " + password);
932             sb.append("\n");
933             sb.append("\n");
934
935             if (companyName != null && !"".equals(companyName)) {
936                 sb.append("Thank you from all of us at " + companyName + ".");
937             }
938
939             sb.append("\n");
940
941             if (companyName != null && !"".equals(homePageURL)) {
942                 sb.append(homePageURL);
943             }
944
945             sb.append("\n");
946
947             String JavaDoc message = sb.toString();
948             notify(subject, message);
949         } catch (Exception JavaDoc e) {
950             throw new DBException("Error in sending account verification follow up message to " +
951                     getLoginName() + " at " + getEmail() + ": " +
952                     e.toString());
953         }
954     } /* sendFollowUpEmail() */
955
956
957     public void setAccountStatus(String JavaDoc accountStatus)
958             throws DBException {
959         setField("AccountStatus", accountStatus);
960     } /* setAccountStatus(String) */
961
962
963     public void setEmail(String JavaDoc email)
964             throws DBException {
965         setField("EMail", email);
966     } /* setEmail(String) */
967
968
969     public void setEmailValCode(String JavaDoc code)
970             throws DBException {
971         setField("EmailValCode", code);
972     } /* setEmailValCode(String) */
973
974
975     public void setLoginName(String JavaDoc loginName)
976             throws DBException {
977         setField("LoginName", loginName);
978     } /* setLoginName(String) */
979
980
981     public void setPassword(String JavaDoc password)
982             throws DBException {
983         setField("Passwd", password);
984     } /* setPassword(String) */
985
986
987     public void setRegComplete(boolean status)
988             throws DBException {
989         String JavaDoc statusString = "N";
990
991         if (status) {
992             statusString = "Y";
993         }
994
995         setField("RegComplete", statusString);
996     } /* setRegistrationComplete(String) */
997
998
999     public void setRegistrationDomain(String JavaDoc domain)
1000            throws DBException {
1001        RegistrationDomain rd = new RegistrationDomain();
1002        rd.setDataContext(getDataContext());
1003        rd.setField("Name", domain);
1004
1005        if (rd.find()) {
1006            setField("RegDomId", rd.getField("RegDomId"));
1007        } else {
1008            throw new DBException("Registration domain \"" + domain +
1009                    "\" has not been defined.");
1010        }
1011    } /* setRegistrationDomain(String) */
1012
1013
1014    /**
1015     * @see com.jcorporate.expresso.core.dbobj.SecuredDBObject#setupFields
1016     */

1017    public void setupFields()
1018            throws DBException {
1019        setTargetTable("USERSTABLE");
1020        setDescription("User Information - Single Database");
1021        setCharset("ISO-8859-1");
1022        addField("ExpUid", "auto-inc", 0, false, "User Id");
1023        addField("LoginName", "char", 30, false, "User Login Name");
1024        addField("Passwd", "varchar", 30, true, "Password");
1025        addField("EMail", "varchar", 80, false, "User E-mail Address");
1026        addField("RegDomId", "int", 0, false, "Registration Domain Id");
1027        addField("AccountStatus", "char", 1, false, "Is User Account Active?");
1028        addField("RegComplete", "char", 1, false,
1029                "Has User Completed Registration?");
1030        addField("CreateDate", "datetime", 0, false, "Account Creation Date");
1031        addField("UpdateDate", "datetime", 0, false, "Account Update Date");
1032        addField("EmailValCode", "varchar", 30, true,
1033                "Validation code for Email");
1034        addField(FULL_NAME, "varchar", 80, true, "User Full Name");
1035
1036        //Set up the string filters.
1037
setStringFilter("LoginName", "stripFilter");
1038
1039        //Nobody should even put special characters here
1040
setStringFilter("UserName", "stripFilter");
1041
1042        //Nobody should even put special characters here
1043
setStringFilter("EMail", "stripFilter");
1044
1045        //Nobody should even put special characters here
1046
setStringFilter("Passwd", "rawFilter");
1047
1048        //Must all all characters through or Password gets mucked up.
1049
setStringFilter("UserName", "rawFilter");
1050
1051        //The default for the field anyway, but included for completeness' sake
1052
setStringFilter("EmailValCode", "stripFilter");
1053
1054        //This only has HEX strings.. no special chars
1055
addKey("ExpUid");
1056        setSecret("Passwd");
1057        setSecret("EmailValCode");
1058        setMultiValued("AccountStatus");
1059        setMultiValued("RegComplete");
1060        setMultiValued("RegDomId");
1061        setLookupObject("RegDomId",
1062                "com.jcorporate.expresso.services.dbobj.RegistrationDomain");
1063        setReadOnly("CreateDate");
1064        setReadOnly("UpdateDate");
1065        this.addIndex("LoginNames", "LoginName", true);
1066        this.addIndex("EMails", "EMail", false);
1067        addDetail("com.jcorporate.expresso.services.dbobj.GroupMembers",
1068                "ExpUid", "ExpUid");
1069    } /* setupFields() */
1070
1071
1072    public void setUserName(String JavaDoc name)
1073            throws DBException {
1074        setField("UserName", name);
1075    } /* setUserName(String) */
1076
1077
1078    /**
1079     * @throws DBException
1080     */

1081    public void update()
1082            throws DBException {
1083        if (noConfig) {
1084            throw new DBException(noConfigMessage);
1085        }
1086
1087        setCheckZeroUpdate(false);
1088
1089        // Check that another user with same email doesn't exist already
1090
SingleDBUserInfo anotherUser = new SingleDBUserInfo();
1091
1092        if (!getField("EMail").equalsIgnoreCase("none")) {
1093            anotherUser.setDataContext(getDataContext());
1094            anotherUser.setEmail(getField("EMail"));
1095
1096            if (anotherUser.find() && (anotherUser.getUid() != getUid())) {
1097                throw new DBException("Another user with the same email address \"" +
1098                        getField("EMail") + "\" already exists");
1099            }
1100        }
1101
1102        // If this site uses email as login name, force login name equal to email
1103
boolean useEmailAsLogin = false;
1104
1105        try {
1106            useEmailAsLogin = ConfigManager.getContext(getDataContext()).useEmailAsLogin();
1107        } catch (ConfigurationException ce) {
1108            throw new DBException(ce);
1109        }
1110        if (useEmailAsLogin) {
1111            if (getField("LoginName").equals("")) {
1112                setField("LoginName", getField("EMail"));
1113            }
1114        } else {
1115
1116            // This site has separate login name, make sure same login name doesn't exist already
1117
anotherUser.clear();
1118            anotherUser.setDataContext(getDataContext());
1119            anotherUser.setLoginName(getField("LoginName"));
1120
1121            if (anotherUser.find() && (anotherUser.getUid() != getUid())) {
1122                throw new DBException("Another user with the same login \"" +
1123                        getField("LoginName") +
1124                        "\" already exists");
1125            }
1126        }
1127        if (getField("UserName").equals("")) {
1128            setField("UserName", getField("LoginName"));
1129        }
1130        // If a User is added without a status, we set the AccountStatus to "I"
1131
// for security reasons
1132
if (getField("AccountStatus").equals("")) {
1133            setField("AccountStatus", "I");
1134        }
1135        // Set the registration domain id
1136
if (getRegistrationDomain().equals("")) {
1137            setRegistrationDomain("default");
1138        }
1139
1140        RegistrationDomain rd = new RegistrationDomain();
1141        rd.setDataContext(getDataContext());
1142        rd.setField("Name", getRegistrationDomain());
1143
1144        if (!rd.find()) {
1145            throw new DBException("Regsitration domain \"" +
1146                    getRegistrationDomain() +
1147                    "\" has not been defined");
1148        }
1149
1150        setField("RegDomId", rd.getField("RegDomId"));
1151
1152        // Check value of registration valid flag
1153
if (getField("RegComplete").equals("")) {
1154            setField("RegComplete", "N");
1155        }
1156        // We should always have a CreateDate
1157
if (getField("CreateDate").equals("")) {
1158            setField("CreateDate", DateTime.getDateTimeForDB(this.getDataContext()));
1159        }
1160        // We should always have a UpdateDate
1161
if (getField("UpdateDate").equals("")) {
1162            setField("UpdateDate", DateTime.getDateTimeForDB(this.getDataContext()));
1163        }
1164
1165        super.update();
1166        User user = new User();
1167        user.setDataContext(this.getDataContext());
1168        user.updateNotify(this);
1169
1170    } /* update() */
1171
1172
1173    public void retrieve()
1174            throws DBException {
1175        if (noConfig) {
1176            throw new DBException(noConfigMessage);
1177        }
1178
1179        super.retrieve();
1180    }
1181
1182    /**
1183     * the primary group of this user is appropriate for unix-like purposes,
1184     * such as setting the group for a file permission
1185     *
1186     * @return name of the primary group of this user; null if no group is primary
1187     */

1188    public String JavaDoc getPrimaryGroup()
1189            throws DBException {
1190        return DefaultUserInfo.getPrimaryGroup(this);
1191    }
1192
1193} /* SingleDBUserInfo */
1194
Popular Tags