001/* 002 * This library is part of OpenCms - 003 * the Open Source Content Management System 004 * 005 * Copyright (c) Alkacon Software GmbH (http://www.alkacon.com) 006 * 007 * This library is free software; you can redistribute it and/or 008 * modify it under the terms of the GNU Lesser General Public 009 * License as published by the Free Software Foundation; either 010 * version 2.1 of the License, or (at your option) any later version. 011 * 012 * This library is distributed in the hope that it will be useful, 013 * but WITHOUT ANY WARRANTY; without even the implied warranty of 014 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 015 * Lesser General Public License for more details. 016 * 017 * For further information about Alkacon Software GmbH, please see the 018 * company website: http://www.alkacon.com 019 * 020 * For further information about OpenCms, please see the 021 * project website: http://www.opencms.org 022 * 023 * You should have received a copy of the GNU Lesser General Public 024 * License along with this library; if not, write to the Free Software 025 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 026 */ 027 028package org.opencms.file; 029 030import org.opencms.db.CmsUserSettings; 031import org.opencms.main.CmsException; 032import org.opencms.main.CmsIllegalArgumentException; 033import org.opencms.main.OpenCms; 034import org.opencms.security.CmsPrincipal; 035import org.opencms.security.CmsSecurityException; 036import org.opencms.security.I_CmsPrincipal; 037import org.opencms.util.CmsMacroResolver; 038import org.opencms.util.CmsStringUtil; 039import org.opencms.util.CmsUUID; 040 041import java.util.Collections; 042import java.util.HashMap; 043import java.util.Locale; 044import java.util.Map; 045 046/** 047 * A user principal in the OpenCms permission system.<p> 048 * 049 * A user in OpenCms is uniquely defined by its user named returned by 050 * <code>{@link #getName()}</code>.<p> 051 * 052 * Basic users in OpenCms are users that can access the OpenCms Workplace. 053 * Moreover, the user must be created by another user with the 054 * <code>{@link org.opencms.security.CmsRole#ACCOUNT_MANAGER}</code> role. 055 * These users are "content managers" that actually have write permissions in 056 * at last some parts of the VFS.<p> 057 * 058 * Another possibility is to have users in a 'Guests' group. 059 * These users do not have access to the OpenCms Workplace. 060 * However, an user in a 'Guests' group can be created by every user, for example 061 * the "Guest" user. The main use case is that these users are used for users of 062 * the website that can generate their own accounts, in a "please register your 063 * account..." scenario. 064 * These user accounts can then be used to build personalized web sites.<p> 065 * 066 * @since 6.0.0 067 * 068 * @see CmsGroup 069 */ 070public class CmsUser extends CmsPrincipal implements Cloneable { 071 072 /** Storage for additional user information. */ 073 private Map<String, Object> m_additionalInfo; 074 075 /** The creation date. */ 076 private long m_dateCreated; 077 078 /** The email of the user. */ 079 private String m_email; 080 081 /** The first name of this user. */ 082 private String m_firstname; 083 084 /** Boolean flag whether the last-login time stamp of this user was modified. */ 085 private boolean m_isTouched; 086 087 /** The last login date of this user. */ 088 private long m_lastlogin; 089 090 /** The last name of this user. */ 091 private String m_lastname; 092 093 /** The password of this user. */ 094 private String m_password; 095 096 /** 097 * Creates a new, empty OpenCms user principal.<p> 098 * 099 * Mostly intended to be used with the <code>org.opencms.workplace.tools.accounts.A_CmsEditUserDialog</code>.<p> 100 */ 101 public CmsUser() { 102 103 this( 104 null, 105 "", 106 "", 107 "", 108 "", 109 "", 110 0, 111 I_CmsPrincipal.FLAG_ENABLED, 112 System.currentTimeMillis(), 113 Collections.singletonMap(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION, (Object)"")); 114 } 115 116 /** 117 * Creates a new OpenCms user principal.<p> 118 * 119 * @param id the unique id of the new user 120 * @param name the fully qualified name of the new user 121 * @param password the password of the user 122 * @param firstname the first name 123 * @param lastname the last name 124 * @param email the email address 125 * @param lastlogin time stamp 126 * @param flags flags 127 * @param dateCreated the creation date 128 * @param additionalInfo user related information 129 */ 130 public CmsUser( 131 CmsUUID id, 132 String name, 133 String password, 134 String firstname, 135 String lastname, 136 String email, 137 long lastlogin, 138 int flags, 139 long dateCreated, 140 Map<String, Object> additionalInfo) { 141 142 m_id = id; 143 m_name = name; 144 m_password = password; 145 m_firstname = firstname; 146 m_lastname = lastname; 147 m_email = email; 148 m_lastlogin = lastlogin; 149 m_flags = flags; 150 m_dateCreated = dateCreated; 151 if (additionalInfo != null) { 152 m_additionalInfo = new HashMap<String, Object>(additionalInfo); 153 } else { 154 m_additionalInfo = new HashMap<String, Object>(); 155 } 156 if (m_additionalInfo.get(CmsUserSettings.ADDITIONAL_INFO_ADDRESS) == null) { 157 m_additionalInfo.put(CmsUserSettings.ADDITIONAL_INFO_ADDRESS, ""); 158 } 159 if (m_additionalInfo.get(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION) == null) { 160 m_additionalInfo.put(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION, ""); 161 } 162 } 163 164 /** 165 * Validates an email address.<p> 166 * 167 * That means, the parameter should only be composed by digits and standard english letters, points, underscores and exact one "At" symbol.<p> 168 * 169 * @param email the email to validate 170 */ 171 public static void checkEmail(String email) { 172 173 OpenCms.getValidationHandler().checkEmail(email); 174 } 175 176 /** 177 * Validates a zip code.<p> 178 * 179 * That means, the parameter should only be composed by digits and standard english letters.<p> 180 * 181 * @param zipcode the zip code to validate 182 */ 183 public static void checkZipCode(String zipcode) { 184 185 OpenCms.getValidationHandler().checkZipCode(zipcode); 186 } 187 188 /** 189 * Returns the "full" name of the given user in the format <code>"{firstname} {lastname} ({username})"</code>, 190 * or the empty String <code>""</code> if the user is null.<p> 191 * 192 * @param user the user to get the full name from 193 * @return the "full" name the user 194 * 195 * @see #getFullName() 196 */ 197 public static String getFullName(CmsUser user) { 198 199 if (user == null) { 200 return ""; 201 } else { 202 return user.getFullName(); 203 } 204 } 205 206 /** 207 * Returns the institution information of this user.<p> 208 * 209 * This information is stored in the "additional information" storage map 210 * using the key <code>{@link CmsUserSettings#ADDITIONAL_INFO_INSTITUTION}</code>.<p> 211 * 212 * @return the institution information of this user 213 */ 214 public String getInstitution() { 215 216 return (String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_INSTITUTION); 217 } 218 219 /** 220 * Checks if the provided user name is a valid user name and can be used as an argument value 221 * for {@link #setName(String)}.<p> 222 * 223 * @param name the user name to check 224 * 225 * @throws CmsIllegalArgumentException if the check fails 226 */ 227 public void checkName(String name) throws CmsIllegalArgumentException { 228 229 OpenCms.getValidationHandler().checkUserName(name); 230 } 231 232 /** 233 * @see java.lang.Object#clone() 234 */ 235 @Override 236 public Object clone() { 237 238 return new CmsUser( 239 m_id, 240 m_name, 241 m_password, 242 m_firstname, 243 m_lastname, 244 m_email, 245 m_lastlogin, 246 m_flags, 247 m_dateCreated, 248 m_additionalInfo); 249 } 250 251 /** 252 * Deletes a value from this users "additional information" storage map.<p> 253 * 254 * @param key the additional user information to delete 255 * 256 * @see #getAdditionalInfo() 257 */ 258 public void deleteAdditionalInfo(String key) { 259 260 m_additionalInfo.remove(key); 261 } 262 263 /** 264 * Returns this users complete "additional information" storage map.<p> 265 * 266 * The "additional information" storage map is a simple {@link java.util.Map} 267 * that can be used to store any key / value pairs for the user. 268 * Some information parts of the users address are stored in this map 269 * by default.<p> 270 * 271 * @return this users complete "additional information" storage map 272 */ 273 public Map<String, Object> getAdditionalInfo() { 274 275 return m_additionalInfo; 276 } 277 278 /** 279 * Returns a value from this users "additional information" storage map, 280 * or <code>null</code> if no value for the given key is available.<p> 281 * 282 * @param key selects the value to return from the "additional information" storage map 283 * 284 * @return the selected value from this users "additional information" storage map 285 * 286 * @see #getAdditionalInfo() 287 */ 288 public Object getAdditionalInfo(String key) { 289 290 return m_additionalInfo.get(key); 291 } 292 293 /** 294 * Returns the address line of this user.<p> 295 * 296 * @return the address line of this user 297 */ 298 public String getAddress() { 299 300 return (String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_ADDRESS); 301 } 302 303 /** 304 * Returns the city information of this user.<p> 305 * 306 * This information is stored in the "additional information" storage map 307 * using the key <code>{@link CmsUserSettings#ADDITIONAL_INFO_CITY}</code>.<p> 308 * 309 * @return the city information of this user 310 */ 311 public String getCity() { 312 313 return (String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_CITY); 314 } 315 316 /** 317 * Returns the country information of this user.<p> 318 * 319 * This information is stored in the "additional information" storage map 320 * using the key <code>{@link CmsUserSettings#ADDITIONAL_INFO_COUNTRY}</code>.<p> 321 * 322 * @return the country information of this user 323 */ 324 public String getCountry() { 325 326 return (String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_COUNTRY); 327 } 328 329 /** 330 * Returns the creation date.<p> 331 * 332 * @return the creation date 333 */ 334 public long getDateCreated() { 335 336 return m_dateCreated; 337 } 338 339 /** 340 * @see org.opencms.security.CmsPrincipal#getDescription() 341 */ 342 @Override 343 public String getDescription() { 344 345 return (String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION); 346 } 347 348 /** 349 * Returns the description of this organizational unit.<p> 350 * 351 * @param locale the locale 352 * 353 * @return the description of this organizational unit 354 */ 355 public String getDescription(Locale locale) { 356 357 CmsMacroResolver macroResolver = new CmsMacroResolver(); 358 macroResolver.setMessages(org.opencms.db.generic.Messages.get().getBundle(locale)); 359 return macroResolver.resolveMacros((String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION)); 360 } 361 362 /** 363 * @see org.opencms.security.CmsPrincipal#getDisplayName(org.opencms.file.CmsObject, java.util.Locale) 364 */ 365 @Override 366 public String getDisplayName(CmsObject cms, Locale locale) throws CmsException { 367 368 if (OpenCms.getOrgUnitManager().getOrganizationalUnits(cms, "", true).size() > 0) { 369 return org.opencms.security.Messages.get().getBundle(locale).key( 370 org.opencms.security.Messages.GUI_PRINCIPAL_DISPLAY_NAME_2, 371 getFullName(), 372 OpenCms.getOrgUnitManager().readOrganizationalUnit(cms, getOuFqn()).getDisplayName(locale)); 373 } else { 374 return getFullName(); 375 } 376 } 377 378 /** 379 * Returns the email address of this user.<p> 380 * 381 * @return the email address of this user 382 */ 383 public String getEmail() { 384 385 return m_email; 386 } 387 388 /** 389 * Returns the first name of this user.<p> 390 * 391 * @return the first name of this user 392 */ 393 public String getFirstname() { 394 395 return m_firstname; 396 } 397 398 /** 399 * Returns the "full" name of the this user in the format <code>"{firstname} {lastname} ({username})"</code>.<p> 400 * 401 * @return the "full" name this user 402 */ 403 public String getFullName() { 404 405 StringBuffer buf = new StringBuffer(); 406 String first = getFirstname(); 407 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(first)) { 408 buf.append(first); 409 buf.append(" "); 410 } 411 String last = getLastname(); 412 if (CmsStringUtil.isNotEmptyOrWhitespaceOnly(last)) { 413 buf.append(last); 414 buf.append(" "); 415 } 416 buf.append("("); 417 buf.append(getSimpleName()); 418 buf.append(")"); 419 return buf.toString(); 420 } 421 422 /** 423 * Returns the time of the last login of this user.<p> 424 * 425 * @return the time of the last login of this user 426 */ 427 public long getLastlogin() { 428 429 return m_lastlogin; 430 } 431 432 /** 433 * Returns the last name of this user.<p> 434 * 435 * @return the last name of this user 436 */ 437 public String getLastname() { 438 439 return m_lastname; 440 } 441 442 /** 443 * Returns the encrypted user password.<p> 444 * 445 * @return the encrypted user password 446 */ 447 public String getPassword() { 448 449 return m_password; 450 } 451 452 /** 453 * Returns the zip code information of this user.<p> 454 * 455 * This information is stored in the "additional information" storage map 456 * using the key <code>{@link CmsUserSettings#ADDITIONAL_INFO_ZIPCODE}</code>.<p> 457 * 458 * @return the zip code information of this user 459 */ 460 public String getZipcode() { 461 462 return (String)getAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_ZIPCODE); 463 } 464 465 /** 466 * @see org.opencms.security.I_CmsPrincipal#isGroup() 467 */ 468 @Override 469 public boolean isGroup() { 470 471 return false; 472 } 473 474 /** 475 * Checks if this user is the default guest user.<p> 476 * 477 * @return <code>true</code> if this user is the default guest user 478 */ 479 public boolean isGuestUser() { 480 481 return OpenCms.getDefaultUsers().isUserGuest(getName()); 482 } 483 484 /** 485 * Returns <code>true</code> if this user is not able to manage itself.<p> 486 * 487 * @return <code>true</code> if this user is not able to manage itself 488 */ 489 public boolean isManaged() { 490 491 return (getFlags() & I_CmsPrincipal.FLAG_USER_MANAGED) == I_CmsPrincipal.FLAG_USER_MANAGED; 492 } 493 494 /** 495 * Returns <code>true</code> if this user was touched.<p> 496 * 497 * @return boolean true if this user was touched 498 */ 499 public boolean isTouched() { 500 501 return m_isTouched; 502 } 503 504 /** 505 * @see org.opencms.security.I_CmsPrincipal#isUser() 506 */ 507 @Override 508 public boolean isUser() { 509 510 return true; 511 } 512 513 /** 514 * Checks if the user is marked as webuser.<p> 515 * 516 * @return <code>true</code> if the user is marked as webuser 517 */ 518 public boolean isWebuser() { 519 520 return (getFlags() & FLAG_USER_WEBUSER) == FLAG_USER_WEBUSER; 521 } 522 523 /** 524 * Sets this users complete "additional information" storage map to the given value.<p> 525 * 526 * @param additionalInfo the complete "additional information" map to set 527 * 528 * @see #getAdditionalInfo() 529 */ 530 public void setAdditionalInfo(Map<String, Object> additionalInfo) { 531 532 m_additionalInfo = additionalInfo; 533 } 534 535 /** 536 * Stores a value in this users "additional information" storage map with the given access key.<p> 537 * 538 * @param key the key to store the value under 539 * @param value the value to store in the users "additional information" storage map 540 * 541 * @see #getAdditionalInfo() 542 */ 543 public void setAdditionalInfo(String key, Object value) { 544 545 if (key == null) { 546 throw new CmsIllegalArgumentException(Messages.get().container( 547 Messages.ERR_USER_ADDINFO_KEY_NULL_1, 548 getFullName())); 549 } 550 m_additionalInfo.put(key, value); 551 } 552 553 /** 554 * Sets the address line of this user.<p> 555 * 556 * @param address the address line to set 557 */ 558 public void setAddress(String address) { 559 560 setAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_ADDRESS, address); 561 } 562 563 /** 564 * Sets the city information of this user.<p> 565 * 566 * @param city the city information to set 567 */ 568 public void setCity(String city) { 569 570 setAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_CITY, city); 571 } 572 573 /** 574 * Sets the country information of this user.<p> 575 * 576 * @param country the city information to set 577 */ 578 public void setCountry(String country) { 579 580 setAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_COUNTRY, country); 581 } 582 583 /** 584 * @see org.opencms.security.CmsPrincipal#setDescription(java.lang.String) 585 */ 586 @Override 587 public void setDescription(String description) { 588 589 setAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_DESCRIPTION, description); 590 } 591 592 /** 593 * Sets the email address of this user.<p> 594 * 595 * @param email the email address to set 596 */ 597 public void setEmail(String email) { 598 599 checkEmail(email); 600 if (email != null) { 601 email = email.trim(); 602 } 603 m_email = email; 604 } 605 606 /** 607 * Sets the first name of this user.<p> 608 * 609 * @param firstname the name to set 610 */ 611 public void setFirstname(String firstname) { 612 613 OpenCms.getValidationHandler().checkFirstname(firstname); 614 if (firstname != null) { 615 firstname = firstname.trim(); 616 } 617 m_firstname = firstname; 618 } 619 620 /** 621 * Sets the institution information of this user.<p> 622 * 623 * @param institution the institution information to set 624 */ 625 public void setInstitution(String institution) { 626 627 setAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_INSTITUTION, institution); 628 } 629 630 /** 631 * Sets the last login time stamp of this user.<p> 632 * 633 * @param value the last login time stamp to set 634 */ 635 public void setLastlogin(long value) { 636 637 m_isTouched = true; 638 m_lastlogin = value; 639 } 640 641 /** 642 * Sets the last name of this user.<p> 643 * 644 * @param lastname the name to set 645 */ 646 public void setLastname(String lastname) { 647 648 OpenCms.getValidationHandler().checkLastname(lastname); 649 if (lastname != null) { 650 lastname = lastname.trim(); 651 } 652 m_lastname = lastname; 653 } 654 655 /** 656 * Sets the managed flag for this user to the given value.<p> 657 * 658 * @param value the value to set 659 */ 660 public void setManaged(boolean value) { 661 662 if (isManaged() != value) { 663 setFlags(getFlags() ^ I_CmsPrincipal.FLAG_USER_MANAGED); 664 } 665 } 666 667 /** 668 * Sets the password of this user.<p> 669 * 670 * @param value the password to set 671 */ 672 public void setPassword(String value) { 673 674 try { 675 OpenCms.getPasswordHandler().validatePassword(value); 676 } catch (CmsSecurityException e) { 677 throw new CmsIllegalArgumentException(e.getMessageContainer()); 678 } 679 m_password = value; 680 } 681 682 /** 683 * Sets the zip code information of this user.<p> 684 * 685 * @param zipcode the zip code information to set 686 */ 687 public void setZipcode(String zipcode) { 688 689 checkZipCode(zipcode); 690 if (zipcode != null) { 691 zipcode = zipcode.toUpperCase(); 692 } 693 setAdditionalInfo(CmsUserSettings.ADDITIONAL_INFO_ZIPCODE, zipcode); 694 } 695 696 /** 697 * @see java.lang.Object#toString() 698 */ 699 @Override 700 public String toString() { 701 702 StringBuffer result = new StringBuffer(); 703 result.append("[User]"); 704 result.append(" name:"); 705 result.append(getName()); 706 result.append(" id:"); 707 result.append(m_id); 708 result.append(" flags:"); 709 result.append(getFlags()); 710 result.append(" description:"); 711 result.append(getDescription()); 712 return result.toString(); 713 } 714 715 /** 716 * Sets the "touched" status of this user to <code>true</code>.<p> 717 */ 718 public void touch() { 719 720 m_isTouched = true; 721 } 722}