View Javadoc

1   package org.apache.turbine.services.security.torque;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *   http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import java.io.ByteArrayOutputStream;
23  import java.io.PrintWriter;
24  import java.sql.Connection;
25  import java.util.Date;
26  import java.util.Hashtable;
27  
28  import javax.servlet.http.HttpSessionBindingEvent;
29  
30  import org.apache.torque.om.Persistent;
31  import org.apache.turbine.om.security.User;
32  import org.apache.turbine.services.security.TurbineSecurity;
33  import org.apache.turbine.util.ObjectUtils;
34  import org.apache.turbine.util.security.TurbineSecurityException;
35  
36  /***
37   * This is the User class used by the TorqueSecurity Service. It decouples
38   * all the database peer access from the actual Peer object
39   *
40   * @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a>
41   * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a>
42   * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a>
43   * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
44   * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a>
45   * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a>
46   * @author <a href="mailto:dlr@collab.net">Daniel Rall</a>
47   * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
48   * @version $Id: TorqueUser.java 534527 2007-05-02 16:10:59Z tv $
49   */
50  
51  public class TorqueUser
52      extends TorqueObject
53      implements User
54  {
55      /*** Serial Version UID */
56      private static final long serialVersionUID = 6623129207135917717L;
57  
58      /*** The date on which the user last accessed the application. */
59      private Date lastAccessDate = null;
60  
61      /*** This is data that will survive a servlet engine restart. */
62      private Hashtable permStorage = null;
63  
64      /*** This is data that will not survive a servlet engine restart. */
65      private Hashtable tempStorage = null;
66  
67      /***
68       * Constructor.
69       * Create a new User and set the createDate.
70       */
71      public TorqueUser()
72      {
73          super();
74          setCreateDate(new Date());
75          tempStorage = new Hashtable(10);
76          setHasLoggedIn(Boolean.FALSE);
77      }
78  
79      /***
80       * This Constructor is used when the UserPeerManager
81       * has retrieved a list of Database Objects from the peer and
82       * must 'wrap' them into TorqueRole Objects. You should not use it directly!
83       *
84       * @param obj An Object from the peer
85       */
86      public TorqueUser(Persistent obj)
87      {
88          super(obj);
89  
90          // Do not set creation date. This is only called on retrieval from
91          // storage!
92  
93          tempStorage = new Hashtable(10);
94          setHasLoggedIn(Boolean.FALSE);
95      }
96  
97      /***
98       * Returns the underlying Object for the Peer
99       *
100      * Used in the UserPeerManager when building a new Criteria.
101      *
102      * @return The underlying persistent object
103      *
104      */
105 
106     public Persistent getPersistentObj()
107     {
108         if (obj == null)
109         {
110             obj = UserPeerManager.newPersistentInstance();
111         }
112         return obj;
113     }
114 
115     /***
116      * Stores the object in the database.  If the object is new,
117      * it inserts it; otherwise an update is performed.
118      *
119      * @param torqueName The name under which the object should be stored.
120      *
121      * @exception Exception This method might throw an exceptions
122      */
123     public void save(String torqueName)
124             throws Exception
125     {
126         setObjectdata(ObjectUtils.serializeHashtable(getPermStorage()));
127         super.save(torqueName);
128     }
129 
130     /***
131      * Stores the object in the database.  If the object is new,
132      * it inserts it; otherwise an update is performed.  This method
133      * is meant to be used as part of a transaction, otherwise use
134      * the save() method and the connection details will be handled
135      * internally
136      *
137      * @param con A Connection object to save the object
138      *
139      * @exception Exception This method might throw an exceptions
140      */
141     public void save(Connection con)
142         throws Exception
143     {
144         setObjectdata(ObjectUtils.serializeHashtable(getPermStorage()));
145         super.save(con);
146     }
147 
148     /***
149      * Makes changes made to the User attributes permanent.
150      *
151      * @throws TurbineSecurityException if there is a problem while
152      *  saving data.
153      */
154     public void save()
155         throws TurbineSecurityException
156     {
157         //
158         // This is inconsistent with all the other security classes
159         // because it calls save() on the underlying object directly.
160         // But the UserManager calls ((Persistent)user).save()
161         // so if we do TurbineSecurity.saveUser(this) here, we get
162         // a nice endless loop. :-(
163         //
164         // Users seem to be a special kind of security objects...
165         //
166 
167         try
168         {
169             setObjectdata(ObjectUtils.serializeHashtable(getPermStorage()));
170             getPersistentObj().save();
171         }
172         catch (Exception e)
173         {
174             throw new TurbineSecurityException("User object said "
175                     + e.getMessage(), e);
176         }
177     }
178 
179     /***
180      * Returns the name of this object.
181      *
182      * @return The name of the object.
183      */
184     public String getName()
185     {
186         return UserPeerManager.getName(getPersistentObj());
187     }
188 
189     /***
190      * Sets the name of this object
191      *
192      * @param name The name of the object
193      */
194     public void setName(String name)
195     {
196         setUserName(name);
197     }
198 
199     /***
200      * Gets the Id of this object
201      *
202      * @return The Id of the object
203      */
204     public int getId()
205     {
206         return UserPeerManager.getIdAsObj(getPersistentObj()).intValue();
207     }
208 
209     /***
210      * Gets the Id of this object
211      *
212      * @return The Id of the object
213      */
214     public Integer getIdAsObj()
215     {
216         return UserPeerManager.getIdAsObj(getPersistentObj());
217     }
218 
219     /***
220      * Sets the Id of this object
221      *
222      * @param id The new Id
223      */
224     public void setId(int id)
225     {
226         UserPeerManager.setId(getPersistentObj(), id);
227     }
228 
229     /***
230      * Returns the name of this user.
231      *
232      * @return The name of the user.
233      * @deprecated Use getName() instead.
234      */
235     public String getUserName()
236     {
237         return getName();
238     }
239 
240     /***
241      * Sets the name of this user.
242      *
243      * @param name The name of the user.
244      */
245     public void setUserName(String name)
246     {
247         UserPeerManager.setUserName(getPersistentObj(), name);
248     }
249 
250     /***
251      * Returns the password of the User
252      *
253      * @return The password of the User
254      */
255     public String getPassword()
256     {
257         return UserPeerManager.getUserPassword(getPersistentObj());
258     }
259 
260     /***
261      * Sets the password of the User
262      *
263      * @param password The new password of the User
264      */
265     public void setPassword(String password)
266     {
267         UserPeerManager.setUserPassword(getPersistentObj(), password);
268     }
269 
270     /***
271      * Returns the first name of the User
272      *
273      * @return The first name of the User
274      */
275     public String getFirstName()
276     {
277         return UserPeerManager.getUserFirstName(getPersistentObj());
278     }
279 
280     /***
281      * Sets the first name of the User
282      *
283      * @param firstName The new first name of the User
284      */
285     public void setFirstName(String firstName)
286     {
287         UserPeerManager.setUserFirstName(getPersistentObj(), firstName);
288     }
289 
290     /***
291      * Returns the last name of the User
292      *
293      * @return The last name of the User
294      */
295     public String getLastName()
296     {
297         return UserPeerManager.getUserLastName(getPersistentObj());
298     }
299 
300     /***
301      * Sets the last name of User
302      *
303      * @param lastName The new last name of the User
304      */
305     public void setLastName(String lastName)
306     {
307         UserPeerManager.setUserLastName(getPersistentObj(), lastName);
308     }
309 
310     /***
311      * Returns the email address of the user
312      *
313      * @return The email address of the user
314      */
315     public String getEmail()
316     {
317         return UserPeerManager.getUserEmail(getPersistentObj());
318     }
319 
320     /***
321      * Sets the new email address of the user
322      *
323      * @param email The new email address of the user
324      */
325     public void setEmail(String email)
326     {
327         UserPeerManager.setUserEmail(getPersistentObj(), email);
328     }
329 
330     /***
331      * Returns the confirm value of the user
332      *
333      * @return The confirm value of the user
334      */
335     public String getConfirmed()
336     {
337         return UserPeerManager.getUserConfirmed(getPersistentObj());
338     }
339 
340     /***
341      * Sets the new confirm value of the user
342      *
343      * @param confirm The new confirm value of the user
344      */
345     public void setConfirmed(String confirm)
346     {
347         UserPeerManager.setUserConfirmed(getPersistentObj(), confirm);
348     }
349 
350     /***
351      * Returns the creation date of the user
352      *
353      * @return The creation date of the user
354      */
355     public java.util.Date getCreateDate()
356     {
357         return UserPeerManager.getUserCreateDate(getPersistentObj());
358     }
359 
360     /***
361      * Sets the new creation date of the user
362      *
363      * @param createDate The new creation date of the user
364      */
365     public void setCreateDate(java.util.Date createDate)
366     {
367         UserPeerManager.setUserCreateDate(getPersistentObj(), createDate);
368     }
369 
370     /***
371      * Returns the date of the last login of the user
372      *
373      * @return The date of the last login of the user
374      */
375     public java.util.Date getLastLogin()
376     {
377         return UserPeerManager.getUserLastLogin(getPersistentObj());
378     }
379 
380     /***
381      * Sets the new date of the last login of the user
382      *
383      * @param lastLogin The new the date of the last login of the user
384      */
385     public void setLastLogin(java.util.Date lastLogin)
386     {
387         UserPeerManager.setUserLastLogin(getPersistentObj(), lastLogin);
388     }
389 
390     /***
391      * Returns the value of the objectdata for this user.
392      * Objectdata is a VARBINARY column in the table used
393      * to store the permanent storage table from the User
394      * object.
395      *
396      * @return The bytes in the objectdata for this user
397      */
398     public byte [] getObjectdata()
399     {
400         return UserPeerManager.getUserObjectdata(getPersistentObj());
401     }
402 
403     /***
404      * Sets the value of the objectdata for the user
405      *
406      * @param objectdata The new the date of the last login of the user
407      */
408     public void setObjectdata(byte [] objectdata)
409     {
410         UserPeerManager.setUserObjectdata(getPersistentObj(), objectdata);
411     }
412 
413 
414     /***
415      * Gets the access counter for a user from perm storage.
416      *
417      * @return The access counter for the user.
418      */
419     public int getAccessCounter()
420     {
421         try
422         {
423             return ((Integer) getPerm(User.ACCESS_COUNTER)).intValue();
424         }
425         catch (Exception e)
426         {
427             return 0;
428         }
429     }
430 
431     /***
432      * Gets the access counter for a user during a session.
433      *
434      * @return The access counter for the user for the session.
435      */
436     public int getAccessCounterForSession()
437     {
438         try
439         {
440             return ((Integer) getTemp(User.SESSION_ACCESS_COUNTER)).intValue();
441         }
442         catch (Exception e)
443         {
444             return 0;
445         }
446     }
447 
448     /***
449      * Increments the permanent hit counter for the user.
450      */
451     public void incrementAccessCounter()
452     {
453         // Ugh. Race city, here I come...
454         setAccessCounter(getAccessCounter() + 1);
455     }
456 
457     /***
458      * Increments the session hit counter for the user.
459      */
460     public void incrementAccessCounterForSession()
461     {
462         setAccessCounterForSession(getAccessCounterForSession() + 1);
463     }
464 
465     /***
466      * Sets the access counter for a user, saved in perm storage.
467      *
468      * @param cnt The new count.
469      */
470     public void setAccessCounter(int cnt)
471     {
472         setPerm(User.ACCESS_COUNTER, new Integer(cnt));
473     }
474 
475     /***
476      * Sets the session access counter for a user, saved in temp
477      * storage.
478      *
479      * @param cnt The new count.
480      */
481     public void setAccessCounterForSession(int cnt)
482     {
483         setTemp(User.SESSION_ACCESS_COUNTER, new Integer(cnt));
484     }
485 
486     /***
487      * This method reports whether or not the user has been confirmed
488      * in the system by checking the User.CONFIRM_VALUE
489      * column in the users record to see if it is equal to
490      * User.CONFIRM_DATA.
491      *
492      * @return True if the user has been confirmed.
493      */
494     public boolean isConfirmed()
495     {
496         String value = getConfirmed();
497         return (value != null && value.equals(User.CONFIRM_DATA));
498     }
499 
500     /***
501      * The user is considered logged in if they have not timed out.
502      *
503      * @return Whether the user has logged in.
504      */
505     public boolean hasLoggedIn()
506     {
507         Boolean loggedIn = getHasLoggedIn();
508         return (loggedIn != null && loggedIn.booleanValue());
509     }
510 
511     /***
512      * This sets whether or not someone has logged in.  hasLoggedIn()
513      * returns this value.
514      *
515      * @param value Whether someone has logged in or not.
516      */
517     public void setHasLoggedIn(Boolean value)
518     {
519         setTemp(User.HAS_LOGGED_IN, value);
520     }
521 
522     /***
523      * Gets the last access date for this User.  This is the last time
524      * that the user object was referenced.
525      *
526      * @return A Java Date with the last access date for the user.
527      */
528     public java.util.Date getLastAccessDate()
529     {
530         if (lastAccessDate == null)
531         {
532             setLastAccessDate();
533         }
534         return lastAccessDate;
535     }
536 
537     /***
538      * Sets the last access date for this User. This is the last time
539      * that the user object was referenced.
540      */
541     public void setLastAccessDate()
542     {
543         lastAccessDate = new java.util.Date();
544     }
545 
546     /***
547      * Returns the permanent storage. This is implemented
548      * as a Hashtable and backed by an VARBINARY column in
549      * the database.
550      *
551      * @return A Hashtable.
552      */
553     public Hashtable getPermStorage()
554     {
555         if (permStorage == null)
556         {
557             byte [] objectdata = getObjectdata();
558 
559             if (objectdata != null)
560             {
561                 permStorage = (Hashtable) ObjectUtils.deserialize(objectdata);
562             }
563 
564             if (permStorage == null)
565             {
566                 permStorage = new Hashtable();
567             }
568         }
569 
570         return permStorage;
571     }
572 
573     /***
574      * This should only be used in the case where we want to save the
575      * data to the database.
576      *
577      * @param storage A Hashtable.
578      */
579     public void setPermStorage(Hashtable permStorage)
580     {
581         if (permStorage != null)
582         {
583             this.permStorage = permStorage;
584         }
585     }
586 
587     /***
588      * Returns the temporary storage. This is implemented
589      * as a Hashtable
590      *
591      * @return A Hashtable.
592      */
593     public Hashtable getTempStorage()
594     {
595         if (tempStorage == null)
596         {
597             tempStorage = new Hashtable();
598         }
599         return tempStorage;
600     }
601 
602     /***
603      * This should only be used in the case where we want to save the
604      * data to the database.
605      *
606      * @param storage A Hashtable.
607      */
608     public void setTempStorage(Hashtable tempStorage)
609     {
610         if (tempStorage != null)
611         {
612             this.tempStorage = tempStorage;
613         }
614     }
615 
616     /***
617      * Get an object from permanent storage.
618      *
619      * @param name The object's name.
620      * @return An Object with the given name.
621      */
622     public Object getPerm(String name)
623     {
624         return getPermStorage().get(name);
625     }
626 
627     /***
628      * Get an object from permanent storage; return default if value
629      * is null.
630      *
631      * @param name The object's name.
632      * @param def A default value to return.
633      * @return An Object with the given name.
634      */
635     public Object getPerm(String name, Object def)
636     {
637         try
638         {
639             Object val = getPermStorage().get(name);
640             return (val == null ? def : val);
641         }
642         catch (Exception e)
643         {
644             return def;
645         }
646     }
647 
648     /***
649      * Put an object into permanent storage. If the value is null,
650      * it will convert that to a "" because the underlying storage
651      * mechanism within TorqueUser is currently a Hashtable and
652      * null is not a valid value.
653      *
654      * @param name The object's name.
655      * @param value The object.
656      */
657     public void setPerm(String name, Object value)
658     {
659         getPermStorage().put(name, (value == null) ? "" : value);
660     }
661 
662     /***
663      * Get an object from temporary storage.
664      *
665      * @param name The object's name.
666      * @return An Object with the given name.
667      */
668     public Object getTemp(String name)
669     {
670         return getTempStorage().get(name);
671     }
672 
673     /***
674      * Get an object from temporary storage; return default if value
675      * is null.
676      *
677      * @param name The object's name.
678      * @param def A default value to return.
679      * @return An Object with the given name.
680      */
681     public Object getTemp(String name, Object def)
682     {
683         Object val;
684         try
685         {
686             val = getTempStorage().get(name);
687             if (val == null)
688             {
689                 val = def;
690             }
691         }
692         catch (Exception e)
693         {
694             val = def;
695         }
696         return val;
697     }
698 
699     /***
700      * Put an object into temporary storage. If the value is null,
701      * it will convert that to a "" because the underlying storage
702      * mechanism within TorqueUser is currently a Hashtable and
703      * null is not a valid value.
704      *
705      * @param name The object's name.
706      * @param value The object.
707      */
708     public void setTemp(String name, Object value)
709     {
710         getTempStorage().put(name, (value == null) ? "" : value);
711     }
712 
713     /***
714      * Remove an object from temporary storage and return the object.
715      *
716      * @param name The name of the object to remove.
717      * @return An Object.
718      */
719     public Object removeTemp(String name)
720     {
721         return getTempStorage().remove(name);
722     }
723 
724     /***
725      * Updates the last login date in the database.
726      *
727      * @exception Exception A generic exception.
728      */
729     public void updateLastLogin()
730         throws Exception
731     {
732         setLastLogin(new java.util.Date());
733     }
734 
735     /***
736      * Implement this method if you wish to be notified when the User
737      * has been Bound to the session.
738      *
739      * @param event Indication of value/session binding.
740      */
741     public void valueBound(HttpSessionBindingEvent hsbe)
742     {
743         // Currently we have no need for this method.
744     }
745 
746     /***
747      * Implement this method if you wish to be notified when the User
748      * has been Unbound from the session.
749      *
750      * @param event Indication of value/session unbinding.
751      */
752     public void valueUnbound(HttpSessionBindingEvent hsbe)
753     {
754         try
755         {
756             if (hasLoggedIn())
757             {
758                 TurbineSecurity.saveOnSessionUnbind(this);
759             }
760         }
761         catch (Exception e)
762         {
763             //Log.error("TorqueUser.valueUnbound(): " + e.getMessage(), e);
764 
765             // To prevent messages being lost in case the logging system
766             // goes away before sessions get unbound on servlet container
767             // shutdown, print the stcktrace to the container's console.
768             ByteArrayOutputStream ostr = new ByteArrayOutputStream();
769             e.printStackTrace(new PrintWriter(ostr, true));
770             String stackTrace = ostr.toString();
771             System.out.println(stackTrace);
772         }
773     }
774 
775     /***
776      * This gets whether or not someone has logged in.  hasLoggedIn()
777      * returns this value as a boolean.  This is private because you
778      * should use hasLoggedIn() instead.
779      *
780      * @return True if someone has logged in.
781      */
782     private Boolean getHasLoggedIn()
783     {
784         return (Boolean) getTemp(User.HAS_LOGGED_IN);
785     }
786 
787 }