001/*
002 * CDDL HEADER START
003 *
004 * The contents of this file are subject to the terms of the
005 * Common Development and Distribution License, Version 1.0 only
006 * (the "License").  You may not use this file except in compliance
007 * with the License.
008 *
009 * You can obtain a copy of the license at legal-notices/CDDLv1_0.txt
010 * or http://forgerock.org/license/CDDLv1.0.html.
011 * See the License for the specific language governing permissions
012 * and limitations under the License.
013 *
014 * When distributing Covered Code, include this CDDL HEADER in each
015 * file and include the License file at legal-notices/CDDLv1_0.txt.
016 * If applicable, add the following below this CDDL HEADER, with the
017 * fields enclosed by brackets "[]" replaced with your own identifying
018 * information:
019 *      Portions Copyright [yyyy] [name of copyright owner]
020 *
021 * CDDL HEADER END
022 *
023 *
024 *      Copyright 2006-2008 Sun Microsystems, Inc.
025 *      Portions Copyright 2014-2015 ForgeRock AS
026 */
027package org.opends.server.controls;
028import org.forgerock.i18n.LocalizableMessage;
029
030
031
032import org.forgerock.opendj.io.ASN1Writer;
033import org.opends.server.types.*;
034import org.forgerock.opendj.ldap.ResultCode;
035import org.forgerock.opendj.ldap.ByteString;
036import org.forgerock.i18n.slf4j.LocalizedLogger;
037import static org.opends.messages.ProtocolMessages.*;
038import static org.opends.server.util.ServerConstants.*;
039import static org.opends.server.util.StaticUtils.*;
040
041import java.io.IOException;
042
043
044/**
045 * This class implements the Netscape password expiring control, which serves as
046 * a warning to clients that the user's password is about to expire. The only
047 * element contained in the control value is a string representation of the
048 * number of seconds until expiration.
049 */
050public class PasswordExpiringControl
051       extends Control
052{
053  /**
054   * ControlDecoder implementation to decode this control from a ByteString.
055   */
056  private static final class Decoder
057      implements ControlDecoder<PasswordExpiringControl>
058  {
059    /** {@inheritDoc} */
060    public PasswordExpiringControl decode(boolean isCritical, ByteString value)
061        throws DirectoryException
062    {
063      if (value == null)
064      {
065        LocalizableMessage message = ERR_PWEXPIRING_NO_CONTROL_VALUE.get();
066        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
067      }
068
069      int secondsUntilExpiration;
070      try
071      {
072        secondsUntilExpiration =
073            Integer.parseInt(value.toString());
074      }
075      catch (Exception e)
076      {
077        logger.traceException(e);
078
079        LocalizableMessage message = ERR_PWEXPIRING_CANNOT_DECODE_SECONDS_UNTIL_EXPIRATION.
080            get(getExceptionMessage(e));
081        throw new DirectoryException(ResultCode.PROTOCOL_ERROR, message);
082      }
083
084
085      return new PasswordExpiringControl(isCritical,
086          secondsUntilExpiration);
087    }
088
089    public String getOID()
090    {
091      return OID_NS_PASSWORD_EXPIRING;
092    }
093
094  }
095
096  /**
097   * The Control Decoder that can be used to decode this control.
098   */
099  public static final ControlDecoder<PasswordExpiringControl> DECODER =
100    new Decoder();
101  private static final LocalizedLogger logger = LocalizedLogger.getLoggerForThisClass();
102
103
104
105
106  /** The length of time in seconds until the password actually expires. */
107  private int secondsUntilExpiration;
108
109
110
111  /**
112   * Creates a new instance of the password expiring control with the provided
113   * information.
114   *
115   * @param  secondsUntilExpiration  The length of time in seconds until the
116   *                                 password actually expires.
117   */
118  public PasswordExpiringControl(int secondsUntilExpiration)
119  {
120    this(false, secondsUntilExpiration);
121  }
122
123
124
125  /**
126   * Creates a new instance of the password expiring control with the provided
127   * information.
128   *
129   * @param  isCritical              Indicates whether support for this control
130   *                                 should be considered a critical part of the
131   *                                 client processing.
132   * @param  secondsUntilExpiration  The length of time in seconds until the
133   *                                 password actually expires.
134   */
135  public PasswordExpiringControl(boolean isCritical, int secondsUntilExpiration)
136  {
137    super(OID_NS_PASSWORD_EXPIRING, isCritical);
138
139
140    this.secondsUntilExpiration = secondsUntilExpiration;
141  }
142
143
144  /**
145   * Writes this control's value to an ASN.1 writer. The value (if any) must be
146   * written as an ASN1OctetString.
147   *
148   * @param writer The ASN.1 output stream to write to.
149   * @throws IOException If a problem occurs while writing to the stream.
150   */
151  @Override
152  public void writeValue(ASN1Writer writer) throws IOException {
153    writer.writeOctetString(String.valueOf(secondsUntilExpiration));
154  }
155
156
157
158  /**
159   * Retrieves the length of time in seconds until the password actually
160   * expires.
161   *
162   * @return  The length of time in seconds until the password actually expires.
163   */
164  public int getSecondsUntilExpiration()
165  {
166    return secondsUntilExpiration;
167  }
168
169
170
171  /**
172   * Appends a string representation of this password expiring control to the
173   * provided buffer.
174   *
175   * @param  buffer  The buffer to which the information should be appended.
176   */
177  @Override
178  public void toString(StringBuilder buffer)
179  {
180    buffer.append("PasswordExpiringControl(secondsUntilExpiration=");
181    buffer.append(secondsUntilExpiration);
182    buffer.append(")");
183  }
184}
185