001/*
002 * Copyright 2015-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2019 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.unboundidds.extensions;
022
023
024
025import java.io.Serializable;
026import java.util.StringTokenizer;
027
028import com.unboundid.ldap.sdk.LDAPException;
029import com.unboundid.ldap.sdk.ResultCode;
030import com.unboundid.util.Debug;
031import com.unboundid.util.NotMutable;
032import com.unboundid.util.StaticUtils;
033import com.unboundid.util.ThreadSafety;
034import com.unboundid.util.ThreadSafetyLevel;
035import com.unboundid.util.Validator;
036
037import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
038
039
040
041/**
042 * This class defines a data structure that will provide information about
043 * warnings that may affect an account's usability.  It includes a number of
044 * predefined warning types, but also allows for the possibility of additional
045 * warning types that have not been defined.
046 * <BR>
047 * <BLOCKQUOTE>
048 *   <B>NOTE:</B>  This class, and other classes within the
049 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
050 *   supported for use against Ping Identity, UnboundID, and
051 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
052 *   for proprietary functionality or for external specifications that are not
053 *   considered stable or mature enough to be guaranteed to work in an
054 *   interoperable way with other types of LDAP servers.
055 * </BLOCKQUOTE>
056 */
057@NotMutable()
058@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
059public final class PasswordPolicyStateAccountUsabilityWarning
060       implements Serializable
061{
062  /**
063   * The numeric value for the warning type that indicates the user's account is
064   * about to expire.
065   */
066  public static final int WARNING_TYPE_ACCOUNT_EXPIRING = 1;
067
068
069
070  /**
071   * The name for the warning type that indicates the user's account is about
072   * to expire.
073   */
074  public static final String WARNING_NAME_ACCOUNT_EXPIRING = "account-expiring";
075
076
077
078  /**
079   * The numeric value for the warning type that indicates the user's password
080   * is about to expire.
081   */
082  public static final int WARNING_TYPE_PASSWORD_EXPIRING = 2;
083
084
085
086  /**
087   * The name for the warning type that indicates the user's password is about
088   * to expire.
089   */
090  public static final String WARNING_NAME_PASSWORD_EXPIRING =
091       "password-expiring";
092
093
094
095  /**
096   * The numeric value for the warning type that indicates the user has one or
097   * more failed authentication attempts since the last successful bind, and
098   * that the account may be locked if there are too many more failures.
099   */
100  public static final int WARNING_TYPE_OUTSTANDING_BIND_FAILURES = 3;
101
102
103
104  /**
105   * The name for the warning type that indicates the user has one or more
106   * failed authentication attempts since the last successful bind, and that the
107   * account may be locked if there are too many more failures.
108   */
109  public static final String WARNING_NAME_OUTSTANDING_BIND_FAILURES =
110       "outstanding-bind-failures";
111
112
113
114  /**
115   * The numeric value for the warning type that indicates the user has not
116   * authenticated in some time, and the account may be locked in the near
117   * future if it remains idle.
118   */
119  public static final int WARNING_TYPE_ACCOUNT_IDLE = 4;
120
121
122
123  /**
124   * The name for the warning type that indicates the user has not authenticated
125   * in some time, and the account may be locked in the near future if it
126   * remains idle.
127   */
128  public static final String WARNING_NAME_ACCOUNT_IDLE = "account-idle";
129
130
131
132  /**
133   * The numeric value for the warning type that indicates the user will be
134   * required to change his/her password by a specific time because the password
135   * policy requires all users to change their passwords by that time.
136   */
137  public static final int WARNING_TYPE_REQUIRE_PASSWORD_CHANGE_BY_TIME = 5;
138
139
140
141  /**
142   * The name for the warning type that indicates the user user will be required
143   * to change his/her password by a specific time because the password policy
144   * requires all users to change their passwords by that time.
145   */
146  public static final String WARNING_NAME_REQUIRE_PASSWORD_CHANGE_BY_TIME =
147       "require-password-change-by-time";
148
149
150
151  /**
152   * The serial version UID for this serializable class.
153   */
154  private static final long serialVersionUID = 4256291819633130578L;
155
156
157
158  // The integer value for this account usability warning.
159  private final int intValue;
160
161  // A human-readable message that provides specific details about this account
162  // usability warning.
163  private final String message;
164
165  // The name for this account usability warning.
166  private final String name;
167
168  // The encoded string representation for this account usability warning.
169  private final String stringRepresentation;
170
171
172
173  /**
174   * Creates a new account usability warning with the provided information.
175   *
176   * @param  intValue  The integer value for this account usability warning.
177   * @param  name      The name for this account usability warning.  It must not
178   *                   be {@code null}.
179   * @param  message   A human-readable message that provides specific details
180   *                   about this account usability warning.  It may be
181   *                   {@code null} if no message is available.
182   */
183  public PasswordPolicyStateAccountUsabilityWarning(final int intValue,
184                                                    final String name,
185                                                    final String message)
186  {
187    Validator.ensureNotNull(name);
188
189    this.intValue = intValue;
190    this.name = name;
191    this.message = message;
192
193    final StringBuilder buffer = new StringBuilder();
194    buffer.append("code=");
195    buffer.append(intValue);
196    buffer.append("\tname=");
197    buffer.append(name);
198
199    if (message != null)
200    {
201      buffer.append("\tmessage=");
202      buffer.append(message);
203    }
204
205    stringRepresentation = buffer.toString();
206  }
207
208
209
210  /**
211   * Creates a new account usability warning that is decoded from the provided
212   * string representation.
213   *
214   * @param  stringRepresentation  The string representation of the account
215   *                               usability warning to decode.  It must not be
216   *                               {@code null}.
217   *
218   * @throws  LDAPException  If the provided string cannot be decoded as a valid
219   *                         account usability warning.
220   */
221  public PasswordPolicyStateAccountUsabilityWarning(
222              final String stringRepresentation)
223         throws LDAPException
224  {
225    this.stringRepresentation = stringRepresentation;
226
227    try
228    {
229      Integer i = null;
230      String  n = null;
231      String  m = null;
232
233      final StringTokenizer tokenizer =
234           new StringTokenizer(stringRepresentation, "\t");
235      while (tokenizer.hasMoreTokens())
236      {
237        final String token = tokenizer.nextToken();
238        final int equalPos = token.indexOf('=');
239        final String fieldName = token.substring(0, equalPos);
240        final String fieldValue = token.substring(equalPos+1);
241        if (fieldName.equals("code"))
242        {
243          i = Integer.valueOf(fieldValue);
244        }
245        else if (fieldName.equals("name"))
246        {
247          n = fieldValue;
248        }
249        else if (fieldName.equals("message"))
250        {
251          m = fieldValue;
252        }
253      }
254
255      if (i == null)
256      {
257        throw new LDAPException(ResultCode.DECODING_ERROR,
258             ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_CANNOT_DECODE.get(
259                  stringRepresentation,
260                  ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_NO_CODE.get()));
261      }
262
263      if (n == null)
264      {
265        throw new LDAPException(ResultCode.DECODING_ERROR,
266             ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_CANNOT_DECODE.get(
267                  stringRepresentation,
268                  ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_NO_NAME.get()));
269      }
270
271      intValue = i;
272      name     = n;
273      message  = m;
274    }
275    catch (final LDAPException le)
276    {
277      Debug.debugException(le);
278
279      throw le;
280    }
281    catch (final Exception e)
282    {
283      Debug.debugException(e);
284
285      throw new LDAPException(ResultCode.DECODING_ERROR,
286           ERR_PWP_STATE_ACCOUNT_USABILITY_WARNING_CANNOT_DECODE.get(
287                stringRepresentation, StaticUtils.getExceptionMessage(e)),
288           e);
289    }
290  }
291
292
293
294  /**
295   * Retrieves the integer value for this account usability warning.
296   *
297   * @return  The integer value for this account usability warning.
298   */
299  public int getIntValue()
300  {
301    return intValue;
302  }
303
304
305
306  /**
307   * Retrieves the name for this account usability warning.
308   *
309   * @return  The name for this account usability warning.
310   */
311  public String getName()
312  {
313    return name;
314  }
315
316
317
318  /**
319   * Retrieves a human-readable message that provides specific details about
320   * this account usability warning.
321   *
322   * @return  A human-readable message that provides specific details about this
323   *          account usability warning, or {@code null} if no message is
324   *          available.
325   */
326  public String getMessage()
327  {
328    return message;
329  }
330
331
332
333  /**
334   * Retrieves a string representation of this account usability warning.
335   *
336   * @return  A string representation of this account usability warning.
337   */
338  @Override()
339  public String toString()
340  {
341    return stringRepresentation;
342  }
343}