001 /*
002 * Copyright 2008-2015 UnboundID Corp.
003 * All Rights Reserved.
004 */
005 /*
006 * Copyright (C) 2015 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.unboundidds.extensions;
022
023
024
025 import com.unboundid.asn1.ASN1Element;
026 import com.unboundid.asn1.ASN1OctetString;
027 import com.unboundid.asn1.ASN1Sequence;
028 import com.unboundid.ldap.sdk.Control;
029 import com.unboundid.ldap.sdk.ExtendedRequest;
030 import com.unboundid.ldap.sdk.ExtendedResult;
031 import com.unboundid.ldap.sdk.LDAPConnection;
032 import com.unboundid.ldap.sdk.LDAPException;
033 import com.unboundid.ldap.sdk.ResultCode;
034 import com.unboundid.util.NotMutable;
035 import com.unboundid.util.ThreadSafety;
036 import com.unboundid.util.ThreadSafetyLevel;
037
038 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
039 import static com.unboundid.util.Debug.*;
040
041
042
043 /**
044 * <BLOCKQUOTE>
045 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
046 * LDAP SDK for Java. It is not available for use in applications that
047 * include only the Standard Edition of the LDAP SDK, and is not supported for
048 * use in conjunction with non-UnboundID products.
049 * </BLOCKQUOTE>
050 * This class provides an implementation of the password policy state extended
051 * request as used in the UnboundID Directory Server. It may be used to
052 * retrieve and/or alter password policy properties for a user account. See the
053 * documentation in the {@link PasswordPolicyStateOperation} class for
054 * information about the types of operations that can be performed.
055 * <BR><BR>
056 * <H2>Example</H2>
057 * The following example demonstrates the use of the password policy state
058 * extended operation to administratively disable a user's account:
059 * <PRE>
060 * PasswordPolicyStateOperation disableOp =
061 * PasswordPolicyStateOperation.createSetAccountDisabledStateOperation(
062 * true);
063 * PasswordPolicyStateExtendedRequest pwpStateRequest =
064 * new PasswordPolicyStateExtendedRequest(
065 * "uid=john.doe,ou=People,dc=example,dc=com", disableOp);
066 * PasswordPolicyStateExtendedResult pwpStateResult =
067 * (PasswordPolicyStateExtendedResult)
068 * connection.processExtendedOperation(pwpStateRequest);
069 *
070 * // NOTE: The processExtendedOperation method will generally only throw an
071 * // exception if a problem occurs while trying to send the request or read
072 * // the response. It will not throw an exception because of a non-success
073 * // response.
074 *
075 * if (pwpStateResult.getResultCode() == ResultCode.SUCCESS)
076 * {
077 * boolean isDisabled = pwpStateResult.getBooleanValue(
078 * PasswordPolicyStateOperation.OP_TYPE_GET_ACCOUNT_DISABLED_STATE);
079 * if (isDisabled)
080 * {
081 * // The user account has been disabled.
082 * }
083 * else
084 * {
085 * // The user account is not disabled.
086 * }
087 * }
088 * </PRE>
089 */
090 @NotMutable()
091 @ThreadSafety(level=ThreadSafetyLevel.NOT_THREADSAFE)
092 public final class PasswordPolicyStateExtendedRequest
093 extends ExtendedRequest
094 {
095 /**
096 * The OID (1.3.6.1.4.1.30221.1.6.1) for the password policy state extended
097 * request.
098 */
099 public static final String PASSWORD_POLICY_STATE_REQUEST_OID =
100 "1.3.6.1.4.1.30221.1.6.1";
101
102
103
104 /**
105 * The serial version UID for this serializable class.
106 */
107 private static final long serialVersionUID = -1644137695182620213L;
108
109
110
111 // The set of password policy state operations to process.
112 private final PasswordPolicyStateOperation[] operations;
113
114 // The DN of the user account on which to operate.
115 private final String userDN;
116
117
118
119 /**
120 * Creates a new password policy state extended request with the provided user
121 * DN and optional set of operations.
122 *
123 * @param userDN The DN of the user account on which to operate.
124 * @param operations The set of password policy state operations to process.
125 * If no operations are provided, then the effect will be
126 * to retrieve the values of all available password policy
127 * state properties.
128 */
129 public PasswordPolicyStateExtendedRequest(final String userDN,
130 final PasswordPolicyStateOperation... operations)
131 {
132 this(userDN, null, operations);
133 }
134
135
136
137 /**
138 * Creates a new password policy state extended request with the provided user
139 * DN, optional set of operations, and optional set of controls.
140 *
141 * @param userDN The DN of the user account on which to operate.
142 * @param controls The set of controls to include in the request.
143 * @param operations The set of password policy state operations to process.
144 * If no operations are provided, then the effect will be
145 * to retrieve the values of all available password policy
146 * state properties.
147 */
148 public PasswordPolicyStateExtendedRequest(final String userDN,
149 final Control[] controls,
150 final PasswordPolicyStateOperation... operations)
151 {
152 super(PASSWORD_POLICY_STATE_REQUEST_OID, encodeValue(userDN, operations),
153 controls);
154
155 this.userDN = userDN;
156 this.operations = operations;
157 }
158
159
160
161 /**
162 * Creates a new password policy state extended request from the provided
163 * generic extended request.
164 *
165 * @param extendedRequest The generic extended request to use to create this
166 * password policy state extended request.
167 *
168 * @throws LDAPException If a problem occurs while decoding the request.
169 */
170 public PasswordPolicyStateExtendedRequest(
171 final ExtendedRequest extendedRequest)
172 throws LDAPException
173 {
174 super(extendedRequest);
175
176 final ASN1OctetString value = extendedRequest.getValue();
177 if (value == null)
178 {
179 throw new LDAPException(ResultCode.DECODING_ERROR,
180 ERR_PWP_STATE_REQUEST_NO_VALUE.get());
181 }
182
183 final ASN1Element[] elements;
184 try
185 {
186 final ASN1Element valueElement = ASN1Element.decode(value.getValue());
187 elements = ASN1Sequence.decodeAsSequence(valueElement).elements();
188 }
189 catch (Exception e)
190 {
191 debugException(e);
192 throw new LDAPException(ResultCode.DECODING_ERROR,
193 ERR_PWP_STATE_REQUEST_VALUE_NOT_SEQUENCE.get(e),
194 e);
195 }
196
197 if ((elements.length < 1) || (elements.length > 2))
198 {
199 throw new LDAPException(ResultCode.DECODING_ERROR,
200 ERR_PWP_STATE_REQUEST_INVALID_ELEMENT_COUNT.get(
201 elements.length));
202 }
203
204 userDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
205
206 if (elements.length == 1)
207 {
208 operations = new PasswordPolicyStateOperation[0];
209 }
210 else
211 {
212 try
213 {
214 final ASN1Element[] opElements =
215 ASN1Sequence.decodeAsSequence(elements[1]).elements();
216 operations = new PasswordPolicyStateOperation[opElements.length];
217 for (int i=0; i < opElements.length; i++)
218 {
219 operations[i] = PasswordPolicyStateOperation.decode(opElements[i]);
220 }
221 }
222 catch (Exception e)
223 {
224 debugException(e);
225 throw new LDAPException(ResultCode.DECODING_ERROR,
226 ERR_PWP_STATE_REQUEST_CANNOT_DECODE_OPS.get(e),
227 e);
228 }
229 }
230 }
231
232
233
234 /**
235 * Encodes the provided information into an ASN.1 octet string that may be
236 * used as the value for this extended request.
237 *
238 * @param userDN The DN of the user account on which to operate.
239 * @param operations The set of operations to be processed.
240 *
241 * @return An ASN.1 octet string containing the encoded value.
242 */
243 private static ASN1OctetString encodeValue(final String userDN,
244 final PasswordPolicyStateOperation[] operations)
245 {
246 final ASN1Element[] elements;
247 if ((operations == null) || (operations.length == 0))
248 {
249 elements = new ASN1Element[]
250 {
251 new ASN1OctetString(userDN)
252 };
253 }
254 else
255 {
256 final ASN1Element[] opElements = new ASN1Element[operations.length];
257 for (int i=0; i < operations.length; i++)
258 {
259 opElements[i] = operations[i].encode();
260 }
261
262 elements = new ASN1Element[]
263 {
264 new ASN1OctetString(userDN),
265 new ASN1Sequence(opElements)
266 };
267 }
268
269 return new ASN1OctetString(new ASN1Sequence(elements).encode());
270 }
271
272
273
274 /**
275 * Retrieves the DN of the user account on which to operate.
276 *
277 * @return The DN of the user account on which to operate.
278 */
279 public String getUserDN()
280 {
281 return userDN;
282 }
283
284
285
286 /**
287 * Retrieves the set of password policy state operations to be processed.
288 *
289 * @return The set of password policy state operations to be processed, or
290 * an empty list if the values of all password policy state
291 * properties should be retrieved.
292 */
293 public PasswordPolicyStateOperation[] getOperations()
294 {
295 return operations;
296 }
297
298
299
300 /**
301 * {@inheritDoc}
302 */
303 @Override()
304 public PasswordPolicyStateExtendedResult
305 process(final LDAPConnection connection, final int depth)
306 throws LDAPException
307 {
308 final ExtendedResult extendedResponse = super.process(connection, depth);
309 return new PasswordPolicyStateExtendedResult(extendedResponse);
310 }
311
312
313
314 /**
315 * {@inheritDoc}
316 */
317 @Override()
318 public PasswordPolicyStateExtendedRequest duplicate()
319 {
320 return duplicate(getControls());
321 }
322
323
324
325 /**
326 * {@inheritDoc}
327 */
328 @Override()
329 public PasswordPolicyStateExtendedRequest duplicate(final Control[] controls)
330 {
331 final PasswordPolicyStateExtendedRequest r =
332 new PasswordPolicyStateExtendedRequest(userDN, controls, operations);
333 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
334 return r;
335 }
336
337
338
339 /**
340 * {@inheritDoc}
341 */
342 @Override()
343 public String getExtendedRequestName()
344 {
345 return INFO_EXTENDED_REQUEST_NAME_PW_POLICY_STATE.get();
346 }
347
348
349
350 /**
351 * {@inheritDoc}
352 */
353 @Override()
354 public void toString(final StringBuilder buffer)
355 {
356 buffer.append("PasswordPolicyStateExtendedRequest(userDN='");
357 buffer.append(userDN);
358
359 if (operations.length > 0)
360 {
361 buffer.append("', operations={");
362 for (int i=0; i < operations.length; i++)
363 {
364 if (i > 0)
365 {
366 buffer.append(", ");
367 }
368
369 operations[i].toString(buffer);
370 }
371 buffer.append('}');
372 }
373
374 final Control[] controls = getControls();
375 if (controls.length > 0)
376 {
377 buffer.append(", controls={");
378 for (int i=0; i < controls.length; i++)
379 {
380 if (i > 0)
381 {
382 buffer.append(", ");
383 }
384
385 buffer.append(controls[i]);
386 }
387 buffer.append('}');
388 }
389
390 buffer.append(')');
391 }
392 }