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