001/* 002 * Copyright 2017-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2017-2024 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) 2017-2024 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.controls; 037 038 039 040import java.io.Serializable; 041 042import com.unboundid.util.Mutable; 043import com.unboundid.util.Nullable; 044import com.unboundid.util.NotNull; 045import com.unboundid.util.ThreadSafety; 046import com.unboundid.util.ThreadSafetyLevel; 047 048 049 050/** 051 * This class provides a set of properties that can be used in conjunction with 052 * the {@link PasswordUpdateBehaviorRequestControl}. 053 * <BR> 054 * <BLOCKQUOTE> 055 * <B>NOTE:</B> This class, and other classes within the 056 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 057 * supported for use against Ping Identity, UnboundID, and 058 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 059 * for proprietary functionality or for external specifications that are not 060 * considered stable or mature enough to be guaranteed to work in an 061 * interoperable way with other types of LDAP servers. 062 * </BLOCKQUOTE> 063 */ 064@Mutable() 065@ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE) 066public final class PasswordUpdateBehaviorRequestControlProperties 067 implements Serializable 068{ 069 /** 070 * The serial version UID for this serializable class. 071 */ 072 private static final long serialVersionUID = -529840713192839805L; 073 074 075 076 // Indicates whether the requester should be allowed to provide a pre-encoded 077 // password. 078 @Nullable private Boolean allowPreEncodedPassword; 079 080 // Indicates whether to ignore any minimum password age configured in the 081 // password policy. 082 @Nullable private Boolean ignoreMinimumPasswordAge; 083 084 // Indicates whether to skip the process of checking whether the provided 085 // password matches the new current password or is in the password history. 086 @Nullable private Boolean ignorePasswordHistory; 087 088 // Indicates whether to treat the password change as a self change. 089 @Nullable private Boolean isSelfChange; 090 091 // Indicates whether to update the user's account to indicate that they must 092 // change their password the next time they authenticate. 093 @Nullable private Boolean mustChangePassword; 094 095 // Indicates whether to skip password validation for the new password. 096 @Nullable private Boolean skipPasswordValidation; 097 098 // Specifies the password storage scheme to use for the new password. 099 @Nullable private String passwordStorageScheme; 100 101 102 103 /** 104 * Creates a new password update behavior request control properties object 105 * with none of the properties set, which will cause the server to behave as 106 * if the control had not been included in the request. 107 */ 108 public PasswordUpdateBehaviorRequestControlProperties() 109 { 110 isSelfChange = null; 111 allowPreEncodedPassword = null; 112 skipPasswordValidation = null; 113 ignorePasswordHistory = null; 114 ignoreMinimumPasswordAge = null; 115 passwordStorageScheme = null; 116 mustChangePassword = null; 117 } 118 119 120 121 /** 122 * Creates a new password update behavior request control properties object 123 * with the settings used for the provided password update behavior request 124 * control. 125 * 126 * @param control The control to use to initialize this properties object. 127 */ 128 public PasswordUpdateBehaviorRequestControlProperties( 129 @NotNull final PasswordUpdateBehaviorRequestControl control) 130 { 131 isSelfChange = control.getIsSelfChange(); 132 allowPreEncodedPassword = control.getAllowPreEncodedPassword(); 133 skipPasswordValidation = control.getSkipPasswordValidation(); 134 ignorePasswordHistory = control.getIgnorePasswordHistory(); 135 ignoreMinimumPasswordAge = control.getIgnoreMinimumPasswordAge(); 136 passwordStorageScheme = control.getPasswordStorageScheme(); 137 mustChangePassword = control.getMustChangePassword(); 138 } 139 140 141 142 /** 143 * Indicates whether the password update behavior request control should 144 * override the server's automatic classification of the password update as a 145 * self change or an administrative reset, and if so, what the overridden 146 * value should be. 147 * 148 * @return {@code Boolean.TRUE} if the server should treat the password 149 * update as a self change, {@code Boolean.FALSE} if the server 150 * should treat the password update as an administrative reset, or 151 * {@code null} if the server should automatically determine whether 152 * the password update is a self change or an administrative reset. 153 */ 154 @Nullable() 155 public Boolean getIsSelfChange() 156 { 157 return isSelfChange; 158 } 159 160 161 162 /** 163 * Specifies whether the password update behavior request control should 164 * override the server's automatic classification of the password update as a 165 * self change or an administrative reset, and if so, what the overridden 166 * value should be. 167 * <BR><BR> 168 * Normally, the server will consider a password update to be a self change if 169 * it contains the user's current password in addition to the new password, or 170 * if the user entry being updated is the entry for the authorization identity 171 * for the requested operation. Conversely, if the password change does not 172 * include the target user's current password in addition to the new password, 173 * and the user performing the password change doesn't own the entry being 174 * updated, then it will be considered an administrative reset. But if this 175 * method is called with a value of {@code Boolean.TRUE}, then the server will 176 * consider the password update to be a self change even if it would have 177 * otherwise been considered an administrative reset, and if this method is 178 * called with a value of {@code Boolean.FALSE}, then the server will consider 179 * the password update to be an administrative reset even if it would have 180 * otherwise been considered a self change. 181 * <BR><BR> 182 * Note that this only applies to modify requests and password modify extended 183 * requests. It does not apply to add requests, which will always be 184 * considered administrative resets because a user can't change their own 185 * password before their account exists in the server. However, the password 186 * update behavior request control can still be used to override the server's 187 * default behavior for other properties that do apply to add operations. 188 * 189 * @param isSelfChange Specifies whether the control should override the 190 * server's automatic classification of the password 191 * update as a self change or an administrative reset. 192 * If this is {@code Boolean.TRUE}, then it indicates 193 * that the server should treat the password update as a 194 * self change. If this is {@code Boolean.FALSE}, then 195 * it indicates that the server should treat the 196 * password update as an administrative reset. If this 197 * is {@code null}, it indicates that the server should 198 * automatically determine whether the password change 199 * is a self change or an administrative reset. 200 */ 201 public void setIsSelfChange(@Nullable final Boolean isSelfChange) 202 { 203 this.isSelfChange = isSelfChange; 204 } 205 206 207 208 /** 209 * Indicates whether the password update behavior request control should 210 * override the value of the {@code allow-pre-encoded-passwords} configuration 211 * property for the target user's password policy, and if so, what the 212 * overridden value should be. 213 * 214 * @return {@code Boolean.TRUE} if the server should accept a pre-encoded 215 * password in the password update even if the server's password 216 * policy configuration would normally not permit this, 217 * {@code Boolean.FALSE} if the server should reject a pre-encoded 218 * password in the password update even if the server's password 219 * policy configuration would normally accept it, or {@code null} if 220 * the password policy configuration should be used to determine 221 * whether to accept pre-encoded passwords. 222 */ 223 @Nullable() 224 public Boolean getAllowPreEncodedPassword() 225 { 226 return allowPreEncodedPassword; 227 } 228 229 230 231 /** 232 * Specifies whether the password update behavior request control should 233 * override the value of the {@code allow-pre-encoded-passwords} configuration 234 * property for the target user's password policy, and if so, what the 235 * overridden value should be. 236 * <BR><BR> 237 * Note that certain types of validation cannot be performed for new passwords 238 * that are pre-encoded. It will not be possible to invoke password 239 * validators on a pre-encoded password, and it will not be possible to 240 * compare the a pre-encoded new password against the current password or one 241 * in the password history. Allowing end users to provide pre-encoded 242 * passwords could create a loophole in which the user could continue using 243 * the same password longer than they would otherwise be permitted to because 244 * they could keep changing the password to a different encoded representation 245 * of the same password, or to a weaker password than the server would 246 * normally allow. 247 * 248 * @param allowPreEncodedPassword Specifies whether the password update 249 * behavior request control should override 250 * the value of the 251 * {@code allow-pre-encoded-passwords} 252 * configuration property for the target 253 * user's password policy, and if so, what 254 * the overridden value should be. If this 255 * is {@code Boolean.TRUE}, then the server 256 * will permit a pre-encoded password, even 257 * if it would normally reject them. If this 258 * is {@code Boolean.FALSE}, then the server 259 * will reject a pre-encoded password, even 260 * if it would normally accept it. If this 261 * is {@code null}, then the server will use 262 * the password policy configuration to 263 * determine whether to accept a pre-encoded 264 * password. 265 */ 266 public void setAllowPreEncodedPassword( 267 @Nullable final Boolean allowPreEncodedPassword) 268 { 269 this.allowPreEncodedPassword = allowPreEncodedPassword; 270 } 271 272 273 274 /** 275 * Indicates whether the password update behavior request control should 276 * override the server's normal behavior with regard to invoking password 277 * validators for any new passwords included in the password update, and if 278 * so, what the overridden behavior should be. 279 * 280 * @return {@code Boolean.TRUE} if the server should skip invoking the 281 * password validators configured in the target user's password 282 * policy validators for any new passwords included in the password 283 * update even if the server would normally perform password 284 * validation, {@code Boolean.FALSE} if the server should invoke the 285 * password validators even if it would normally skip them, or 286 * {@code null} if the password policy configuration should be used 287 * to determine whether to skip password validation. 288 */ 289 @Nullable() 290 public Boolean getSkipPasswordValidation() 291 { 292 return skipPasswordValidation; 293 } 294 295 296 297 /** 298 * Specifies whether the password update behavior request control should 299 * override the server's normal behavior with regard to invoking password 300 * validators for any new passwords included in the password update, and if 301 * so, what the overridden behavior should be. 302 * <BR><BR> 303 * Note that if password validation is to be performed, it will use the set of 304 * password validators set in the target user's password policy. It is not 305 * possible to customize which validators will be used on a per-request basis. 306 * <BR><BR> 307 * Also note that password validation can only be performed for new passwords 308 * that are not pre-encoded. Pre-encoded passwords cannot be checked against 309 * password validators or the password history. 310 * 311 * @param skipPasswordValidation Specifies whether the password update 312 * behavior request control should override 313 * the server's normal behavior with regard to 314 * invoking password validators for any new 315 * passwords included in the password update, 316 * and if so, what the overridden behavior 317 * should be. If this is 318 * {@code Boolean.TRUE}, then the server will 319 * skip new password validation even if it 320 * would normally perform it. If this is 321 * {@code Boolean.FALSE}, then the server will 322 * perform new password validation even if it 323 * would normally skip it. If this is 324 * {@code null}, then the server will use the 325 * password policy configuration to determine 326 * whether to perform new password validation. 327 */ 328 public void setSkipPasswordValidation( 329 @Nullable final Boolean skipPasswordValidation) 330 { 331 this.skipPasswordValidation = skipPasswordValidation; 332 } 333 334 335 336 /** 337 * Indicates whether the password update behavior request control should 338 * override the server's normal behavior with regard to checking the password 339 * history for any new passwords included in the password update, and if so, 340 * what the overridden behavior should be. 341 * 342 * @return {@code Boolean.TRUE} if the server should not check to see whether 343 * any new password matches the current password or is in the user's 344 * password history even if it would normally perform that check, 345 * {@code Boolean.FALSE} if the server should check to see whether 346 * any new password matches the current or previous password even if 347 * it would normally not perform such a check, or {@code null} if the 348 * password policy configuration should be used to determine whether 349 * to ignore the password history. 350 */ 351 @Nullable() 352 public Boolean getIgnorePasswordHistory() 353 { 354 return ignorePasswordHistory; 355 } 356 357 358 359 /** 360 * Specifies whether the password update behavior request control should 361 * override the server's normal behavior with regard to checking the password 362 * history for any new passwords included in the password update, and if so, 363 * what the overridden behavior should be. 364 * <BR><BR> 365 * Note that if the target user's password policy is not configured to 366 * maintain a password history, then there may not be any previous passwords 367 * to check. In that case, overriding the behavior to check the password 368 * history will only compare the new password against the current password. 369 * <BR><BR> 370 * Also note that this setting only applies to the validation of the new 371 * password. It will not affect the server's behavior with regard to storing 372 * the new or previous password in the password history. 373 * <BR><BR> 374 * Finally, password history validation can only be performed for new 375 * passwords that are not pre-encoded. Pre-encoded passwords cannot be 376 * checked against password validators or the password history. 377 * 378 * @param ignorePasswordHistory Specifies whether the password update 379 * behavior request control should override the 380 * server's normal behavior with regard to 381 * checking the password history for any new 382 * passwords included in the password update, 383 * and if so, what the overridden behavior 384 * should be. If this is {@code Boolean.TRUE}, 385 * then the server will skip password history 386 * validation even if it would have normally 387 * performed it. If this is 388 * {@code Boolean.FALSE}, then the server will 389 * perform password history validation even if 390 * it would have normally skipped it. If this 391 * is {@code null}, then the server will use 392 * the password policy configuration to 393 * determine whether to perform password 394 * history validation. 395 */ 396 public void setIgnorePasswordHistory( 397 @Nullable final Boolean ignorePasswordHistory) 398 { 399 this.ignorePasswordHistory = ignorePasswordHistory; 400 } 401 402 403 404 /** 405 * Indicates whether the password update behavior request control should 406 * override the server's normal behavior with regard to checking the 407 * minimum password age, and if so, what the overridden behavior should be. 408 * 409 * @return {@code Boolean.TRUE} if the server should accept the password 410 * change even if it has been less than the configured minimum 411 * password age since the password was last changed, 412 * {@code Boolean.FALSE} if the server should reject the password 413 * change if it has been less than teh configured minimum password 414 * age, or {@code null} if the password policy configuration should 415 * be used to determine the appropriate behavior. 416 */ 417 @Nullable() 418 public Boolean getIgnoreMinimumPasswordAge() 419 { 420 return ignoreMinimumPasswordAge; 421 } 422 423 424 425 /** 426 * Specifies whether the password update behavior request control should 427 * override the server's normal behavior with regard to checking the 428 * minimum password age, and if so, what the overridden behavior should be. 429 * <BR><BR> 430 * Normally, if a minimum password age is configured, then it will apply only 431 * for self password changes but not for administrative resets. With this 432 * value set to {@code Boolean.TRUE}, then the configured minimum password 433 * age will be ignored even for self changes. With this value set to 434 * {@code Boolean.FALSE}, then the configured minimum password age will be 435 * enforced even for administrative resets. In any case, this will only be 436 * used if the target user's password policy is configured with a nonzero 437 * minimum password age. 438 * 439 * @param ignoreMinimumPasswordAge Specifies whether the password update 440 * behavior request control should override 441 * the server's normal behavior with regard 442 * to checking the minimum password age, and 443 * if so, what the overridden behavior 444 * should be. If this is 445 * {@code Boolean.TRUE}, then the minimum 446 * password age will not be enforced, even 447 * for self password changes. If this is 448 * {@code Boolean.FALSE}, then the minimum 449 * password age will be enforced, even for 450 * administrative resets. If this is 451 * {@code null}, then the server's default 452 * behavior will be used so that the minimum 453 * password age will be enforced for self 454 * changes but not for administrative 455 * resets. 456 */ 457 public void setIgnoreMinimumPasswordAge( 458 @Nullable final Boolean ignoreMinimumPasswordAge) 459 { 460 this.ignoreMinimumPasswordAge = ignoreMinimumPasswordAge; 461 } 462 463 464 465 /** 466 * Indicates whether the password update behavior request control should 467 * override the server's normal behavior with regard to selecting the password 468 * storage scheme to use to encode new password values, and if so, which 469 * password storage scheme should be used. 470 * 471 * @return The name of the password storage scheme that should be used to 472 * encode any new password values, or {@code null} if the target 473 * user's password policy configuration should determine the 474 * appropriate schemes for encoding new passwords. 475 */ 476 @Nullable() 477 public String getPasswordStorageScheme() 478 { 479 return passwordStorageScheme; 480 } 481 482 483 484 /** 485 * Specifies whether the password update behavior request control should 486 * override the server's normal behavior with regard to selecting the password 487 * storage scheme to use to encode new password values, and if so, which 488 * password storage scheme should be used. 489 * <BR><BR> 490 * If a non-{@code null} password storage scheme name is provided, then it 491 * must be the prefix used in front of passwords encoded with that scheme, 492 * optionally including or omitting the curly braces. The specified scheme 493 * must be enabled for use in the server but does not otherwise need to be 494 * associated with the target user's password policy. 495 * 496 * @param passwordStorageScheme The name of the password storage scheme that 497 * should be used to encode any new password 498 * values. It may optionally be enclosed in 499 * curly braces. It may be {@code null} if the 500 * password policy configuration should be used 501 * to determine which password storage schemes 502 * should be used to encode new passwords. 503 */ 504 public void setPasswordStorageScheme( 505 @Nullable final String passwordStorageScheme) 506 { 507 this.passwordStorageScheme = passwordStorageScheme; 508 } 509 510 511 512 /** 513 * Indicates whether the password update behavior request control should 514 * override the server's normal behavior with regard to requiring a password 515 * change, and if so, what that behavior should be. 516 * 517 * @return {@code Boolean.TRUE} if the user will be required to change their 518 * password before being allowed to perform any other operation, 519 * {@code Boolean.FALSE} if the user will not be required to change 520 * their password before being allowed to perform any other 521 * operation, or {@code null} if the password policy configuration 522 * should be used to control this behavior. 523 */ 524 @Nullable() 525 public Boolean getMustChangePassword() 526 { 527 return mustChangePassword; 528 } 529 530 531 532 /** 533 * Specifies whether the password update behavior request control should 534 * override the server's normal behavior with regard to requiring a password 535 * change, and if so, what that behavior should be. 536 * <BR><BR> 537 * Note that the "must change password" behavior will only be enforced if the 538 * target user's password policy is configured with either 539 * {@code force-change-on-add} or {@code force-change-on-reset} set to 540 * {@code true}. If both of those properties are set to {@code false}, then 541 * this method will have no effect. 542 * <BR><BR> 543 * Normally, if {@code force-change-on-reset} is {@code true}, then the server 544 * will put the user's account into a "must change password" state after an 545 * administrative password reset, but not after a self change. If this 546 * method is called with a value of {@code Boolean.TRUE}, then the "must 547 * change password" flag will be set, even if the password update is a self 548 * change. It this method is called with a value of {@code Boolean.FALSE}, 549 * then the "must change password" flag will not be set even if the password 550 * update is an administrative change. If this method is called with a value 551 * of {@code null}, then the server's normal logic will be used to determine 552 * whether to set the "must change password" flag. 553 * 554 * @param mustChangePassword Specifies whether the password update behavior 555 * request control should override the server's 556 * normal behavior with regard to requiring a 557 * password change, and if so, what that behavior 558 * should be. If this is {@code Boolean.TRUE}, 559 * then the user entry will be required to change 560 * their password after their next login even if 561 * this is a self change. If this is 562 * {@code Boolean.FALSE}, then the user will not 563 * be required to change their password after the 564 * next login even if this is an administrative 565 * reset. If this is {@code null}, then the 566 * server's normal logic will be used to make the 567 * determination. 568 */ 569 public void setMustChangePassword(@Nullable final Boolean mustChangePassword) 570 { 571 this.mustChangePassword = mustChangePassword; 572 } 573 574 575 576 /** 577 * Retrieves a string representation of this password update behavior request 578 * control properties object. 579 * 580 * @return A string representation of this password update behavior request 581 * control properties object. 582 */ 583 @Override() 584 @NotNull() 585 public String toString() 586 { 587 final StringBuilder buffer = new StringBuilder(); 588 toString(buffer); 589 return buffer.toString(); 590 } 591 592 593 594 /** 595 * Appends a string representation of this password update behavior request 596 * control properties object to the provided buffer. 597 * 598 * @param buffer The buffer to which the information should be appended. 599 */ 600 public void toString(@NotNull final StringBuilder buffer) 601 { 602 buffer.append("PasswordUpdateBehaviorRequestControlProperties("); 603 604 boolean appended = appendNameValuePair(buffer, "isSelfChange", isSelfChange, 605 false); 606 appended = appendNameValuePair(buffer, "allowPreEncodedPassword", 607 allowPreEncodedPassword, appended); 608 appended = appendNameValuePair(buffer, "skipPasswordValidation", 609 skipPasswordValidation, appended); 610 appended = appendNameValuePair(buffer, "ignorePasswordHistory", 611 ignorePasswordHistory, appended); 612 appended = appendNameValuePair(buffer, "ignoreMinimumPasswordAge", 613 ignoreMinimumPasswordAge, appended); 614 appended = appendNameValuePair(buffer, "passwordStorageScheme", 615 passwordStorageScheme, appended); 616 appendNameValuePair(buffer, "mustChangePassword", 617 mustChangePassword, appended); 618 619 buffer.append(')'); 620 } 621 622 623 624 /** 625 * Appends a name-value pair to the provided buffer, if appropriate. 626 * 627 * @param buffer The buffer to which the name-value pair 628 * should be appended. It must not be 629 * {@code null}. 630 * @param propertyName The name for the property to consider 631 * appending. It must not be {@code null}. 632 * @param propertyValue The value for the property to consider 633 * appending. It may be {@code null} if the 634 * name-value pair should not be appended. If 635 * it is non-{@code null}, then it must have a 636 * type of {@code Boolean} or {@code String}. 637 * @param appendedPreviousPair Indicates whether a previous name-value pair 638 * has already been appended to the buffer. If 639 * the provided name-value pair should not be 640 * appended, then this will be returned. If the 641 * provided name-value pair should be appended, 642 * then this will be used to indicate whether it 643 * should be preceded by a comma. 644 * 645 * @return {@code true} if this or a previous name-value pair has been 646 * appended to the buffer, or {@code false} if no name-value pair has 647 * yet been appended to the buffer. 648 */ 649 private static boolean appendNameValuePair( 650 @NotNull final StringBuilder buffer, 651 @NotNull final String propertyName, 652 @Nullable final Object propertyValue, 653 final boolean appendedPreviousPair) 654 { 655 if (propertyValue == null) 656 { 657 return appendedPreviousPair; 658 } 659 660 if (appendedPreviousPair) 661 { 662 buffer.append(", "); 663 } 664 665 buffer.append(propertyName); 666 buffer.append('='); 667 668 if (propertyValue instanceof Boolean) 669 { 670 buffer.append(((Boolean) propertyValue).booleanValue()); 671 } 672 else 673 { 674 buffer.append('"'); 675 buffer.append(propertyValue); 676 buffer.append('"'); 677 } 678 679 return true; 680 } 681}