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