001/* 002 Licensed to the Apache Software Foundation (ASF) under one 003 or more contributor license agreements. See the NOTICE file 004 distributed with this work for additional information 005 regarding copyright ownership. The ASF licenses this file 006 to you under the Apache License, Version 2.0 (the 007 "License"); you may not use this file except in compliance 008 with the License. You may obtain a copy of the License at 009 010 http://www.apache.org/licenses/LICENSE-2.0 011 012 Unless required by applicable law or agreed to in writing, 013 software distributed under the License is distributed on an 014 "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 015 KIND, either express or implied. See the License for the 016 specific language governing permissions and limitations 017 under the License. 018 */ 019package org.apache.wiki.auth.user; 020 021import java.io.Serializable; 022import java.util.Date; 023import java.util.HashMap; 024import java.util.Map; 025 026import javax.servlet.http.HttpServletRequest; 027 028import org.apache.commons.lang.StringUtils; 029import org.apache.wiki.WikiSession; 030 031/** 032 * Default implementation for representing wiki user information, such as the 033 * login name, full name, wiki name, and e-mail address. 034 * @since 2.3 035 */ 036 037public final class DefaultUserProfile implements UserProfile 038{ 039 private static final long serialVersionUID = -5600466893735300647L; 040 041 private static final String EMPTY_STRING = ""; 042 043 private static final String WHITESPACE = "\\s"; 044 045 private Map<String,Serializable> attributes = new HashMap<>(); 046 047 private Date created = null; 048 049 private String email = null; 050 051 private String fullname = null; 052 053 private Date lockExpiry = null; 054 055 private String loginName = null; 056 057 private Date modified = null; 058 059 private String password = null; 060 061 private String uid = null; 062 063 private String wikiname = null; 064 065 /** 066 * Private constructor to prevent direct instantiation. 067 */ 068 private DefaultUserProfile() {} 069 070 /** 071 * Static factory method that creates a new DefaultUserProfile 072 * and sets a unique identifier (uid) for the supplied UserDatabase. 073 * @param db the UserDatabase for which the uid should be 074 * created 075 * @return the new profile 076 */ 077 protected static UserProfile newProfile( UserDatabase db ) 078 { 079 UserProfile profile = new DefaultUserProfile(); 080 profile.setUid( AbstractUserDatabase.generateUid( db ) ); 081 return profile; 082 } 083 084 /** 085 * {@inheritDoc} 086 */ 087 @Override 088 public boolean equals( Object o ) 089 { 090 if ( ( o != null ) && ( o instanceof UserProfile ) ) 091 { 092 DefaultUserProfile u = (DefaultUserProfile) o; 093 return same( fullname, u.fullname ) && same( password, u.password ) 094 && same( loginName, u.loginName ) && same(StringUtils.lowerCase( email ), StringUtils.lowerCase( u.email ) ) && same( wikiname, 095 u.wikiname ); 096 } 097 098 return false; 099 } 100 101 @Override 102 public int hashCode() 103 { 104 return (fullname != null ? fullname.hashCode() : 0) ^ 105 (password != null ? password.hashCode() : 0) ^ 106 (loginName != null ? loginName.hashCode() : 0) ^ 107 (wikiname != null ? wikiname.hashCode() : 0) ^ 108 (email != null ? StringUtils.lowerCase( email ).hashCode() : 0); 109 } 110 111 /** 112 * Returns the creation date 113 * @return the creation date 114 * @see org.apache.wiki.auth.user.UserProfile#getCreated() 115 */ 116 @Override 117 public Date getCreated() 118 { 119 return created; 120 } 121 122 /** 123 * Returns the user's e-mail address. 124 * @return the e-mail address 125 */ 126 @Override 127 public String getEmail() 128 { 129 return email; 130 } 131 132 /** 133 * Returns the user's full name. 134 * @return the full name 135 */ 136 @Override 137 public String getFullname() 138 { 139 return fullname; 140 } 141 142 /** 143 * Returns the last-modified date. 144 * @return the last-modified date 145 * @see org.apache.wiki.auth.user.UserProfile#getLastModified() 146 */ 147 @Override 148 public Date getLastModified() 149 { 150 return modified; 151 } 152 153 /** 154 * Returns the user's login name. 155 * @return the login name 156 */ 157 @Override 158 public String getLoginName() 159 { 160 return loginName; 161 } 162 163 /** 164 * Returns the user password for use with custom authentication. Note that 165 * the password field is not meaningful for container authentication; the 166 * user's private credentials are generally stored elsewhere. While it 167 * depends on the {@link UserDatabase}implementation, in most cases the 168 * value returned by this method will be a password hash, not the password 169 * itself. 170 * @return the password 171 */ 172 @Override 173 public String getPassword() 174 { 175 return password; 176 } 177 178 /** 179 * Returns the user's wiki name. 180 * @return the wiki name. 181 */ 182 @Override 183 public String getWikiName() 184 { 185 return wikiname; 186 } 187 188 /** 189 * Returns <code>true</code> if the user profile is 190 * new. This implementation checks whether 191 * {@link #getLastModified()} returns <code>null</code> 192 * to determine the status. 193 * @see org.apache.wiki.auth.user.UserProfile#isNew() 194 */ 195 @Override 196 public boolean isNew() 197 { 198 return modified == null; 199 } 200 201 /** 202 * @param date the creation date 203 * @see org.apache.wiki.auth.user.UserProfile#setCreated(java.util.Date) 204 */ 205 @Override 206 public void setCreated(Date date) 207 { 208 created = date; 209 } 210 211 /** 212 * Sets the user's e-mail address. 213 * @param email the e-mail address 214 */ 215 @Override 216 public void setEmail( String email ) 217 { 218 this.email = email; 219 } 220 221 /** 222 * Sets the user's full name. For example, "Janne Jalkanen." 223 * @param arg the full name 224 */ 225 @Override 226 public void setFullname( String arg ) 227 { 228 fullname = arg; 229 230 // Compute wiki name 231 if ( fullname != null ) 232 { 233 wikiname = fullname.replaceAll(WHITESPACE, EMPTY_STRING); 234 } 235 } 236 237 /** 238 * Sets the last-modified date. 239 * @param date the last-modified date 240 * @see org.apache.wiki.auth.user.UserProfile#setLastModified(java.util.Date) 241 */ 242 @Override 243 public void setLastModified( Date date ) 244 { 245 modified = date; 246 } 247 248 /** 249 * Sets the name by which the user logs in. The login name is used as the 250 * username for custom authentication (see 251 * {@link org.apache.wiki.auth.AuthenticationManager#login(WikiSession,HttpServletRequest, String, String)}). 252 * The login name is typically a short name ("jannej"). In contrast, the 253 * wiki name is typically of type FirstnameLastName ("JanneJalkanen"). 254 * @param name the login name 255 */ 256 @Override 257 public void setLoginName( String name ) 258 { 259 loginName = name; 260 } 261 262 /** 263 * Sets the user's password for use with custom authentication. It is 264 * <em>not</em> the responsibility of implementing classes to hash the 265 * password; that responsibility is borne by the UserDatabase implementation 266 * during save operations (see {@link UserDatabase#save(UserProfile)}). 267 * Note that the password field is not meaningful for container 268 * authentication; the user's private credentials are generally stored 269 * elsewhere. 270 * @param arg the password 271 */ 272 @Override 273 public void setPassword( String arg ) 274 { 275 password = arg; 276 } 277 278 /** 279 * No-op method. In previous versions of JSPWiki, the method 280 * set the user's wiki name directly. Now, the wiki name is automatically 281 * calculated based on the full name. 282 * @param name the wiki name 283 * @deprecated This method will be removed in a future release. 284 */ 285 @Deprecated 286 @Override 287 public void setWikiName( String name ) 288 { 289 } 290 291 /** 292 * Returns a string representation of this user profile. 293 * @return the string 294 */ 295 @Override 296 public String toString() 297 { 298 return "[DefaultUserProfile: '" + getFullname() + "']"; 299 } 300 301 /** 302 * Private method that compares two objects and determines whether they are 303 * equal. Two nulls are considered equal. 304 * @param arg1 the first object 305 * @param arg2 the second object 306 * @return the result of the comparison 307 */ 308 private boolean same( Object arg1, Object arg2 ) 309 { 310 if ( arg1 == null && arg2 == null ) 311 { 312 return true; 313 } 314 if ( arg1 == null || arg2 == null ) 315 { 316 return false; 317 } 318 return arg1.equals( arg2 ); 319 } 320 321 //--------------------------- Attribute and lock interface implementations --------------------------- 322 323 /** 324 * {@inheritDoc} 325 */ 326 @Override 327 public Map<String,Serializable> getAttributes() 328 { 329 return attributes; 330 } 331 332 /** 333 * {@inheritDoc} 334 */ 335 @Override 336 public Date getLockExpiry() 337 { 338 return isLocked() ? lockExpiry : null; 339 } 340 341 /** 342 * {@inheritDoc} 343 */ 344 @Override 345 public String getUid() 346 { 347 return uid; 348 } 349 350 /** 351 * {@inheritDoc} 352 */ 353 @Override 354 public boolean isLocked() 355 { 356 boolean locked = lockExpiry != null && System.currentTimeMillis() < lockExpiry.getTime(); 357 358 // Clear the lock if it's expired already 359 if ( !locked && lockExpiry != null ) 360 { 361 lockExpiry = null; 362 } 363 return locked; 364 } 365 366 /** 367 * {@inheritDoc} 368 */ 369 @Override 370 public void setLockExpiry( Date expiry ) 371 { 372 this.lockExpiry = expiry; 373 } 374 375 /** 376 * {@inheritDoc} 377 */ 378 @Override 379 public void setUid( String uid ) 380 { 381 this.uid = uid; 382 } 383}