001/* 002 * Copyright 2015-2020 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2015-2020 Ping Identity Corporation 007 * 008 * Licensed under the Apache License, Version 2.0 (the "License"); 009 * you may not use this file except in compliance with the License. 010 * You may obtain a copy of the License at 011 * 012 * http://www.apache.org/licenses/LICENSE-2.0 013 * 014 * Unless required by applicable law or agreed to in writing, software 015 * distributed under the License is distributed on an "AS IS" BASIS, 016 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 017 * See the License for the specific language governing permissions and 018 * limitations under the License. 019 */ 020/* 021 * Copyright (C) 2015-2020 Ping Identity Corporation 022 * 023 * This program is free software; you can redistribute it and/or modify 024 * it under the terms of the GNU General Public License (GPLv2 only) 025 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only) 026 * as published by the Free Software Foundation. 027 * 028 * This program is distributed in the hope that it will be useful, 029 * but WITHOUT ANY WARRANTY; without even the implied warranty of 030 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 031 * GNU General Public License for more details. 032 * 033 * You should have received a copy of the GNU General Public License 034 * along with this program; if not, see <http://www.gnu.org/licenses>. 035 */ 036package com.unboundid.ldap.sdk.unboundidds.extensions; 037 038 039 040import java.util.ArrayList; 041import java.util.Collections; 042import java.util.Iterator; 043import java.util.List; 044 045import com.unboundid.asn1.ASN1Element; 046import com.unboundid.asn1.ASN1OctetString; 047import com.unboundid.asn1.ASN1Sequence; 048import com.unboundid.ldap.sdk.Control; 049import com.unboundid.ldap.sdk.ExtendedRequest; 050import com.unboundid.ldap.sdk.ExtendedResult; 051import com.unboundid.ldap.sdk.LDAPConnection; 052import com.unboundid.ldap.sdk.LDAPException; 053import com.unboundid.ldap.sdk.ResultCode; 054import com.unboundid.util.Debug; 055import com.unboundid.util.NotMutable; 056import com.unboundid.util.ObjectPair; 057import com.unboundid.util.StaticUtils; 058import com.unboundid.util.ThreadSafety; 059import com.unboundid.util.ThreadSafetyLevel; 060import com.unboundid.util.Validator; 061 062import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 063 064 065 066/** 067 * This class provides an implementation of an extended request that can be used 068 * to trigger the delivery of a temporary one-time password reset token to a 069 * specified user. This token can be provided to the password modify extended 070 * request in lieu of the current password for the purpose of performing a self 071 * change and setting a new password. This token cannot be used to authenticate 072 * to the server in any other way, and it can only be used once. The token will 073 * expire after a short period of time, and any attempt to use it after its 074 * expiration will fail. In addition, because this token is only intended for 075 * use in the event that the current password cannot be used (e.g., because it 076 * has been forgotten or the account is locked), a successful bind with the 077 * current password will cause the server to invalidate any password reset token 078 * for that user. 079 * <BR> 080 * <BLOCKQUOTE> 081 * <B>NOTE:</B> This class, and other classes within the 082 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 083 * supported for use against Ping Identity, UnboundID, and 084 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 085 * for proprietary functionality or for external specifications that are not 086 * considered stable or mature enough to be guaranteed to work in an 087 * interoperable way with other types of LDAP servers. 088 * </BLOCKQUOTE> 089 * <BR> 090 * The server will use the same mechanisms for delivering password reset tokens 091 * as it uses for delivering one-time passwords via the 092 * {@link DeliverOneTimePasswordExtendedRequest}. See the 093 * ds-supported-otp-delivery-mechanism attribute in the root DSE for a list of 094 * the one-time password delivery mechanisms that are configured for use in the 095 * server. 096 * <BR><BR> 097 * This extended request is expected to be used to help applications provide a 098 * secure, automated password reset feature. In the event that a user has 099 * forgotten his/her password, has allowed the password to expire, or has 100 * allowed the account to become locked, the application can collect a 101 * sufficient set of information to identify the user and request that the 102 * server generate and deliver the password reset token to the end user. 103 * <BR><BR> 104 * The OID for this extended request is 1.3.6.1.4.1.30221.2.6.45. It must have 105 * a value with the following encoding: 106 * <PRE> 107 * DeliverPasswordResetTokenRequestValue ::= SEQUENCE { 108 * userDN LDAPDN, 109 * messageSubject [0] OCTET STRING OPTIONAL, 110 * fullTextBeforeToken [1] OCTET STRING OPTIONAL, 111 * fullTextAfterToken [2] OCTET STRING OPTIONAL, 112 * compactTextBeforeToken [3] OCTET STRING OPTIONAL, 113 * compactTextAfterToken [4] OCTET STRING OPTIONAL, 114 * preferredDeliveryMechanism [5] SEQUENCE OF SEQUENCE { 115 * mechanismName OCTET STRING, 116 * recipientID OCTET STRING OPTIONAL }, 117 * ... } 118 * </PRE> 119 * 120 * @see DeliverPasswordResetTokenExtendedResult 121 */ 122@NotMutable() 123@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 124public final class DeliverPasswordResetTokenExtendedRequest 125 extends ExtendedRequest 126{ 127 /** 128 * The OID (1.3.6.1.4.1.30221.2.6.45) for the deliver password reset token 129 * extended request. 130 */ 131 public static final String DELIVER_PW_RESET_TOKEN_REQUEST_OID = 132 "1.3.6.1.4.1.30221.2.6.45"; 133 134 135 136 /** 137 * The BER type for the "message subject" element of the value sequence. 138 */ 139 private static final byte MESSAGE_SUBJECT_BER_TYPE = (byte) 0x80; 140 141 142 143 /** 144 * The BER type for the "full text before token" element of the value 145 * sequence. 146 */ 147 private static final byte FULL_TEXT_BEFORE_TOKEN_BER_TYPE = (byte) 0x81; 148 149 150 151 /** 152 * The BER type for the "full text after token" element of the value 153 * sequence. 154 */ 155 private static final byte FULL_TEXT_AFTER_TOKEN_BER_TYPE = (byte) 0x82; 156 157 158 159 /** 160 * The BER type for the "compact text before token" element of the value 161 * sequence. 162 */ 163 private static final byte COMPACT_TEXT_BEFORE_TOKEN_BER_TYPE = (byte) 0x83; 164 165 166 167 /** 168 * The BER type for the "compact text after token" element of the value 169 * sequence. 170 */ 171 private static final byte COMPACT_TEXT_AFTER_TOKEN_BER_TYPE = (byte) 0x84; 172 173 174 175 /** 176 * The BER type for the "preferred delivery mechanism" element of the value 177 * sequence. 178 */ 179 private static final byte PREFERRED_DELIVERY_MECHANISM_BER_TYPE = (byte) 0xA5; 180 181 182 183 /** 184 * The serial version UID for this serializable class. 185 */ 186 private static final long serialVersionUID = 7608072810737347230L; 187 188 189 190 // An ordered list of the preferred delivery mechanisms for the token, 191 // paired with an optional recipient ID for each mechanism. 192 private final List<ObjectPair<String, String>> preferredDeliveryMechanisms; 193 194 // The text to include after the token in a compact message. 195 private final String compactTextAfterToken; 196 197 // The text to include before the token in a compact message. 198 private final String compactTextBeforeToken; 199 200 // The text to include after the token in a message without size constraints. 201 private final String fullTextAfterToken; 202 203 // The text to include before the token in a message without size constraints. 204 private final String fullTextBeforeToken; 205 206 // The text to use as the message subject. 207 private final String messageSubject; 208 209 // The DN of the user to whom the password reset token should be delivered. 210 private final String userDN; 211 212 213 214 /** 215 * Creates a new deliver password reset token extended request with the 216 * provided information. 217 * 218 * @param userDN The DN of the user to whom the 219 * password reset token should be 220 * generated. 221 * @param preferredDeliveryMechanisms An optional ordered list of preferred 222 * delivery mechanisms that should be 223 * used to deliver the token to the user. 224 * It may be {@code null} or empty to 225 * allow the server to select an 226 * appropriate delivery mechanism. If it 227 * is non-{@code null} and non-empty, 228 * then only the listed mechanisms will 229 * be considered for use, even if the 230 * server supports alternate mechanisms 231 * not included in this list. 232 */ 233 public DeliverPasswordResetTokenExtendedRequest(final String userDN, 234 final String... preferredDeliveryMechanisms) 235 { 236 this(userDN, preferredMechanismsToList(preferredDeliveryMechanisms)); 237 } 238 239 240 241 /** 242 * Creates a new deliver password reset token extended request with the 243 * provided information. 244 * 245 * @param userDN The DN of the user to whom the 246 * password reset token should be 247 * generated. 248 * @param preferredDeliveryMechanisms An optional ordered list of preferred 249 * delivery mechanisms that should be 250 * used to deliver the token to the user. 251 * It may be {@code null} or empty to 252 * allow the server to select an 253 * appropriate delivery mechanism. If it 254 * is non-{@code null} and non-empty, 255 * then only the listed mechanisms will 256 * be considered for use, even if the 257 * server supports alternate mechanisms 258 * not included in this list. Each 259 * {@code ObjectPair} item must have 260 * a non-{@code null} value for the first 261 * element, which is the name of the 262 * target delivery mechanism. It may 263 * optionally have a non-{@code null} 264 * value for the second element, which is 265 * a recipient ID to use for that 266 * mechanism (e.g., the target mobile 267 * phone number for SMS delivery, an 268 * email address for email delivery, 269 * etc.). If no recipient ID is provided 270 * for a mechanism, then the server will 271 * attempt to select a value for the 272 * user. 273 * @param controls An optional set of controls to include 274 * in the request. It may be 275 * {@code null} or empty if no controls 276 * should be included in the request. 277 */ 278 public DeliverPasswordResetTokenExtendedRequest(final String userDN, 279 final List<ObjectPair<String,String>> preferredDeliveryMechanisms, 280 final Control... controls) 281 { 282 this(userDN, null, null, null, null, null, preferredDeliveryMechanisms, 283 controls); 284 } 285 286 287 288 /** 289 * Creates a new deliver password reset token extended request with the 290 * provided information. 291 * 292 * @param userDN The DN of the user to whom the 293 * password reset token should be 294 * generated. 295 * @param messageSubject The text (if any) that should be used 296 * as the message subject if the delivery 297 * mechanism accepts a subject. This may 298 * be {@code null} if no subject is 299 * required or a subject should be 300 * automatically generated. 301 * @param fullTextBeforeToken The text (if any) that should appear 302 * before the generated password reset 303 * token in the message delivered to the 304 * user via a delivery mechanism that 305 * does not impose significant 306 * constraints on message size. This may 307 * be {@code null} if no text is required 308 * before the token. 309 * @param fullTextAfterToken The text (if any) that should appear 310 * after the generated password reset 311 * token in the message delivered to the 312 * user via a delivery mechanism that 313 * does not impose significant 314 * constraints on message size. This may 315 * be {@code null} if no text is required 316 * after the token. 317 * @param compactTextBeforeToken The text (if any) that should appear 318 * before the generated password reset 319 * token in the message delivered to the 320 * user via a delivery mechanism that 321 * imposes significant constraints on 322 * message size. This may be 323 * {@code null} if no text is required 324 * before the token. 325 * @param compactTextAfterToken The text (if any) that should appear 326 * after the generated password reset 327 * token in the message delivered to the 328 * user via a delivery mechanism that 329 * imposes significant constraints on 330 * message size. This may be 331 * {@code null} if no text is required 332 * after the token. 333 * @param preferredDeliveryMechanisms An optional ordered list of preferred 334 * delivery mechanisms that should be 335 * used to deliver the token to the user. 336 * It may be {@code null} or empty to 337 * allow the server to select an 338 * appropriate delivery mechanism. If it 339 * is non-{@code null} and non-empty, 340 * then only the listed mechanisms will 341 * be considered for use, even if the 342 * server supports alternate mechanisms 343 * not included in this list. Each 344 * {@code ObjectPair} item must have 345 * a non-{@code null} value for the first 346 * element, which is the name of the 347 * target delivery mechanism. It may 348 * optionally have a non-{@code null} 349 * value for the second element, which is 350 * a recipient ID to use for that 351 * mechanism (e.g., the target mobile 352 * phone number for SMS delivery, an 353 * email address for email delivery, 354 * etc.). If no recipient ID is provided 355 * for a mechanism, then the server will 356 * attempt to select a value for the 357 * user. 358 * @param controls An optional set of controls to include 359 * in the request. It may be 360 * {@code null} or empty if no controls 361 * should be included in the request. 362 */ 363 public DeliverPasswordResetTokenExtendedRequest(final String userDN, 364 final String messageSubject, final String fullTextBeforeToken, 365 final String fullTextAfterToken, 366 final String compactTextBeforeToken, 367 final String compactTextAfterToken, 368 final List<ObjectPair<String,String>> preferredDeliveryMechanisms, 369 final Control... controls) 370 { 371 super(DELIVER_PW_RESET_TOKEN_REQUEST_OID, 372 encodeValue(userDN, messageSubject, fullTextBeforeToken, 373 fullTextAfterToken, compactTextBeforeToken, compactTextAfterToken, 374 preferredDeliveryMechanisms), controls); 375 376 this.userDN = userDN; 377 this.messageSubject = messageSubject; 378 this.fullTextBeforeToken = fullTextBeforeToken; 379 this.fullTextAfterToken = fullTextAfterToken; 380 this.compactTextBeforeToken = compactTextBeforeToken; 381 this.compactTextAfterToken = compactTextAfterToken; 382 383 if (preferredDeliveryMechanisms == null) 384 { 385 this.preferredDeliveryMechanisms = Collections.emptyList(); 386 } 387 else 388 { 389 this.preferredDeliveryMechanisms = Collections.unmodifiableList( 390 new ArrayList<>(preferredDeliveryMechanisms)); 391 } 392 } 393 394 395 396 /** 397 * Creates a new deliver password reset token extended request that is decoded 398 * from the provided extended request. 399 * 400 * @param request The generic extended request to decode as a deliver 401 * password reset token request. It must not be 402 * {@code null}. 403 * 404 * @throws LDAPException If an unexpected problem occurs. 405 */ 406 public DeliverPasswordResetTokenExtendedRequest(final ExtendedRequest request) 407 throws LDAPException 408 { 409 super(request); 410 411 final ASN1OctetString value = request.getValue(); 412 if (value == null) 413 { 414 throw new LDAPException(ResultCode.DECODING_ERROR, 415 ERR_DELIVER_PW_RESET_TOKEN_REQUEST_NO_VALUE.get()); 416 } 417 418 try 419 { 420 final ASN1Element[] elements = 421 ASN1Sequence.decodeAsSequence(value.getValue()).elements(); 422 userDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue(); 423 424 String subject = null; 425 String fullBefore = null; 426 String fullAfter = null; 427 String compactBefore = null; 428 String compactAfter = null; 429 final ArrayList<ObjectPair<String,String>> pdmList = new ArrayList<>(10); 430 for (int i=1; i < elements.length; i++) 431 { 432 switch (elements[i].getType()) 433 { 434 case MESSAGE_SUBJECT_BER_TYPE: 435 subject = 436 ASN1OctetString.decodeAsOctetString(elements[i]).stringValue(); 437 break; 438 439 case FULL_TEXT_BEFORE_TOKEN_BER_TYPE: 440 fullBefore = 441 ASN1OctetString.decodeAsOctetString(elements[i]).stringValue(); 442 break; 443 444 case FULL_TEXT_AFTER_TOKEN_BER_TYPE: 445 fullAfter = 446 ASN1OctetString.decodeAsOctetString(elements[i]).stringValue(); 447 break; 448 449 case COMPACT_TEXT_BEFORE_TOKEN_BER_TYPE: 450 compactBefore = 451 ASN1OctetString.decodeAsOctetString(elements[i]).stringValue(); 452 break; 453 454 case COMPACT_TEXT_AFTER_TOKEN_BER_TYPE: 455 compactAfter = 456 ASN1OctetString.decodeAsOctetString(elements[i]).stringValue(); 457 break; 458 459 case PREFERRED_DELIVERY_MECHANISM_BER_TYPE: 460 final ASN1Element[] pdmElements = 461 ASN1Sequence.decodeAsSequence(elements[i]).elements(); 462 for (final ASN1Element e : pdmElements) 463 { 464 final ASN1Element[] mechElements = 465 ASN1Sequence.decodeAsSequence(e).elements(); 466 final String mech = ASN1OctetString.decodeAsOctetString( 467 mechElements[0]).stringValue(); 468 469 final String recipientID; 470 if (mechElements.length > 1) 471 { 472 recipientID = ASN1OctetString.decodeAsOctetString( 473 mechElements[1]).stringValue(); 474 } 475 else 476 { 477 recipientID = null; 478 } 479 480 pdmList.add(new ObjectPair<>(mech, recipientID)); 481 } 482 break; 483 484 default: 485 throw new LDAPException(ResultCode.DECODING_ERROR, 486 ERR_DELIVER_PW_RESET_TOKEN_REQUEST_UNEXPECTED_TYPE.get( 487 StaticUtils.toHex(elements[i].getType()))); 488 } 489 } 490 491 preferredDeliveryMechanisms = Collections.unmodifiableList(pdmList); 492 messageSubject = subject; 493 fullTextBeforeToken = fullBefore; 494 fullTextAfterToken = fullAfter; 495 compactTextBeforeToken = compactBefore; 496 compactTextAfterToken = compactAfter; 497 } 498 catch (final LDAPException le) 499 { 500 Debug.debugException(le); 501 throw le; 502 } 503 catch (final Exception e) 504 { 505 Debug.debugException(e); 506 throw new LDAPException(ResultCode.DECODING_ERROR, 507 ERR_DELIVER_PW_RESET_TOKEN_REQUEST_ERROR_DECODING_VALUE.get( 508 StaticUtils.getExceptionMessage(e)), 509 e); 510 } 511 } 512 513 514 515 /** 516 * Encodes the provided set of preferred delivery mechanisms into a form 517 * acceptable to the constructor that expects an object pair. All of the 518 * recipient IDs will be {@code null}. 519 * 520 * @param preferredDeliveryMechanisms An optional ordered list of preferred 521 * delivery mechanisms that should be 522 * used to deliver the token to the user. 523 * It may be {@code null} or empty to 524 * allow the server to select an 525 * appropriate delivery mechanism. If it 526 * is non-{@code null} and non-empty, 527 * then only the listed mechanisms will 528 * be considered for use, even if the 529 * server supports alternate mechanisms 530 * not included in this list. 531 * 532 * @return The resulting list of preferred delivery mechanisms with 533 * {@code null} recipient IDs. 534 */ 535 private static List<ObjectPair<String,String>> preferredMechanismsToList( 536 final String... preferredDeliveryMechanisms) 537 { 538 if (preferredDeliveryMechanisms == null) 539 { 540 return null; 541 } 542 543 final ArrayList<ObjectPair<String,String>> l = 544 new ArrayList<>(preferredDeliveryMechanisms.length); 545 for (final String s : preferredDeliveryMechanisms) 546 { 547 l.add(new ObjectPair<String,String>(s, null)); 548 } 549 return l; 550 } 551 552 553 554 /** 555 * Creates an ASN.1 octet string suitable for use as the value of this 556 * extended request. 557 * 558 * @param userDN The DN of the user to whom the 559 * password reset token should be 560 * generated. 561 * @param messageSubject The text (if any) that should be used 562 * as the message subject if the delivery 563 * mechanism accepts a subject. This may 564 * be {@code null} if no subject is 565 * required or a subject should be 566 * automatically generated. 567 * @param fullTextBeforeToken The text (if any) that should appear 568 * before the generated password reset 569 * token in the message delivered to the 570 * user via a delivery mechanism that 571 * does not impose significant 572 * constraints on message size. This may 573 * be {@code null} if no text is required 574 * before the token. 575 * @param fullTextAfterToken The text (if any) that should appear 576 * after the generated password reset 577 * token in the message delivered to the 578 * user via a delivery mechanism that 579 * does not impose significant 580 * constraints on message size. This may 581 * be {@code null} if no text is required 582 * after the token. 583 * @param compactTextBeforeToken The text (if any) that should appear 584 * before the generated password reset 585 * token in the message delivered to the 586 * user via a delivery mechanism that 587 * imposes significant constraints on 588 * message size. This may be 589 * {@code null} if no text is required 590 * before the token. 591 * @param compactTextAfterToken The text (if any) that should appear 592 * after the generated password reset 593 * token in the message delivered to the 594 * user via a delivery mechanism that 595 * imposes significant constraints on 596 * message size. This may be 597 * {@code null} if no text is required 598 * after the token. 599 * @param preferredDeliveryMechanisms An optional ordered list of preferred 600 * delivery mechanisms that should be 601 * used to deliver the token to the user. 602 * It may be {@code null} or empty to 603 * allow the server to select an 604 * appropriate delivery mechanism. If it 605 * is non-{@code null} and non-empty, 606 * then only the listed mechanisms will 607 * be considered for use, even if the 608 * server supports alternate mechanisms 609 * not included in this list. Each 610 * {@code ObjectPair} item must have 611 * a non-{@code null} value for the first 612 * element, which is the name of the 613 * target delivery mechanism. It may 614 * optionally have a non-{@code null} 615 * value for the second element, which is 616 * a recipient ID to use for that 617 * mechanism (e.g., the target mobile 618 * phone number for SMS delivery, an 619 * email address for email delivery, 620 * etc.). If no recipient ID is provided 621 * for a mechanism, then the server will 622 * attempt to select a value for the 623 * user. 624 * 625 * @return The ASN.1 octet string containing the encoded request value. 626 */ 627 private static ASN1OctetString encodeValue(final String userDN, 628 final String messageSubject, final String fullTextBeforeToken, 629 final String fullTextAfterToken, final String compactTextBeforeToken, 630 final String compactTextAfterToken, 631 final List<ObjectPair<String,String>> preferredDeliveryMechanisms) 632 { 633 Validator.ensureNotNull(userDN); 634 635 final ArrayList<ASN1Element> elements = new ArrayList<>(7); 636 elements.add(new ASN1OctetString(userDN)); 637 638 if (messageSubject != null) 639 { 640 elements.add(new ASN1OctetString(MESSAGE_SUBJECT_BER_TYPE, 641 messageSubject)); 642 } 643 644 if (fullTextBeforeToken != null) 645 { 646 elements.add(new ASN1OctetString(FULL_TEXT_BEFORE_TOKEN_BER_TYPE, 647 fullTextBeforeToken)); 648 } 649 650 if (fullTextAfterToken != null) 651 { 652 elements.add(new ASN1OctetString(FULL_TEXT_AFTER_TOKEN_BER_TYPE, 653 fullTextAfterToken)); 654 } 655 656 if (compactTextBeforeToken != null) 657 { 658 elements.add(new ASN1OctetString(COMPACT_TEXT_BEFORE_TOKEN_BER_TYPE, 659 compactTextBeforeToken)); 660 } 661 662 if (compactTextAfterToken != null) 663 { 664 elements.add(new ASN1OctetString(COMPACT_TEXT_AFTER_TOKEN_BER_TYPE, 665 compactTextAfterToken)); 666 } 667 668 if ((preferredDeliveryMechanisms != null) && 669 (! preferredDeliveryMechanisms.isEmpty())) 670 { 671 final ArrayList<ASN1Element> pdmElements = 672 new ArrayList<>(preferredDeliveryMechanisms.size()); 673 for (final ObjectPair<String,String> p : preferredDeliveryMechanisms) 674 { 675 if (p.getSecond() == null) 676 { 677 pdmElements.add(new ASN1Sequence( 678 new ASN1OctetString(p.getFirst()))); 679 } 680 else 681 { 682 pdmElements.add(new ASN1Sequence( 683 new ASN1OctetString(p.getFirst()), 684 new ASN1OctetString(p.getSecond()))); 685 } 686 } 687 688 elements.add(new ASN1Sequence(PREFERRED_DELIVERY_MECHANISM_BER_TYPE, 689 pdmElements)); 690 } 691 692 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 693 } 694 695 696 697 /** 698 * Retrieves the DN of the user to whom the password reset token should be 699 * delivered. 700 * 701 * @return The DN of the user to whom the password reset token should be 702 * delivered. 703 */ 704 public String getUserDN() 705 { 706 return userDN; 707 } 708 709 710 711 /** 712 * Retrieves the text (if any) that should be used as the message subject for 713 * delivery mechanisms that can make use of a subject. 714 * 715 * @return The text that should be used as the message subject for delivery 716 * mechanisms that can make use of a subject, or {@code null} if no 717 * subject should be used, or if the delivery mechanism should 718 * attempt to automatically determine a subject. 719 */ 720 public String getMessageSubject() 721 { 722 return messageSubject; 723 } 724 725 726 727 /** 728 * Retrieves the text (if any) that should appear before the single-use token 729 * in the message delivered to the user via a mechanism that does not impose 730 * significant constraints on message size. 731 * 732 * @return The text that should appear before the single-use token in the 733 * message delivered to the user via a mechanism that does not impose 734 * significant constraints on message size, or {@code null} if there 735 * should not be any text before the token. 736 */ 737 public String getFullTextBeforeToken() 738 { 739 return fullTextBeforeToken; 740 } 741 742 743 744 /** 745 * Retrieves the text (if any) that should appear after the single-use token 746 * in the message delivered to the user via a mechanism that does not impose 747 * significant constraints on message size. 748 * 749 * @return The text that should appear after the single-use token in the 750 * message delivered to the user via a mechanism that does not impose 751 * significant constraints on message size, or {@code null} if there 752 * should not be any text after the token. 753 */ 754 public String getFullTextAfterToken() 755 { 756 return fullTextAfterToken; 757 } 758 759 760 761 /** 762 * Retrieves the text (if any) that should appear before the single-use token 763 * in the message delivered to the user via a mechanism that imposes 764 * significant constraints on message size. 765 * 766 * @return The text that should appear before the single-use token in the 767 * message delivered to the user via a mechanism that imposes 768 * significant constraints on message size, or {@code null} if there 769 * should not be any text before the token. 770 */ 771 public String getCompactTextBeforeToken() 772 { 773 return compactTextBeforeToken; 774 } 775 776 777 778 /** 779 * Retrieves the text (if any) that should appear after the single-use token 780 * in the message delivered to the user via a mechanism that imposes 781 * significant constraints on message size. 782 * 783 * @return The text that should appear after the single-use token in the 784 * message delivered to the user via a mechanism that imposes 785 * significant constraints on message size, or {@code null} if there 786 * should not be any text after the token. 787 */ 788 public String getCompactTextAfterToken() 789 { 790 return compactTextAfterToken; 791 } 792 793 794 795 /** 796 * Retrieves an ordered list of the preferred delivery mechanisms that should 797 * be used to provide the password reset token to the user, optionally paired 798 * with a mechanism-specific recipient ID (e.g., a mobile phone number for SMS 799 * delivery, or an email address for email delivery) that can be used in the 800 * delivery. If this list is non-empty, then the server will use the first 801 * mechanism in the list that the server supports and is available for the 802 * target user, and the server will only consider mechanisms in the provided 803 * list even if the server supports alternate mechanisms that are not 804 * included. If this list is empty, then the server will attempt to select an 805 * appropriate delivery mechanism for the user. 806 * 807 * @return An ordered list of the preferred delivery mechanisms for the 808 * password reset token, or an empty list if none were provided. 809 */ 810 public List<ObjectPair<String,String>> getPreferredDeliveryMechanisms() 811 { 812 return preferredDeliveryMechanisms; 813 } 814 815 816 817 /** 818 * {@inheritDoc} 819 */ 820 @Override() 821 public DeliverPasswordResetTokenExtendedResult process( 822 final LDAPConnection connection, final int depth) 823 throws LDAPException 824 { 825 final ExtendedResult extendedResponse = super.process(connection, depth); 826 return new DeliverPasswordResetTokenExtendedResult(extendedResponse); 827 } 828 829 830 831 /** 832 * {@inheritDoc}. 833 */ 834 @Override() 835 public DeliverPasswordResetTokenExtendedRequest duplicate() 836 { 837 return duplicate(getControls()); 838 } 839 840 841 842 /** 843 * {@inheritDoc}. 844 */ 845 @Override() 846 public DeliverPasswordResetTokenExtendedRequest duplicate( 847 final Control[] controls) 848 { 849 final DeliverPasswordResetTokenExtendedRequest r = 850 new DeliverPasswordResetTokenExtendedRequest(userDN, 851 messageSubject, fullTextBeforeToken, fullTextAfterToken, 852 compactTextBeforeToken, compactTextAfterToken, 853 preferredDeliveryMechanisms, controls); 854 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 855 return r; 856 } 857 858 859 860 /** 861 * {@inheritDoc} 862 */ 863 @Override() 864 public String getExtendedRequestName() 865 { 866 return INFO_EXTENDED_REQUEST_NAME_DELIVER_PW_RESET_TOKEN.get(); 867 } 868 869 870 871 /** 872 * {@inheritDoc} 873 */ 874 @Override() 875 public void toString(final StringBuilder buffer) 876 { 877 buffer.append("DeliverPasswordResetTokenExtendedRequest(userDN='"); 878 buffer.append(userDN); 879 buffer.append('\''); 880 881 if (messageSubject != null) 882 { 883 buffer.append(", messageSubject='"); 884 buffer.append(messageSubject); 885 buffer.append('\''); 886 } 887 888 if (fullTextBeforeToken != null) 889 { 890 buffer.append(", fullTextBeforeToken='"); 891 buffer.append(fullTextBeforeToken); 892 buffer.append('\''); 893 } 894 895 if (fullTextAfterToken != null) 896 { 897 buffer.append(", fullTextAfterToken='"); 898 buffer.append(fullTextAfterToken); 899 buffer.append('\''); 900 } 901 902 if (compactTextBeforeToken != null) 903 { 904 buffer.append(", compactTextBeforeToken='"); 905 buffer.append(compactTextBeforeToken); 906 buffer.append('\''); 907 } 908 909 if (compactTextAfterToken != null) 910 { 911 buffer.append(", compactTextAfterToken='"); 912 buffer.append(compactTextAfterToken); 913 buffer.append('\''); 914 } 915 916 if (preferredDeliveryMechanisms != null) 917 { 918 buffer.append(", preferredDeliveryMechanisms={"); 919 920 final Iterator<ObjectPair<String,String>> iterator = 921 preferredDeliveryMechanisms.iterator(); 922 while (iterator.hasNext()) 923 { 924 final ObjectPair<String,String> p = iterator.next(); 925 buffer.append('\''); 926 buffer.append(p.getFirst()); 927 if (p.getSecond() != null) 928 { 929 buffer.append('('); 930 buffer.append(p.getSecond()); 931 buffer.append(')'); 932 } 933 buffer.append('\''); 934 if (iterator.hasNext()) 935 { 936 buffer.append(','); 937 } 938 } 939 } 940 941 final Control[] controls = getControls(); 942 if (controls.length > 0) 943 { 944 buffer.append(", controls={"); 945 for (int i=0; i < controls.length; i++) 946 { 947 if (i > 0) 948 { 949 buffer.append(", "); 950 } 951 952 buffer.append(controls[i]); 953 } 954 buffer.append('}'); 955 } 956 957 buffer.append(')'); 958 } 959}