001 /*
002 * Copyright 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.ASN1Null;
028 import com.unboundid.asn1.ASN1Sequence;
029 import com.unboundid.ldap.sdk.Control;
030 import com.unboundid.ldap.sdk.ExtendedRequest;
031 import com.unboundid.ldap.sdk.ExtendedResult;
032 import com.unboundid.ldap.sdk.LDAPConnection;
033 import com.unboundid.ldap.sdk.LDAPException;
034 import com.unboundid.ldap.sdk.ResultCode;
035 import com.unboundid.util.Debug;
036 import com.unboundid.util.NotMutable;
037 import com.unboundid.util.StaticUtils;
038 import com.unboundid.util.ThreadSafety;
039 import com.unboundid.util.ThreadSafetyLevel;
040
041 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
042
043
044
045 /**
046 * <BLOCKQUOTE>
047 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
048 * LDAP SDK for Java. It is not available for use in applications that
049 * include only the Standard Edition of the LDAP SDK, and is not supported for
050 * use in conjunction with non-UnboundID products.
051 * </BLOCKQUOTE>
052 * This class provides an implementation of an extended request that may be used
053 * to retrieve the set of password quality requirements that the Directory
054 * Server will impose for a specified operation, which may include adding a new
055 * user (including a password), a user changing his/her own password (a self
056 * change), or one user changing the password for another user (an
057 * administrative reset).
058 * <BR><BR>
059 * This extended request has an OID of 1.3.6.1.4.1.30221.2.6.43 and a value with
060 * the following encoding:
061 * <PRE>
062 * GetPasswordQualityRequirementsRequestValue ::= SEQUENCE {
063 * target CHOICE {
064 * addWithDefaultPasswordPolicy [0] NULL,
065 * addWithSpecifiedPasswordPolicy [1] LDAPDN,
066 * selfChangeForAuthorizationIdentity [2] NULL,
067 * selfChangeForSpecifiedUser [3] LDAPDN,
068 * administrativeResetForUser [4] LDAPDN,
069 * ... },
070 * ... }
071 * </PRE>
072 */
073 @NotMutable()
074 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
075 public final class GetPasswordQualityRequirementsExtendedRequest
076 extends ExtendedRequest
077 {
078 /**
079 * The OID (1.3.6.1.4.1.30221.2.6.43) for the get password quality
080 * requirements extended request.
081 */
082 public static final String OID_GET_PASSWORD_QUALITY_REQUIREMENTS_REQUEST =
083 "1.3.6.1.4.1.30221.2.6.43";
084
085
086
087 /**
088 * The serial version UID for this serializable class.
089 */
090 private static final long serialVersionUID = -3652010872400265557L;
091
092
093
094
095 // The target type for this get password quality requirements extended
096 // request.
097 private final GetPasswordQualityRequirementsTargetType targetType;
098
099 // The target DN for this get password quality requirements extended request.
100 private final String targetDN;
101
102
103
104 /**
105 * Creates a new get password quality requirements extended request with the
106 * provided information.
107 *
108 * @param targetType The target type for this request. It must not be
109 * {@code null}.
110 * @param targetDN The target DN for this request. It may be {@code null}
111 * if no target DN is required for the specified target
112 * type.
113 * @param controls The set of controls to include in the request. It may
114 * be {@code null} or empty if no controls should be
115 * included.
116 */
117 private GetPasswordQualityRequirementsExtendedRequest(
118 final GetPasswordQualityRequirementsTargetType targetType,
119 final String targetDN,
120 final Control... controls)
121 {
122 super(OID_GET_PASSWORD_QUALITY_REQUIREMENTS_REQUEST,
123 encodeValue(targetType, targetDN), controls);
124
125 this.targetType = targetType;
126 this.targetDN = targetDN;
127 }
128
129
130
131 /**
132 * Creates a new get password quality requirements extended request decoded
133 * from the provided generic extended request.
134 *
135 * @param r The extended request to decode as a get password quality
136 * requirements request.
137 *
138 * @throws LDAPException If a problem is encountered while attempting to
139 * decoded the provided extended request as a
140 * get password quality requirements request.
141 */
142 public GetPasswordQualityRequirementsExtendedRequest(final ExtendedRequest r)
143 throws LDAPException
144 {
145 super(r);
146
147 final ASN1OctetString value = r.getValue();
148 if (value == null)
149 {
150 throw new LDAPException(ResultCode.DECODING_ERROR,
151 ERR_GET_PW_QUALITY_REQS_REQUEST_NO_VALUE.get());
152 }
153
154 try
155 {
156 final ASN1Element[] elements =
157 ASN1Sequence.decodeAsSequence(value.getValue()).elements();
158
159 targetType = GetPasswordQualityRequirementsTargetType.forBERType(
160 elements[0].getType());
161 if (targetType == null)
162 {
163 throw new LDAPException(ResultCode.DECODING_ERROR,
164 ERR_GET_PW_QUALITY_REQS_REQUEST_UNKNOWN_TARGET_TYPE.get(
165 StaticUtils.toHex(elements[0].getType())));
166 }
167
168 switch (targetType)
169 {
170 case ADD_WITH_SPECIFIED_PASSWORD_POLICY:
171 case SELF_CHANGE_FOR_SPECIFIED_USER:
172 case ADMINISTRATIVE_RESET_FOR_SPECIFIED_USER:
173 targetDN = ASN1OctetString.decodeAsOctetString(
174 elements[0]).stringValue();
175 break;
176
177 case ADD_WITH_DEFAULT_PASSWORD_POLICY:
178 case SELF_CHANGE_FOR_AUTHORIZATION_IDENTITY:
179 default:
180 targetDN = null;
181 break;
182 }
183 }
184 catch (final LDAPException le)
185 {
186 Debug.debugException(le);
187 throw le;
188 }
189 catch (final Exception e)
190 {
191 Debug.debugException(e);
192 throw new LDAPException(ResultCode.DECODING_ERROR,
193 ERR_GET_PW_QUALITY_REQS_REQUEST_CANNOT_DECODE.get(
194 StaticUtils.getExceptionMessage(e)),
195 e);
196 }
197 }
198
199
200
201 /**
202 * Encodes the provided information into an ASN.1 octet string suitable for
203 * use as the value of this extended request.
204 *
205 * @param targetType The target type for this request. It must not be
206 * {@code null}.
207 * @param targetDN The target DN for this request. It may be {@code null}
208 * if no target DN is required for the specified target
209 * type.
210 *
211 * @return The ASN.1 octet string containing the encoded request value.
212 */
213 private static ASN1OctetString encodeValue(
214 final GetPasswordQualityRequirementsTargetType targetType,
215 final String targetDN)
216 {
217 final ASN1Element targetElement;
218 switch (targetType)
219 {
220 case ADD_WITH_SPECIFIED_PASSWORD_POLICY:
221 case SELF_CHANGE_FOR_SPECIFIED_USER:
222 case ADMINISTRATIVE_RESET_FOR_SPECIFIED_USER:
223 targetElement = new ASN1OctetString(targetType.getBERType(), targetDN);
224 break;
225
226 case ADD_WITH_DEFAULT_PASSWORD_POLICY:
227 case SELF_CHANGE_FOR_AUTHORIZATION_IDENTITY:
228 default:
229 targetElement = new ASN1Null(targetType.getBERType());
230 break;
231 }
232
233 final ASN1Sequence valueSequence = new ASN1Sequence(
234 targetElement);
235
236 return new ASN1OctetString(valueSequence.encode());
237 }
238
239
240
241 /**
242 * Creates a new get password quality requirements extended request that will
243 * retrieve the password requirements for an add operation governed by the
244 * server's default password policy.
245 *
246 * @param controls The set of controls to include in the request. It may be
247 * {@code null} or empty if no controls should be included
248 * in the request.
249 *
250 * @return A new get password quality requirements extended request that will
251 * retrieve the password requirements for an add operation governed
252 * by the server's default password policy.
253 */
254 public static GetPasswordQualityRequirementsExtendedRequest
255 createAddWithDefaultPasswordPolicyRequest(
256 final Control... controls)
257 {
258 return new GetPasswordQualityRequirementsExtendedRequest(
259 GetPasswordQualityRequirementsTargetType.
260 ADD_WITH_DEFAULT_PASSWORD_POLICY,
261 null, controls);
262 }
263
264
265
266 /**
267 * Creates a new get password quality requirements extended request that will
268 * retrieve the password requirements for an add operation governed by the
269 * specified password policy.
270 *
271 * @param policyDN The DN of the entry that defines the password policy from
272 * which to determine the password quality requirements.
273 * @param controls The set of controls to include in the request. It may be
274 * {@code null} or empty if no controls should be included
275 * in the request.
276 *
277 * @return A new get password quality requirements extended request that will
278 * retrieve the password requirements for an add operation governed
279 * by the specified password policy.
280 */
281 public static GetPasswordQualityRequirementsExtendedRequest
282 createAddWithSpecifiedPasswordPolicyRequest(
283 final String policyDN, final Control... controls)
284 {
285 return new GetPasswordQualityRequirementsExtendedRequest(
286 GetPasswordQualityRequirementsTargetType.
287 ADD_WITH_SPECIFIED_PASSWORD_POLICY,
288 policyDN, controls);
289 }
290
291
292
293 /**
294 * Creates a new get password quality requirements extended request that will
295 * retrieve the password requirements for a self change requested with the
296 * same authorization identity as this extended request.
297 *
298 * @param controls The set of controls to include in the request. It may be
299 * {@code null} or empty if no controls should be included
300 * in the request.
301 *
302 * @return A new get password quality requirements extended request that will
303 * retrieve the password requirements for a self change requested
304 * with the same authorization identity as this extended request.
305 */
306 public static GetPasswordQualityRequirementsExtendedRequest
307 createSelfChangeWithSameAuthorizationIdentityRequest(
308 final Control... controls)
309 {
310 return new GetPasswordQualityRequirementsExtendedRequest(
311 GetPasswordQualityRequirementsTargetType.
312 SELF_CHANGE_FOR_AUTHORIZATION_IDENTITY,
313 null, controls);
314 }
315
316
317
318 /**
319 * Creates a new get password quality requirements extended request that will
320 * retrieve the password requirements for a self change requested by the
321 * specified user.
322 *
323 * @param userDN The DN of the user for whom to retrieve the self change
324 * password requirements.
325 * @param controls The set of controls to include in the request. It may be
326 * {@code null} or empty if no controls should be included
327 * in the request.
328 *
329 * @return A new get password quality requirements extended request that will
330 * retrieve the password requirements for a self change requested by
331 * the specified user.
332 */
333 public static GetPasswordQualityRequirementsExtendedRequest
334 createSelfChangeForSpecifiedUserRequest(
335 final String userDN, final Control... controls)
336 {
337 return new GetPasswordQualityRequirementsExtendedRequest(
338 GetPasswordQualityRequirementsTargetType.
339 SELF_CHANGE_FOR_SPECIFIED_USER,
340 userDN, controls);
341 }
342
343
344
345 /**
346 * Creates a new get password quality requirements extended request that will
347 * retrieve the password requirements for an administrative reset targeting
348 * the specified user.
349 *
350 * @param userDN The DN of the user for whom to retrieve the
351 * administrative reset password requirements.
352 * @param controls The set of controls to include in the request. It may be
353 * {@code null} or empty if no controls should be included
354 * in the request.
355 *
356 * @return A new get password quality requirements extended request that will
357 * retrieve the password requirements for an administrative reset
358 * targeting the specified user.
359 */
360 public static GetPasswordQualityRequirementsExtendedRequest
361 createAdministrativeResetForSpecifiedUserRequest(
362 final String userDN, final Control... controls)
363 {
364 return new GetPasswordQualityRequirementsExtendedRequest(
365 GetPasswordQualityRequirementsTargetType.
366 ADMINISTRATIVE_RESET_FOR_SPECIFIED_USER,
367 userDN, controls);
368 }
369
370
371
372 /**
373 * Retrieves the target type for this get password quality requirements
374 * request.
375 *
376 * @return The target type for this get password quality requirements
377 * request.
378 */
379 public GetPasswordQualityRequirementsTargetType getTargetType()
380 {
381 return targetType;
382 }
383
384
385
386 /**
387 * Retrieves the target DN for this get password quality requirements request.
388 * For a request with a target type of
389 * {@code ADD_WITH_SPECIFIED_PASSWORD_POLICY}, this will be the DN of the
390 * password policy from which to obtain the password quality requirements.
391 * For a request with a target type of either
392 * {@code SELF_CHANGE_FOR_SPECIFIED_USER} or
393 * {@code ADMINISTRATIVE_RESET_FOR_SPECIFIED_USER}, this will be the DN of the
394 * user for which to obtain the password quality requirements. For a request
395 * with a target type of either {@code ADD_WITH_DEFAULT_PASSWORD_POLICY} or
396 * {@code SELF_CHANGE_FOR_AUTHORIZATION_IDENTITY}, no target DN is required
397 * and the value returned will be {@code null}.
398 *
399 * @return The target DN for this get password quality requirements request.
400 */
401 public String getTargetDN()
402 {
403 return targetDN;
404 }
405
406
407
408 /**
409 * {@inheritDoc}
410 */
411 @Override()
412 public GetPasswordQualityRequirementsExtendedResult process(
413 final LDAPConnection connection, final int depth)
414 throws LDAPException
415 {
416 final ExtendedResult result = super.process(connection, depth);
417 return new GetPasswordQualityRequirementsExtendedResult(result);
418 }
419
420
421
422 /**
423 * {@inheritDoc}
424 */
425 @Override()
426 public GetPasswordQualityRequirementsExtendedRequest duplicate()
427 {
428 return duplicate(getControls());
429 }
430
431
432
433 /**
434 * {@inheritDoc}
435 */
436 @Override()
437 public GetPasswordQualityRequirementsExtendedRequest duplicate(
438 final Control[] controls)
439 {
440 final GetPasswordQualityRequirementsExtendedRequest r =
441 new GetPasswordQualityRequirementsExtendedRequest(targetType,
442 targetDN, controls);
443 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
444 return r;
445 }
446
447
448
449 /**
450 * {@inheritDoc}
451 */
452 @Override()
453 public String getExtendedRequestName()
454 {
455 return INFO_EXTENDED_REQUEST_NAME_GET_PW_QUALITY_REQS.get();
456 }
457
458
459
460 /**
461 * {@inheritDoc}
462 */
463 @Override()
464 public void toString(final StringBuilder buffer)
465 {
466 buffer.append("GetPasswordQualityRequirementsExtendedRequest(targetType=");
467 buffer.append(targetType.name());
468
469 if (targetDN != null)
470 {
471 buffer.append(", targetDN='");
472 buffer.append(targetDN);
473 buffer.append('\'');
474 }
475
476 final Control[] controls = getControls();
477 if (controls.length > 0)
478 {
479 buffer.append(", controls={");
480 for (int i=0; i < controls.length; i++)
481 {
482 if (i > 0)
483 {
484 buffer.append(", ");
485 }
486
487 buffer.append(controls[i]);
488 }
489 buffer.append('}');
490 }
491
492 buffer.append(')');
493 }
494 }