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