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.util.Date;
023import java.util.HashMap;
024import java.util.Map;
025import java.util.Set;
026
027import javax.servlet.http.HttpSessionBindingEvent;
028
029import org.apache.fulcrum.security.model.turbine.entity.TurbineUser;
030import org.apache.fulcrum.security.model.turbine.entity.TurbineUserGroupRole;
031import org.apache.fulcrum.security.util.DataBackendException;
032import org.apache.turbine.services.TurbineServices;
033import org.apache.turbine.services.security.SecurityService;
034import org.apache.turbine.util.ObjectUtils;
035
036/**
037 * This is the Default user implementation. It is a wrapper around
038 * a TurbineUser object
039 *
040 * @author <a href="mailto:tv@apache.org">Thomas Vandahl</a>
041 * @version $Id: TorqueUser.java 1199856 2011-11-09 17:06:04Z tv $
042 */
043
044public class DefaultUserImpl implements User
045{
046    /** Serial version */
047    private static final long serialVersionUID = -1866504873085624111L;
048
049    /** The date on which the user last accessed the application. */
050    private Date lastAccessDate = null;
051
052    /** This is data that will survive a servlet engine restart. */
053    private Map<String, Object> permStorage = null;
054
055    /** This is data that will not survive a servlet engine restart. */
056    private Map<String, Object> tempStorage = null;
057
058    /** The Fulcrum user instance to delegate to */
059    private TurbineUser userDelegate = null;
060
061    /**
062     * Constructor
063     *
064     * @param user the user object to wrap
065     */
066    public DefaultUserImpl(TurbineUser user)
067    {
068        super();
069        setUserDelegate( user );
070        setCreateDate(new Date());
071        tempStorage = new HashMap<>(10);
072        setHasLoggedIn(Boolean.FALSE);
073    }
074
075    /**
076     * Implement this method if you wish to be notified when the User
077     * has been Bound to the session.
078     *
079     * @param hsbe Indication of value/session binding.
080     */
081    @Override
082    public void valueBound(HttpSessionBindingEvent hsbe)
083    {
084        // Currently we have no need for this method.
085    }
086
087    /**
088     * Implement this method if you wish to be notified when the User
089     * has been Unbound from the session.
090     *
091     * @param hsbe Indication of value/session unbinding.
092     */
093    @Override
094    public void valueUnbound(HttpSessionBindingEvent hsbe)
095    {
096        try
097        {
098            if (hasLoggedIn())
099            {
100                SecurityService securityService =
101                        (SecurityService)TurbineServices.getInstance()
102                            .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            e.printStackTrace(System.out);
114        }
115    }
116
117    /**
118     * Get the Name of the SecurityEntity.
119     *
120     * @return The Name of the SecurityEntity.
121     */
122    @Override
123    public String getName()
124    {
125        return userDelegate.getName();
126    }
127
128    /**
129     * Sets the Name of the SecurityEntity.
130     *
131     * @param name
132     *            Name of the SecurityEntity.
133     */
134    @Override
135    public void setName(String name)
136    {
137        userDelegate.setName(name);
138    }
139
140    /**
141     * Get the Id of the SecurityEntity.
142     *
143     * @return The Id of the SecurityEntity.
144     */
145    @Override
146    public Object getId()
147    {
148        return userDelegate.getId();
149    }
150
151    /**
152     * Sets the Id of the SecurityEntity.
153     *
154     * @param id
155     *            The new Id of the SecurityEntity
156     */
157    @Override
158    public void setId(Object id)
159    {
160        userDelegate.setId(id);
161    }
162
163    /**
164     * Returns the user's password. This method should not be used by
165     * the application directly, because it's meaning depends upon
166     * the implementation of UserManager that manages this particular
167     * user object. Some implementations will use this attribute for
168     * storing a password encrypted in some way, other will not use
169     * it at all, when user entered password is presented to some external
170     * authority (like NT domain controller) to validate it.
171     * See also {@link org.apache.turbine.services.security.UserManager#authenticate(User,String)}.
172     *
173     * @return A String with the password for the user.
174     */
175    @Override
176    public String getPassword()
177    {
178        return userDelegate.getPassword();
179    }
180
181    /**
182     * Set password. Application should not use this method
183     * directly, see {@link #getPassword()}.
184     * See also {@link org.apache.turbine.services.security.UserManager#changePassword(User,String,String)}.
185     *
186     * @param password The new password.
187     */
188    @Override
189    public void setPassword(String password)
190    {
191        userDelegate.setPassword(password);
192    }
193
194    /**
195     * Returns the first name for this user.
196     *
197     * @return A String with the user's first name.
198     */
199    @Override
200    public String getFirstName()
201    {
202        return userDelegate.getFirstName();
203    }
204
205    /**
206     * Sets the first name for this user.
207     *
208     * @param firstName User's first name.
209     */
210    @Override
211    public void setFirstName(String firstName)
212    {
213        userDelegate.setFirstName(firstName);
214    }
215
216    /**
217     * Returns the last name for this user.
218     *
219     * @return A String with the user's last name.
220     */
221    @Override
222    public String getLastName()
223    {
224        return userDelegate.getLastName();
225    }
226
227    /**
228     * Sets the last name for this user.
229     *
230     * @param lastName User's last name.
231     */
232    @Override
233    public void setLastName(String lastName)
234    {
235        userDelegate.setLastName(lastName);
236    }
237
238    /**
239     * Returns the email address for this user.
240     *
241     * @return A String with the user's email address.
242     */
243    @Override
244    public String getEmail()
245    {
246        return userDelegate.getEmail();
247    }
248
249    /**
250     * Sets the email address.
251     *
252     * @param address The email address.
253     */
254    @Override
255    public void setEmail(String address)
256    {
257        userDelegate.setEmail(address);
258    }
259
260    /**
261     * Returns the value of the objectdata for this user.
262     * Objectdata is a storage area used
263     * to store the permanent storage table from the User
264     * object.
265     *
266     * @return The bytes in the objectdata for this user
267     */
268    @Override
269    public byte[] getObjectdata()
270    {
271        return userDelegate.getObjectdata();
272    }
273
274    /**
275     * Sets the value of the objectdata for the user
276     *
277     * @param objectdata The new permanent storage for the user
278     */
279    @Override
280    public void setObjectdata(byte[] objectdata)
281    {
282        userDelegate.setObjectdata(objectdata);
283    }
284
285    /**
286     * Get the User/Group/Role set associated with this entity
287     *
288     * @return a set of User/Group/Role relations
289     * @throws DataBackendException if there was an error accessing the data
290     *         backend.
291     */
292    @Override
293    public <T extends TurbineUserGroupRole> Set<T> getUserGroupRoleSet() throws DataBackendException
294    {
295        return userDelegate.getUserGroupRoleSet();
296    }
297
298    /**
299     * Set the User/Group/Role set associated with this entity
300     *
301     * @param userGroupRoleSet
302     *            a set of User/Group/Role relations
303     */
304    @Override
305    public <T extends TurbineUserGroupRole> void setUserGroupRoleSet(Set<T> userGroupRoleSet)
306    {
307        userDelegate.setUserGroupRoleSet(userGroupRoleSet);
308    }
309
310    /**
311     * Add a User/Group/Role relation to this entity
312     *
313     * @param userGroupRole
314     *            a User/Group/Role relation to add
315     * @throws DataBackendException if there was an error accessing the data
316     *         backend.
317     */
318    @Override
319    public void addUserGroupRole(TurbineUserGroupRole userGroupRole) throws DataBackendException
320    {
321        userDelegate.addUserGroupRole(userGroupRole);
322    }
323
324    /**
325     * Remove a User/Group/Role relation from this entity
326     *
327     * @param userGroupRole
328     *            a User/Group/Role relation to remove
329     * @throws DataBackendException if there was an error accessing the data
330     *         backend.
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 Date getLastAccessDate()
424    {
425        if (lastAccessDate == null)
426        {
427            setLastAccessDate();
428        }
429        return Date.from( lastAccessDate.toInstant()); //immutable
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 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 synchronized 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<>();
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<>();
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 Date getCreateDate()
653    {
654        return (Date)getPerm(CREATE_DATE, new 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(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 Date getLastLogin()
675    {
676        return (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(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 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}