001/* 002 * Copyright 2020-2022 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2020-2022 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) 2020-2022 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; 037 038 039 040import java.io.Serializable; 041import java.util.ArrayList; 042import java.util.Collections; 043import java.util.Date; 044import java.util.LinkedHashMap; 045import java.util.List; 046import java.util.Map; 047 048import com.unboundid.ldap.sdk.Entry; 049import com.unboundid.ldap.sdk.LDAPException; 050import com.unboundid.ldap.sdk.LDAPInterface; 051import com.unboundid.ldap.sdk.ResultCode; 052import com.unboundid.ldap.sdk.SearchResultEntry; 053import com.unboundid.ldap.sdk.unboundidds.controls.RecentLoginHistory; 054import com.unboundid.ldap.sdk.unboundidds.extensions. 055 PasswordPolicyStateAccountUsabilityError; 056import com.unboundid.ldap.sdk.unboundidds.extensions. 057 PasswordPolicyStateAccountUsabilityNotice; 058import com.unboundid.ldap.sdk.unboundidds.extensions. 059 PasswordPolicyStateAccountUsabilityWarning; 060import com.unboundid.ldap.sdk.unboundidds.extensions. 061 PasswordPolicyStateExtendedRequest; 062import com.unboundid.ldap.sdk.unboundidds.extensions.PasswordQualityRequirement; 063import com.unboundid.util.Debug; 064import com.unboundid.util.NotMutable; 065import com.unboundid.util.NotNull; 066import com.unboundid.util.Nullable; 067import com.unboundid.util.StaticUtils; 068import com.unboundid.util.ThreadSafety; 069import com.unboundid.util.ThreadSafetyLevel; 070import com.unboundid.util.json.JSONObject; 071import com.unboundid.util.json.JSONString; 072import com.unboundid.util.json.JSONValue; 073 074import static com.unboundid.ldap.sdk.unboundidds.PasswordPolicyStateJSONField.*; 075import static com.unboundid.ldap.sdk.unboundidds.UnboundIDDSMessages.*; 076 077 078 079/** 080 * This class provides support for reading and decoding the value of the 081 * {@code ds-pwp-state-json} virtual attribute, which holds information about a 082 * user's password policy state. 083 * <BR> 084 * <BLOCKQUOTE> 085 * <B>NOTE:</B> This class, and other classes within the 086 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 087 * supported for use against Ping Identity, UnboundID, and 088 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 089 * for proprietary functionality or for external specifications that are not 090 * considered stable or mature enough to be guaranteed to work in an 091 * interoperable way with other types of LDAP servers. 092 * </BLOCKQUOTE> 093 * 094 * 095 * @see ModifiablePasswordPolicyStateJSON 096 * @see PasswordPolicyStateExtendedRequest 097 * @see PasswordPolicyStateJSONField 098 */ 099@NotMutable() 100@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 101public final class PasswordPolicyStateJSON 102 implements Serializable 103{ 104 /** 105 * The name of the operational attribute that holds a JSON representation of a 106 * user's password policy state. 107 */ 108 @NotNull public static final String PASSWORD_POLICY_STATE_JSON_ATTRIBUTE = 109 "ds-pwp-state-json"; 110 111 112 113 /** 114 * The name of the field that will be used to indicate whether a password 115 * quality requirement applies to add operations. 116 */ 117 @NotNull private static final String REQUIREMENT_FIELD_APPLIES_TO_ADD = 118 "applies-to-add"; 119 120 121 122 /** 123 * The name of the field that will be used to indicate whether a password 124 * quality requirement applies to administrative password resets. 125 */ 126 @NotNull private static final String 127 REQUIREMENT_FIELD_APPLIES_TO_ADMIN_RESET = 128 "applies-to-administrative-reset"; 129 130 131 132 /** 133 * The name of the field that will be used to indicate whether a password 134 * quality requirement applies to bind operations. 135 */ 136 @NotNull private static final String REQUIREMENT_FIELD_APPLIES_TO_BIND = 137 "applies-to-bind"; 138 139 140 141 /** 142 * The name of the field that will be used to indicate whether a password 143 * quality requirement applies to self password changes. 144 */ 145 @NotNull private static final String 146 REQUIREMENT_FIELD_APPLIES_TO_SELF_CHANGE = "applies-to-self-change"; 147 148 149 150 /** 151 * The name of the field that will be used to hold the set of client-side 152 * validation properties. 153 */ 154 @NotNull private static final String 155 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_PROPERTIES = 156 "client-side-validation-properties"; 157 158 159 160 /** 161 * The name of the field that will be used to hold the name of a client-side 162 * validation property. 163 */ 164 @NotNull private static final String 165 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_PROPERTY_NAME = "name"; 166 167 168 169 /** 170 * The name of the field that will be used to hold the value of a client-side 171 * validation property. 172 */ 173 @NotNull private static final String 174 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_PROPERTY_VALUE = "value"; 175 176 177 178 /** 179 * The name of the field that will be used to hold the name of the client-side 180 * validation type for a password quality requirement. 181 */ 182 @NotNull private static final String 183 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_TYPE = 184 "client-side-validation-type"; 185 186 187 188 /** 189 * The name of the field that will be used to hold the description component 190 * of a password quality requirement. 191 */ 192 @NotNull private static final String REQUIREMENT_FIELD_DESCRIPTION = 193 "description"; 194 195 196 197 /** 198 * The name of the field that will be used to hold the message component of an 199 * account usability error, warning, or notice. 200 */ 201 @NotNull private static final String USABILITY_FIELD_MESSAGE = "message"; 202 203 204 205 /** 206 * The name of the field that will be used to hold the integer version of 207 * the identifier for of an account usability error, warning, or notice. 208 */ 209 @NotNull private static final String USABILITY_FIELD_TYPE_ID = "type-id"; 210 211 212 213 /** 214 * The name of the field that will be used to hold the name of the identifier 215 * for of an account usability error, warning, or notice. 216 */ 217 @NotNull private static final String USABILITY_FIELD_TYPE_NAME = "type-name"; 218 219 220 221 /** 222 * The serial version UID for this serializable class. 223 */ 224 private static final long serialVersionUID = -3953182526241789456L; 225 226 227 228 229 // The JSON object that contains the password policy state information. 230 @NotNull private final JSONObject passwordPolicyStateObject; 231 232 233 234 /** 235 * Creates a new instance of this object from the provided JSON object. 236 * 237 * @param passwordPolicyStateObject The JSON object containing the encoded 238 * password policy state. 239 */ 240 public PasswordPolicyStateJSON( 241 @NotNull final JSONObject passwordPolicyStateObject) 242 { 243 this.passwordPolicyStateObject = passwordPolicyStateObject; 244 } 245 246 247 248 /** 249 * Attempts to retrieve and decode the password policy state information for 250 * the specified user. 251 * 252 * @param connection The connection to use to communicate with the server. 253 * It must not be {@code null}, and it must be established 254 * and authenticated as an account with permission to 255 * access the target user's password policy state 256 * information. 257 * @param userDN The DN of the user for whom to retrieve the password 258 * policy state. It must not be {@code null}. 259 * 260 * @return The password policy state information for the specified user, or 261 * {@code null} because no password policy state information is 262 * available for the user. 263 * 264 * @throws LDAPException If a problem is encountered while trying to 265 * retrieve the user's entry or decode the password 266 * policy state JSON object. 267 */ 268 @Nullable() 269 public static PasswordPolicyStateJSON get( 270 @NotNull final LDAPInterface connection, 271 @NotNull final String userDN) 272 throws LDAPException 273 { 274 final SearchResultEntry userEntry = connection.getEntry(userDN, 275 PASSWORD_POLICY_STATE_JSON_ATTRIBUTE); 276 if (userEntry == null) 277 { 278 throw new LDAPException(ResultCode.NO_SUCH_OBJECT, 279 ERR_PW_POLICY_STATE_JSON_GET_NO_SUCH_USER.get(userDN)); 280 } 281 282 return get(userEntry); 283 } 284 285 286 287 /** 288 * Attempts to retrieve and decode the password policy state information from 289 * the provided user entry. 290 * 291 * @param userEntry The entry for the user for whom to obtain the password 292 * policy state information. It must not be {@code null}. 293 * 294 * @return The password policy state information from the provided user 295 * entry, or {@code null} if no password policy state information is 296 * available for the user. 297 * 298 * @throws LDAPException If a problem is encountered while trying to decode 299 * the password policy state JSON object. 300 */ 301 @Nullable() 302 public static PasswordPolicyStateJSON get(@NotNull final Entry userEntry) 303 throws LDAPException 304 { 305 final String valueString = 306 userEntry.getAttributeValue(PASSWORD_POLICY_STATE_JSON_ATTRIBUTE); 307 if (valueString == null) 308 { 309 return null; 310 } 311 312 final JSONObject jsonObject; 313 try 314 { 315 jsonObject = new JSONObject(valueString); 316 } 317 catch (final Exception e) 318 { 319 Debug.debugException(e); 320 throw new LDAPException(ResultCode.DECODING_ERROR, 321 ERR_PW_POLICY_STATE_JSON_GET_CANNOT_DECODE.get( 322 PASSWORD_POLICY_STATE_JSON_ATTRIBUTE, userEntry.getDN()), 323 e); 324 } 325 326 return new PasswordPolicyStateJSON(jsonObject); 327 } 328 329 330 331 /** 332 * Retrieves the JSON object that contains the encoded password policy state 333 * information. 334 * 335 * @return The JSON object that contains the encoded password policy state 336 * information. 337 */ 338 @NotNull() 339 public JSONObject getPasswordPolicyStateJSONObject() 340 { 341 return passwordPolicyStateObject; 342 } 343 344 345 346 /** 347 * Retrieves the DN of the entry that defines the password policy that governs 348 * the associated user. 349 * 350 * @return The DN of the entry that defines hte password policy that governs 351 * the associated user, or {@code null} if this was not included in 352 * the password policy state JSON object. 353 */ 354 @Nullable() 355 public String getPasswordPolicyDN() 356 { 357 return passwordPolicyStateObject.getFieldAsString( 358 PASSWORD_POLICY_DN.getFieldName()); 359 } 360 361 362 363 /** 364 * Retrieves the value of a flag that indicates whether the user's account is 365 * in a state that the server considers usable. 366 * 367 * @return {@code Boolean.TRUE} if the account is in a usable state, 368 * {@code Boolean.FALSE} if the account is not in a usable state, or 369 * {@code null} if this flag was not included in the password policy 370 * state JSON object. 371 */ 372 @Nullable() 373 public Boolean getAccountIsUsable() 374 { 375 return passwordPolicyStateObject.getFieldAsBoolean( 376 ACCOUNT_IS_USABLE.getFieldName()); 377 } 378 379 380 381 /** 382 * Retrieves a list of information about any error conditions that may 383 * affect usability of the user's account. 384 * 385 * @return A list of information about any error conditions that may affect 386 * the usability of the user's account. The returned list may be 387 * empty if there are no account usability errors or if this was not 388 * included in the password policy state JSON object. 389 */ 390 @NotNull() 391 public List<PasswordPolicyStateAccountUsabilityError> 392 getAccountUsabilityErrors() 393 { 394 final List<PasswordPolicyStateAccountUsabilityError> errors = 395 new ArrayList<>(); 396 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 397 ACCOUNT_USABILITY_ERRORS.getFieldName()); 398 if (values != null) 399 { 400 for (final JSONValue v : values) 401 { 402 if (v instanceof JSONObject) 403 { 404 final JSONObject o = (JSONObject) v; 405 final String typeName = o.getFieldAsString(USABILITY_FIELD_TYPE_NAME); 406 final Integer typeID = o.getFieldAsInteger(USABILITY_FIELD_TYPE_ID); 407 final String message = o.getFieldAsString(USABILITY_FIELD_MESSAGE); 408 if ((typeName != null) && (typeID != null)) 409 { 410 errors.add(new PasswordPolicyStateAccountUsabilityError(typeID, 411 typeName, message)); 412 } 413 } 414 } 415 } 416 417 return Collections.unmodifiableList(errors); 418 } 419 420 421 422 /** 423 * Retrieves a list of information about any warning conditions that may soon 424 * affect usability of the user's account. 425 * 426 * @return A list of information about any warning conditions that may soon 427 * affect the usability of the user's account. The returned list may 428 * be empty if there are no account usability warnings or if this was 429 * not included in the password policy state JSON object. 430 */ 431 @NotNull() 432 public List<PasswordPolicyStateAccountUsabilityWarning> 433 getAccountUsabilityWarnings() 434 { 435 final List<PasswordPolicyStateAccountUsabilityWarning> warnings = 436 new ArrayList<>(); 437 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 438 ACCOUNT_USABILITY_WARNINGS.getFieldName()); 439 if (values != null) 440 { 441 for (final JSONValue v : values) 442 { 443 if (v instanceof JSONObject) 444 { 445 final JSONObject o = (JSONObject) v; 446 final String typeName = o.getFieldAsString(USABILITY_FIELD_TYPE_NAME); 447 final Integer typeID = o.getFieldAsInteger(USABILITY_FIELD_TYPE_ID); 448 final String message = o.getFieldAsString(USABILITY_FIELD_MESSAGE); 449 if ((typeName != null) && (typeID != null)) 450 { 451 warnings.add(new PasswordPolicyStateAccountUsabilityWarning(typeID, 452 typeName, message)); 453 } 454 } 455 } 456 } 457 458 return Collections.unmodifiableList(warnings); 459 } 460 461 462 463 /** 464 * Retrieves a list of information about any notices related to the usability 465 * of the user's account. 466 * 467 * @return A list of information about any notices related to the usability 468 * of the user's account. The returned list may be empty if there 469 * are no account usability notices or if this was not included in 470 * the password policy state JSON object. 471 */ 472 @NotNull() 473 public List<PasswordPolicyStateAccountUsabilityNotice> 474 getAccountUsabilityNotices() 475 { 476 final List<PasswordPolicyStateAccountUsabilityNotice> notices = 477 new ArrayList<>(); 478 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 479 ACCOUNT_USABILITY_NOTICES.getFieldName()); 480 if (values != null) 481 { 482 for (final JSONValue v : values) 483 { 484 if (v instanceof JSONObject) 485 { 486 final JSONObject o = (JSONObject) v; 487 final String typeName = o.getFieldAsString(USABILITY_FIELD_TYPE_NAME); 488 final Integer typeID = o.getFieldAsInteger(USABILITY_FIELD_TYPE_ID); 489 final String message = o.getFieldAsString(USABILITY_FIELD_MESSAGE); 490 if ((typeName != null) && (typeID != null)) 491 { 492 notices.add(new PasswordPolicyStateAccountUsabilityNotice(typeID, 493 typeName, message)); 494 } 495 } 496 } 497 } 498 499 return Collections.unmodifiableList(notices); 500 } 501 502 503 504 /** 505 * Retrieves the value of a flag that indicates whether the user's account 506 * contains at least one static password. 507 * 508 * @return {@code Boolean.TRUE} if the account has at least one static 509 * password, {@code Boolean.FALSE} if the account does not have any 510 * static password, or {@code null} if this flag was not included in 511 * the password policy state JSON object. 512 */ 513 @Nullable() 514 public Boolean getHasStaticPassword() 515 { 516 return passwordPolicyStateObject.getFieldAsBoolean( 517 HAS_STATIC_PASSWORD.getFieldName()); 518 } 519 520 521 522 /** 523 * Retrieves the time that the user's password was last changed. 524 * 525 * @return The time that the user's password was last changed, or 526 * {@code null} if this was not included in the password policy state 527 * JSON object. 528 */ 529 @Nullable() 530 public Date getPasswordChangedTime() 531 { 532 return getDate(PASSWORD_CHANGED_TIME); 533 } 534 535 536 537 /** 538 * Retrieves the length of time in seconds that has passed since the user's 539 * password was last changed. 540 * 541 * @return The length of time in seconds that has passed since the user's 542 * password was last changed, or {@code null} if this was not 543 * included in the password policy state JSON object. 544 */ 545 @Nullable() 546 public Integer getSecondsSincePasswordChange() 547 { 548 return passwordPolicyStateObject.getFieldAsInteger( 549 SECONDS_SINCE_PASSWORD_CHANGE.getFieldName()); 550 } 551 552 553 554 /** 555 * Retrieves the value of a flag that indicates whether the user's account has 556 * been administratively disabled. 557 * 558 * @return {@code Boolean.TRUE} if the account has been administratively 559 * disabled, {@code Boolean.FALSE} if the account has not been 560 * administratively disabled, or {@code null} if this flag was not 561 * included in the password policy state JSON object. 562 */ 563 @Nullable() 564 public Boolean getAccountIsDisabled() 565 { 566 return passwordPolicyStateObject.getFieldAsBoolean( 567 ACCOUNT_IS_DISABLED.getFieldName()); 568 } 569 570 571 572 /** 573 * Retrieves the value of a flag that indicates whether the user's account is 574 * not yet active because it has an activation time that is in the future. 575 * 576 * @return {@code Boolean.TRUE} if the account is not yet active, 577 * {@code Boolean.FALSE} if the account either does not have an 578 * activation time or if that time has already passed, or 579 * {@code null} if this flag was not included in the password policy 580 * state JSON object. 581 */ 582 @Nullable() 583 public Boolean getAccountIsNotYetActive() 584 { 585 return passwordPolicyStateObject.getFieldAsBoolean( 586 ACCOUNT_IS_NOT_YET_ACTIVE.getFieldName()); 587 } 588 589 590 591 /** 592 * Retrieves the time that the user's account became (or will become) active. 593 * 594 * @return The time that the user's account became (or will become) active, 595 * or {@code null} if this was not included in the password policy 596 * state JSON object. 597 */ 598 @Nullable() 599 public Date getAccountActivationTime() 600 { 601 return getDate(ACCOUNT_ACTIVATION_TIME); 602 } 603 604 605 606 /** 607 * Retrieves the length of time in seconds until the user's account will 608 * become active. 609 * 610 * @return The length of time in seconds until the user's account will become 611 * active, or {@code null} if this was not included in the password 612 * policy state JSON object (e.g., because the user does not have an 613 * activation time in the future). 614 */ 615 @Nullable() 616 public Integer getSecondsUntilAccountActivation() 617 { 618 return passwordPolicyStateObject.getFieldAsInteger( 619 SECONDS_UNTIL_ACCOUNT_ACTIVATION.getFieldName()); 620 } 621 622 623 624 /** 625 * Retrieves the length of time in seconds since the user's account became 626 * active. 627 * 628 * @return The length of time in seconds since the user's account became 629 * active, or {@code null} if this was not included in the password 630 * policy state JSON object (e.g., because the user does not have an 631 * activation time in the past). 632 */ 633 @Nullable() 634 public Integer getSecondsSinceAccountActivation() 635 { 636 return passwordPolicyStateObject.getFieldAsInteger( 637 SECONDS_SINCE_ACCOUNT_ACTIVATION.getFieldName()); 638 } 639 640 641 642 /** 643 * Retrieves the value of a flag that indicates whether the user's account is 644 * expired. 645 * 646 * @return {@code Boolean.TRUE} if the account is expired, 647 * {@code Boolean.FALSE} if the account is not expired, or 648 * {@code null} if this flag was not included in the password policy 649 * state JSON object. 650 */ 651 @Nullable() 652 public Boolean getAccountIsExpired() 653 { 654 return passwordPolicyStateObject.getFieldAsBoolean( 655 ACCOUNT_IS_EXPIRED.getFieldName()); 656 } 657 658 659 660 /** 661 * Retrieves the time that the user's account will (or did) expire. 662 * 663 * @return The time that the user's account will (or did) expire, or 664 * {@code null} if this was not included in the password policy state 665 * JSON object. 666 */ 667 @Nullable() 668 public Date getAccountExpirationTime() 669 { 670 return getDate(ACCOUNT_EXPIRATION_TIME); 671 } 672 673 674 675 /** 676 * Retrieves the length of time in seconds until the user's account will 677 * expire. 678 * 679 * @return The length of time in seconds until the user's account will 680 * expire, or {@code null} if this was not included in the password 681 * policy state JSON object (e.g., because the user does not have an 682 * expiration time in the future). 683 */ 684 @Nullable() 685 public Integer getSecondsUntilAccountExpiration() 686 { 687 return passwordPolicyStateObject.getFieldAsInteger( 688 SECONDS_UNTIL_ACCOUNT_EXPIRATION.getFieldName()); 689 } 690 691 692 693 /** 694 * Retrieves the length of time in seconds since the user's account expired. 695 * 696 * @return The length of time in seconds since the user's account expired, 697 * or {@code null} if this was not included in the password policy 698 * state JSON object (e.g., because the user does not have an 699 * expiration time in the past). 700 */ 701 @Nullable() 702 public Integer getSecondsSinceAccountExpiration() 703 { 704 return passwordPolicyStateObject.getFieldAsInteger( 705 SECONDS_SINCE_ACCOUNT_EXPIRATION.getFieldName()); 706 } 707 708 709 710 /** 711 * Retrieves the value of a flag that indicates whether the user's password is 712 * expired. 713 * 714 * @return {@code Boolean.TRUE} if the password is expired, 715 * {@code Boolean.FALSE} if the password is not expired, or 716 * {@code null} if this flag was not included in the password policy 717 * state JSON object. 718 */ 719 @Nullable() 720 public Boolean getPasswordIsExpired() 721 { 722 return passwordPolicyStateObject.getFieldAsBoolean( 723 PASSWORD_IS_EXPIRED.getFieldName()); 724 } 725 726 727 728 /** 729 * Retrieves the maximum length of time in seconds after a password change 730 * that the user is allowed to keep using that password. 731 * 732 * @return The maximum length of time in seconds after a password change that 733 * the user is allowed to keep using that password, or {@code null} 734 * if this flag was not included in the password policy state JSON 735 * object (e.g., because password expiration is not configured in the 736 * password policy that governs the user). 737 */ 738 @Nullable() 739 public Integer getMaximumPasswordAgeSeconds() 740 { 741 return passwordPolicyStateObject.getFieldAsInteger( 742 MAXIMUM_PASSWORD_AGE_SECONDS.getFieldName()); 743 } 744 745 746 747 /** 748 * Retrieves the time that the user's password will (or did) expire. 749 * 750 * @return The time that the user's password will (or did) expire, or 751 * {@code null} if this was not included in the password policy state 752 * JSON object (e.g., because password expiration is not configured 753 * in the password policy that governs the user). 754 */ 755 @Nullable() 756 public Date getPasswordExpirationTime() 757 { 758 return getDate(PASSWORD_EXPIRATION_TIME); 759 } 760 761 762 763 /** 764 * Retrieves the length of time in seconds until the user's password will 765 * expire. 766 * 767 * @return The length of time in seconds until the user's password will 768 * expire, or {@code null} if this was not included in the password 769 * policy state JSON object (e.g., because password expiration is not 770 * configured in the password policy that governs the user, or 771 * because the user's password is already expired). 772 */ 773 @Nullable() 774 public Integer getSecondsUntilPasswordExpiration() 775 { 776 return passwordPolicyStateObject.getFieldAsInteger( 777 SECONDS_UNTIL_PASSWORD_EXPIRATION.getFieldName()); 778 } 779 780 781 782 /** 783 * Retrieves the length of time in seconds since the user's password expired. 784 * 785 * @return The length of time in seconds since the user's password expired, 786 * or {@code null} if this was not included in the password policy 787 * state JSON object (e.g., because password expiration is not 788 * configured in the password policy that governs the user, or 789 * because the user's password is not expired). 790 */ 791 @Nullable() 792 public Integer getSecondsSincePasswordExpiration() 793 { 794 return passwordPolicyStateObject.getFieldAsInteger( 795 SECONDS_SINCE_PASSWORD_EXPIRATION.getFieldName()); 796 } 797 798 799 800 /** 801 * Retrieves the length of time in seconds before an upcoming password 802 * expiration that the user will be eligible to start receving warnings about 803 * that expiration. 804 * 805 * @return The length of time in seconds before an upcoming password 806 * expiration that the user will be eligible to start receiving 807 * messages about that expiration, or {@code null} if this was not 808 * included in the password policy state JSON object (e.g., because 809 * password expiration is not configured in the password policy that 810 * governs the user). 811 */ 812 @Nullable() 813 public Integer getPasswordExpirationWarningIntervalSeconds() 814 { 815 return passwordPolicyStateObject.getFieldAsInteger( 816 PASSWORD_EXPIRATION_WARNING_INTERVAL_SECONDS.getFieldName()); 817 } 818 819 820 821 /** 822 * Retrieves the value of a flag that indicates whether the server will allow 823 * a user's password to expire even if they have not yet received any warnings 824 * about an upcoming expiration. 825 * 826 * @return {@code Boolean.TRUE} if the server will allow a user's password to 827 * expire even if they have not been warned about an upcoming 828 * expiration, {@code Boolean.FALSE} if the server will ensure that 829 * the user receives at least one warning before expiring the 830 * password, or {@code null} if this flag was not included in the 831 * password policy state JSON object (e.g., because password 832 * expiration is not configured in the password policy that governs 833 * the user). 834 */ 835 @Nullable() 836 public Boolean getExpirePasswordsWithoutWarning() 837 { 838 return passwordPolicyStateObject.getFieldAsBoolean( 839 EXPIRE_PASSWORDS_WITHOUT_WARNING.getFieldName()); 840 } 841 842 843 844 /** 845 * Retrieves the value of a flag that indicates whether the user has 846 * received at least one warning about an upcoming password expiration. 847 * 848 * @return {@code Boolean.TRUE} if the user has received at least one warning 849 * about an upcoming password expiration, {@code Boolean.FALSE} if 850 * the user has not been warned about an upcoming password 851 * expiration, or {@code null} if this flag was not included in the 852 * password policy state JSON object (e.g., because password 853 * expiration is not configured in the password policy that governs 854 * the user). 855 */ 856 @Nullable() 857 public Boolean getPasswordExpirationWarningIssued() 858 { 859 return passwordPolicyStateObject.getFieldAsBoolean( 860 PASSWORD_EXPIRATION_WARNING_ISSUED.getFieldName()); 861 } 862 863 864 865 /** 866 * Retrieves the time that the user will be eligible to receive (or the time 867 * that the user first received) a warning about an upcoming password 868 * expiration. 869 * 870 * @return The time that the user will be eligible to receive (or the time 871 * that the user first received) a warning about an upcoming password 872 * expiration, or {@code null} if this was not included in the 873 * password policy state JSON object (e.g., because password 874 * expiration is not configured in the password policy that governs 875 * the user). 876 */ 877 @Nullable() 878 public Date getPasswordExpirationWarningTime() 879 { 880 return getDate(PASSWORD_EXPIRATION_WARNING_TIME); 881 } 882 883 884 885 /** 886 * Retrieves the length of time in seconds until the user will be eligible to 887 * receive a warning about an upcoming password expiration. 888 * 889 * @return The length of time in seconds until the user will be eligible to 890 * receive a warning about an upcoming password expiration, or 891 * {@code null} if this was not included in the password policy state 892 * JSON object (e.g., because password expiration is not configured 893 * in the password policy that governs the user, or because the user 894 * has already been warned about an upcoming expiration). 895 */ 896 @Nullable() 897 public Integer getSecondsUntilPasswordExpirationWarning() 898 { 899 return passwordPolicyStateObject.getFieldAsInteger( 900 SECONDS_UNTIL_PASSWORD_EXPIRATION_WARNING.getFieldName()); 901 } 902 903 904 905 /** 906 * Retrieves the length of time in seconds since the user received the first 907 * warning about an upcoming password expiration. 908 * 909 * @return The length of time in seconds since the user received the first 910 * warning about an upcoming password expiration, or {@code null} if 911 * this was not included in the password policy state JSON object 912 * (e.g., because password expiration is not configured in the 913 * password policy that governs the user, or because the user has 914 * not yet been warned about an upcoming expiration). 915 */ 916 @Nullable() 917 public Integer getSecondsSincePasswordExpirationWarning() 918 { 919 return passwordPolicyStateObject.getFieldAsInteger( 920 SECONDS_SINCE_PASSWORD_EXPIRATION_WARNING.getFieldName()); 921 } 922 923 924 925 /** 926 * Retrieves the value of a flag that indicates whether the user account is 927 * currently locked as a result of too many failed authentication attempts. 928 * 929 * @return {@code Boolean.TRUE} if the user account is locked as a result of 930 * too many failed authentication attempts, {@code Boolean.FALSE} if 931 * the user account is not locked because of too many failed 932 * authentication attempts, or {@code null} if this flag was not 933 * included in the password policy state JSON object. 934 */ 935 @Nullable() 936 public Boolean getAccountIsFailureLocked() 937 { 938 return passwordPolicyStateObject.getFieldAsBoolean( 939 ACCOUNT_IS_FAILURE_LOCKED.getFieldName()); 940 } 941 942 943 944 /** 945 * Retrieves the number of consecutive failed authentication attempts that are 946 * required to lock the user's account. 947 * 948 * @return The number of consecutive failed authentication attempts that are 949 * required to lock the user's account, or {@code null} if this was 950 * not included in the password policy state JSON object (e.g., 951 * because account lockout is not configured in the password policy 952 * that governs the user). 953 */ 954 @Nullable() 955 public Integer getFailureLockoutCount() 956 { 957 return passwordPolicyStateObject.getFieldAsInteger( 958 FAILURE_LOCKOUT_COUNT.getFieldName()); 959 } 960 961 962 963 /** 964 * Retrieves the current number of failed authentication attempts for the 965 * user account. 966 * 967 * @return The current number of failed authentication attempts for the user 968 * account, or {@code null} if this was not included in the password 969 * policy state JSON object (e.g., because account lockout is not 970 * configured in the password policy that governs the user). 971 */ 972 @Nullable() 973 public Integer getCurrentAuthenticationFailureCount() 974 { 975 return passwordPolicyStateObject.getFieldAsInteger( 976 CURRENT_AUTHENTICATION_FAILURE_COUNT.getFieldName()); 977 } 978 979 980 981 /** 982 * Retrieves the remaining number of failed authentication attempts required 983 * to lock the user account. 984 * 985 * @return The remaining number of failed authentication attempts required to 986 * lock the user account, or {@code null} if this was not included in 987 * the password policy state JSON object (e.g., because account 988 * lockout is not configured in the password policy that governs the 989 * user). 990 */ 991 @Nullable() 992 public Integer getRemainingAuthenticationFailureCount() 993 { 994 return passwordPolicyStateObject.getFieldAsInteger( 995 REMAINING_AUTHENTICATION_FAILURE_COUNT.getFieldName()); 996 } 997 998 999 1000 /** 1001 * Retrieves a list of the outstanding authentication failure times for the 1002 * user account. 1003 * 1004 * @return A list of the outstanding authentication failure times for the 1005 * user account, or an empty list if there are no outstanding 1006 * authentication failures or if this was not included in the 1007 * password policy state JSON object (e.g., because account lockout 1008 * is not configured in the password policy that governs the user). 1009 */ 1010 @NotNull() 1011 public List<Date> getAuthenticationFailureTimes() 1012 { 1013 final List<Date> authFailureTimes = new ArrayList<>(); 1014 1015 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 1016 AUTHENTICATION_FAILURE_TIMES.getFieldName()); 1017 if (values != null) 1018 { 1019 for (final JSONValue v : values) 1020 { 1021 try 1022 { 1023 final String valueString = ((JSONString) v).stringValue(); 1024 authFailureTimes.add(StaticUtils.decodeRFC3339Time(valueString)); 1025 } 1026 catch (final Exception e) 1027 { 1028 Debug.debugException(e); 1029 } 1030 } 1031 } 1032 1033 return Collections.unmodifiableList(authFailureTimes); 1034 } 1035 1036 1037 1038 /** 1039 * Retrieves the time that the user's account was locked as a result of too 1040 * many failed authentication attempts. 1041 * 1042 * @return The time that the user's account was locked as a result of too 1043 * many failed authentication attempts, or {@code null} if this was 1044 * not included in the password policy state JSON object (e.g., 1045 * because the user's account is not failure locked). 1046 */ 1047 @Nullable() 1048 public Date getFailureLockoutTime() 1049 { 1050 return getDate(FAILURE_LOCKOUT_TIME); 1051 } 1052 1053 1054 1055 /** 1056 * Retrieves the length of time in seconds that a user's account will be 1057 * locked after too many failed authentication attempts. 1058 * 1059 * @return The length of time in seconds that a user's account will be 1060 * locked after too many failed authentication attempts, or 1061 * {@code null} if this was not included in the password policy state 1062 * JSON object (e.g., because account lockout is not configured in 1063 * the password policy that governs the user, or because account 1064 * lockout is not temporary). 1065 */ 1066 @Nullable() 1067 public Integer getFailureLockoutDurationSeconds() 1068 { 1069 return passwordPolicyStateObject.getFieldAsInteger( 1070 FAILURE_LOCKOUT_DURATION_SECONDS.getFieldName()); 1071 1072 } 1073 1074 1075 1076 /** 1077 * Retrieves the time that the user's failure-locked account will be 1078 * automatically unlocked. 1079 * 1080 * @return The time that the user's failure-locked account will be 1081 * automatically unlocked, or {@code null} if this was not included 1082 * in the password policy state JSON object (e.g., because the user's 1083 * account is not failure locked, or because the lockout is not 1084 * temporary). 1085 */ 1086 @Nullable() 1087 public Date getFailureLockoutExpirationTime() 1088 { 1089 return getDate(FAILURE_LOCKOUT_EXPIRATION_TIME); 1090 } 1091 1092 1093 1094 /** 1095 * Retrieves the length of time in seconds remaining until the user's 1096 * failure-locked account will be automatically unlocked. 1097 * 1098 * @return The length of time in seconds remaining until the user's 1099 * failure-locked account will be automatically unlocked, or 1100 * {@code null} if this was not included in the password policy state 1101 * JSON object (e.g., because the user's account is not failure 1102 * locked, or because the lockout is not temporary). 1103 */ 1104 @Nullable() 1105 public Integer getSecondsRemainingInFailureLockout() 1106 { 1107 return passwordPolicyStateObject.getFieldAsInteger( 1108 SECONDS_REMAINING_IN_FAILURE_LOCKOUT.getFieldName()); 1109 } 1110 1111 1112 1113 /** 1114 * Retrieves the time that the user last successfully authenticated to the 1115 * server. 1116 * 1117 * @return The time that the user last successfully authenticated to the 1118 * server, or {@code null} if this was not included in the password 1119 * policy state JSON object (e.g., because last login time tracking 1120 * is not configured in the password policy that governs the user). 1121 */ 1122 @Nullable() 1123 public Date getLastLoginTime() 1124 { 1125 return getDate(LAST_LOGIN_TIME); 1126 } 1127 1128 1129 1130 /** 1131 * Retrieves the length of time in seconds since the user last successfully 1132 * authenticated to the server. 1133 * 1134 * @return The length of time in seconds since the user last successfully 1135 * authenticated to the server, or {@code null} if this was not 1136 * included in the password policy state JSON object (e.g., because 1137 * last login time tracking is not configured in the password policy 1138 * that governs the user). 1139 */ 1140 @Nullable() 1141 public Integer getSecondsSinceLastLogin() 1142 { 1143 return passwordPolicyStateObject.getFieldAsInteger( 1144 SECONDS_SINCE_LAST_LOGIN.getFieldName()); 1145 } 1146 1147 1148 1149 /** 1150 * Retrieves the IP address of the client from which the user last 1151 * successfully authenticated. 1152 * 1153 * @return The IP address of the client from which the user last successfully 1154 * authenticated, or {@code null} if this was not included in the 1155 * password policy state JSON object (e.g., because last login IP 1156 * address tracking is not configured in the password policy that 1157 * governs the user). 1158 */ 1159 @Nullable() 1160 public String getLastLoginIPAddress() 1161 { 1162 return passwordPolicyStateObject.getFieldAsString( 1163 LAST_LOGIN_IP_ADDRESS.getFieldName()); 1164 } 1165 1166 1167 1168 /** 1169 * Retrieves the value of a flag that indicates whether the user's account is 1170 * currently locked because it has been too long since they last authenticated 1171 * to the server. 1172 * 1173 * @return {@code Boolean.TRUE} if the user's account is currently 1174 * idle-locked, {@code Boolean.FALSE} if the user's account is not 1175 * currently idle-locked, or {@code null} if this flag was not 1176 * included in the password policy state JSON object. 1177 */ 1178 @Nullable() 1179 public Boolean getAccountIsIdleLocked() 1180 { 1181 return passwordPolicyStateObject.getFieldAsBoolean( 1182 ACCOUNT_IS_IDLE_LOCKED.getFieldName()); 1183 } 1184 1185 1186 1187 /** 1188 * Retrieves the maximum length of time in seconds that can elapse between 1189 * successful authentications before the user's account is locked. 1190 * 1191 * @return The maximum length of time in seconds that can elapse between 1192 * successful authentications before the user's account is locked, or 1193 * {@code null} if this was not included in the password policy state 1194 * JSON object (e.g., because idle lockout is not configured in the 1195 * password policy that governs the user). 1196 */ 1197 @Nullable() 1198 public Integer getIdleLockoutIntervalSeconds() 1199 { 1200 return passwordPolicyStateObject.getFieldAsInteger( 1201 IDLE_LOCKOUT_INTERVAL_SECONDS.getFieldName()); 1202 } 1203 1204 1205 1206 /** 1207 * Retrieves the time that the user's account will be (or was) locked for 1208 * allowing too much time to elapse between successful authentications. 1209 * 1210 * @return The time that the user's account will be (or was) locked for 1211 * allowing too much time to elapse between successful 1212 * authentications, or {@code null} if this was not included in the 1213 * password policy state JSON object (e.g., because idle lockout is 1214 * not configured in the password policy that governs the user). 1215 */ 1216 @Nullable() 1217 public Date getIdleLockoutTime() 1218 { 1219 return getDate(IDLE_LOCKOUT_TIME); 1220 } 1221 1222 1223 1224 /** 1225 * Retrieves the length of time in seconds until the user's account will be 1226 * locked for allowing too much time to elapse between successful 1227 * authentications. 1228 * 1229 * @return The length of time in seconds until the user's account will be 1230 * locked for allowing too much time to elapse between successful 1231 * authentication, or {@code null} if this was not included in the 1232 * password policy state JSON object (e.g., because idle lockout is 1233 * not configured in the password policy that governs the user, or 1234 * because the user's account is already idle-locked). 1235 */ 1236 @Nullable() 1237 public Integer getSecondsUntilIdleLockout() 1238 { 1239 return passwordPolicyStateObject.getFieldAsInteger( 1240 SECONDS_UNTIL_IDLE_LOCKOUT.getFieldName()); 1241 } 1242 1243 1244 1245 /** 1246 * Retrieves the length of time in seconds since the user's account was 1247 * locked for allowing too much time to elapse between successful 1248 * authentications. 1249 * 1250 * @return The length of time in seconds since the user's account was locked 1251 * for allowing too much time to elapse between successful 1252 * authentication, or {@code null} if this was not included in the 1253 * password policy state JSON object (e.g., because idle lockout is 1254 * not configured in the password policy that governs the user, or 1255 * because the user's account is not idle-locked). 1256 */ 1257 @Nullable() 1258 public Integer getSecondsSinceIdleLockout() 1259 { 1260 return passwordPolicyStateObject.getFieldAsInteger( 1261 SECONDS_SINCE_IDLE_LOCKOUT.getFieldName()); 1262 } 1263 1264 1265 1266 /** 1267 * Retrieves the value of a flag that indicates whether the user must change 1268 * their password before they will be allowed to perform any other operations 1269 * in the server. 1270 * 1271 * @return {@code Boolean.TRUE} if the user must change their password before 1272 * they will be allowed to perform any other operations in the 1273 * server, {@code Boolean.FALSE} if the user is not required to 1274 * change their password, or {@code null} if this flag was not 1275 * included in the password policy state JSON object. 1276 */ 1277 @Nullable() 1278 public Boolean getMustChangePassword() 1279 { 1280 return passwordPolicyStateObject.getFieldAsBoolean( 1281 MUST_CHANGE_PASSWORD.getFieldName()); 1282 } 1283 1284 1285 1286 /** 1287 * Retrieves the value of a flag that indicates whether the user's account is 1288 * locked because they failed to choose a new password in a timely manner 1289 * after an administrative reset. 1290 * 1291 * @return {@code Boolean.TRUE} if the user's account is currently 1292 * reset-locked, {@code Boolean.FALSE} if the user's account is not 1293 * reset-locked, or {@code null} if this flag was not included in the 1294 * password policy state JSON object. 1295 */ 1296 @Nullable() 1297 public Boolean getAccountIsResetLocked() 1298 { 1299 return passwordPolicyStateObject.getFieldAsBoolean( 1300 ACCOUNT_IS_RESET_LOCKED.getFieldName()); 1301 } 1302 1303 1304 1305 /** 1306 * Retrieves the value of a flag that indicates whether the password policy 1307 * that governs the user is configured to require users to choose a new 1308 * password the first time they authenticate after their account is created. 1309 * 1310 * @return {@code Boolean.TRUE} if users are required to choose a new 1311 * password the first time they authenticate after their account is 1312 * created, {@code Boolean.FALSE} if users are not required to choose 1313 * a new password after their account is created, or {@code null} if 1314 * this flag was not included in the password policy state JSON 1315 * object. 1316 */ 1317 @Nullable() 1318 public Boolean getForceChangeOnAdd() 1319 { 1320 return passwordPolicyStateObject.getFieldAsBoolean( 1321 FORCE_CHANGE_ON_ADD.getFieldName()); 1322 } 1323 1324 1325 1326 /** 1327 * Retrieves the value of a flag that indicates whether the password policy 1328 * that governs the user is configured to require users to choose a new 1329 * password the first time they authenticate after their password has been 1330 * reset by an administrator. 1331 * 1332 * @return {@code Boolean.TRUE} if users are required to choose a new 1333 * password the first time they authenticate after their password is 1334 * reset, {@code Boolean.FALSE} if users are not required to choose 1335 * a new password after their password is reset, or {@code null} if 1336 * this flag was not included in the password policy state JSON 1337 * object. 1338 */ 1339 @Nullable() 1340 public Boolean getForceChangeOnReset() 1341 { 1342 return passwordPolicyStateObject.getFieldAsBoolean( 1343 FORCE_CHANGE_ON_RESET.getFieldName()); 1344 } 1345 1346 1347 1348 /** 1349 * Retrieves the maximum length of time in seconds that a user has to change 1350 * their password after an administrative reset before their account will be 1351 * locked. 1352 * 1353 * @return The maximum length of time in seconds that a user has to change 1354 * their password after an administrative reset before their account 1355 * will be locked, or {@code null} if this was not included in the 1356 * password policy state JSON object (e.g., because reset lockout is 1357 * not configured in the password policy that governs the user). 1358 */ 1359 @Nullable() 1360 public Integer getMaximumPasswordResetAgeSeconds() 1361 { 1362 return passwordPolicyStateObject.getFieldAsInteger( 1363 MAXIMUM_PASSWORD_RESET_AGE_SECONDS.getFieldName()); 1364 } 1365 1366 1367 1368 /** 1369 * Retrieves the time that the user's account will be (or was) locked after 1370 * failing to choose a new password in a timely manner after an administrative 1371 * reset. 1372 * 1373 * @return The time that the user's account will be (or wa) locked after 1374 * failing to choose a new password in a timely manner after an 1375 * administrative reset, or {@code null} if this was not included in 1376 * the password policy state JSON object (e.g., because reset lockout 1377 * is not configured in the password policy that governs the user, 1378 * or because the user's password has not been reset). 1379 */ 1380 @Nullable() 1381 public Date getResetLockoutTime() 1382 { 1383 return getDate(RESET_LOCKOUT_TIME); 1384 } 1385 1386 1387 1388 /** 1389 * Retrieves the length of time in seconds until the user's account will be 1390 * locked for failing to choose a new password after an administrative 1391 * reset. 1392 * 1393 * @return The length of time in seconds until the user's account will be 1394 * locked for failing to choose a new password after an 1395 * administrative reset, or {@code null} if this was not included in 1396 * the password policy state JSON object (e.g., because reset lockout 1397 * is not configured in the password policy that governs the user, 1398 * because the user's password has not been reset, or because the 1399 * user's account is already reset-locked). 1400 */ 1401 @Nullable() 1402 public Integer getSecondsUntilResetLockout() 1403 { 1404 return passwordPolicyStateObject.getFieldAsInteger( 1405 SECONDS_UNTIL_RESET_LOCKOUT.getFieldName()); 1406 } 1407 1408 1409 1410 /** 1411 * Retrieves the maximum number of passwords that the server will maintain in 1412 * the user's password history. 1413 * 1414 * @return The maximum number of passwords that the server will maintain in 1415 * the user's password history, or {@code null} if this was not 1416 * included in the password policy state JSON object (e.g., because 1417 * the password policy that governs the user is not configured to 1418 * maintain a password history, or because it maintains a password 1419 * history based on a duration rather than a count). 1420 */ 1421 @Nullable() 1422 public Integer getMaximumPasswordHistoryCount() 1423 { 1424 return passwordPolicyStateObject.getFieldAsInteger( 1425 MAXIMUM_PASSWORD_HISTORY_COUNT.getFieldName()); 1426 } 1427 1428 1429 1430 /** 1431 * Retrieves the maximum length of time in seconds that the server will 1432 * maintain passwords in the user's password history. 1433 * 1434 * @return The maximum length of time in seconds that the server will 1435 * maintain passwords in the user's password history, or 1436 * {@code null} if this was not included in the password policy 1437 * state JSON object (e.g., because the password policy that governs 1438 * the user is not configured to maintain a password history, or 1439 * because it maintains a password history based on a count rather 1440 * than a duration). 1441 */ 1442 @Nullable() 1443 public Integer getMaximumPasswordHistoryDurationSeconds() 1444 { 1445 return passwordPolicyStateObject.getFieldAsInteger( 1446 MAXIMUM_PASSWORD_HISTORY_DURATION_SECONDS.getFieldName()); 1447 } 1448 1449 1450 1451 /** 1452 * Retrieves the number of passwords currently held in the user's password 1453 * history. 1454 * 1455 * @return The number of passwords currently held in the user's password 1456 * history, or {@code null} if this was not incldued in the password 1457 * policy state JSON object (e.g., because the password policy that 1458 * governs the user is not configured to maintain a password 1459 * history). 1460 */ 1461 @Nullable() 1462 public Integer getCurrentPasswordHistoryCount() 1463 { 1464 return passwordPolicyStateObject.getFieldAsInteger( 1465 CURRENT_PASSWORD_HISTORY_COUNT.getFieldName()); 1466 } 1467 1468 1469 1470 /** 1471 * Indicates whether the user is currently prohibited from changing their 1472 * password because not enough time has elapsed since they last changed their 1473 * password. 1474 * 1475 * @return {@code Boolean.TRUE} if the user is currently prohibited from 1476 * changing their password because not enough time has elapsed since 1477 * they last changed their password, {@code Boolean.FALSE} if the 1478 * user is not prohibited from changing their password because of the 1479 * minimum password age, or {@code null} if this flag was not 1480 * included in the password policy state JSON object. 1481 */ 1482 @Nullable() 1483 public Boolean getIsWithinMinimumPasswordAge() 1484 { 1485 return passwordPolicyStateObject.getFieldAsBoolean( 1486 IS_WITHIN_MINIMUM_PASSWORD_AGE.getFieldName()); 1487 } 1488 1489 1490 1491 /** 1492 * Retrieves the minimum length of time in seconds that must elapse after a 1493 * user changes their password before they will be permitted to change it 1494 * again. 1495 * 1496 * @return The minimum length of time in seconds that must elapse after a 1497 * user changes their password before they will be permitted to 1498 * change it again, or {@code null} if this was not included in the 1499 * password policy state JSON object (e.g., because no minimum 1500 * password age is configured in the password policy that governs the 1501 * user). 1502 */ 1503 @Nullable() 1504 public Integer getMinimumPasswordAgeSeconds() 1505 { 1506 return passwordPolicyStateObject.getFieldAsInteger( 1507 MINIMUM_PASSWORD_AGE_SECONDS.getFieldName()); 1508 } 1509 1510 1511 1512 /** 1513 * Retrieves the earliest time that the user will be permitted to change their 1514 * password as a result of the minimum password age. 1515 * 1516 * @return The earliest time that the user will be permitted to change their 1517 * password as a result of the minimum password age, or {@code null} 1518 * if this was not included in the password policy state JSON 1519 * object (e.g., because no minimum password age is configured in the 1520 * password policy that governs the user, or because it has been 1521 * longer than the minimum age since they last changed their 1522 * password). 1523 */ 1524 @Nullable() 1525 public Date getMinimumPasswordAgeExpirationTime() 1526 { 1527 return getDate(MINIMUM_PASSWORD_AGE_EXPIRATION_TIME); 1528 } 1529 1530 1531 1532 /** 1533 * Retrieves the length of time in seconds remaining until the user will be 1534 * permitted to change their password as a result of the minimum password age. 1535 * 1536 * @return The length of time in seconds remaining until the user will be 1537 * permitted to change their password as a result of the minimum 1538 * password age, or {@code null} if this was not included in the 1539 * password policy state JSON object (e.g., because no minimum 1540 * password age is configured in the password policy that governs the 1541 * user, or because it has been longer than the minimum age since 1542 * they last changed their password). 1543 */ 1544 @Nullable() 1545 public Integer getSecondsRemainingInMinimumPasswordAge() 1546 { 1547 return passwordPolicyStateObject.getFieldAsInteger( 1548 SECONDS_REMAINING_IN_MINIMUM_PASSWORD_AGE.getFieldName()); 1549 } 1550 1551 1552 1553 /** 1554 * Retrieves the maximum number of grace login attempts that the user will 1555 * have to allow them to change an expired password. 1556 * 1557 * @return The maximum number of grace login attempts that the user will have 1558 * to allow them to change an expired password, or {@code null} if 1559 * this was not included in the password policy state JSON object 1560 * (e.g., if grace logins are not configured in the password policy 1561 * that governs the user). 1562 */ 1563 @Nullable() 1564 public Integer getMaximumGraceLoginCount() 1565 { 1566 return passwordPolicyStateObject.getFieldAsInteger( 1567 MAXIMUM_GRACE_LOGIN_COUNT.getFieldName()); 1568 } 1569 1570 1571 1572 /** 1573 * Retrieves the number of grace logins that the user has currently used. 1574 * 1575 * @return The number of grace login attempts that the user has currently 1576 * used, or {@code null} if this was not included in the password 1577 * policy state JSON object (e.g., if grace logins are not configured 1578 * in the password policy that governs the user). 1579 */ 1580 @Nullable() 1581 public Integer getUsedGraceLoginCount() 1582 { 1583 return passwordPolicyStateObject.getFieldAsInteger( 1584 USED_GRACE_LOGIN_COUNT.getFieldName()); 1585 } 1586 1587 1588 1589 /** 1590 * Retrieves the remaining number of grace logins for the user. 1591 * 1592 * @return The remaining number of grace logins for the user, or {@code null} 1593 * if this was not included in the password policy state JSON object 1594 * (e.g., if grace logins are not configured in the password policy 1595 * that governs the user). 1596 */ 1597 @Nullable() 1598 public Integer getRemainingGraceLoginCount() 1599 { 1600 return passwordPolicyStateObject.getFieldAsInteger( 1601 REMAINING_GRACE_LOGIN_COUNT.getFieldName()); 1602 } 1603 1604 1605 1606 /** 1607 * Retrieves a list of the times that the user has used a grace login to 1608 * authenticate. 1609 * 1610 * @return A list of the times that the user has used a grace login to 1611 * authenticate, or an empty list if the user has not used any grace 1612 * logins, or if this was not included in the password policy state 1613 * JSON object (e.g., if grace logins are not configured in the 1614 * password policy that governs the user). 1615 */ 1616 @NotNull() 1617 public List<Date> getGraceLoginUseTimes() 1618 { 1619 final List<Date> graceLoginTimes = new ArrayList<>(); 1620 1621 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 1622 GRACE_LOGIN_USE_TIMES.getFieldName()); 1623 if (values != null) 1624 { 1625 for (final JSONValue v : values) 1626 { 1627 try 1628 { 1629 final String valueString = ((JSONString) v).stringValue(); 1630 graceLoginTimes.add(StaticUtils.decodeRFC3339Time(valueString)); 1631 } 1632 catch (final Exception e) 1633 { 1634 Debug.debugException(e); 1635 } 1636 } 1637 } 1638 1639 return Collections.unmodifiableList(graceLoginTimes); 1640 } 1641 1642 1643 1644 /** 1645 * Retrieves the value of a flag that indicates whether the user account has a 1646 * retired former password that may still be used to authenticate. 1647 * 1648 * @return {@code Boolean.TRUE} if the user account currently has a valid 1649 * retired password, {@code Boolean.FALSE} if the user account does 1650 * not have a valid retired password, or {@code null} if this flag 1651 * was not included in the password policy state JSON object. 1652 */ 1653 @Nullable() 1654 public Boolean getHasRetiredPassword() 1655 { 1656 return passwordPolicyStateObject.getFieldAsBoolean( 1657 HAS_RETIRED_PASSWORD.getFieldName()); 1658 } 1659 1660 1661 1662 /** 1663 * Retrieves the time that the user's retired password will expire and can no 1664 * longer be used to authenticate. 1665 * 1666 * @return The time that the user's retired password will expire, or 1667 * {@code null} if this was not included in the password policy state 1668 * JSON object (e.g., because the user does not have a retired 1669 * password). 1670 */ 1671 @Nullable() 1672 public Date getRetiredPasswordExpirationTime() 1673 { 1674 return getDate(RETIRED_PASSWORD_EXPIRATION_TIME); 1675 } 1676 1677 1678 1679 /** 1680 * Retrieves the length of time in seconds remaining until the user's retired 1681 * password expires and can no longer be used to authenticate. 1682 * 1683 * @return The length of time in seconds remaining until the user's retired 1684 * password expires, or {@code null} if this was not included in the 1685 * password policy state JSON object (e.g., because the user does not 1686 * have a retired password). 1687 */ 1688 @Nullable() 1689 public Integer getSecondsUntilRetiredPasswordExpiration() 1690 { 1691 return passwordPolicyStateObject.getFieldAsInteger( 1692 SECONDS_UNTIL_RETIRED_PASSWORD_EXPIRATION.getFieldName()); 1693 } 1694 1695 1696 1697 /** 1698 * Retrieves the value of a flag that indicates whether the user will be 1699 * required to authenticate in a secure manner that does not reveal their 1700 * credentials to an observer. 1701 * 1702 * @return {@code Boolean.TRUE} if the user will be required to authenticate 1703 * in a secure manner, {@code Boolean.FALSE} if the user will not be 1704 * required to authenticate in a secure manner, or {@code null} if 1705 * this flag was not included in the password policy state JSON 1706 * object. 1707 */ 1708 @Nullable() 1709 public Boolean getRequireSecureAuthentication() 1710 { 1711 return passwordPolicyStateObject.getFieldAsBoolean( 1712 REQUIRE_SECURE_AUTHENTICATION.getFieldName()); 1713 } 1714 1715 1716 1717 /** 1718 * Retrieves the value of a flag that indicates whether the user will be 1719 * required to change their password in a secure manner that does not reveal 1720 * their credentials to an observer. 1721 * 1722 * @return {@code Boolean.TRUE} if the user will be required to change their 1723 * password in a secure manner, {@code Boolean.FALSE} if the user 1724 * will not be required to change their password in a secure manner, 1725 * or {@code null} if this flag was not included in the password 1726 * policy state JSON object. 1727 */ 1728 @Nullable() 1729 public Boolean getRequireSecurePasswordChanges() 1730 { 1731 return passwordPolicyStateObject.getFieldAsBoolean( 1732 REQUIRE_SECURE_PASSWORD_CHANGES.getFieldName()); 1733 } 1734 1735 1736 1737 /** 1738 * Retrieves a list of the names of the SASL mechanisms that the user can use 1739 * to authenticate. 1740 * 1741 * @return A list of the names of the SASL mechanisms that the user can use 1742 * to authenticate, or an empty list if no SASL mechanisms are 1743 * available to the user or if this was not included in the password 1744 * policy state JSON object. 1745 */ 1746 @NotNull() 1747 public List<String> getAvailableSASLMechanisms() 1748 { 1749 final List<String> saslMechanismNames = new ArrayList<>(); 1750 1751 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 1752 AVAILABLE_SASL_MECHANISMS.getFieldName()); 1753 if (values != null) 1754 { 1755 for (final JSONValue v : values) 1756 { 1757 try 1758 { 1759 saslMechanismNames.add(((JSONString) v).stringValue()); 1760 } 1761 catch (final Exception e) 1762 { 1763 Debug.debugException(e); 1764 } 1765 } 1766 } 1767 1768 return Collections.unmodifiableList(saslMechanismNames); 1769 } 1770 1771 1772 1773 /** 1774 * Retrieves a list of the names of the OTP delivery mechanisms that the user 1775 * can use to receive one-time passwords, password reset tokens, and 1776 * single-use tokens. 1777 * 1778 * @return A list of the names of the OTP delivery mechanisms that the user 1779 * can use, or an empty list if no OTP delivery mechanisms are 1780 * available to the user or if this was not included in the password 1781 * policy state JSON object. 1782 */ 1783 @NotNull() 1784 public List<String> getAvailableOTPDeliveryMechanisms() 1785 { 1786 final List<String> deliveryMechanismNames = new ArrayList<>(); 1787 1788 final List<JSONValue> values = passwordPolicyStateObject.getFieldAsArray( 1789 AVAILABLE_OTP_DELIVERY_MECHANISMS.getFieldName()); 1790 if (values != null) 1791 { 1792 for (final JSONValue v : values) 1793 { 1794 try 1795 { 1796 deliveryMechanismNames.add(((JSONString) v).stringValue()); 1797 } 1798 catch (final Exception e) 1799 { 1800 Debug.debugException(e); 1801 } 1802 } 1803 } 1804 1805 return Collections.unmodifiableList(deliveryMechanismNames); 1806 } 1807 1808 1809 1810 /** 1811 * Retrieves the value of a flag that indicates whether the user account has 1812 * at least one TOTP shared secret that can be used to authenticate with 1813 * time-based one-time passwords via the UNBOUNDID-TOTP SASL mechanism. 1814 * 1815 * @return {@code Boolean.TRUE} if the user account has at least one TOTP 1816 * shared secret, {@code Boolean.FALSE} if the user account does not 1817 * have any TOTP shared secrets, or {@code null} if this flag was not 1818 * included in the password policy state JSON object. 1819 */ 1820 @Nullable() 1821 public Boolean getHasTOTPSharedSecret() 1822 { 1823 return passwordPolicyStateObject.getFieldAsBoolean( 1824 HAS_TOTP_SHARED_SECRET.getFieldName()); 1825 } 1826 1827 1828 1829 /** 1830 * Retrieves the value of a flag that indicates whether the user account has 1831 * at least one registered YubiKey OTP device that can be used to authenticate 1832 * via the UNBOUNDID-YUBIKEY-OTP SASL mechanism. 1833 * 1834 * @return {@code Boolean.TRUE} if the user account has at least one 1835 * registered YubiKey OTP device, {@code Boolean.FALSE} if the user 1836 * account does not have any registered YubiKey OTP devices, or 1837 * {@code null} if this flag was not included in the password policy 1838 * state JSON object. 1839 */ 1840 @Nullable() 1841 public Boolean getHasRegisteredYubiKeyOTPDevice() 1842 { 1843 return passwordPolicyStateObject.getFieldAsBoolean( 1844 HAS_REGISTERED_YUBIKEY_OTP_DEVICE.getFieldName()); 1845 } 1846 1847 1848 1849 /** 1850 * Retrieves the value of a flag that indicates whether the user account is 1851 * currently locked because it contains a password that does not satisfy all 1852 * of the configured password validators. 1853 * 1854 * @return {@code Boolean.TRUE} if the user account is locked because it 1855 * contains a password that does not satisfy all of the configured 1856 * password validators, {@code Boolean.FALSE} if the account is not 1857 * validation-locked, or {@code null} if this flag was not included 1858 * in the password policy state JSON object. 1859 */ 1860 @Nullable() 1861 public Boolean getAccountIsValidationLocked() 1862 { 1863 return passwordPolicyStateObject.getFieldAsBoolean( 1864 ACCOUNT_IS_VALIDATION_LOCKED.getFieldName()); 1865 } 1866 1867 1868 1869 /** 1870 * Retrieves the time that the server last invoked password validators during 1871 * a bind operation for the user. 1872 * 1873 * @return The time that the server last invoked password validators during a 1874 * bind operation for the user, or {@code null} if this was not 1875 * included in the password policy state JSON object. 1876 */ 1877 @Nullable() 1878 public Date getLastBindPasswordValidationTime() 1879 { 1880 return getDate(LAST_BIND_PASSWORD_VALIDATION_TIME); 1881 } 1882 1883 1884 1885 /** 1886 * Retrieves the length of time in seconds that has passed since the server 1887 * last invoked password validators during a bind operation for the user. 1888 * 1889 * @return The length of time in seconds that has passed since the server 1890 * last invoked password validators during a bind operation for the 1891 * user, or {@code null} if this was not included in the password 1892 * policy state JSON object. 1893 */ 1894 @Nullable() 1895 public Integer getSecondsSinceLastBindPasswordValidation() 1896 { 1897 return passwordPolicyStateObject.getFieldAsInteger( 1898 SECONDS_SINCE_LAST_BIND_PASSWORD_VALIDATION.getFieldName()); 1899 } 1900 1901 1902 1903 /** 1904 * Retrieves the minimum length of time in seconds that should pass between 1905 * invocations of password validators during a bind operation for the user. 1906 * 1907 * @return The minimum length of time in seconds that should pass between 1908 * invocations of password validators during a bind operation for 1909 * each user, or {@code null} if this was not included in the 1910 * password policy state JSON object. 1911 */ 1912 @Nullable() 1913 public Integer getMinimumBindPasswordValidationFrequencySeconds() 1914 { 1915 return passwordPolicyStateObject.getFieldAsInteger( 1916 MINIMUM_BIND_PASSWORD_VALIDATION_FREQUENCY_SECONDS.getFieldName()); 1917 } 1918 1919 1920 1921 /** 1922 * Retrieves the name of the action that the server should take if the 1923 * password provided during a bind operation fails to satisfy one or more 1924 * password validators. 1925 * 1926 * @return The name of the action that the server should take if the password 1927 * provided during a bind operation fails to satisfy one or more 1928 * password validators, or {@code null} if this was not included in 1929 * the password policy state JSON object. 1930 */ 1931 @Nullable() 1932 public String getBindPasswordValidationFailureAction() 1933 { 1934 return passwordPolicyStateObject.getFieldAsString( 1935 BIND_PASSWORD_VALIDATION_FAILURE_ACTION.getFieldName()); 1936 } 1937 1938 1939 1940 /** 1941 * Retrieves the recent login history for the user. 1942 * 1943 * @return The recent login history for the user, or {@code null} if this was 1944 * not included in the password policy state JSON object. 1945 * 1946 * @throws LDAPException If a problem occurs while trying to parse the 1947 * recent login history for the user. 1948 */ 1949 @Nullable() 1950 public RecentLoginHistory getRecentLoginHistory() 1951 throws LDAPException 1952 { 1953 final JSONObject o = passwordPolicyStateObject.getFieldAsObject( 1954 RECENT_LOGIN_HISTORY.getFieldName()); 1955 if (o == null) 1956 { 1957 return null; 1958 } 1959 else 1960 { 1961 return new RecentLoginHistory(o); 1962 } 1963 } 1964 1965 1966 1967 /** 1968 * Retrieves the maximum number of recent successful login attempts the server 1969 * should maintain for a user. 1970 * 1971 * @return The maximum number of recent successful login attempts the server 1972 * should maintain for a user, or {@code null}if this was not 1973 * included in the password policy state JSON object. 1974 */ 1975 @Nullable() 1976 public Integer getMaximumRecentLoginHistorySuccessfulAuthenticationCount() 1977 { 1978 return passwordPolicyStateObject.getFieldAsInteger( 1979 MAXIMUM_RECENT_LOGIN_HISTORY_SUCCESSFUL_AUTHENTICATION_COUNT. 1980 getFieldName()); 1981 } 1982 1983 1984 1985 /** 1986 * Retrieves the maximum age in seconds of recent successful login attempts 1987 * the server should maintain for a user. 1988 * 1989 * @return The maximum age in seconds of recent successful login attempts the 1990 * server should maintain for a user, or {@code null}if this was not 1991 * included in the password policy state JSON object. 1992 */ 1993 @Nullable() 1994 public Integer 1995 getMaximumRecentLoginHistorySuccessfulAuthenticationDurationSeconds() 1996 { 1997 return passwordPolicyStateObject.getFieldAsInteger( 1998 MAXIMUM_RECENT_LOGIN_HISTORY_SUCCESSFUL_AUTHENTICATION_DURATION_SECONDS 1999 .getFieldName()); 2000 } 2001 2002 2003 2004 /** 2005 * Retrieves the maximum number of recent failed login attempts the server 2006 * should maintain for a user. 2007 * 2008 * @return The maximum number of recent failed login attempts the server 2009 * should maintain for a user, or {@code null}if this was not 2010 * included in the password policy state JSON object. 2011 */ 2012 @Nullable() 2013 public Integer getMaximumRecentLoginHistoryFailedAuthenticationCount() 2014 { 2015 return passwordPolicyStateObject.getFieldAsInteger( 2016 MAXIMUM_RECENT_LOGIN_HISTORY_FAILED_AUTHENTICATION_COUNT. 2017 getFieldName()); 2018 } 2019 2020 2021 2022 /** 2023 * Retrieves the maximum age in seconds of recent failed login attempts 2024 * the server should maintain for a user. 2025 * 2026 * @return The maximum age in seconds of recent failed login attempts the 2027 * server should maintain for a user, or {@code null}if this was not 2028 * included in the password policy state JSON object. 2029 */ 2030 @Nullable() 2031 public Integer 2032 getMaximumRecentLoginHistoryFailedAuthenticationDurationSeconds() 2033 { 2034 return passwordPolicyStateObject.getFieldAsInteger( 2035 MAXIMUM_RECENT_LOGIN_HISTORY_FAILED_AUTHENTICATION_DURATION_SECONDS. 2036 getFieldName()); 2037 } 2038 2039 2040 2041 /** 2042 * Retrieves the list of quality requirements that must be satisfied for 2043 * passwords included in new entries that are added using the same password 2044 * policy as the associated entry. 2045 * 2046 * @return The list of password quality requirements that will be enforced 2047 * for adds using the same password policy as the associated entry, 2048 * or an empty list if no requirements will be imposed. 2049 */ 2050 @NotNull() 2051 public List<PasswordQualityRequirement> getAddPasswordQualityRequirements() 2052 { 2053 return getPasswordQualityRequirements(REQUIREMENT_FIELD_APPLIES_TO_ADD); 2054 } 2055 2056 2057 2058 /** 2059 * Retrieves the list of quality requirements that must be satisfied when the 2060 * associated user attempts to change their own password. 2061 * 2062 * @return The list of password quality requirements that will be enforced 2063 * for self password changes, or an empty list if no requirements 2064 * will be imposed. 2065 */ 2066 @NotNull() 2067 public List<PasswordQualityRequirement> 2068 getSelfChangePasswordQualityRequirements() 2069 { 2070 return getPasswordQualityRequirements( 2071 REQUIREMENT_FIELD_APPLIES_TO_SELF_CHANGE); 2072 } 2073 2074 2075 2076 /** 2077 * Retrieves the list of quality requirements that must be satisfied when an 2078 * administrator attempts to change the user's password. 2079 * 2080 * @return The list of password quality requirements that will be enforced 2081 * for administrative password resets, or an empty list if no 2082 * requirements will be imposed. 2083 */ 2084 @NotNull() 2085 public List<PasswordQualityRequirement> 2086 getAdministrativeResetPasswordQualityRequirements() 2087 { 2088 return getPasswordQualityRequirements( 2089 REQUIREMENT_FIELD_APPLIES_TO_ADMIN_RESET); 2090 } 2091 2092 2093 2094 /** 2095 * Retrieves the list of quality requirements that must be satisfied when the 2096 * associated user authenticates in a manner that makes the clear-text 2097 * password available to the server. 2098 * 2099 * @return The list of password quality requirements that will be enforced 2100 * for binds, or an empty list if no requirements will be imposed. 2101 */ 2102 @NotNull() 2103 public List<PasswordQualityRequirement> getBindPasswordQualityRequirements() 2104 { 2105 return getPasswordQualityRequirements(REQUIREMENT_FIELD_APPLIES_TO_BIND); 2106 } 2107 2108 2109 2110 /** 2111 * Retrieves a list of the password quality requirements that are contained in 2112 * the JSON object in which the indicated Boolean field is present and set to 2113 * {@code true}. 2114 * 2115 * @param booleanFieldName The name of the field that is expected to be 2116 * present with a Boolean value of true for each 2117 * requirement to be included in the list that is 2118 * returned. 2119 * 2120 * @return The appropriate list of password quality requirements, or an empty 2121 * list if no requirements will be imposed. 2122 */ 2123 @NotNull() 2124 private List<PasswordQualityRequirement> getPasswordQualityRequirements( 2125 @NotNull final String booleanFieldName) 2126 { 2127 final List<JSONValue> requirementObjectLst = 2128 passwordPolicyStateObject.getFieldAsArray( 2129 PASSWORD_QUALITY_REQUIREMENTS.getFieldName()); 2130 if ((requirementObjectLst == null) || requirementObjectLst.isEmpty()) 2131 { 2132 return Collections.emptyList(); 2133 } 2134 2135 final List<PasswordQualityRequirement> requirements = 2136 new ArrayList<>(requirementObjectLst.size()); 2137 for (final JSONValue requirementObjectValue : requirementObjectLst) 2138 { 2139 if (! (requirementObjectValue instanceof JSONObject)) 2140 { 2141 continue; 2142 } 2143 2144 final JSONObject requirementObject = (JSONObject) requirementObjectValue; 2145 final Boolean include = requirementObject.getFieldAsBoolean( 2146 booleanFieldName); 2147 if ((include == null) || (! include.booleanValue())) 2148 { 2149 continue; 2150 } 2151 2152 final String description = 2153 requirementObject.getFieldAsString(REQUIREMENT_FIELD_DESCRIPTION); 2154 if (description == null) 2155 { 2156 continue; 2157 } 2158 2159 final String clientSideValidationType = 2160 requirementObject.getFieldAsString( 2161 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_TYPE); 2162 2163 final Map<String,String> clientSideValidationProperties = 2164 new LinkedHashMap<>(); 2165 final List<JSONValue> propertyValues = requirementObject.getFieldAsArray( 2166 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_PROPERTIES); 2167 if (propertyValues != null) 2168 { 2169 for (final JSONValue propertyValue : propertyValues) 2170 { 2171 if (! (propertyValue instanceof JSONObject)) 2172 { 2173 continue; 2174 } 2175 2176 final JSONObject propertyObject = (JSONObject) propertyValue; 2177 final String name = propertyObject.getFieldAsString( 2178 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_PROPERTY_NAME); 2179 final String value = propertyObject.getFieldAsString( 2180 REQUIREMENT_FIELD_CLIENT_SIDE_VALIDATION_PROPERTY_VALUE); 2181 if ((name != null) && (value != null)) 2182 { 2183 clientSideValidationProperties.put(name, value); 2184 } 2185 } 2186 } 2187 2188 requirements.add(new PasswordQualityRequirement(description, 2189 clientSideValidationType, clientSideValidationProperties)); 2190 } 2191 2192 return requirements; 2193 } 2194 2195 2196 2197 /** 2198 * Retrieves the value of the specified field as a {@code Date}. 2199 * 2200 * @param field The field whose value is to be retrieved and parsed as a 2201 * {@code Date}. 2202 * 2203 * @return The value of the specified field as a {@code Date}, or 2204 * {@code null} if the field is not contained in the JSON object or 2205 * if its value cannot be parsed as a {@code Date}. 2206 */ 2207 @Nullable() 2208 private Date getDate(@NotNull final PasswordPolicyStateJSONField field) 2209 { 2210 final String stringValue = 2211 passwordPolicyStateObject.getFieldAsString(field.getFieldName()); 2212 if (stringValue == null) 2213 { 2214 return null; 2215 } 2216 2217 try 2218 { 2219 return StaticUtils.decodeRFC3339Time(stringValue); 2220 } 2221 catch (final Exception e) 2222 { 2223 Debug.debugException(e); 2224 return null; 2225 } 2226 } 2227 2228 2229 2230 /** 2231 * Retrieves a string representation of the password policy state information. 2232 * 2233 * @return A string representation of the password policy state information. 2234 */ 2235 @Override() 2236 @NotNull() 2237 public String toString() 2238 { 2239 return passwordPolicyStateObject.toSingleLineString(); 2240 } 2241}