001package org.apache.turbine.om.security;
002
003/*
004 * Licensed to the Apache Software Foundation (ASF) under one
005 * or more contributor license agreements.  See the NOTICE file
006 * distributed with this work for additional information
007 * regarding copyright ownership.  The ASF licenses this file
008 * to you under the Apache License, Version 2.0 (the
009 * "License"); you may not use this file except in compliance
010 * with the License.  You may obtain a copy of the License at
011 *
012 *   http://www.apache.org/licenses/LICENSE-2.0
013 *
014 * Unless required by applicable law or agreed to in writing,
015 * software distributed under the License is distributed on an
016 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
017 * KIND, either express or implied.  See the License for the
018 * specific language governing permissions and limitations
019 * under the License.
020 */
021
022import java.io.ByteArrayOutputStream;
023import java.io.PrintWriter;
024import java.util.Date;
025import java.util.HashMap;
026import java.util.Map;
027import java.util.Set;
028
029import javax.servlet.http.HttpSessionBindingEvent;
030
031import org.apache.fulcrum.security.model.turbine.entity.TurbineUser;
032import org.apache.fulcrum.security.model.turbine.entity.TurbineUserGroupRole;
033import org.apache.fulcrum.security.util.DataBackendException;
034import org.apache.turbine.services.TurbineServices;
035import org.apache.turbine.services.security.SecurityService;
036import org.apache.turbine.util.ObjectUtils;
037
038/**
039 * This is the Default user implementation. It is a wrapper around
040 * a TurbineUser object
041 *
042 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
043 * @version $Id: TorqueUser.java 1199856 2011-11-09 17:06:04Z tv $
044 */
045
046public class DefaultUserImpl implements User
047{
048    /** Serial version */
049    private static final long serialVersionUID = -1866504873085624111L;
050
051    /** The date on which the user last accessed the application. */
052    private Date lastAccessDate = null;
053
054    /** This is data that will survive a servlet engine restart. */
055    private Map<String, Object> permStorage = null;
056
057    /** This is data that will not survive a servlet engine restart. */
058    private Map<String, Object> tempStorage = null;
059
060    /** The Fulcrum user instance to delegate to */
061    private TurbineUser userDelegate = null;
062
063    /**
064     * Constructor
065     *
066     * @param user the user object to wrap
067     */
068    public DefaultUserImpl(TurbineUser user)
069    {
070        super();
071        setUserDelegate( user );;
072        setCreateDate(new Date());
073        tempStorage = new HashMap<String, Object>(10);
074        setHasLoggedIn(Boolean.FALSE);
075    }
076
077    /**
078     * Implement this method if you wish to be notified when the User
079     * has been Bound to the session.
080     *
081     * @param hsbe Indication of value/session binding.
082     */
083    @Override
084    public void valueBound(HttpSessionBindingEvent hsbe)
085    {
086        // Currently we have no need for this method.
087    }
088
089    /**
090     * Implement this method if you wish to be notified when the User
091     * has been Unbound from the session.
092     *
093     * @param hsbe Indication of value/session unbinding.
094     */
095    @Override
096    public void valueUnbound(HttpSessionBindingEvent hsbe)
097    {
098        try
099        {
100            if (hasLoggedIn())
101            {
102                SecurityService securityService = (SecurityService)TurbineServices.getInstance().getService(SecurityService.SERVICE_NAME);
103                securityService.saveOnSessionUnbind(this);
104            }
105        }
106        catch (Exception e)
107        {
108            //Log.error("TorqueUser.valueUnbound(): " + e.getMessage(), e);
109
110            // To prevent messages being lost in case the logging system
111            // goes away before sessions get unbound on servlet container
112            // shutdown, print the stacktrace to the container's console.
113            ByteArrayOutputStream ostr = new ByteArrayOutputStream();
114            e.printStackTrace(new PrintWriter(ostr, true));
115            String stackTrace = ostr.toString();
116            System.out.println(stackTrace);
117        }
118    }
119
120    /**
121     * Get the Name of the SecurityEntity.
122     *
123     * @return The Name of the SecurityEntity.
124     */
125    @Override
126    public String getName()
127    {
128        return userDelegate.getName();
129    }
130
131    /**
132     * Sets the Name of the SecurityEntity.
133     *
134     * @param name
135     *            Name of the SecurityEntity.
136     */
137    @Override
138    public void setName(String name)
139    {
140        userDelegate.setName(name);
141    }
142
143    /**
144     * Get the Id of the SecurityEntity.
145     *
146     * @return The Id of the SecurityEntity.
147     */
148    @Override
149    public Object getId()
150    {
151        return userDelegate.getId();
152    }
153
154    /**
155     * Sets the Id of the SecurityEntity.
156     *
157     * @param id
158     *            The new Id of the SecurityEntity
159     */
160    @Override
161    public void setId(Object id)
162    {
163        userDelegate.setId(id);
164    }
165
166    /**
167     * Returns the user's password. This method should not be used by
168     * the application directly, because it's meaning depends upon
169     * the implementation of UserManager that manages this particular
170     * user object. Some implementations will use this attribute for
171     * storing a password encrypted in some way, other will not use
172     * it at all, when user entered password is presented to some external
173     * authority (like NT domain controller) to validate it.
174     * See also {@link org.apache.turbine.services.security.UserManager#authenticate(User,String)}.
175     *
176     * @return A String with the password for the user.
177     */
178    @Override
179    public String getPassword()
180    {
181        return userDelegate.getPassword();
182    }
183
184    /**
185     * Set password. Application should not use this method
186     * directly, see {@link #getPassword()}.
187     * See also {@link org.apache.turbine.services.security.UserManager#changePassword(User,String,String)}.
188     *
189     * @param password The new password.
190     */
191    @Override
192    public void setPassword(String password)
193    {
194        userDelegate.setPassword(password);
195    }
196
197    /**
198     * Returns the first name for this user.
199     *
200     * @return A String with the user's first name.
201     */
202    @Override
203    public String getFirstName()
204    {
205        return userDelegate.getFirstName();
206    }
207
208    /**
209     * Sets the first name for this user.
210     *
211     * @param firstName User's first name.
212     */
213    @Override
214    public void setFirstName(String firstName)
215    {
216        userDelegate.setFirstName(firstName);
217    }
218
219    /**
220     * Returns the last name for this user.
221     *
222     * @return A String with the user's last name.
223     */
224    @Override
225    public String getLastName()
226    {
227        return userDelegate.getLastName();
228    }
229
230    /**
231     * Sets the last name for this user.
232     *
233     * @param lastName User's last name.
234     */
235    @Override
236    public void setLastName(String lastName)
237    {
238        userDelegate.setLastName(lastName);
239    }
240
241    /**
242     * Returns the email address for this user.
243     *
244     * @return A String with the user's email address.
245     */
246    @Override
247    public String getEmail()
248    {
249        return userDelegate.getEmail();
250    }
251
252    /**
253     * Sets the email address.
254     *
255     * @param address The email address.
256     */
257    @Override
258    public void setEmail(String address)
259    {
260        userDelegate.setEmail(address);
261    }
262
263    /**
264     * Returns the value of the objectdata for this user.
265     * Objectdata is a storage area used
266     * to store the permanent storage table from the User
267     * object.
268     *
269     * @return The bytes in the objectdata for this user
270     */
271    @Override
272    public byte[] getObjectdata()
273    {
274        return userDelegate.getObjectdata();
275    }
276
277    /**
278     * Sets the value of the objectdata for the user
279     *
280     * @param objectdata The new permanent storage for the user
281     */
282    @Override
283    public void setObjectdata(byte[] objectdata)
284    {
285        userDelegate.setObjectdata(objectdata);
286    }
287
288    /**
289     * Get the User/Group/Role set associated with this entity
290     *
291     * @return a set of User/Group/Role relations
292     * @throws DataBackendException 
293     */
294    @Override
295    public <T extends TurbineUserGroupRole> Set<T> getUserGroupRoleSet() throws DataBackendException
296    {
297        return userDelegate.getUserGroupRoleSet();
298    }
299
300    /**
301     * Set the User/Group/Role set associated with this entity
302     *
303     * @param userGroupRoleSet
304     *            a set of User/Group/Role relations
305     */
306    @Override
307    public <T extends TurbineUserGroupRole> void setUserGroupRoleSet(Set<T> userGroupRoleSet)
308    {
309        userDelegate.setUserGroupRoleSet(userGroupRoleSet);
310    }
311
312    /**
313     * Add a User/Group/Role relation to this entity
314     *
315     * @param userGroupRole
316     *            a User/Group/Role relation to add
317     * @throws DataBackendException 
318     */
319    @Override
320    public void addUserGroupRole(TurbineUserGroupRole userGroupRole) throws DataBackendException
321    {
322        userDelegate.addUserGroupRole(userGroupRole);
323    }
324
325    /**
326     * Remove a User/Group/Role relation from this entity
327     *
328     * @param userGroupRole
329     *            a User/Group/Role relation to remove
330     * @throws DataBackendException 
331     */
332    @Override
333    public void removeUserGroupRole(TurbineUserGroupRole userGroupRole) throws DataBackendException
334    {
335        userDelegate.removeUserGroupRole(userGroupRole);
336    }
337
338    /**
339     * Gets the access counter for a user from perm storage.
340     *
341     * @return The access counter for the user.
342     */
343    @Override
344    public int getAccessCounter()
345    {
346        try
347        {
348            return ((Integer) getPerm(User.ACCESS_COUNTER)).intValue();
349        }
350        catch (Exception e)
351        {
352            return 0;
353        }
354    }
355
356    /**
357     * Gets the access counter for a user during a session.
358     *
359     * @return The access counter for the user for the session.
360     */
361    @Override
362    public int getAccessCounterForSession()
363    {
364        try
365        {
366            return ((Integer) getTemp(User.SESSION_ACCESS_COUNTER)).intValue();
367        }
368        catch (Exception e)
369        {
370            return 0;
371        }
372    }
373
374    /**
375     * Increments the permanent hit counter for the user.
376     */
377    @Override
378    public void incrementAccessCounter()
379    {
380        // Ugh. Race city, here I come...
381        setAccessCounter(getAccessCounter() + 1);
382    }
383
384    /**
385     * Increments the session hit counter for the user.
386     */
387    @Override
388    public void incrementAccessCounterForSession()
389    {
390        setAccessCounterForSession(getAccessCounterForSession() + 1);
391    }
392
393    /**
394     * Sets the access counter for a user, saved in perm storage.
395     *
396     * @param cnt The new count.
397     */
398    @Override
399    public void setAccessCounter(int cnt)
400    {
401        setPerm(User.ACCESS_COUNTER, Integer.valueOf(cnt));
402    }
403
404    /**
405     * Sets the session access counter for a user, saved in temp
406     * storage.
407     *
408     * @param cnt The new count.
409     */
410    @Override
411    public void setAccessCounterForSession(int cnt)
412    {
413        setTemp(User.SESSION_ACCESS_COUNTER, Integer.valueOf(cnt));
414    }
415
416    /**
417     * Gets the last access date for this User.  This is the last time
418     * that the user object was referenced.
419     *
420     * @return A Java Date with the last access date for the user.
421     */
422    @Override
423    public java.util.Date getLastAccessDate()
424    {
425        if (lastAccessDate == null)
426        {
427            setLastAccessDate();
428        }
429        return lastAccessDate;
430    }
431
432    /**
433     * Sets the last access date for this User. This is the last time
434     * that the user object was referenced.
435     */
436    @Override
437    public void setLastAccessDate()
438    {
439        lastAccessDate = new java.util.Date();
440    }
441
442    /**
443     * Returns the permanent storage. This is implemented
444     * as a Map
445     *
446     * @return A Map.
447     */
448    @Override
449    public Map<String, Object> getPermStorage()
450    {
451        if (permStorage == null)
452        {
453            byte [] objectdata = getObjectdata();
454
455            if (objectdata != null)
456            {
457                permStorage = ObjectUtils.deserialize(objectdata);
458            }
459
460            if (permStorage == null)
461            {
462                permStorage = new HashMap<String, Object>();
463            }
464        }
465
466        return permStorage;
467    }
468
469    /**
470     * This should only be used in the case where we want to make the
471     * data persistent.
472     *
473     * @param permStorage A Map.
474     */
475    @Override
476    public void setPermStorage(Map<String, Object> permStorage)
477    {
478        if (permStorage != null)
479        {
480            this.permStorage = permStorage;
481        }
482    }
483
484    /**
485     * Returns the temporary storage. This is implemented
486     * as a Map
487     *
488     * @return A Map.
489     */
490    @Override
491    public Map<String, Object> getTempStorage()
492    {
493        if (tempStorage == null)
494        {
495            tempStorage = new HashMap<String, Object>();
496        }
497        return tempStorage;
498    }
499
500    /**
501     * This should only be used in the case where we want to save the
502     * data to the database.
503     *
504     * @param tempStorage A Map.
505     */
506    @Override
507    public void setTempStorage(Map<String, Object> tempStorage)
508    {
509        if (tempStorage != null)
510        {
511            this.tempStorage = tempStorage;
512        }
513    }
514
515    /**
516     * Get an object from permanent storage.
517     *
518     * @param name The object's name.
519     * @return An Object with the given name.
520     */
521    @Override
522    public Object getPerm(String name)
523    {
524        return getPermStorage().get(name);
525    }
526
527    /**
528     * Get an object from permanent storage; return default if value
529     * is null.
530     *
531     * @param name The object's name.
532     * @param def A default value to return.
533     * @return An Object with the given name.
534     */
535    @Override
536    public Object getPerm(String name, Object def)
537    {
538        try
539        {
540            Object val = getPermStorage().get(name);
541            return (val == null ? def : val);
542        }
543        catch (Exception e)
544        {
545            return def;
546        }
547    }
548
549    /**
550     * Put an object into permanent storage.
551     *
552     * @param name The object's name.
553     * @param value The object.
554     */
555    @Override
556    public void setPerm(String name, Object value)
557    {
558        getPermStorage().put(name, value);
559    }
560
561    /**
562     * Get an object from temporary storage.
563     *
564     * @param name The object's name.
565     * @return An Object with the given name.
566     */
567    @Override
568    public Object getTemp(String name)
569    {
570        return getTempStorage().get(name);
571    }
572
573    /**
574     * Get an object from temporary storage; return default if value
575     * is null.
576     *
577     * @param name The object's name.
578     * @param def A default value to return.
579     * @return An Object with the given name.
580     */
581    @Override
582    public Object getTemp(String name, Object def)
583    {
584        Object val;
585        try
586        {
587            val = getTempStorage().get(name);
588            if (val == null)
589            {
590                val = def;
591            }
592        }
593        catch (Exception e)
594        {
595            val = def;
596        }
597        return val;
598    }
599
600    /**
601     * Put an object into temporary storage.
602     *
603     * @param name The object's name.
604     * @param value The object.
605     */
606    @Override
607    public void setTemp(String name, Object value)
608    {
609        getTempStorage().put(name, value);
610    }
611
612    /**
613     * Remove an object from temporary storage and return the object.
614     *
615     * @param name The name of the object to remove.
616     * @return An Object.
617     */
618    @Override
619    public Object removeTemp(String name)
620    {
621        return getTempStorage().remove(name);
622    }
623
624    /**
625     * Returns the confirm value of the user
626     *
627     * @return The confirm value of the user
628     */
629    @Override
630    public String getConfirmed()
631    {
632        return (String) getPerm(User.CONFIRM_VALUE);
633    }
634
635    /**
636     * Sets the new confirm value of the user
637     *
638     * @param confirm The new confirm value of the user
639     */
640    @Override
641    public void setConfirmed(String confirm)
642    {
643        setPerm(User.CONFIRM_VALUE, confirm);
644    }
645
646    /**
647     * Returns the creation date of the user
648     *
649     * @return The creation date of the user
650     */
651    @Override
652    public java.util.Date getCreateDate()
653    {
654        return (java.util.Date)getPerm(CREATE_DATE, new java.util.Date());
655    }
656
657    /**
658     * Sets the new creation date of the user
659     *
660     * @param createDate The new creation date of the user
661     */
662    @Override
663    public void setCreateDate(java.util.Date createDate)
664    {
665        setPerm(CREATE_DATE, createDate);
666    }
667
668    /**
669     * Returns the date of the last login of the user
670     *
671     * @return The date of the last login of the user
672     */
673    @Override
674    public java.util.Date getLastLogin()
675    {
676        return (java.util.Date) getPerm(User.LAST_LOGIN);
677    }
678
679    /**
680     * Sets the new date of the last login of the user
681     *
682     * @param lastLogin The new the date of the last login of the user
683     */
684    @Override
685    public void setLastLogin(java.util.Date lastLogin)
686    {
687        setPerm(User.LAST_LOGIN, lastLogin);
688    }
689
690    /**
691     * The user is considered logged in if they have not timed out.
692     *
693     * @return Whether the user has logged in.
694     */
695    @Override
696    public boolean hasLoggedIn()
697    {
698        Boolean loggedIn = (Boolean) getTemp(User.HAS_LOGGED_IN);
699        return (loggedIn != null && loggedIn.booleanValue());
700    }
701
702    /**
703     * This sets whether or not someone has logged in.  hasLoggedIn()
704     * returns this value.
705     *
706     * @param value Whether someone has logged in or not.
707     */
708    @Override
709    public void setHasLoggedIn(Boolean value)
710    {
711        setTemp(User.HAS_LOGGED_IN, value);
712    }
713
714    /**
715     * This method reports whether or not the user has been confirmed
716     * in the system by checking the User.CONFIRM_VALUE
717     * column in the users record to see if it is equal to
718     * User.CONFIRM_DATA.
719     *
720     * @return True if the user has been confirmed.
721     */
722    @Override
723    public boolean isConfirmed()
724    {
725        String value = getConfirmed();
726        return (value != null && value.equals(User.CONFIRM_DATA));
727    }
728
729    /**
730     * Updates the last login date in the database.
731     *
732     * @throws Exception A generic exception.
733     */
734    @Override
735    public void updateLastLogin()
736        throws Exception
737    {
738        setLastLogin(new java.util.Date());
739    }
740
741    /* (non-Javadoc)
742         * @see org.apache.turbine.om.security.UserDelegate#getUserDelegate()
743         */
744    @Override
745        public TurbineUser getUserDelegate()
746    {
747        return userDelegate;
748    }
749
750    /* (non-Javadoc)
751         * @see org.apache.turbine.om.security.UserDelegate#setUserDelegate(org.apache.fulcrum.security.model.turbine.entity.TurbineUser)
752         */
753    @Override
754        public void setUserDelegate(TurbineUser userDelegate)
755    {
756        this.userDelegate = userDelegate;
757    }
758}