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