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