001/* 002 * Copyright 2015-2018 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright (C) 2015-2018 Ping Identity Corporation 007 * 008 * This program is free software; you can redistribute it and/or modify 009 * it under the terms of the GNU General Public License (GPLv2 only) 010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 011 * as published by the Free Software Foundation. 012 * 013 * This program is distributed in the hope that it will be useful, 014 * but WITHOUT ANY WARRANTY; without even the implied warranty of 015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 016 * GNU General Public License for more details. 017 * 018 * You should have received a copy of the GNU General Public License 019 * along with this program; if not, see <http://www.gnu.org/licenses>. 020 */ 021package com.unboundid.ldap.sdk.unboundidds.extensions; 022 023 024 025import java.io.Serializable; 026import java.util.StringTokenizer; 027 028import com.unboundid.ldap.sdk.LDAPException; 029import com.unboundid.ldap.sdk.ResultCode; 030import com.unboundid.util.Debug; 031import com.unboundid.util.NotMutable; 032import com.unboundid.util.StaticUtils; 033import com.unboundid.util.ThreadSafety; 034import com.unboundid.util.ThreadSafetyLevel; 035import com.unboundid.util.Validator; 036 037import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 038 039 040 041/** 042 * This class defines a data structure that will provide information about 043 * errors that may affect an account's usability. It includes a number of 044 * predefined error types, but also allows for the possibility of additional 045 * error types that have not been defined. 046 * <BR> 047 * <BLOCKQUOTE> 048 * <B>NOTE:</B> This class, and other classes within the 049 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 050 * supported for use against Ping Identity, UnboundID, and Alcatel-Lucent 8661 051 * server products. These classes provide support for proprietary 052 * functionality or for external specifications that are not considered stable 053 * or mature enough to be guaranteed to work in an interoperable way with 054 * other types of LDAP servers. 055 * </BLOCKQUOTE> 056 */ 057@NotMutable() 058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 059public final class PasswordPolicyStateAccountUsabilityError 060 implements Serializable 061{ 062 /** 063 * The numeric value for the error type that indicates the user's account is 064 * disabled. 065 */ 066 public static final int ERROR_TYPE_ACCOUNT_DISABLED = 1; 067 068 069 070 /** 071 * The name for the error type that indicates the user's account is disabled. 072 */ 073 public static final String ERROR_NAME_ACCOUNT_DISABLED = "account-disabled"; 074 075 076 077 /** 078 * The numeric value for the error type that indicates the user's account is 079 * not yet active. 080 */ 081 public static final int ERROR_TYPE_ACCOUNT_NOT_YET_ACTIVE = 2; 082 083 084 085 /** 086 * The name for the error type that indicates the user's account is not yet 087 * valid. 088 */ 089 public static final String ERROR_NAME_ACCOUNT_NOT_YET_ACTIVE = 090 "account-not-yet-active"; 091 092 093 094 /** 095 * The numeric value for the error type that indicates the user's account is 096 * expired. 097 */ 098 public static final int ERROR_TYPE_ACCOUNT_EXPIRED = 3; 099 100 101 102 /** 103 * The name for the error type that indicates the user's account is expired. 104 */ 105 public static final String ERROR_NAME_ACCOUNT_EXPIRED = "account-expired"; 106 107 108 109 /** 110 * The numeric value for the error type that indicates the user's account is 111 * permanently locked (until the password is reset by an administrator) as a 112 * result of too many failed authentication attempts. 113 */ 114 public static final int 115 ERROR_TYPE_ACCOUNT_PERMANENTLY_LOCKED_DUE_TO_BIND_FAILURES = 4; 116 117 118 119 /** 120 * The name for the error type that indicates the user's account is 121 * permanently locked (until the password is reset by an administrator) as a 122 * result of too many failed authentication attempts. 123 */ 124 public static final String 125 ERROR_NAME_ACCOUNT_PERMANENTLY_LOCKED_DUE_TO_BIND_FAILURES = 126 "account-permanently-locked-due-to-bind-failures"; 127 128 129 130 /** 131 * The numeric value for the error type that indicates the user's account is 132 * temporarily locked (until the lockout period elapses or the password is 133 * reset by an administrator) as a result of too many failed authentication 134 * attempts. 135 */ 136 public static final int 137 ERROR_TYPE_ACCOUNT_TEMPORARILY_LOCKED_DUE_TO_BIND_FAILURES = 5; 138 139 140 141 /** 142 * The name for the error type that indicates the user's account is 143 * temporarily locked (until the lockout period elapses or the password is 144 * reset by an administrator) as a result of too many failed authentication 145 * attempts. 146 */ 147 public static final String 148 ERROR_NAME_ACCOUNT_TEMPORARILY_LOCKED_DUE_TO_BIND_FAILURES = 149 "account-temporarily-locked-due-to-bind-failures"; 150 151 152 153 /** 154 * The numeric value for the error type that indicates the user's account is 155 * locked (until the password is reset by an administrator) as a result of 156 * remaining idle for too long (i.e., it has been too long since the user last 157 * authenticated). 158 */ 159 public static final int ERROR_TYPE_ACCOUNT_IDLE_LOCKED = 6; 160 161 162 163 /** 164 * The name for the error type that indicates the user's account is locked 165 * (until the password is reset by an administrator) as a result of remaining 166 * idle for too long (i.e., it has been too long since the user last 167 * authenticated). 168 */ 169 public static final String ERROR_NAME_ACCOUNT_IDLE_LOCKED = 170 "account-idle-locked"; 171 172 173 174 /** 175 * The numeric value for the error type that indicates the user's account is 176 * locked (until the password is reset by an administrator) as a result of 177 * failing to change the password in a timely manner after it was reset by an 178 * administrator. 179 */ 180 public static final int ERROR_TYPE_ACCOUNT_RESET_LOCKED = 7; 181 182 183 184 /** 185 * The name for the error type that indicates the user's account is locked 186 * (until the password is reset by an administrator) as a result of failing to 187 * change the password in a timely manner after it was reset by an 188 * administrator. 189 */ 190 public static final String ERROR_NAME_ACCOUNT_RESET_LOCKED = 191 "account-reset-locked"; 192 193 194 195 /** 196 * The numeric value for the error type that indicates the user's password 197 * is expired. 198 */ 199 public static final int ERROR_TYPE_PASSWORD_EXPIRED = 8; 200 201 202 203 /** 204 * The name for the error type that indicates the user's password is expired. 205 */ 206 public static final String ERROR_NAME_PASSWORD_EXPIRED = "password-expired"; 207 208 209 210 /** 211 * The numeric value for the error type that indicates the user's account is 212 * locked (until the password is reset by an administrator) as a result of 213 * failing to change the password by a required time. 214 */ 215 public static final int ERROR_TYPE_PASSWORD_NOT_CHANGED_BY_REQUIRED_TIME = 9; 216 217 218 219 /** 220 * The name for the error type that indicates the user's account is locked 221 * (until the password is reset by an administrator) as a result of failing to 222 * change the password by a required time. 223 */ 224 public static final String ERROR_NAME_PASSWORD_NOT_CHANGED_BY_REQUIRED_TIME = 225 "password-not-changed-by-required-time"; 226 227 228 229 /** 230 * The numeric value for the warning type that indicates the user's password 231 * has expired, but the user has one or more grace logins remaining. The 232 * user may still authenticate with a grace login, but will not be permitted 233 * to submit any other requests until changing the password. 234 */ 235 public static final int ERROR_TYPE_PASSWORD_EXPIRED_WITH_GRACE_LOGINS = 10; 236 237 238 239 /** 240 * The name for the warning type that indicates the user's password has 241 * expired, but the user has one or more grace logins remaining. The user may 242 * still authenticate with a grace login, but will not be permitted to submit 243 * any other requests until changing the password. 244 */ 245 public static final String ERROR_NAME_PASSWORD_EXPIRED_WITH_GRACE_LOGINS = 246 "password-expired-with-grace-logins"; 247 248 249 250 /** 251 * The numeric value for the warning type that indicates the user must change 252 * their password after an administrative reset (or for a newly-created 253 * account) before they will be submit any requests. The user's account may 254 * be locked if they do not change their password in a timely manner. 255 */ 256 public static final int ERROR_TYPE_MUST_CHANGE_PASSWORD = 11; 257 258 259 260 /** 261 * The name for the warning type that indicates the user must change their 262 * password after an administrative reset (or for a newly-created account) 263 * before they will be submit any requests. The user's account may be locked 264 * if they do not change their password in a timely manner. 265 */ 266 public static final String ERROR_NAME_MUST_CHANGE_PASSWORD = 267 "must-change-password"; 268 269 270 271 /** 272 * The serial version UID for this serializable class. 273 */ 274 private static final long serialVersionUID = -2482863468368980580L; 275 276 277 278 // The integer value for this account usability error. 279 private final int intValue; 280 281 // A human-readable message that provides specific details about this account 282 // usability error. 283 private final String message; 284 285 // The name for this account usability error. 286 private final String name; 287 288 // The encoded string representation for this account usability error. 289 private final String stringRepresentation; 290 291 292 293 /** 294 * Creates a new account usability error with the provided information. 295 * 296 * @param intValue The integer value for this account usability error. 297 * @param name The name for this account usability error. It must not 298 * be {@code null}. 299 * @param message A human-readable message that provides specific details 300 * about this account usability error. It may be 301 * {@code null} if no message is available. 302 */ 303 public PasswordPolicyStateAccountUsabilityError(final int intValue, 304 final String name, 305 final String message) 306 { 307 Validator.ensureNotNull(name); 308 309 this.intValue = intValue; 310 this.name = name; 311 this.message = message; 312 313 final StringBuilder buffer = new StringBuilder(); 314 buffer.append("code="); 315 buffer.append(intValue); 316 buffer.append("\tname="); 317 buffer.append(name); 318 319 if (message != null) 320 { 321 buffer.append("\tmessage="); 322 buffer.append(message); 323 } 324 325 stringRepresentation = buffer.toString(); 326 } 327 328 329 330 /** 331 * Creates a new account usability error that is decoded from the provided 332 * string representation. 333 * 334 * @param stringRepresentation The string representation of the account 335 * usability error to decode. It must not be 336 * {@code null}. 337 * 338 * @throws LDAPException If the provided string cannot be decoded as a valid 339 * account usability error. 340 */ 341 public PasswordPolicyStateAccountUsabilityError( 342 final String stringRepresentation) 343 throws LDAPException 344 { 345 this.stringRepresentation = stringRepresentation; 346 347 try 348 { 349 Integer i = null; 350 String n = null; 351 String m = null; 352 353 final StringTokenizer tokenizer = 354 new StringTokenizer(stringRepresentation, "\t"); 355 while (tokenizer.hasMoreTokens()) 356 { 357 final String token = tokenizer.nextToken(); 358 final int equalPos = token.indexOf('='); 359 final String fieldName = token.substring(0, equalPos); 360 final String fieldValue = token.substring(equalPos+1); 361 if (fieldName.equals("code")) 362 { 363 i = Integer.valueOf(fieldValue); 364 } 365 else if (fieldName.equals("name")) 366 { 367 n = fieldValue; 368 } 369 else if (fieldName.equals("message")) 370 { 371 m = fieldValue; 372 } 373 } 374 375 if (i == null) 376 { 377 throw new LDAPException(ResultCode.DECODING_ERROR, 378 ERR_PWP_STATE_ACCOUNT_USABILITY_ERROR_CANNOT_DECODE.get( 379 stringRepresentation, 380 ERR_PWP_STATE_ACCOUNT_USABILITY_ERROR_NO_CODE.get())); 381 } 382 383 if (n == null) 384 { 385 throw new LDAPException(ResultCode.DECODING_ERROR, 386 ERR_PWP_STATE_ACCOUNT_USABILITY_ERROR_CANNOT_DECODE.get( 387 stringRepresentation, 388 ERR_PWP_STATE_ACCOUNT_USABILITY_ERROR_NO_NAME.get())); 389 } 390 391 intValue = i; 392 name = n; 393 message = m; 394 } 395 catch (final LDAPException le) 396 { 397 Debug.debugException(le); 398 399 throw le; 400 } 401 catch (final Exception e) 402 { 403 Debug.debugException(e); 404 405 throw new LDAPException(ResultCode.DECODING_ERROR, 406 ERR_PWP_STATE_ACCOUNT_USABILITY_ERROR_CANNOT_DECODE.get( 407 stringRepresentation, StaticUtils.getExceptionMessage(e)), 408 e); 409 } 410 } 411 412 413 414 /** 415 * Retrieves the integer value for this account usability error. 416 * 417 * @return The integer value for this account usability error. 418 */ 419 public int getIntValue() 420 { 421 return intValue; 422 } 423 424 425 426 /** 427 * Retrieves the name for this account usability error. 428 * 429 * @return The name for this account usability error. 430 */ 431 public String getName() 432 { 433 return name; 434 } 435 436 437 438 /** 439 * Retrieves a human-readable message that provides specific details about 440 * this account usability error. 441 * 442 * @return A human-readable message that provides specific details about this 443 * account usability error, or {@code null} if no message is 444 * available. 445 */ 446 public String getMessage() 447 { 448 return message; 449 } 450 451 452 453 /** 454 * Retrieves a string representation of this account usability error. 455 * 456 * @return A string representation of this account usability error. 457 */ 458 @Override() 459 public String toString() 460 { 461 return stringRepresentation; 462 } 463}