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