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