001 package org.apache.turbine.services.security.torque; 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.Date; 026 import java.util.Hashtable; 027 028 import javax.servlet.http.HttpSessionBindingEvent; 029 030 import org.apache.torque.om.Persistent; 031 import org.apache.turbine.om.security.User; 032 import org.apache.turbine.services.security.TurbineSecurity; 033 import org.apache.turbine.util.ObjectUtils; 034 import org.apache.turbine.util.security.TurbineSecurityException; 035 036 /** 037 * This is the User class used by the TorqueSecurity Service. It decouples 038 * all the database peer access from the actual Peer object 039 * 040 * @author <a href="mailto:josh@stonecottage.com">Josh Lucas</a> 041 * @author <a href="mailto:jon@collab.net">Jon S. Stevens</a> 042 * @author <a href="mailto:jmcnally@collab.net">John D. McNally</a> 043 * @author <a href="mailto:frank.kim@clearink.com">Frank Y. Kim</a> 044 * @author <a href="mailto:cberry@gluecode.com">Craig D. Berry</a> 045 * @author <a href="mailto:mpoeschl@marmot.at">Martin Poeschl</a> 046 * @author <a href="mailto:dlr@collab.net">Daniel Rall</a> 047 * @author <a href="mailto:hps@intermeta.de">Henning P. Schmiedehausen</a> 048 * @version $Id: TorqueUser.java 1096130 2011-04-23 10:37:19Z ludwig $ 049 */ 050 051 public class TorqueUser 052 extends TorqueObject 053 implements User 054 { 055 /** Serial Version UID */ 056 private static final long serialVersionUID = 6623129207135917717L; 057 058 /** The date on which the user last accessed the application. */ 059 private Date lastAccessDate = null; 060 061 /** This is data that will survive a servlet engine restart. */ 062 private Hashtable permStorage = null; 063 064 /** This is data that will not survive a servlet engine restart. */ 065 private Hashtable tempStorage = null; 066 067 /** 068 * Constructor. 069 * Create a new User and set the createDate. 070 */ 071 public TorqueUser() 072 { 073 super(); 074 setCreateDate(new Date()); 075 tempStorage = new Hashtable(10); 076 setHasLoggedIn(Boolean.FALSE); 077 } 078 079 /** 080 * This Constructor is used when the UserPeerManager 081 * has retrieved a list of Database Objects from the peer and 082 * must 'wrap' them into TorqueRole Objects. You should not use it directly! 083 * 084 * @param obj An Object from the peer 085 */ 086 public TorqueUser(Persistent obj) 087 { 088 super(obj); 089 090 // Do not set creation date. This is only called on retrieval from 091 // storage! 092 093 tempStorage = new Hashtable(10); 094 setHasLoggedIn(Boolean.FALSE); 095 } 096 097 /** 098 * Returns the underlying Object for the Peer 099 * 100 * Used in the UserPeerManager when building a new Criteria. 101 * 102 * @return The underlying persistent object 103 * 104 */ 105 106 public Persistent getPersistentObj() 107 { 108 if (obj == null) 109 { 110 obj = UserPeerManager.newPersistentInstance(); 111 } 112 return obj; 113 } 114 115 /** 116 * Stores the object in the database. If the object is new, 117 * it inserts it; otherwise an update is performed. 118 * 119 * @param torqueName The name under which the object should be stored. 120 * 121 * @exception Exception This method might throw an exceptions 122 */ 123 public void save(String torqueName) 124 throws Exception 125 { 126 setObjectdata(ObjectUtils.serializeHashtable(getPermStorage())); 127 super.save(torqueName); 128 } 129 130 /** 131 * Stores the object in the database. If the object is new, 132 * it inserts it; otherwise an update is performed. This method 133 * is meant to be used as part of a transaction, otherwise use 134 * the save() method and the connection details will be handled 135 * internally 136 * 137 * @param con A Connection object to save the object 138 * 139 * @exception Exception This method might throw an exceptions 140 */ 141 public void save(Connection con) 142 throws Exception 143 { 144 setObjectdata(ObjectUtils.serializeHashtable(getPermStorage())); 145 super.save(con); 146 } 147 148 /** 149 * Makes changes made to the User attributes permanent. 150 * 151 * @throws TurbineSecurityException if there is a problem while 152 * saving data. 153 */ 154 public void save() 155 throws TurbineSecurityException 156 { 157 // 158 // This is inconsistent with all the other security classes 159 // because it calls save() on the underlying object directly. 160 // But the UserManager calls ((Persistent)user).save() 161 // so if we do TurbineSecurity.saveUser(this) here, we get 162 // a nice endless loop. :-( 163 // 164 // Users seem to be a special kind of security objects... 165 // 166 167 try 168 { 169 setObjectdata(ObjectUtils.serializeHashtable(getPermStorage())); 170 getPersistentObj().save(); 171 } 172 catch (Exception e) 173 { 174 throw new TurbineSecurityException("User object said " 175 + e.getMessage(), e); 176 } 177 } 178 179 /** 180 * Returns the name of this object. 181 * 182 * @return The name of the object. 183 */ 184 public String getName() 185 { 186 return UserPeerManager.getName(getPersistentObj()); 187 } 188 189 /** 190 * Sets the name of this object 191 * 192 * @param name The name of the object 193 */ 194 public void setName(String name) 195 { 196 setUserName(name); 197 } 198 199 /** 200 * Gets the Id of this object 201 * 202 * @return The Id of the object 203 */ 204 public int getId() 205 { 206 return UserPeerManager.getIdAsObj(getPersistentObj()).intValue(); 207 } 208 209 /** 210 * Gets the Id of this object 211 * 212 * @return The Id of the object 213 */ 214 public Integer getIdAsObj() 215 { 216 return UserPeerManager.getIdAsObj(getPersistentObj()); 217 } 218 219 /** 220 * Sets the Id of this object 221 * 222 * @param id The new Id 223 */ 224 public void setId(int id) 225 { 226 UserPeerManager.setId(getPersistentObj(), id); 227 } 228 229 /** 230 * Returns the name of this user. 231 * 232 * @return The name of the user. 233 * @deprecated Use getName() instead. 234 */ 235 public String getUserName() 236 { 237 return getName(); 238 } 239 240 /** 241 * Sets the name of this user. 242 * 243 * @param name The name of the user. 244 */ 245 public void setUserName(String name) 246 { 247 UserPeerManager.setUserName(getPersistentObj(), name); 248 } 249 250 /** 251 * Returns the password of the User 252 * 253 * @return The password of the User 254 */ 255 public String getPassword() 256 { 257 return UserPeerManager.getUserPassword(getPersistentObj()); 258 } 259 260 /** 261 * Sets the password of the User 262 * 263 * @param password The new password of the User 264 */ 265 public void setPassword(String password) 266 { 267 UserPeerManager.setUserPassword(getPersistentObj(), password); 268 } 269 270 /** 271 * Returns the first name of the User 272 * 273 * @return The first name of the User 274 */ 275 public String getFirstName() 276 { 277 return UserPeerManager.getUserFirstName(getPersistentObj()); 278 } 279 280 /** 281 * Sets the first name of the User 282 * 283 * @param firstName The new first name of the User 284 */ 285 public void setFirstName(String firstName) 286 { 287 UserPeerManager.setUserFirstName(getPersistentObj(), firstName); 288 } 289 290 /** 291 * Returns the last name of the User 292 * 293 * @return The last name of the User 294 */ 295 public String getLastName() 296 { 297 return UserPeerManager.getUserLastName(getPersistentObj()); 298 } 299 300 /** 301 * Sets the last name of User 302 * 303 * @param lastName The new last name of the User 304 */ 305 public void setLastName(String lastName) 306 { 307 UserPeerManager.setUserLastName(getPersistentObj(), lastName); 308 } 309 310 /** 311 * Returns the email address of the user 312 * 313 * @return The email address of the user 314 */ 315 public String getEmail() 316 { 317 return UserPeerManager.getUserEmail(getPersistentObj()); 318 } 319 320 /** 321 * Sets the new email address of the user 322 * 323 * @param email The new email address of the user 324 */ 325 public void setEmail(String email) 326 { 327 UserPeerManager.setUserEmail(getPersistentObj(), email); 328 } 329 330 /** 331 * Returns the confirm value of the user 332 * 333 * @return The confirm value of the user 334 */ 335 public String getConfirmed() 336 { 337 return UserPeerManager.getUserConfirmed(getPersistentObj()); 338 } 339 340 /** 341 * Sets the new confirm value of the user 342 * 343 * @param confirm The new confirm value of the user 344 */ 345 public void setConfirmed(String confirm) 346 { 347 UserPeerManager.setUserConfirmed(getPersistentObj(), confirm); 348 } 349 350 /** 351 * Returns the creation date of the user 352 * 353 * @return The creation date of the user 354 */ 355 public java.util.Date getCreateDate() 356 { 357 return UserPeerManager.getUserCreateDate(getPersistentObj()); 358 } 359 360 /** 361 * Sets the new creation date of the user 362 * 363 * @param createDate The new creation date of the user 364 */ 365 public void setCreateDate(java.util.Date createDate) 366 { 367 UserPeerManager.setUserCreateDate(getPersistentObj(), createDate); 368 } 369 370 /** 371 * Returns the date of the last login of the user 372 * 373 * @return The date of the last login of the user 374 */ 375 public java.util.Date getLastLogin() 376 { 377 return UserPeerManager.getUserLastLogin(getPersistentObj()); 378 } 379 380 /** 381 * Sets the new date of the last login of the user 382 * 383 * @param lastLogin The new the date of the last login of the user 384 */ 385 public void setLastLogin(java.util.Date lastLogin) 386 { 387 UserPeerManager.setUserLastLogin(getPersistentObj(), lastLogin); 388 } 389 390 /** 391 * Returns the value of the objectdata for this user. 392 * Objectdata is a VARBINARY column in the table used 393 * to store the permanent storage table from the User 394 * object. 395 * 396 * @return The bytes in the objectdata for this user 397 */ 398 public byte [] getObjectdata() 399 { 400 return UserPeerManager.getUserObjectdata(getPersistentObj()); 401 } 402 403 /** 404 * Sets the value of the objectdata for the user 405 * 406 * @param objectdata The new the date of the last login of the user 407 */ 408 public void setObjectdata(byte [] objectdata) 409 { 410 UserPeerManager.setUserObjectdata(getPersistentObj(), objectdata); 411 } 412 413 414 /** 415 * Gets the access counter for a user from perm storage. 416 * 417 * @return The access counter for the user. 418 */ 419 public int getAccessCounter() 420 { 421 try 422 { 423 return ((Integer) getPerm(User.ACCESS_COUNTER)).intValue(); 424 } 425 catch (Exception e) 426 { 427 return 0; 428 } 429 } 430 431 /** 432 * Gets the access counter for a user during a session. 433 * 434 * @return The access counter for the user for the session. 435 */ 436 public int getAccessCounterForSession() 437 { 438 try 439 { 440 return ((Integer) getTemp(User.SESSION_ACCESS_COUNTER)).intValue(); 441 } 442 catch (Exception e) 443 { 444 return 0; 445 } 446 } 447 448 /** 449 * Increments the permanent hit counter for the user. 450 */ 451 public void incrementAccessCounter() 452 { 453 // Ugh. Race city, here I come... 454 setAccessCounter(getAccessCounter() + 1); 455 } 456 457 /** 458 * Increments the session hit counter for the user. 459 */ 460 public void incrementAccessCounterForSession() 461 { 462 setAccessCounterForSession(getAccessCounterForSession() + 1); 463 } 464 465 /** 466 * Sets the access counter for a user, saved in perm storage. 467 * 468 * @param cnt The new count. 469 */ 470 public void setAccessCounter(int cnt) 471 { 472 setPerm(User.ACCESS_COUNTER, new Integer(cnt)); 473 } 474 475 /** 476 * Sets the session access counter for a user, saved in temp 477 * storage. 478 * 479 * @param cnt The new count. 480 */ 481 public void setAccessCounterForSession(int cnt) 482 { 483 setTemp(User.SESSION_ACCESS_COUNTER, new Integer(cnt)); 484 } 485 486 /** 487 * This method reports whether or not the user has been confirmed 488 * in the system by checking the User.CONFIRM_VALUE 489 * column in the users record to see if it is equal to 490 * User.CONFIRM_DATA. 491 * 492 * @return True if the user has been confirmed. 493 */ 494 public boolean isConfirmed() 495 { 496 String value = getConfirmed(); 497 return (value != null && value.equals(User.CONFIRM_DATA)); 498 } 499 500 /** 501 * The user is considered logged in if they have not timed out. 502 * 503 * @return Whether the user has logged in. 504 */ 505 public boolean hasLoggedIn() 506 { 507 Boolean loggedIn = getHasLoggedIn(); 508 return (loggedIn != null && loggedIn.booleanValue()); 509 } 510 511 /** 512 * This sets whether or not someone has logged in. hasLoggedIn() 513 * returns this value. 514 * 515 * @param value Whether someone has logged in or not. 516 */ 517 public void setHasLoggedIn(Boolean value) 518 { 519 setTemp(User.HAS_LOGGED_IN, value); 520 } 521 522 /** 523 * Gets the last access date for this User. This is the last time 524 * that the user object was referenced. 525 * 526 * @return A Java Date with the last access date for the user. 527 */ 528 public java.util.Date getLastAccessDate() 529 { 530 if (lastAccessDate == null) 531 { 532 setLastAccessDate(); 533 } 534 return lastAccessDate; 535 } 536 537 /** 538 * Sets the last access date for this User. This is the last time 539 * that the user object was referenced. 540 */ 541 public void setLastAccessDate() 542 { 543 lastAccessDate = new java.util.Date(); 544 } 545 546 /** 547 * Returns the permanent storage. This is implemented 548 * as a Hashtable and backed by an VARBINARY column in 549 * the database. 550 * 551 * @return A Hashtable. 552 */ 553 public Hashtable getPermStorage() 554 { 555 if (permStorage == null) 556 { 557 byte [] objectdata = getObjectdata(); 558 559 if (objectdata != null) 560 { 561 permStorage = (Hashtable) ObjectUtils.deserialize(objectdata); 562 } 563 564 if (permStorage == null) 565 { 566 permStorage = new Hashtable(); 567 } 568 } 569 570 return permStorage; 571 } 572 573 /** 574 * This should only be used in the case where we want to save the 575 * data to the database. 576 * 577 * @param storage A Hashtable. 578 */ 579 public void setPermStorage(Hashtable permStorage) 580 { 581 if (permStorage != null) 582 { 583 this.permStorage = permStorage; 584 } 585 } 586 587 /** 588 * Returns the temporary storage. This is implemented 589 * as a Hashtable 590 * 591 * @return A Hashtable. 592 */ 593 public Hashtable getTempStorage() 594 { 595 if (tempStorage == null) 596 { 597 tempStorage = new Hashtable(); 598 } 599 return tempStorage; 600 } 601 602 /** 603 * This should only be used in the case where we want to save the 604 * data to the database. 605 * 606 * @param storage A Hashtable. 607 */ 608 public void setTempStorage(Hashtable tempStorage) 609 { 610 if (tempStorage != null) 611 { 612 this.tempStorage = tempStorage; 613 } 614 } 615 616 /** 617 * Get an object from permanent storage. 618 * 619 * @param name The object's name. 620 * @return An Object with the given name. 621 */ 622 public Object getPerm(String name) 623 { 624 return getPermStorage().get(name); 625 } 626 627 /** 628 * Get an object from permanent storage; return default if value 629 * is null. 630 * 631 * @param name The object's name. 632 * @param def A default value to return. 633 * @return An Object with the given name. 634 */ 635 public Object getPerm(String name, Object def) 636 { 637 try 638 { 639 Object val = getPermStorage().get(name); 640 return (val == null ? def : val); 641 } 642 catch (Exception e) 643 { 644 return def; 645 } 646 } 647 648 /** 649 * Put an object into permanent storage. If the value is null, 650 * it will convert that to a "" because the underlying storage 651 * mechanism within TorqueUser is currently a Hashtable and 652 * null is not a valid value. 653 * 654 * @param name The object's name. 655 * @param value The object. 656 */ 657 public void setPerm(String name, Object value) 658 { 659 getPermStorage().put(name, (value == null) ? "" : value); 660 } 661 662 /** 663 * Get an object from temporary storage. 664 * 665 * @param name The object's name. 666 * @return An Object with the given name. 667 */ 668 public Object getTemp(String name) 669 { 670 return getTempStorage().get(name); 671 } 672 673 /** 674 * Get an object from temporary storage; return default if value 675 * is null. 676 * 677 * @param name The object's name. 678 * @param def A default value to return. 679 * @return An Object with the given name. 680 */ 681 public Object getTemp(String name, Object def) 682 { 683 Object val; 684 try 685 { 686 val = getTempStorage().get(name); 687 if (val == null) 688 { 689 val = def; 690 } 691 } 692 catch (Exception e) 693 { 694 val = def; 695 } 696 return val; 697 } 698 699 /** 700 * Put an object into temporary storage. If the value is null, 701 * it will convert that to a "" because the underlying storage 702 * mechanism within TorqueUser is currently a Hashtable and 703 * null is not a valid value. 704 * 705 * @param name The object's name. 706 * @param value The object. 707 */ 708 public void setTemp(String name, Object value) 709 { 710 getTempStorage().put(name, (value == null) ? "" : value); 711 } 712 713 /** 714 * Remove an object from temporary storage and return the object. 715 * 716 * @param name The name of the object to remove. 717 * @return An Object. 718 */ 719 public Object removeTemp(String name) 720 { 721 return getTempStorage().remove(name); 722 } 723 724 /** 725 * Updates the last login date in the database. 726 * 727 * @exception Exception A generic exception. 728 */ 729 public void updateLastLogin() 730 throws Exception 731 { 732 setLastLogin(new java.util.Date()); 733 } 734 735 /** 736 * Implement this method if you wish to be notified when the User 737 * has been Bound to the session. 738 * 739 * @param event Indication of value/session binding. 740 */ 741 public void valueBound(HttpSessionBindingEvent hsbe) 742 { 743 // Currently we have no need for this method. 744 } 745 746 /** 747 * Implement this method if you wish to be notified when the User 748 * has been Unbound from the session. 749 * 750 * @param event Indication of value/session unbinding. 751 */ 752 public void valueUnbound(HttpSessionBindingEvent hsbe) 753 { 754 try 755 { 756 if (hasLoggedIn()) 757 { 758 TurbineSecurity.saveOnSessionUnbind(this); 759 } 760 } 761 catch (Exception e) 762 { 763 //Log.error("TorqueUser.valueUnbound(): " + e.getMessage(), e); 764 765 // To prevent messages being lost in case the logging system 766 // goes away before sessions get unbound on servlet container 767 // shutdown, print the stcktrace to the container's console. 768 ByteArrayOutputStream ostr = new ByteArrayOutputStream(); 769 e.printStackTrace(new PrintWriter(ostr, true)); 770 String stackTrace = ostr.toString(); 771 System.out.println(stackTrace); 772 } 773 } 774 775 /** 776 * This gets whether or not someone has logged in. hasLoggedIn() 777 * returns this value as a boolean. This is private because you 778 * should use hasLoggedIn() instead. 779 * 780 * @return True if someone has logged in. 781 */ 782 private Boolean getHasLoggedIn() 783 { 784 return (Boolean) getTemp(User.HAS_LOGGED_IN); 785 } 786 787 }