001 /*
002 * Copyright 2007-2013 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2008-2013 UnboundID Corp.
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 */
021 package com.unboundid.ldap.sdk.controls;
022
023
024
025 import com.unboundid.asn1.ASN1OctetString;
026 import com.unboundid.ldap.sdk.Control;
027 import com.unboundid.ldap.sdk.DecodeableControl;
028 import com.unboundid.ldap.sdk.LDAPException;
029 import com.unboundid.ldap.sdk.LDAPResult;
030 import com.unboundid.ldap.sdk.ResultCode;
031 import com.unboundid.util.NotMutable;
032 import com.unboundid.util.ThreadSafety;
033 import com.unboundid.util.ThreadSafetyLevel;
034
035 import static com.unboundid.ldap.sdk.controls.ControlMessages.*;
036 import static com.unboundid.util.Debug.*;
037
038
039
040 /**
041 * This class provides an implementation of the expiring expiring control as
042 * described in draft-vchu-ldap-pwd-policy. It may be used to indicate that the
043 * authenticated user's password will expire in the near future. The value of
044 * this control includes the length of time in seconds until the user's
045 * password actually expires.
046 * <BR><BR>
047 * No request control is required to trigger the server to send the password
048 * expiring response control. If the server supports the use of this control
049 * and the user's password will expire within a time frame that the server
050 * considers to be the near future, then it will be included in the bind
051 * response returned to the client.
052 * <BR><BR>
053 * See the documentation for the {@link PasswordExpiredControl} to see an
054 * example that demonstrates the use of both the password expiring and password
055 * expired controls.
056 */
057 @NotMutable()
058 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
059 public final class PasswordExpiringControl
060 extends Control
061 implements DecodeableControl
062 {
063 /**
064 * The OID (2.16.840.1.113730.3.4.5) for the password expiring response
065 * control.
066 */
067 public static final String PASSWORD_EXPIRING_OID = "2.16.840.1.113730.3.4.5";
068
069
070
071 /**
072 * The serial version UID for this serializable class.
073 */
074 private static final long serialVersionUID = 1250220480854441338L;
075
076
077
078 // The length of time in seconds until the password expires.
079 private final int secondsUntilExpiration;
080
081
082
083 /**
084 * Creates a new empty control instance that is intended to be used only for
085 * decoding controls via the {@code DecodeableControl} interface.
086 */
087 PasswordExpiringControl()
088 {
089 secondsUntilExpiration = -1;
090 }
091
092
093
094 /**
095 * Creates a new password expiring control with the provided information.
096 *
097 * @param secondsUntilExpiration The length of time in seconds until the
098 * password expires.
099 */
100 public PasswordExpiringControl(final int secondsUntilExpiration)
101 {
102 super(PASSWORD_EXPIRING_OID, false,
103 new ASN1OctetString(String.valueOf(secondsUntilExpiration)));
104
105 this.secondsUntilExpiration = secondsUntilExpiration;
106 }
107
108
109
110 /**
111 * Creates a new password expiring control with the provided information.
112 *
113 * @param oid The OID for the control.
114 * @param isCritical Indicates whether the control should be marked
115 * critical.
116 * @param value The encoded value for the control. This may be
117 * {@code null} if no value was provided.
118 *
119 * @throws LDAPException If the provided control cannot be decoded as a
120 * password expiring response control.
121 */
122 public PasswordExpiringControl(final String oid, final boolean isCritical,
123 final ASN1OctetString value)
124 throws LDAPException
125 {
126 super(oid, isCritical, value);
127
128 if (value == null)
129 {
130 throw new LDAPException(ResultCode.DECODING_ERROR,
131 ERR_PW_EXPIRING_NO_VALUE.get());
132 }
133
134 try
135 {
136 secondsUntilExpiration = Integer.parseInt(value.stringValue());
137 }
138 catch (NumberFormatException nfe)
139 {
140 debugException(nfe);
141 throw new LDAPException(ResultCode.DECODING_ERROR,
142 ERR_PW_EXPIRING_VALUE_NOT_INTEGER.get(), nfe);
143 }
144 }
145
146
147
148 /**
149 * {@inheritDoc}
150 */
151 public PasswordExpiringControl
152 decodeControl(final String oid, final boolean isCritical,
153 final ASN1OctetString value)
154 throws LDAPException
155 {
156 return new PasswordExpiringControl(oid, isCritical, value);
157 }
158
159
160
161 /**
162 * Extracts a password expiring control from the provided result.
163 *
164 * @param result The result from which to retrieve the password expiring
165 * control.
166 *
167 * @return The password expiring control contained in the provided result, or
168 * {@code null} if the result did not contain a password expiring
169 * control.
170 *
171 * @throws LDAPException If a problem is encountered while attempting to
172 * decode the password expiring control contained in
173 * the provided result.
174 */
175 public static PasswordExpiringControl get(final LDAPResult result)
176 throws LDAPException
177 {
178 final Control c = result.getResponseControl(PASSWORD_EXPIRING_OID);
179 if (c == null)
180 {
181 return null;
182 }
183
184 if (c instanceof PasswordExpiringControl)
185 {
186 return (PasswordExpiringControl) c;
187 }
188 else
189 {
190 return new PasswordExpiringControl(c.getOID(), c.isCritical(),
191 c.getValue());
192 }
193 }
194
195
196
197 /**
198 * Retrieves the length of time in seconds until the password expires.
199 *
200 * @return The length of time in seconds until the password expires.
201 */
202 public int getSecondsUntilExpiration()
203 {
204 return secondsUntilExpiration;
205 }
206
207
208
209 /**
210 * {@inheritDoc}
211 */
212 @Override()
213 public String getControlName()
214 {
215 return INFO_CONTROL_NAME_PW_EXPIRING.get();
216 }
217
218
219
220 /**
221 * {@inheritDoc}
222 */
223 @Override()
224 public void toString(final StringBuilder buffer)
225 {
226 buffer.append("PasswordExpiringControl(secondsUntilExpiration=");
227 buffer.append(secondsUntilExpiration);
228 buffer.append(", isCritical=");
229 buffer.append(isCritical());
230 buffer.append(')');
231 }
232 }