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 1096130 2011-04-23 10:37:19Z ludwig $
    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 }