001/*
002 * Copyright 2015-2018 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2018 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 * notices pertaining to a user's password policy state (items that might be
044 * of interest, but do not necessarily represent a current or imminent problem
045 * with the account).  It includes a number of predefined notice types, but also
046 * allows for the possibility of additional notice types that have not been
047 * defined.
048 * <BR>
049 * <BLOCKQUOTE>
050 *   <B>NOTE:</B>  This class, and other classes within the
051 *   {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
052 *   supported for use against Ping Identity, UnboundID, and
053 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
054 *   for proprietary functionality or for external specifications that are not
055 *   considered stable or mature enough to be guaranteed to work in an
056 *   interoperable way with other types of LDAP servers.
057 * </BLOCKQUOTE>
058 */
059@NotMutable()
060@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
061public final class PasswordPolicyStateAccountUsabilityNotice
062       implements Serializable
063{
064  /**
065   * The numeric value for the notice type that indicates the user has a valid
066   * outstanding retired password.
067   */
068  public static final int NOTICE_TYPE_OUTSTANDING_RETIRED_PASSWORD = 1;
069
070
071
072  /**
073   * The name for the notice type that indicates the user user has a valid
074   * outstanding retired password.
075   */
076  public static final String NOTICE_NAME_OUTSTANDING_RETIRED_PASSWORD =
077       "outstanding-retired-password";
078
079
080
081  /**
082   * The numeric value for the notice type that indicates the user has a valid
083   * outstanding one-time password.
084   */
085  public static final int NOTICE_TYPE_OUTSTANDING_ONE_TIME_PASSWORD = 2;
086
087
088
089  /**
090   * The name for the notice type that indicates the user has a valid
091   * outstanding one-time password.
092   */
093  public static final String NOTICE_NAME_OUTSTANDING_ONE_TIME_PASSWORD =
094       "outstanding-one-time-password";
095
096
097
098  /**
099   * The numeric value for the notice type that indicates the user has a valid
100   * outstanding password reset token.
101   */
102  public static final int NOTICE_TYPE_OUTSTANDING_PASSWORD_RESET_TOKEN = 3;
103
104
105
106  /**
107   * The name for the notice type that indicates the user has a valid
108   * outstanding password reset token that will expire in the near future.
109   */
110  public static final String NOTICE_NAME_OUTSTANDING_PASSWORD_RESET_TOKEN =
111       "outstanding-password-reset-token";
112
113
114
115  /**
116   * The numeric value for the notice type that indicates the user is not
117   * currently allowed to change his/her password because they are within the
118   * minimum password age.
119   */
120  public static final int NOTICE_TYPE_IN_MINIMUM_PASSWORD_AGE = 4;
121
122
123
124  /**
125   * The name for the notice type that indicates the user is not currently
126   * allowed to change his/her password because they are within the minimum
127   * password age.
128   */
129  public static final  String NOTICE_NAME_IN_MINIMUM_PASSWORD_AGE =
130       "in-minimum-password-age";
131
132
133
134  /**
135   * The numeric value for the notice type that indicates that the user does not
136   * have a static password.
137   */
138  public static final int NOTICE_TYPE_NO_STATIC_PASSWORD = 5;
139
140
141
142  /**
143   * The name for the notice type that indicates that the user does not have a
144   * static password.
145   */
146  public static final  String NOTICE_NAME_NO_STATIC_PASSWORD =
147       "no-static-password";
148
149
150
151  /**
152   * The serial version UID for this serializable class.
153   */
154  private static final long serialVersionUID = 6147730018701385799L;
155
156
157
158  // The integer value for this account usability notice.
159  private final int intValue;
160
161  // A human-readable message that provides specific details about this account
162  // usability notice.
163  private final String message;
164
165  // The name for this account usability notice.
166  private final String name;
167
168  // The encoded string representation for this account usability notice.
169  private final String stringRepresentation;
170
171
172
173  /**
174   * Creates a new account usability notice with the provided information.
175   *
176   * @param  intValue  The integer value for this account usability notice.
177   * @param  name      The name for this account usability notice.  It must not
178   *                   be {@code null}.
179   * @param  message   A human-readable message that provides specific details
180   *                   about this account usability notice.  It may be
181   *                   {@code null} if no message is available.
182   */
183  public PasswordPolicyStateAccountUsabilityNotice(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 notice that is decoded from the provided
212   * string representation.
213   *
214   * @param  stringRepresentation  The string representation of the account
215   *                               usability notice 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 notice.
220   */
221  public PasswordPolicyStateAccountUsabilityNotice(
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_NOTICE_CANNOT_DECODE.get(
259                  stringRepresentation,
260                  ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_NO_CODE.get()));
261      }
262
263      if (n == null)
264      {
265        throw new LDAPException(ResultCode.DECODING_ERROR,
266             ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_CANNOT_DECODE.get(
267                  stringRepresentation,
268                  ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_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_NOTICE_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 notice.
296   *
297   * @return  The integer value for this account usability notice.
298   */
299  public int getIntValue()
300  {
301    return intValue;
302  }
303
304
305
306  /**
307   * Retrieves the name for this account usability notice.
308   *
309   * @return  The name for this account usability notice.
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 notice.
321   *
322   * @return  A human-readable message that provides specific details about this
323   *          account usability notice, 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 notice.
335   *
336   * @return  A string representation of this account usability notice.
337   */
338  @Override()
339  public String toString()
340  {
341    return stringRepresentation;
342  }
343}