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 }