001    package org.apache.turbine.om.security;
002    
003    
004    /*
005     * Licensed to the Apache Software Foundation (ASF) under one
006     * or more contributor license agreements.  See the NOTICE file
007     * distributed with this work for additional information
008     * regarding copyright ownership.  The ASF licenses this file
009     * to you under the Apache License, Version 2.0 (the
010     * "License"); you may not use this file except in compliance
011     * with the License.  You may obtain a copy of the License at
012     *
013     *   http://www.apache.org/licenses/LICENSE-2.0
014     *
015     * Unless required by applicable law or agreed to in writing,
016     * software distributed under the License is distributed on an
017     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
018     * KIND, either express or implied.  See the License for the
019     * specific language governing permissions and limitations
020     * under the License.
021     */
022    
023    
024    import java.sql.Connection;
025    import java.util.Date;
026    import java.util.Hashtable;
027    
028    import javax.servlet.http.HttpSessionBindingEvent;
029    
030    import org.apache.commons.logging.Log;
031    import org.apache.commons.logging.LogFactory;
032    import org.apache.turbine.services.security.TurbineSecurity;
033    
034    /**
035     * A generic implementation of User interface.
036     *
037     * This basic implementation contains the functionality that is
038     * expected to be common among all User implementations.
039     * You are welcome to extend this class if you wish to have
040     * custom functionality in your user objects (like accessor methods
041     * for custom attributes). <b>Note</b> that implementing a different scheme
042     * of user data storage normally involves writing an implementation of
043     * {@link org.apache.turbine.services.security.UserManager} interface.
044     *
045     * @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a>
046     * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a>
047     * @author <a href="mailto:john.mcnally@clearink.com">John D. McNally</a>
048     * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a>
049     * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a>
050     * @author <a href="mailto:epugh@upstate.com">Eric Pugh</a>
051     * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a>
052     * @version $Id: TurbineUser.java 1078552 2011-03-06 19:58:46Z tv $
053     */
054    public class TurbineUser extends SecurityObject<User> implements User
055    {
056        /** Serial version */
057        private static final long serialVersionUID = 6380024466902321258L;
058    
059        /** Logging */
060        private static Log log = LogFactory.getLog(TurbineUser.class);
061    
062        /** The date on which the user account was created. */
063        private Date createDate = null;
064    
065        /** The date on which the user last accessed the application. */
066        private Date lastAccessDate = null;
067    
068        /** This is data that will survive a servlet engine restart. */
069        private Hashtable<String, Object> permStorage = null;
070    
071        /** This is data that will not survive a servlet engine restart. */
072        private Hashtable<String, Object> tempStorage = null;
073    
074        /**
075         * Constructor.
076         *
077         * Create a new User and set the createDate.
078         */
079        public TurbineUser()
080        {
081            super();
082            createDate = new Date();
083            setHasLoggedIn(Boolean.FALSE);
084        }
085    
086        /**
087         * Gets the access counter for a user during a session.
088         *
089         * @return The access counter for the user for the session.
090         */
091        public int getAccessCounterForSession()
092        {
093            try
094            {
095                return ((Integer) getTemp(User.SESSION_ACCESS_COUNTER)).intValue();
096            }
097            catch (Exception e)
098            {
099                return 0;
100            }
101        }
102    
103        /**
104         * Gets the access counter for a user from perm storage.
105         *
106         * @return The access counter for the user.
107         */
108        public int getAccessCounter()
109        {
110            try
111            {
112                return ((Integer) getPerm(User.ACCESS_COUNTER)).intValue();
113            }
114            catch (Exception e)
115            {
116                return 0;
117            }
118        }
119    
120        /**
121         * Gets the create date for this User.  This is the time at which
122         * the user object was created.
123         *
124         * @return A Java Date with the date of creation for the user.
125         */
126        public java.util.Date getCreateDate()
127        {
128            return createDate;
129        }
130    
131        /**
132         * Gets the last access date for this User.  This is the last time
133         * that the user object was referenced.
134         *
135         * @return A Java Date with the last access date for the user.
136         */
137        public java.util.Date getLastAccessDate()
138        {
139            if (lastAccessDate == null)
140            {
141                setLastAccessDate();
142            }
143            return lastAccessDate;
144        }
145    
146        /**
147         * Get last login date/time for this user.
148         *
149         * @return A Java Date with the last login date for the user.
150         */
151        public java.util.Date getLastLogin()
152        {
153            return (java.util.Date) getPerm(User.LAST_LOGIN);
154        }
155    
156        /**
157         * Get password for this user.
158         *
159         * @return A String with the password for the user.
160         */
161        public String getPassword()
162        {
163            return (String) getPerm(User.PASSWORD);
164        }
165    
166        /**
167         * Get an object from permanent storage.
168         *
169         * @param name The object's name.
170         * @return An Object with the given name, or null if not found.
171         */
172        public Object getPerm(String name)
173        {
174            return getPerm(name,null);
175        }
176    
177        /**
178         * Get an object from permanent storage; return default if value
179         * is null.
180         *
181         * @param name The object's name.
182         * @param def A default value to return.
183         * @return An Object with the given name.
184         */
185        public Object getPerm(String name, Object def)
186        {
187            Object val;
188            try
189            {
190                val = getPermStorage().get(name);
191                if (val == null)
192                {
193                    val = def;
194                }
195            }
196            catch (Exception e)
197            {
198                val = def;
199            }
200            return val;
201        }
202    
203        /**
204         * This should only be used in the case where we want to save the
205         * data to the database.
206         *
207         * @return A Hashtable.
208         */
209        public Hashtable<String, Object> getPermStorage()
210        {
211            if (permStorage == null)
212            {
213                permStorage = new Hashtable<String, Object>(10);
214            }
215            return permStorage;
216        }
217    
218        /**
219         * Get an object from temporary storage; return null if the
220         * object can't be found.
221         *
222         * @param name The object's name.
223         * @return An Object with the given name.
224         */
225        public Object getTemp(String name)
226        {
227            return getTemp(name, null);
228        }
229    
230        /**
231         * Get an object from temporary storage; return default if value
232         * is null.
233         *
234         * @param name The object's name.
235         * @param def A default value to return.
236         * @return An Object with the given name.
237         */
238        public Object getTemp(String name, Object def)
239        {
240            Object val;
241            try
242            {
243                val = getTempStorage().get(name);
244                if (val == null)
245                {
246                    val = def;
247                }
248    
249            }
250            catch (Exception e)
251            {
252                val = def;
253            }
254            return val;
255        }
256    
257    
258        /**
259         * Returns the first name for this user.
260         *
261         * @return A String with the user's first name.
262         */
263        public String getFirstName()
264        {
265            String tmp = null;
266            try
267            {
268                tmp = (String) getPerm(User.FIRST_NAME);
269                if(tmp.length() == 0)
270                {
271                    tmp = null;
272                }
273            }
274            catch (Exception e)
275            {
276                // ignore
277            }
278            return tmp;
279        }
280    
281        /**
282         * Returns the last name for this user.
283         *
284         * @return A String with the user's last name.
285         */
286        public String getLastName()
287        {
288            String tmp = null;
289            try
290            {
291                tmp = (String) getPerm(User.LAST_NAME);
292                if (tmp.length() == 0)
293                    tmp = null;
294            }
295            catch (Exception e)
296            {
297                // ignore
298            }
299            return tmp;
300        }
301    
302        /**
303         * The user is considered logged in if they have not timed out.
304         *
305         * @return Whether the user has logged in.
306         */
307        public boolean hasLoggedIn()
308        {
309            Boolean loggedIn = getHasLoggedIn();
310            return (loggedIn != null && loggedIn.booleanValue());
311        }
312    
313        /**
314         * Returns the email address for this user.
315         *
316         * @return A String with the user's email address.
317         */
318        public String getEmail()
319        {
320            return (String) getPerm(User.EMAIL);
321        }
322    
323        /**
324         * Increments the permanent hit counter for the user.
325         */
326        public void incrementAccessCounter()
327        {
328            setAccessCounter(getAccessCounter() + 1);
329        }
330    
331        /**
332         * Increments the session hit counter for the user.
333         */
334        public void incrementAccessCounterForSession()
335        {
336            setAccessCounterForSession(getAccessCounterForSession() + 1);
337        }
338    
339        /**
340         * Remove an object from temporary storage and return the object.
341         *
342         * @param name The name of the object to remove.
343         * @return An Object.
344         */
345        public Object removeTemp(String name)
346        {
347            return getTempStorage().remove(name);
348        }
349    
350        /**
351         * Sets the access counter for a user, saved in perm storage.
352         *
353         * @param cnt The new count.
354         */
355        public void setAccessCounter(int cnt)
356        {
357            setPerm(User.ACCESS_COUNTER, new Integer(cnt));
358        }
359    
360        /**
361         * Sets the session access counter for a user, saved in temp
362         * storage.
363         *
364         * @param cnt The new count.
365         */
366        public void setAccessCounterForSession(int cnt)
367        {
368            setTemp(User.SESSION_ACCESS_COUNTER, new Integer(cnt));
369        }
370    
371        /**
372         * Sets the last access date for this User. This is the last time
373         * that the user object was referenced.
374         */
375        public void setLastAccessDate()
376        {
377            lastAccessDate = new java.util.Date();
378        }
379    
380        /**
381         * Sets the create date for this User. This is the time at which
382         * the user object was created.
383         *
384         * @param date The create date.
385         */
386        public void setCreateDate(java.util.Date date)
387        {
388            createDate = date;
389        }
390    
391        /**
392         * Set last login date/time.
393         *
394         * @param date The last login date.
395         */
396        public void setLastLogin(java.util.Date date)
397        {
398            setPerm(User.LAST_LOGIN, date);
399        }
400    
401        /**
402         * Set password.
403         *
404         * @param password The new password.
405         */
406        public void setPassword(String password)
407        {
408            setPerm(User.PASSWORD, password);
409        }
410    
411        /**
412         * Put an object into permanent storage. If the value is null,
413         * it will convert that to a "" because the underlying storage
414         * mechanism within TurbineUser is currently a Hashtable and
415         * null is not a valid value.
416         *
417         * @param name The object's name.
418         * @param value The object.
419         */
420        public void setPerm(String name, Object value)
421        {
422            getPermStorage().put(name, (value == null) ? "" : value);
423        }
424    
425        /**
426         * This should only be used in the case where we want to save the
427         * data to the database.
428         *
429         * @param permStorage A Hashtable.
430         */
431        public void setPermStorage(Hashtable<String, Object> permStorage)
432        {
433            this.permStorage = permStorage;
434        }
435    
436        /**
437         * This should only be used in the case where we want to save the
438         * data to the database.
439         *
440         * @return A Hashtable.
441         */
442        public Hashtable<String, Object> getTempStorage()
443        {
444            if (tempStorage == null)
445            {
446                tempStorage = new Hashtable<String, Object>(10);
447            }
448            return tempStorage;
449        }
450    
451        /**
452         * This should only be used in the case where we want to save the
453         * data to the database.
454         *
455         * @param storage A Hashtable.
456         */
457        public void setTempStorage(Hashtable<String, Object> tempStorage)
458        {
459            this.tempStorage = tempStorage;
460        }
461    
462        /**
463         * This gets whether or not someone has logged in.  hasLoggedIn()
464         * returns this value as a boolean.  This is private because you
465         * should use hasLoggedIn() instead.
466         *
467         * @return True if someone has logged in.
468         */
469        private Boolean getHasLoggedIn()
470        {
471            return (Boolean) getTemp(User.HAS_LOGGED_IN);
472        }
473    
474        /**
475         * This sets whether or not someone has logged in.  hasLoggedIn()
476         * returns this value.
477         *
478         * @param value Whether someone has logged in or not.
479         */
480        public void setHasLoggedIn(Boolean value)
481        {
482            setTemp(User.HAS_LOGGED_IN, value);
483        }
484    
485        /**
486         * Put an object into temporary storage. If the value is null,
487         * it will convert that to a "" because the underlying storage
488         * mechanism within TurbineUser is currently a Hashtable and
489         * null is not a valid value.
490         *
491         * @param name The object's name.
492         * @param value The object.
493         */
494        public void setTemp(String name, Object value)
495        {
496            getTempStorage().put(name, (value == null) ? "" : value);
497        }
498    
499    
500        /**
501         * Sets the first name for this user.
502         *
503         * @param firstName User's first name.
504         */
505        public void setFirstName(String firstName)
506        {
507            setPerm(User.FIRST_NAME, firstName);
508        }
509    
510        /**
511         * Sets the last name for this user.
512         *
513         * @param lastName User's last name.
514         */
515        public void setLastName(String lastName)
516        {
517            setPerm(User.LAST_NAME, lastName);
518        }
519    
520        /**
521         * Sets the email address.
522         *
523         * @param address The email address.
524         */
525        public void setEmail(String address)
526        {
527            setPerm(User.EMAIL, address);
528        }
529    
530        /**
531         * This method reports whether or not the user has been confirmed
532         * in the system by checking the User.CONFIRM_VALUE
533         * column in the users record to see if it is equal to
534         * User.CONFIRM_DATA.
535         *
536         * @return True if the user has been confirmed.
537         */
538        public boolean isConfirmed()
539        {
540            String value = getConfirmed();
541            return (value != null && value.equals(User.CONFIRM_DATA));
542        }
543    
544        /**
545         * Sets the confirmation value. The value should
546         * be either a random string or User.CONFIRM_DATA
547         *
548         * @param value The confirmation key value.
549         */
550        public void setConfirmed(String value)
551        {
552            String val = "";
553            if (value != null)
554            {
555                val = value;
556            }
557            setPerm(User.CONFIRM_VALUE, val);
558        }
559    
560        /**
561         * Gets the confirmation value.
562         *
563         * @return status The confirmation value for this User
564         */
565        public String getConfirmed()
566        {
567            return (String) getPerm(User.CONFIRM_VALUE);
568        }
569    
570        /**
571         * Updates the last login date in the database.
572         *
573         * @exception Exception a generic exception.
574         */
575        public void updateLastLogin()
576                throws Exception
577        {
578            setPerm(User.LAST_LOGIN, new java.util.Date());
579        }
580    
581        /**
582         * Implement this method if you wish to be notified when the User
583         * has been Bound to the session.
584         *
585         * @param hsbe The HttpSessionBindingEvent.
586         */
587        public void valueBound(HttpSessionBindingEvent hsbe)
588        {
589            // Currently we have no need for this method.
590        }
591    
592        /**
593         * Implement this method if you wish to be notified when the User
594         * has been Unbound from the session.
595         *
596         * @param hsbe The HttpSessionBindingEvent.
597         */
598        public void valueUnbound(HttpSessionBindingEvent hsbe)
599        {
600            try
601            {
602                if (hasLoggedIn())
603                {
604                    TurbineSecurity.saveOnSessionUnbind(this);
605                }
606            }
607            catch (Exception e)
608            {
609                log.error("TurbineUser.valueUnbound(): " + e.getMessage(), e);
610            }
611        }
612    
613        /**
614         * Saves this object to the data store.
615         */
616        public void save()
617                throws Exception
618        {
619            if (TurbineSecurity.accountExists(this))
620            {
621                TurbineSecurity.saveUser(this);
622            }
623            else
624            {
625                TurbineSecurity.addUser(this, getPassword());
626            }
627        }
628    
629        /**
630         * not implemented
631         *
632         * @param conn
633         * @throws Exception
634         */
635        public void save(Connection conn) throws Exception
636        {
637            throw new Exception("not implemented");
638        }
639    
640        /**
641         * not implemented
642         *
643         * @param dbname
644         * @throws Exception
645         */
646        public void save(String dbname) throws Exception
647        {
648            throw new Exception("not implemented");
649        }
650    
651        /**
652         * Returns the name of this user.  This will be the user name/
653         * login name.
654         *
655         * @return The name of the user.
656         */
657        @Override
658        public String getName()
659        {
660            return (String) getPerm(User.USERNAME);
661        }
662    
663        /**
664         * Sets the name of this user.  This will be the user name/
665         * login name.
666         *
667         * @param name The name of the object.
668         */
669        @Override
670        public void setName(String name)
671        {
672            setPerm(User.USERNAME, name);
673        }
674    }