1 package org.apache.turbine.services.security.ldap;
2
3 /*
4 * Licensed to the Apache Software Foundation (ASF) under one
5 * or more contributor license agreements. See the NOTICE file
6 * distributed with this work for additional information
7 * regarding copyright ownership. The ASF licenses this file
8 * to you under the Apache License, Version 2.0 (the
9 * "License"); you may not use this file except in compliance
10 * with the License. You may obtain a copy of the License at
11 *
12 * http://www.apache.org/licenses/LICENSE-2.0
13 *
14 * Unless required by applicable law or agreed to in writing,
15 * software distributed under the License is distributed on an
16 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17 * KIND, either express or implied. See the License for the
18 * specific language governing permissions and limitations
19 * under the License.
20 */
21
22 import java.io.ByteArrayOutputStream;
23 import java.io.PrintWriter;
24 import java.sql.Connection;
25 import java.util.Hashtable;
26
27 import javax.naming.NamingException;
28 import javax.naming.directory.Attribute;
29 import javax.naming.directory.Attributes;
30 import javax.naming.directory.BasicAttribute;
31 import javax.naming.directory.BasicAttributes;
32 import javax.servlet.http.HttpSessionBindingEvent;
33
34 import org.apache.commons.logging.Log;
35 import org.apache.commons.logging.LogFactory;
36 import org.apache.turbine.om.security.User;
37 import org.apache.turbine.services.security.TurbineSecurity;
38
39 /**
40 * LDAPUser implements User and provides access to a user who accesses the
41 * system via LDAP.
42 *
43 * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a>
44 * @author <a href="mailto:tadewunmi@gluecode.com">Tracy M. Adewunmi</a>
45 * @author <a href="mailto:lflournoy@gluecode.com">Leonard J. Flournoy </a>
46 * @author <a href="mailto:dlr@finemaltcoding.com">Daniel Rall</a>
47 * @author <a href="mailto:hhernandez@itweb.com.mx">Humberto Hernandez</a>
48 */
49 public class LDAPUser implements User
50 {
51
52 /** Logging */
53 private static Log log = LogFactory.getLog(LDAPUser.class);
54
55 /* A few attributes common to a User. */
56
57 /** Date when the user was created */
58 private java.util.Date createDate = null;
59
60 /** Date when the user was last accessed */
61 private java.util.Date lastAccessDate = null;
62
63 /** timeout */
64 private int timeout = 15;
65
66 /** This is data that will survive a servlet engine restart. */
67 private Hashtable permStorage = null;
68
69 /** This is data that will not survive a servlet engine restart. */
70 private Hashtable tempStorage = null;
71
72 /**
73 * Constructor.
74 * Create a new User and set the createDate.
75 */
76 public LDAPUser()
77 {
78 createDate = new java.util.Date();
79 tempStorage = new Hashtable(10);
80 permStorage = new Hashtable(10);
81 setHasLoggedIn(Boolean.FALSE);
82 }
83
84 /**
85 * Populates the user with values obtained from the LDAP Service.
86 * This method could be redefined in subclasses.
87 * @param attribs The attributes obtained from LDAP.
88 * @throws NamingException if there was an error with JNDI.
89 */
90 public void setLDAPAttributes(Attributes attribs)
91 throws NamingException
92 {
93
94 Attribute attr;
95 String attrName;
96
97 // Set the User id.
98 attrName = LDAPSecurityConstants.getUserIdAttribute();
99 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 }