001/*
002 * Copyright 2015-2017 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2017 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 Alcatel-Lucent 8661
053 *   server products.  These classes provide support for proprietary
054 *   functionality or for external specifications that are not considered stable
055 *   or mature enough to be guaranteed to work in an interoperable way with
056 *   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 serial version UID for this serializable class.
136   */
137  private static final long serialVersionUID = 3676573634197714542L;
138
139
140
141  // The integer value for this account usability notice.
142  private final int intValue;
143
144  // A human-readable message that provides specific details about this account
145  // usability notice.
146  private final String message;
147
148  // The name for this account usability notice.
149  private final String name;
150
151  // The encoded string representation for this account usability notice.
152  private final String stringRepresentation;
153
154
155
156  /**
157   * Creates a new account usability notice with the provided information.
158   *
159   * @param  intValue  The integer value for this account usability notice.
160   * @param  name      The name for this account usability notice.  It must not
161   *                   be {@code null}.
162   * @param  message   A human-readable message that provides specific details
163   *                   about this account usability notice.  It may be
164   *                   {@code null} if no message is available.
165   */
166  public PasswordPolicyStateAccountUsabilityNotice(final int intValue,
167                                                   final String name,
168                                                   final String message)
169  {
170    Validator.ensureNotNull(name);
171
172    this.intValue = intValue;
173    this.name = name;
174    this.message = message;
175
176    final StringBuilder buffer = new StringBuilder();
177    buffer.append("code=");
178    buffer.append(intValue);
179    buffer.append("\tname=");
180    buffer.append(name);
181
182    if (message != null)
183    {
184      buffer.append("\tmessage=");
185      buffer.append(message);
186    }
187
188    stringRepresentation = buffer.toString();
189  }
190
191
192
193  /**
194   * Creates a new account usability notice that is decoded from the provided
195   * string representation.
196   *
197   * @param  stringRepresentation  The string representation of the account
198   *                               usability notice to decode.  It must not be
199   *                               {@code null}.
200   *
201   * @throws LDAPException  If the provided string cannot be decoded as a valid
202   *                         account usability notice.
203   */
204  public PasswordPolicyStateAccountUsabilityNotice(
205       final String stringRepresentation)
206       throws LDAPException
207  {
208    this.stringRepresentation = stringRepresentation;
209
210    try
211    {
212      Integer i = null;
213      String n = null;
214      String m = null;
215
216      final StringTokenizer tokenizer =
217           new StringTokenizer(stringRepresentation, "\t");
218      while (tokenizer.hasMoreTokens())
219      {
220        final String token = tokenizer.nextToken();
221        final int equalPos = token.indexOf('=');
222        final String fieldName = token.substring(0, equalPos);
223        final String fieldValue = token.substring(equalPos+1);
224        if (fieldName.equals("code"))
225        {
226          i = Integer.valueOf(fieldValue);
227        }
228        else if (fieldName.equals("name"))
229        {
230          n = fieldValue;
231        }
232        else if (fieldName.equals("message"))
233        {
234          m = fieldValue;
235        }
236      }
237
238      if (i == null)
239      {
240        throw new LDAPException(ResultCode.DECODING_ERROR,
241             ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_CANNOT_DECODE.get(
242                  stringRepresentation,
243                  ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_NO_CODE.get()));
244      }
245
246      if (n == null)
247      {
248        throw new LDAPException(ResultCode.DECODING_ERROR,
249             ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_CANNOT_DECODE.get(
250                  stringRepresentation,
251                  ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_NO_NAME.get()));
252      }
253
254      intValue = i;
255      name     = n;
256      message  = m;
257    }
258    catch (final LDAPException le)
259    {
260      Debug.debugException(le);
261
262      throw le;
263    }
264    catch (final Exception e)
265    {
266      Debug.debugException(e);
267
268      throw new LDAPException(ResultCode.DECODING_ERROR,
269           ERR_PWP_STATE_ACCOUNT_USABILITY_NOTICE_CANNOT_DECODE.get(
270                stringRepresentation, StaticUtils.getExceptionMessage(e)),
271           e);
272    }
273  }
274
275
276
277  /**
278   * Retrieves the integer value for this account usability notice.
279   *
280   * @return  The integer value for this account usability notice.
281   */
282  public int getIntValue()
283  {
284    return intValue;
285  }
286
287
288
289  /**
290   * Retrieves the name for this account usability notice.
291   *
292   * @return  The name for this account usability notice.
293   */
294  public String getName()
295  {
296    return name;
297  }
298
299
300
301  /**
302   * Retrieves a human-readable message that provides specific details about
303   * this account usability notice.
304   *
305   * @return  A human-readable message that provides specific details about this
306   *          account usability notice, or {@code null} if no message is
307   *          available.
308   */
309  public String getMessage()
310  {
311    return message;
312  }
313
314
315
316  /**
317   * Retrieves a string representation of this account usability notice.
318   *
319   * @return  A string representation of this account usability notice.
320   */
321  @Override()
322  public String toString()
323  {
324    return stringRepresentation;
325  }
326}