001    package org.apache.turbine.services.security.ldap;
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    
022    import java.io.ByteArrayOutputStream;
023    import java.io.PrintWriter;
024    import java.sql.Connection;
025    import java.util.Hashtable;
026    
027    import javax.naming.NamingException;
028    import javax.naming.directory.Attribute;
029    import javax.naming.directory.Attributes;
030    import javax.naming.directory.BasicAttribute;
031    import javax.naming.directory.BasicAttributes;
032    import javax.servlet.http.HttpSessionBindingEvent;
033    
034    import org.apache.commons.logging.Log;
035    import org.apache.commons.logging.LogFactory;
036    import org.apache.turbine.om.security.User;
037    import org.apache.turbine.services.security.TurbineSecurity;
038    
039    /**
040     * LDAPUser implements User and provides access to a user who accesses the
041     * system via LDAP.
042     *
043     * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a>
044     * @author <a href="mailto:tadewunmi@gluecode.com">Tracy M. Adewunmi</a>
045     * @author <a href="mailto:lflournoy@gluecode.com">Leonard J. Flournoy </a>
046     * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
047     * @author <a href="mailto:hhernandez@itweb.com.mx">Humberto Hernandez</a>
048     */
049    public class LDAPUser implements User
050    {
051    
052        /** Logging */
053        private static Log log = LogFactory.getLog(LDAPUser.class);
054    
055        /* A few attributes common to a User. */
056    
057        /** Date when the user was created */
058        private java.util.Date createDate = null;
059    
060        /** Date when the user was last accessed */
061        private java.util.Date lastAccessDate = null;
062    
063        /** timeout */
064        private int timeout = 15;
065    
066        /** This is data that will survive a servlet engine restart. */
067        private Hashtable permStorage = null;
068    
069        /** This is data that will not survive a servlet engine restart. */
070        private Hashtable tempStorage = null;
071    
072        /**
073         * Constructor.
074         * Create a new User and set the createDate.
075         */
076        public LDAPUser()
077        {
078            createDate = new java.util.Date();
079            tempStorage = new Hashtable(10);
080            permStorage = new Hashtable(10);
081            setHasLoggedIn(Boolean.FALSE);
082        }
083    
084        /**
085         * Populates the user with values obtained from the LDAP Service.
086         * This method could be redefined in subclasses.
087         * @param attribs The attributes obtained from LDAP.
088         * @throws NamingException if there was an error with JNDI.
089         */
090        public void setLDAPAttributes(Attributes attribs)
091                throws NamingException
092        {
093    
094            Attribute attr;
095            String attrName;
096    
097            // Set the User id.
098            attrName = LDAPSecurityConstants.getUserIdAttribute();
099            if (attrName != null)
100            {
101                attr = attribs.get(attrName);
102                if (attr != null && attr.get() != null)
103                {
104                    try
105                    {
106                        //setPrimaryKey(attr.get().toString());
107                    }
108                    catch (Exception ex)
109                    {
110                        log.error("Exception caught:", ex);
111                    }
112                }
113            }
114    
115            // Set the Username.
116            attrName = LDAPSecurityConstants.getNameAttribute();
117            if (attrName != null)
118            {
119                attr = attribs.get(attrName);
120                if (attr != null && attr.get() != null)
121                {
122                    setName(attr.get().toString());
123                }
124            }
125            else
126            {
127                log.error("There is no LDAP attribute for the username.");
128            }
129    
130            // Set the Firstname.
131            attrName = LDAPSecurityConstants.getFirstNameAttribute();
132            if (attrName != null)
133            {
134                attr = attribs.get(attrName);
135                if (attr != null && attr.get() != null)
136                {
137                    setFirstName(attr.get().toString());
138                }
139            }
140    
141            // Set the Lastname.
142            attrName = LDAPSecurityConstants.getLastNameAttribute();
143            if (attrName != null)
144            {
145                attr = attribs.get(attrName);
146                if (attr != null && attr.get() != null)
147                {
148                    setLastName(attr.get().toString());
149                }
150            }
151    
152            // Set the E-Mail
153            attrName = LDAPSecurityConstants.getEmailAttribute();
154            if (attrName != null)
155            {
156                attr = attribs.get(attrName);
157                if (attr != null && attr.get() != null)
158                {
159                    setEmail(attr.get().toString());
160                }
161            }
162        }
163    
164        /**
165         * Get the JNDI Attributes used to store the user in LDAP.
166         * This method could be redefined in a subclass.
167         *
168         * @throws NamingException if there is a JNDI error.
169         * @return The JNDI attributes of the user.
170         */
171        public Attributes getLDAPAttributes()
172                throws NamingException
173        {
174            Attributes attribs = new BasicAttributes();
175            String attrName;
176    
177            // Set the objectClass
178            attrName = "objectClass";
179            if (attrName != null)
180            {
181                Object value = "turbineUser";
182    
183                if (value != null)
184                {
185                    Attribute attr = new BasicAttribute(attrName, value);
186    
187                    attribs.put(attr);
188                }
189            }
190    
191            // Set the User id.
192            attrName = LDAPSecurityConstants.getUserIdAttribute();
193            if (attrName != null)
194            {
195                Object value = this.getIdAsObj();
196    
197                if (value != null)
198                {
199                    Attribute attr = new BasicAttribute(attrName, value);
200    
201                    attribs.put(attr);
202                }
203            }
204    
205            // Set the Username.
206            attrName = LDAPSecurityConstants.getNameAttribute();
207            if (attrName != null)
208            {
209                Object value = getName();
210    
211                if (value != null)
212                {
213                    Attribute attr = new BasicAttribute(attrName, value);
214    
215                    attribs.put(attr);
216                }
217            }
218    
219            // Set the Firstname.
220            attrName = LDAPSecurityConstants.getFirstNameAttribute();
221            if (attrName != null)
222            {
223                Object value = getFirstName();
224    
225                if (value != null)
226                {
227                    Attribute attr = new BasicAttribute(attrName, value);
228    
229                    attribs.put(attr);
230                }
231            }
232    
233            // Set the Lastname.
234            attrName = LDAPSecurityConstants.getLastNameAttribute();
235            if (attrName != null)
236            {
237                Object value = getLastName();
238    
239                if (value != null)
240                {
241                    Attribute attr = new BasicAttribute(attrName, value);
242    
243                    attribs.put(attr);
244                }
245            }
246    
247            // Set the E-Mail.
248            attrName = LDAPSecurityConstants.getEmailAttribute();
249            if (attrName != null)
250            {
251                Object value = getEmail();
252    
253                if (value != null)
254                {
255                    Attribute attr = new BasicAttribute(attrName, value);
256    
257                    attribs.put(attr);
258                }
259            }
260    
261            // Set the Password
262            attrName = LDAPSecurityConstants.getPasswordAttribute();
263            if (attrName != null)
264            {
265                Object value = getPassword();
266    
267                if (value != null)
268                {
269                    Attribute attr = new BasicAttribute(attrName, value);
270    
271                    attribs.put(attr);
272                }
273            }
274    
275            return attribs;
276        }
277    
278        /**
279         * Gets the distinguished name (DN) of the User.
280         * This method could be redefined in a subclass.
281         * @return The Distinguished Name of the user.
282         */
283        public String getDN()
284        {
285            String filterAttribute = LDAPSecurityConstants.getNameAttribute();
286            String userBaseSearch = LDAPSecurityConstants.getBaseSearch();
287            String userName = getName();
288    
289            String dn = filterAttribute + "=" + userName + "," + userBaseSearch;
290    
291            return dn;
292        }
293    
294        /**
295         * Gets the access counter for a user during a session.
296         *
297         * @return The access counter for the user for the session.
298         */
299        public int getAccessCounterForSession()
300        {
301            try
302            {
303                return ((Integer) getTemp(User.SESSION_ACCESS_COUNTER)).intValue();
304            }
305            catch (Exception e)
306            {
307                return 0;
308            }
309        }
310    
311        /**
312         * Gets the access counter for a user from perm storage.
313         *
314         * @return The access counter for the user.
315         */
316        public int getAccessCounter()
317        {
318            try
319            {
320                return ((Integer) getPerm(User.ACCESS_COUNTER)).intValue();
321            }
322            catch (Exception e)
323            {
324                return 0;
325            }
326        }
327    
328        /**
329         * Gets the create date for this User.  This is the time at which
330         * the user object was created.
331         *
332         * @return A Java Date with the date of creation for the user.
333         */
334        public java.util.Date getCreateDate()
335        {
336            return createDate;
337        }
338    
339        /**
340         * Returns the value of Confirmed variable
341         * @return the confirm value.
342         */
343        public String getConfirmed()
344        {
345            String tmp = null;
346    
347            tmp = (String) getPerm(User.CONFIRM_VALUE);
348            if (tmp != null && tmp.length() == 0)
349            {
350                tmp = null;
351            }
352            return tmp;
353        }
354    
355        /**
356         * Returns the Email for this user.  If this is defined, then
357         * the user is considered logged in.
358         *
359         * @return A String with the user's Email.
360         */
361        public String getEmail()
362        {
363            String tmp = null;
364    
365            tmp = (String) getPerm(User.EMAIL);
366            if (tmp != null && tmp.length() == 0)
367            {
368                tmp = null;
369            }
370            return tmp;
371        }
372    
373        /**
374         * Gets the last access date for this User.  This is the last time
375         * that the user object was referenced.
376         *
377         * @return A Java Date with the last access date for the user.
378         */
379        public java.util.Date getLastAccessDate()
380        {
381            if (lastAccessDate == null)
382            {
383                setLastAccessDate();
384            }
385            return lastAccessDate;
386        }
387    
388        /**
389         * Get last login date/time for this user.
390         *
391         * @return A Java Date with the last login date for the user.
392         */
393        public java.util.Date getLastLogin()
394        {
395            return (java.util.Date) getPerm(User.LAST_LOGIN);
396        }
397    
398        /**
399         * Get password for this user.
400         *
401         * @return A String with the password for the user.
402         */
403        public String getPassword()
404        {
405            return (String) getPerm(User.PASSWORD);
406        }
407    
408        /**
409         * Get an object from permanent storage.
410         * @param name The object's name.
411         * @return An Object with the given name.
412         */
413        public Object getPerm(String name)
414        {
415            return permStorage.get(name);
416        }
417    
418        /**
419         * Get an object from permanent storage; return default if value
420         * is null.
421         *
422         * @param name The object's name.
423         * @param def A default value to return.
424         * @return An Object with the given name.
425         */
426        public Object getPerm(String name, Object def)
427        {
428            try
429            {
430                Object val = permStorage.get(name);
431    
432                if (val == null)
433                {
434                    return def;
435                }
436                return val;
437            }
438            catch (Exception e)
439            {
440                return def;
441            }
442        }
443    
444        /**
445         * This should only be used in the case where we want to save the
446         * data to the database.
447         *
448         * @return A Hashtable.
449         */
450        public Hashtable getPermStorage()
451        {
452            if (this.permStorage == null)
453            {
454                this.permStorage = new Hashtable();
455            }
456            return this.permStorage;
457        }
458    
459        /**
460         * Get an object from temporary storage.
461         *
462         * @param name The object's name.
463         * @return An Object with the given name.
464         */
465        public Object getTemp(String name)
466        {
467            return tempStorage.get(name);
468        }
469    
470        /**
471         * Get an object from temporary storage; return default if value
472         * is null.
473         *
474         * @param name The object's name.
475         * @param def A default value to return.
476         * @return An Object with the given name.
477         */
478        public Object getTemp(String name, Object def)
479        {
480            Object val;
481    
482            try
483            {
484                val = tempStorage.get(name);
485                if (val == null)
486                {
487                    val = def;
488                }
489            }
490            catch (Exception e)
491            {
492                val = def;
493            }
494            return val;
495        }
496    
497        /**
498         * A User object can have a variable Timeout, which is defined in
499         * minutes.  If the user has been timed out, then the
500         * hasLoggedIn() value will return false.
501         *
502         * @return An int specifying the timeout.
503         */
504        public int getTimeout()
505        {
506            return this.timeout;
507        }
508    
509    
510        /**
511         * Returns the first name for this user.  If this is defined, then
512         * the user is considered logged in.
513         *
514         * @return A String with the user's first name.
515         */
516        public String getFirstName()
517        {
518            String tmp = null;
519    
520            tmp = (String) getPerm(User.FIRST_NAME);
521            if (tmp != null && tmp.length() == 0)
522            {
523                tmp = null;
524            }
525            return tmp;
526        }
527    
528        /**
529         * Returns the last name for this user.  If this is defined, then
530         * the user is considered logged in.
531         *
532         * @return A String with the user's last name.
533         */
534        public String getLastName()
535        {
536            String tmp = null;
537    
538            tmp = (String) getPerm(User.LAST_NAME);
539            if (tmp != null && tmp.length() == 0)
540            {
541                tmp = null;
542            }
543            return tmp;
544        }
545    
546        /**
547         * The user is considered logged in if they have not timed out.
548         *
549         * @return True if the user has logged in.
550         */
551        public boolean hasLoggedIn()
552        {
553            Boolean tmp = getHasLoggedIn();
554    
555            if (tmp != null && tmp.booleanValue())
556            {
557                return true;
558            }
559            else
560            {
561                return false;
562            }
563        }
564    
565        /**
566         * This method reports whether or not the user has been confirmed
567         * in the system by checking the <code>CONFIRM_VALUE</code>
568         * column to see if it is equal to <code>CONFIRM_DATA</code>.
569         *
570         * @return True if the user has been confirmed.
571         */
572        public boolean isConfirmed()
573        {
574            return ((String) getTemp(CONFIRM_VALUE, "")).equals(CONFIRM_DATA);
575        }
576    
577        /**
578         * Increments the permanent hit counter for the user.
579         */
580        public void incrementAccessCounter()
581        {
582            setAccessCounter(getAccessCounter() + 1);
583        }
584    
585        /**
586         * Increments the session hit counter for the user.
587         */
588        public void incrementAccessCounterForSession()
589        {
590            setAccessCounterForSession(getAccessCounterForSession() + 1);
591        }
592    
593        /**
594         * Remove an object from temporary storage and return the object.
595         *
596         * @param name The name of the object to remove.
597         * @return An Object.
598         */
599        public Object removeTemp(String name)
600        {
601            return tempStorage.remove(name);
602        }
603    
604        /**
605         * Sets the access counter for a user, saved in perm storage.
606         *
607         * @param cnt The new count.
608         */
609        public void setAccessCounter(int cnt)
610        {
611            setPerm(User.ACCESS_COUNTER, new Integer(cnt));
612        }
613    
614        /**
615         * Sets the session access counter for a user, saved in temp
616         * storage.
617         *
618         * @param cnt The new count.
619         */
620        public void setAccessCounterForSession(int cnt)
621        {
622            setTemp(User.SESSION_ACCESS_COUNTER, new Integer(cnt));
623        }
624    
625        /**
626         * Set the users confirmed variable
627         *
628         * @param confirm The new confim value.
629         */
630        public void setConfirmed(String confirm)
631        {
632            getPerm(User.CONFIRM_VALUE, confirm);
633        }
634    
635        /**
636         * Sets the last access date for this User. This is the last time
637         * that the user object was referenced.
638         */
639        public void setLastAccessDate()
640        {
641            lastAccessDate = new java.util.Date();
642        }
643    
644        /**
645         * Sets the create date for this User. This is the time at which
646         * the user object was created.
647         *
648         * @param date The create date.
649         */
650        public void setCreateDate(java.util.Date date)
651        {
652            createDate = date;
653        }
654    
655        /**
656         * Set the users Email
657         *
658         * @param email The new email.
659         */
660        public void setEmail(String email)
661        {
662            setPerm(User.EMAIL, email);
663        }
664    
665        /**
666         * Set the users First Name
667         *
668         * @param fname The new firstname.
669         */
670        public void setFirstName(String fname)
671        {
672            setPerm(User.FIRST_NAME, fname);
673        }
674    
675        /**
676         * Set last login date/time.
677         *
678         * @param date The last login date.
679         */
680        public void setLastLogin(java.util.Date date)
681        {
682            setPerm(User.LAST_LOGIN, date);
683        }
684    
685        /**
686         * Set the users Last Name
687         * Sets the last name for this user.
688         *
689         * @param lname The new lastname.
690         */
691        public void setLastName(String lname)
692        {
693            setPerm(User.LAST_NAME, lname);
694        }
695    
696        /**
697         * Set password.
698         *
699         * @param password The new password.
700         */
701        public void setPassword(String password)
702        {
703            setPerm(User.PASSWORD, password);
704        }
705    
706        /**
707         * Put an object into permanent storage.
708         *
709         * @param name The object's name.
710         * @param value The object.
711         */
712        public void setPerm(String name, Object value)
713        {
714            permStorage.put(name, value);
715        }
716    
717        /**
718         * This should only be used in the case where we want to save the
719         * data to the database.
720         *
721         * @param stuff A Hashtable.
722         */
723        public void setPermStorage(Hashtable stuff)
724        {
725            this.permStorage = stuff;
726        }
727    
728        /**
729         * This should only be used in the case where we want to save the
730         * data to the database.
731         *
732         * @return A Hashtable.
733         */
734        public Hashtable getTempStorage()
735        {
736            if (this.tempStorage == null)
737            {
738                this.tempStorage = new Hashtable();
739            }
740            return this.tempStorage;
741        }
742    
743        /**
744         * This should only be used in the case where we want to save the
745         * data to the database.
746         *
747         * @param storage A Hashtable.
748         */
749        public void setTempStorage(Hashtable storage)
750        {
751            this.tempStorage = storage;
752        }
753    
754        /**
755         * This gets whether or not someone has logged in.  hasLoggedIn()
756         * returns this value as a boolean.  This is private because you
757         * should use hasLoggedIn() instead.
758         *
759         * @return True if someone has logged in.
760         */
761        private Boolean getHasLoggedIn()
762        {
763            return (Boolean) getTemp(User.HAS_LOGGED_IN);
764        }
765    
766        /**
767         * This sets whether or not someone has logged in.  hasLoggedIn()
768         * returns this value.
769         *
770         * @param value Whether someone has logged in or not.
771         */
772        public void setHasLoggedIn(Boolean value)
773        {
774            setTemp(User.HAS_LOGGED_IN, value);
775        }
776    
777        /**
778         * Put an object into temporary storage.
779         *
780         * @param name The object's name.
781         * @param value The object.
782         */
783        public void setTemp(String name, Object value)
784        {
785            tempStorage.put(name, value);
786        }
787    
788        /**
789         * A User object can have a variable Timeout which is defined in
790         * minutes.  If the user has been timed out, then the
791         * hasLoggedIn() value will return false.
792         *
793         * @param time The user's timeout.
794         */
795        public void setTimeout(int time)
796        {
797            this.timeout = time;
798        }
799    
800        /**
801         * Updates the last login date in the database.
802         *
803         * @exception Exception a generic exception.
804         */
805        public void updateLastLogin() throws Exception
806        {
807            setPerm(User.LAST_LOGIN, new java.util.Date());
808        }
809    
810        /**
811         * Implement this method if you wish to be notified when the User
812         * has been Bound to the session.
813         *
814         * @param hsbe The HttpSessionBindingEvent.
815         */
816        public void valueBound(HttpSessionBindingEvent hsbe)
817        {
818            // Do not currently need this method.
819        }
820    
821        /**
822         * Implement this method if you wish to be notified when the User
823         * has been Unbound from the session.
824         *
825         * @param hsbe The HttpSessionBindingEvent.
826         */
827        public void valueUnbound(HttpSessionBindingEvent hsbe)
828        {
829            try
830            {
831                if (hasLoggedIn())
832                {
833                    TurbineSecurity.saveUser(this);
834                }
835            }
836            catch (Exception e)
837            {
838                log.error("BaseUser.valueUnbobund(): "
839                        + e.getMessage());
840                log.error(e);
841    
842                // To prevent messages being lost in case the logging system
843                // goes away before sessions get unbound on servlet container
844                // shutdown, print the stcktrace to the container's console.
845                ByteArrayOutputStream ostr = new ByteArrayOutputStream();
846    
847                e.printStackTrace(new PrintWriter(ostr, true));
848                String stackTrace = ostr.toString();
849    
850                System.out.println(stackTrace);
851            }
852        }
853    
854        /**
855         * Returns the username for this user.  If this is defined, then
856         * the user is considered logged in.
857         *
858         * @return A String with the username.
859         */
860        public String getName()
861        {
862            String tmp = null;
863    
864            tmp = (String) getPerm(User.USERNAME);
865            if (tmp != null && tmp.length() == 0)
866            {
867                tmp = null;
868            }
869            return tmp;
870        }
871    
872        /**
873         * Set the users name.
874         * @param name the name of the User.
875         */
876        public void setName(String name)
877        {
878                    setPerm(User.USERNAME, name);
879        }
880    
881        /**
882         * Not implemented.
883         * @return 0
884         */
885        public int getId()
886        {
887            return 0;
888        }
889    
890        /**
891         * Not implemented.
892         * @return null
893         */
894        public Integer getIdAsObj()
895        {
896            return new Integer(0);
897        }
898    
899        /**
900         * Not implemented.
901         *
902         * @param id The id of the User.
903         */
904        public void setId(int id)
905        {
906        }
907    
908        /**
909         * Saves this object to the data store.
910         * @throws Exception if it cannot be saved
911         */
912        public void save()
913                throws Exception
914        {
915            if (TurbineSecurity.accountExists(this))
916            {
917                TurbineSecurity.saveUser(this);
918            }
919            else
920            {
921                TurbineSecurity.addUser(this, getPassword());
922            }
923        }
924    
925        /**
926         * not implemented
927         *
928         * @param conn the database connection
929         * @throws Exception if there is an error
930         */
931        public void save(Connection conn) throws Exception
932        {
933            throw new Exception("not implemented");
934        }
935    
936        /**
937         * not implemented
938         *
939         * @param dbname the database name
940         * @throws Exception if there is an error
941         */
942        public void save(String dbname) throws Exception
943        {
944            throw new Exception("not implemented");
945        }
946    
947    }