001/* 002 * Copyright 2013-2024 Ping Identity Corporation 003 * All Rights Reserved. 004 */ 005/* 006 * Copyright 2013-2024 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) 2013-2024 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.LinkedHashSet; 044import java.util.List; 045 046import com.unboundid.asn1.ASN1Element; 047import com.unboundid.asn1.ASN1OctetString; 048import com.unboundid.asn1.ASN1Sequence; 049import com.unboundid.ldap.sdk.Control; 050import com.unboundid.ldap.sdk.ExtendedRequest; 051import com.unboundid.ldap.sdk.ExtendedResult; 052import com.unboundid.ldap.sdk.LDAPConnection; 053import com.unboundid.ldap.sdk.LDAPException; 054import com.unboundid.ldap.sdk.ResultCode; 055import com.unboundid.util.Debug; 056import com.unboundid.util.NotMutable; 057import com.unboundid.util.NotNull; 058import com.unboundid.util.Nullable; 059import com.unboundid.util.ObjectPair; 060import com.unboundid.util.StaticUtils; 061import com.unboundid.util.ThreadSafety; 062import com.unboundid.util.ThreadSafetyLevel; 063 064import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*; 065 066 067 068/** 069 * This class provides an implementation of an extended request that may be used 070 * to request that the Directory Server deliver a one-time password to an end 071 * user that they may use to authenticate via an 072 * {@link com.unboundid.ldap.sdk.unboundidds.UnboundIDDeliveredOTPBindRequest}. 073 * <BR> 074 * <BLOCKQUOTE> 075 * <B>NOTE:</B> This class, and other classes within the 076 * {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only 077 * supported for use against Ping Identity, UnboundID, and 078 * Nokia/Alcatel-Lucent 8661 server products. These classes provide support 079 * for proprietary functionality or for external specifications that are not 080 * considered stable or mature enough to be guaranteed to work in an 081 * interoperable way with other types of LDAP servers. 082 * </BLOCKQUOTE> 083 * <BR> 084 * Notes on the recommended use of this extended request: 085 * <UL> 086 * <LI>Whenever possible, the user's static password should be provided. 087 * However, the server will allow the static password to be omitted if the 088 * authentication ID included in the request matches the authorization 089 * identity of the extended operation (either because that user is already 090 * authenticated on the connection, or because the request includes a 091 * proxied authorization or intermediate client control specifying that 092 * identity). In that case, the operation will be able to act as a 093 * "step-up" mechanism, providing further proof of the identity of an 094 * already-authenticated client rather than performing the complete 095 * authentication process.</LI> 096 * <LI>The request offers two mechanisms for indicating which delivery 097 * mechanism(s) should be considered: an option to specify just the 098 * delivery mechanism names, and an option to specify the names along with 099 * recipient IDs. At most one of these elements must be present in the 100 * request. If neither is present, the server will attempt to determine 101 * which delivery mechanisms and recipient IDs should be used. If the 102 * set of preferred delivery mechanisms includes multiple items, the 103 * server will attempt them in the order provided until it is able to 104 * successfully deliver the message. The server will not attempt to 105 * use any other delivery mechanisms that may be configured if the request 106 * includes a list of preferred delivery mechanisms.</LI> 107 * <LI>Although the message elements (message subject, and full and compact 108 * text before and after the OTP) are optional, it is recommended that 109 * they be supplied by the client. The server will provide a generic 110 * message if no message elements are included in the request.</LI> 111 * </UL> 112 * <BR><BR> 113 * The OID for this extended request is 1.3.6.1.4.1.30221.2.6.24. It must have 114 * a value, and that value should have the following encoding: 115 * <BR><BR> 116 * <PRE> 117 * DeliverOTPRequest ::= SEQUENCE { 118 * authenticationID [0] OCTET STRING, 119 * staticPassword [1] OCTET STRING OPTIONAL, 120 * preferredMechNames [2] SEQUENCE OF OCTET STRING OPTIONAL, 121 * preferredMechNamesAndIDs [3] SEQUENCE OF SEQUENCE, 122 * mechanismName OCTET STRING, 123 * recipientID OCTET STRING OPTIONAL } OPTIONAL, 124 * messageSubject [4] OCTET STRING OPTIONAL, 125 * fullTextBeforeOTP [5] OCTET STRING OPTIONAL, 126 * fullTextAfterOTP [6] OCTET STRING OPTIONAL, 127 * compactTextBeforeOTP [7] OCTET STRING OPTIONAL, 128 * compactTextAfterOTP [8] OCTET STRING OPTIONAL, 129 * ... } 130 * </PRE> 131 * 132 * @see com.unboundid.ldap.sdk.unboundidds.UnboundIDDeliveredOTPBindRequest 133 * @see DeliverOneTimePasswordExtendedResult 134 */ 135@NotMutable() 136@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE) 137public final class DeliverOneTimePasswordExtendedRequest 138 extends ExtendedRequest 139{ 140 /** 141 * The OID (1.3.6.1.4.1.30221.2.6.24) for the deliver one-time password 142 * extended request. 143 */ 144 @NotNull public static final String DELIVER_OTP_REQUEST_OID = 145 "1.3.6.1.4.1.30221.2.6.24"; 146 147 148 149 /** 150 * The BER type for the authentication ID element. 151 */ 152 private static final byte TYPE_AUTHN_ID = (byte) 0x80; 153 154 155 156 /** 157 * The BER type for the static password element. 158 */ 159 private static final byte TYPE_PASSWORD = (byte) 0x81; 160 161 162 163 /** 164 * The BER type for the preferred delivery mechanism names element. 165 */ 166 private static final byte TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES = 167 (byte) 0xA2; 168 169 170 171 /** 172 * The BER type for the preferred delivery mechanism names and IDs element. 173 */ 174 private static final byte TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES_AND_IDS = 175 (byte) 0xA3; 176 177 178 179 /** 180 * The BER type for the "message subject" element of the value sequence. 181 */ 182 private static final byte MESSAGE_SUBJECT_BER_TYPE = (byte) 0x84; 183 184 185 186 /** 187 * The BER type for the "full text before OTP" element of the value 188 * sequence. 189 */ 190 private static final byte FULL_TEXT_BEFORE_OTP_BER_TYPE = (byte) 0x85; 191 192 193 194 /** 195 * The BER type for the "full text after OTP" element of the value 196 * sequence. 197 */ 198 private static final byte FULL_TEXT_AFTER_OTP_BER_TYPE = (byte) 0x86; 199 200 201 202 /** 203 * The BER type for the "compact text before OTP" element of the value 204 * sequence. 205 */ 206 private static final byte COMPACT_TEXT_BEFORE_OTP_BER_TYPE = (byte) 0x87; 207 208 209 210 /** 211 * The BER type for the "compact text after OTP" element of the value 212 * sequence. 213 */ 214 private static final byte COMPACT_TEXT_AFTER_OTP_BER_TYPE = (byte) 0x88; 215 216 217 218 /** 219 * The serial version UID for this serializable class. 220 */ 221 private static final long serialVersionUID = 1259250969726758847L; 222 223 224 225 // The static password to include in the request. 226 @Nullable private final ASN1OctetString staticPassword; 227 228 // The list of preferred delivery mechanisms to include in the request. 229 @NotNull private final List<ObjectPair<String, String>> 230 preferredDeliveryMechanisms; 231 232 // The authentication ID to include in the request. 233 @NotNull private final String authenticationID; 234 235 // The text to include after the OTP in a compact message. 236 @Nullable private final String compactTextAfterOTP; 237 238 // The text to include before the OTP in a compact message. 239 @Nullable private final String compactTextBeforeOTP; 240 241 // The text to include after the OTP in a message without size constraints. 242 @Nullable private final String fullTextAfterOTP; 243 244 // The text to include before the OTP in a message without size constraints. 245 @Nullable private final String fullTextBeforeOTP; 246 247 // The text to use as the message subject. 248 @Nullable private final String messageSubject; 249 250 251 252 /** 253 * Creates a new deliver one-time password extended request with the provided 254 * information. 255 * 256 * @param authenticationID The authentication ID for the user to 257 * whom the one-time password should be 258 * delivered. It must not be 259 * {@code null}. 260 * @param staticPassword The static password for the user to 261 * whom the one-time password should be 262 * delivered. It may be {@code null} if 263 * this request is intended to be used 264 * to step-up an existing authentication 265 * rather than perform a new 266 * authentication (in which case the 267 * provided authentication ID must match 268 * the operation's authorization ID). 269 * @param preferredDeliveryMechanisms The names of the preferred delivery 270 * mechanisms for the one-time password. 271 * It may be {@code null} or empty if the 272 * server should select an appropriate 273 * delivery mechanism. If it is 274 * non-{@code null} and non-empty, then 275 * only the listed mechanisms will be 276 * considered for use, even if the server 277 * supports alternate mechanisms not 278 * included in this list. 279 */ 280 public DeliverOneTimePasswordExtendedRequest( 281 @NotNull final String authenticationID, 282 @Nullable final String staticPassword, 283 @Nullable final String... preferredDeliveryMechanisms) 284 { 285 this(authenticationID, staticPassword, 286 StaticUtils.toList(preferredDeliveryMechanisms)); 287 } 288 289 290 291 /** 292 * Creates a new deliver one-time password extended request with the provided 293 * information. 294 * 295 * @param authenticationID The authentication ID for the user to 296 * whom the one-time password should be 297 * delivered. It must not be 298 * {@code null}. 299 * @param staticPassword The static password for the user to 300 * whom the one-time password should be 301 * delivered. It may be {@code null} if 302 * this request is intended to be used 303 * to step-up an existing authentication 304 * rather than perform a new 305 * authentication (in which case the 306 * provided authentication ID must match 307 * the operation's authorization ID). 308 * @param preferredDeliveryMechanisms The names of the preferred delivery 309 * mechanisms for the one-time password. 310 * It may be {@code null} or empty if the 311 * server should select an appropriate 312 * delivery mechanism. If it is 313 * non-{@code null} and non-empty, then 314 * only the listed mechanisms will be 315 * considered for use, even if the server 316 * supports alternate mechanisms not 317 * included in this list. 318 */ 319 public DeliverOneTimePasswordExtendedRequest( 320 @NotNull final String authenticationID, 321 @Nullable final byte[] staticPassword, 322 @Nullable final String... preferredDeliveryMechanisms) 323 { 324 this(authenticationID, staticPassword, 325 StaticUtils.toList(preferredDeliveryMechanisms)); 326 } 327 328 329 330 /** 331 * Creates a new deliver one-time password extended request with the provided 332 * information. 333 * 334 * @param authenticationID The authentication ID for the user to 335 * whom the one-time password should be 336 * delivered. It must not be 337 * {@code null}. 338 * @param staticPassword The static password for the user to 339 * whom the one-time password should be 340 * delivered. It may be {@code null} if 341 * this request is intended to be used 342 * to step-up an existing authentication 343 * rather than perform a new 344 * authentication (in which case the 345 * provided authentication ID must match 346 * the operation's authorization ID). 347 * @param preferredDeliveryMechanisms The names of the preferred delivery 348 * mechanisms for the one-time password. 349 * It may be {@code null} or empty if the 350 * server should select an appropriate 351 * delivery mechanism. If it is 352 * non-{@code null} and non-empty, then 353 * only the listed mechanisms will be 354 * considered for use, even if the server 355 * supports alternate mechanisms not 356 * included in this list. 357 * @param controls The set of controls to include in the 358 * request. It may be {@code null} or 359 * empty if no controls should be 360 * included. 361 */ 362 public DeliverOneTimePasswordExtendedRequest( 363 @NotNull final String authenticationID, 364 @Nullable final String staticPassword, 365 @Nullable final List<String> preferredDeliveryMechanisms, 366 @Nullable final Control... controls) 367 { 368 this(authenticationID, 369 (staticPassword == null 370 ? null 371 : new ASN1OctetString(TYPE_PASSWORD, staticPassword)), 372 preferredDeliveryMechanisms, controls); 373 } 374 375 376 377 /** 378 * Creates a new deliver one-time password extended request with the provided 379 * information. 380 * 381 * @param authenticationID The authentication ID for the user to 382 * whom the one-time password should be 383 * delivered. It must not be 384 * {@code null}. 385 * @param staticPassword The static password for the user to 386 * whom the one-time password should be 387 * delivered. It may be {@code null} if 388 * this request is intended to be used 389 * to step-up an existing authentication 390 * rather than perform a new 391 * authentication (in which case the 392 * provided authentication ID must match 393 * the operation's authorization ID). 394 * @param preferredDeliveryMechanisms The names of the preferred delivery 395 * mechanisms for the one-time password. 396 * It may be {@code null} or empty if the 397 * server should select an appropriate 398 * delivery mechanism. If it is 399 * non-{@code null} and non-empty, then 400 * only the listed mechanisms will be 401 * considered for use, even if the server 402 * supports alternate mechanisms not 403 * included in this list. 404 * @param controls The set of controls to include in the 405 * request. It may be {@code null} or 406 * empty if no controls should be 407 * included. 408 */ 409 public DeliverOneTimePasswordExtendedRequest( 410 @NotNull final String authenticationID, 411 @Nullable final byte[] staticPassword, 412 @Nullable final List<String> preferredDeliveryMechanisms, 413 @Nullable final Control... controls) 414 { 415 this(authenticationID, 416 (staticPassword == null 417 ? null 418 : new ASN1OctetString(TYPE_PASSWORD, staticPassword)), 419 preferredDeliveryMechanisms, controls); 420 } 421 422 423 424 /** 425 * Creates a new deliver one-time password extended request with the provided 426 * information. 427 * 428 * @param authenticationID The authentication ID for the user to 429 * whom the one-time password should be 430 * delivered. It must not be 431 * {@code null}. 432 * @param staticPassword The static password for the user to 433 * whom the one-time password should be 434 * delivered. It may be {@code null} if 435 * this request is intended to be used 436 * to step-up an existing authentication 437 * rather than perform a new 438 * authentication (in which case the 439 * provided authentication ID must match 440 * the operation's authorization ID). 441 * @param preferredDeliveryMechanisms The names of the preferred delivery 442 * mechanisms for the one-time password. 443 * It may be {@code null} or empty if the 444 * server should select an appropriate 445 * delivery mechanism. If it is 446 * non-{@code null} and non-empty, then 447 * only the listed mechanisms will be 448 * considered for use, even if the server 449 * supports alternate mechanisms not 450 * included in this list. 451 * @param controls The set of controls to include in the 452 * request. It may be {@code null} or 453 * empty if no controls should be 454 * included. 455 */ 456 private DeliverOneTimePasswordExtendedRequest( 457 @NotNull final String authenticationID, 458 @Nullable final ASN1OctetString staticPassword, 459 @Nullable final List<String> preferredDeliveryMechanisms, 460 @Nullable final Control... controls) 461 { 462 super(DELIVER_OTP_REQUEST_OID, 463 encodeValue(authenticationID, staticPassword, 464 preferredDeliveryMechanisms), 465 controls); 466 467 this.authenticationID = authenticationID; 468 this.staticPassword = staticPassword; 469 470 if ((preferredDeliveryMechanisms == null) || 471 preferredDeliveryMechanisms.isEmpty()) 472 { 473 this.preferredDeliveryMechanisms = Collections.emptyList(); 474 } 475 else 476 { 477 final ArrayList<ObjectPair<String,String>> l = 478 new ArrayList<>(preferredDeliveryMechanisms.size()); 479 for (final String s : preferredDeliveryMechanisms) 480 { 481 l.add(new ObjectPair<String,String>(s, null)); 482 } 483 this.preferredDeliveryMechanisms = Collections.unmodifiableList(l); 484 } 485 486 messageSubject = null; 487 fullTextBeforeOTP = null; 488 fullTextAfterOTP = null; 489 compactTextBeforeOTP = null; 490 compactTextAfterOTP = null; 491 } 492 493 494 495 /** 496 * Creates a new deliver one-time password extended request with the provided 497 * information. 498 * 499 * @param authenticationID The authentication ID for the user to 500 * whom the one-time password should be 501 * delivered. It must not be 502 * {@code null}. 503 * @param staticPassword The static password for the user to 504 * whom the one-time password should be 505 * delivered. It may be {@code null} if 506 * this request is intended to be used 507 * to step-up an existing authentication 508 * rather than perform a new 509 * authentication (in which case the 510 * provided authentication ID must match 511 * the operation's authorization ID). 512 * @param messageSubject The text (if any) that should be used 513 * as the message subject if the delivery 514 * mechanism accepts a subject. This may 515 * be {@code null} if no subject is 516 * required or a subject should be 517 * automatically generated. 518 * @param fullTextBeforeOTP The text (if any) that should appear 519 * before the generated one-time password 520 * in the message delivered to the user 521 * via a delivery mechanism that does not 522 * impose significant constraints on 523 * message size. This may be 524 * {@code null} if no text is required 525 * before the one-time password. 526 * @param fullTextAfterOTP The text (if any) that should appear 527 * after the one-time password in the 528 * message delivered to the user via a 529 * delivery mechanism that does not 530 * impose significant constraints on 531 * message size. This may be 532 * {@code null} if no text is required 533 * after the one-time password. 534 * @param compactTextBeforeOTP The text (if any) that should appear 535 * before the generated one-time password 536 * in the message delivered to the user 537 * via a delivery mechanism that imposes 538 * significant constraints on message 539 * size. This may be {@code null} if no 540 * text is required before the one-time 541 * password. 542 * @param compactTextAfterOTP The text (if any) that should appear 543 * after the generated one-time password 544 * in the message delivered to the user 545 * via a delivery mechanism that imposes 546 * significant constraints on message 547 * size. This may be {@code null} if no 548 * text is required after the one-time 549 * password. 550 * @param preferredDeliveryMechanisms An optional ordered list of preferred 551 * delivery mechanisms that should be 552 * used to deliver the one-time password 553 * to the user. It may be {@code null} 554 * or empty to allow the server to select 555 * an appropriate delivery mechanism. If 556 * it is non-{@code null} and non-empty, 557 * then only the listed mechanisms will 558 * be considered for use, even if the 559 * server supports alternate mechanisms 560 * not included in this list. Each 561 * {@code ObjectPair} item must have 562 * a non-{@code null} value for the first 563 * element, which is the name of the 564 * target delivery mechanism. It may 565 * optionally have a non-{@code null} 566 * value for the second element, which is 567 * a recipient ID to use for that 568 * mechanism (e.g., the target mobile 569 * phone number for SMS delivery, an 570 * email address for email delivery, 571 * etc.). If no recipient ID is provided 572 * for a mechanism, then the server will 573 * attempt to select a value for the 574 * user. 575 * @param controls The set of controls to include in the 576 * request. It may be {@code null} or 577 * empty if no controls should be 578 * included. 579 */ 580 public DeliverOneTimePasswordExtendedRequest( 581 @NotNull final String authenticationID, 582 @Nullable final String staticPassword, 583 @Nullable final String messageSubject, 584 @Nullable final String fullTextBeforeOTP, 585 @Nullable final String fullTextAfterOTP, 586 @Nullable final String compactTextBeforeOTP, 587 @Nullable final String compactTextAfterOTP, 588 @Nullable final List<ObjectPair<String,String>> 589 preferredDeliveryMechanisms, 590 @Nullable final Control... controls) 591 { 592 this(authenticationID, 593 (staticPassword == null 594 ? null 595 : new ASN1OctetString(TYPE_PASSWORD, staticPassword)), 596 messageSubject, fullTextBeforeOTP, fullTextAfterOTP, 597 compactTextBeforeOTP, compactTextAfterOTP, preferredDeliveryMechanisms, 598 controls); 599 } 600 601 602 603 /** 604 * Creates a new deliver one-time password extended request with the provided 605 * information. 606 * 607 * @param authenticationID The authentication ID for the user to 608 * whom the one-time password should be 609 * delivered. It must not be 610 * {@code null}. 611 * @param staticPassword The static password for the user to 612 * whom the one-time password should be 613 * delivered. It may be {@code null} if 614 * this request is intended to be used 615 * to step-up an existing authentication 616 * rather than perform a new 617 * authentication (in which case the 618 * provided authentication ID must match 619 * the operation's authorization ID). 620 * @param messageSubject The text (if any) that should be used 621 * as the message subject if the delivery 622 * mechanism accepts a subject. This may 623 * be {@code null} if no subject is 624 * required or a subject should be 625 * automatically generated. 626 * @param fullTextBeforeOTP The text (if any) that should appear 627 * before the generated one-time password 628 * in the message delivered to the user 629 * via a delivery mechanism that does not 630 * impose significant constraints on 631 * message size. This may be 632 * {@code null} if no text is required 633 * before the one-time password. 634 * @param fullTextAfterOTP The text (if any) that should appear 635 * after the one-time password in the 636 * message delivered to the user via a 637 * delivery mechanism that does not 638 * impose significant constraints on 639 * message size. This may be 640 * {@code null} if no text is required 641 * after the one-time password. 642 * @param compactTextBeforeOTP The text (if any) that should appear 643 * before the generated one-time password 644 * in the message delivered to the user 645 * via a delivery mechanism that imposes 646 * significant constraints on message 647 * size. This may be {@code null} if no 648 * text is required before the one-time 649 * password. 650 * @param compactTextAfterOTP The text (if any) that should appear 651 * after the generated one-time password 652 * in the message delivered to the user 653 * via a delivery mechanism that imposes 654 * significant constraints on message 655 * size. This may be {@code null} if no 656 * text is required after the one-time 657 * password. 658 * @param preferredDeliveryMechanisms An optional ordered list of preferred 659 * delivery mechanisms that should be 660 * used to deliver the one-time password 661 * to the user. It may be {@code null} 662 * or empty to allow the server to select 663 * an appropriate delivery mechanism. If 664 * it is non-{@code null} and non-empty, 665 * then only the listed mechanisms will 666 * be considered for use, even if the 667 * server supports alternate mechanisms 668 * not included in this list. Each 669 * {@code ObjectPair} item must have 670 * a non-{@code null} value for the first 671 * element, which is the name of the 672 * target delivery mechanism. It may 673 * optionally have a non-{@code null} 674 * value for the second element, which is 675 * a recipient ID to use for that 676 * mechanism (e.g., the target mobile 677 * phone number for SMS delivery, an 678 * email address for email delivery, 679 * etc.). If no recipient ID is provided 680 * for a mechanism, then the server will 681 * attempt to select a value for the 682 * user. 683 * @param controls The set of controls to include in the 684 * request. It may be {@code null} or 685 * empty if no controls should be 686 * included. 687 */ 688 public DeliverOneTimePasswordExtendedRequest( 689 @NotNull final String authenticationID, 690 @Nullable final byte[] staticPassword, 691 @Nullable final String messageSubject, 692 @Nullable final String fullTextBeforeOTP, 693 @Nullable final String fullTextAfterOTP, 694 @Nullable final String compactTextBeforeOTP, 695 @Nullable final String compactTextAfterOTP, 696 @Nullable final List<ObjectPair<String,String>> 697 preferredDeliveryMechanisms, 698 @Nullable final Control... controls) 699 { 700 this(authenticationID, 701 (staticPassword == null 702 ? null 703 : new ASN1OctetString(TYPE_PASSWORD, staticPassword)), 704 messageSubject, fullTextBeforeOTP, fullTextAfterOTP, 705 compactTextBeforeOTP, compactTextAfterOTP, preferredDeliveryMechanisms, 706 controls); 707 } 708 709 710 711 /** 712 * Creates a new deliver one-time password extended request with the provided 713 * information. 714 * 715 * @param authenticationID The authentication ID for the user to 716 * whom the one-time password should be 717 * delivered. It must not be 718 * {@code null}. 719 * @param staticPassword The static password for the user to 720 * whom the one-time password should be 721 * delivered. It may be {@code null} if 722 * this request is intended to be used 723 * to step-up an existing authentication 724 * rather than perform a new 725 * authentication (in which case the 726 * provided authentication ID must match 727 * the operation's authorization ID). 728 * @param messageSubject The text (if any) that should be used 729 * as the message subject if the delivery 730 * mechanism accepts a subject. This may 731 * be {@code null} if no subject is 732 * required or a subject should be 733 * automatically generated. 734 * @param fullTextBeforeOTP The text (if any) that should appear 735 * before the generated one-time password 736 * in the message delivered to the user 737 * via a delivery mechanism that does not 738 * impose significant constraints on 739 * message size. This may be 740 * {@code null} if no text is required 741 * before the one-time password. 742 * @param fullTextAfterOTP The text (if any) that should appear 743 * after the one-time password in the 744 * message delivered to the user via a 745 * delivery mechanism that does not 746 * impose significant constraints on 747 * message size. This may be 748 * {@code null} if no text is required 749 * after the one-time password. 750 * @param compactTextBeforeOTP The text (if any) that should appear 751 * before the generated one-time password 752 * in the message delivered to the user 753 * via a delivery mechanism that imposes 754 * significant constraints on message 755 * size. This may be {@code null} if no 756 * text is required before the one-time 757 * password. 758 * @param compactTextAfterOTP The text (if any) that should appear 759 * after the generated one-time password 760 * in the message delivered to the user 761 * via a delivery mechanism that imposes 762 * significant constraints on message 763 * size. This may be {@code null} if no 764 * text is required after the one-time 765 * password. 766 * @param preferredDeliveryMechanisms An optional ordered list of preferred 767 * delivery mechanisms that should be 768 * used to deliver the one-time password 769 * to the user. It may be {@code null} 770 * or empty to allow the server to select 771 * an appropriate delivery mechanism. If 772 * it is non-{@code null} and non-empty, 773 * then only the listed mechanisms will 774 * be considered for use, even if the 775 * server supports alternate mechanisms 776 * not included in this list. Each 777 * {@code ObjectPair} item must have 778 * a non-{@code null} value for the first 779 * element, which is the name of the 780 * target delivery mechanism. It may 781 * optionally have a non-{@code null} 782 * value for the second element, which is 783 * a recipient ID to use for that 784 * mechanism (e.g., the target mobile 785 * phone number for SMS delivery, an 786 * email address for email delivery, 787 * etc.). If no recipient ID is provided 788 * for a mechanism, then the server will 789 * attempt to select a value for the 790 * user. 791 * @param controls The set of controls to include in the 792 * request. It may be {@code null} or 793 * empty if no controls should be 794 * included. 795 */ 796 private DeliverOneTimePasswordExtendedRequest( 797 @NotNull final String authenticationID, 798 @Nullable final ASN1OctetString staticPassword, 799 @Nullable final String messageSubject, 800 @Nullable final String fullTextBeforeOTP, 801 @Nullable final String fullTextAfterOTP, 802 @Nullable final String compactTextBeforeOTP, 803 @Nullable final String compactTextAfterOTP, 804 @Nullable final List<ObjectPair<String,String>> 805 preferredDeliveryMechanisms, 806 @Nullable final Control... controls) 807 { 808 super(DELIVER_OTP_REQUEST_OID, 809 encodeValue(authenticationID, staticPassword, messageSubject, 810 fullTextBeforeOTP, fullTextAfterOTP, compactTextBeforeOTP, 811 compactTextAfterOTP, preferredDeliveryMechanisms), 812 controls); 813 814 this.authenticationID = authenticationID; 815 this.staticPassword = staticPassword; 816 this.messageSubject = messageSubject; 817 this.fullTextBeforeOTP = fullTextBeforeOTP; 818 this.fullTextAfterOTP = fullTextAfterOTP; 819 this.compactTextBeforeOTP = compactTextBeforeOTP; 820 this.compactTextAfterOTP = compactTextAfterOTP; 821 822 if ((preferredDeliveryMechanisms == null) || 823 preferredDeliveryMechanisms.isEmpty()) 824 { 825 this.preferredDeliveryMechanisms = Collections.emptyList(); 826 } 827 else 828 { 829 this.preferredDeliveryMechanisms = 830 Collections.unmodifiableList(preferredDeliveryMechanisms); 831 } 832 } 833 834 835 836 /** 837 * Creates a new deliver one-time password extended request from the 838 * information contained in the provided generic extended request. 839 * 840 * @param request The generic extended request to be decoded as a deliver 841 * one-time password extended request. 842 * 843 * @throws LDAPException If a problem is encountered while attempting to 844 * decode the provided generic extended request as a 845 * deliver one-time password extended request. 846 */ 847 public DeliverOneTimePasswordExtendedRequest( 848 @NotNull final ExtendedRequest request) 849 throws LDAPException 850 { 851 super(request); 852 853 // The request must have a value. 854 final ASN1OctetString value = request.getValue(); 855 if (value == null) 856 { 857 throw new LDAPException(ResultCode.DECODING_ERROR, 858 ERR_DELIVER_OTP_REQ_NO_VALUE.get()); 859 } 860 861 862 // Parse the value. 863 ASN1OctetString password = null; 864 String authnID = null; 865 String subject = null; 866 String fullBefore = null; 867 String fullAfter = null; 868 String compactBefore = null; 869 String compactAfter = null; 870 final ArrayList<ObjectPair<String,String>> pdmList = new ArrayList<>(10); 871 try 872 { 873 for (final ASN1Element e : 874 ASN1Sequence.decodeAsSequence(value.getValue()).elements()) 875 { 876 switch (e.getType()) 877 { 878 case TYPE_AUTHN_ID: 879 authnID = ASN1OctetString.decodeAsOctetString(e).stringValue(); 880 break; 881 882 case TYPE_PASSWORD: 883 password = ASN1OctetString.decodeAsOctetString(e); 884 break; 885 886 case TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES: 887 final ASN1Element[] mechNameElements = 888 ASN1Sequence.decodeAsSequence(e).elements(); 889 for (final ASN1Element mechElement : mechNameElements) 890 { 891 pdmList.add(new ObjectPair<String,String>( 892 ASN1OctetString.decodeAsOctetString(mechElement). 893 stringValue(), 894 null)); 895 } 896 break; 897 898 case TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES_AND_IDS: 899 final ASN1Element[] pdmElements = 900 ASN1Sequence.decodeAsSequence(e).elements(); 901 for (final ASN1Element pdmElement : pdmElements) 902 { 903 final ASN1Element[] mechElements = 904 ASN1Sequence.decodeAsSequence(pdmElement).elements(); 905 final String mech = ASN1OctetString.decodeAsOctetString( 906 mechElements[0]).stringValue(); 907 908 final String recipientID; 909 if (mechElements.length > 1) 910 { 911 recipientID = ASN1OctetString.decodeAsOctetString( 912 mechElements[1]).stringValue(); 913 } 914 else 915 { 916 recipientID = null; 917 } 918 919 pdmList.add(new ObjectPair<>(mech, recipientID)); 920 } 921 break; 922 923 case MESSAGE_SUBJECT_BER_TYPE: 924 subject = 925 ASN1OctetString.decodeAsOctetString(e).stringValue(); 926 break; 927 928 case FULL_TEXT_BEFORE_OTP_BER_TYPE: 929 fullBefore = 930 ASN1OctetString.decodeAsOctetString(e).stringValue(); 931 break; 932 933 case FULL_TEXT_AFTER_OTP_BER_TYPE: 934 fullAfter = 935 ASN1OctetString.decodeAsOctetString(e).stringValue(); 936 break; 937 938 case COMPACT_TEXT_BEFORE_OTP_BER_TYPE: 939 compactBefore = 940 ASN1OctetString.decodeAsOctetString(e).stringValue(); 941 break; 942 943 case COMPACT_TEXT_AFTER_OTP_BER_TYPE: 944 compactAfter = 945 ASN1OctetString.decodeAsOctetString(e).stringValue(); 946 break; 947 948 default: 949 throw new LDAPException(ResultCode.DECODING_ERROR, 950 ERR_DELIVER_OTP_REQ_UNEXPECTED_ELEMENT_TYPE.get( 951 StaticUtils.toHex(e.getType()))); 952 953 } 954 } 955 } 956 catch (final LDAPException le) 957 { 958 Debug.debugException(le); 959 throw le; 960 } 961 catch (final Exception e) 962 { 963 Debug.debugException(e); 964 throw new LDAPException(ResultCode.DECODING_ERROR, 965 ERR_DELIVER_OTP_REQ_ERROR_PARSING_VALUE.get( 966 StaticUtils.getExceptionMessage(e)), 967 e); 968 } 969 970 if (authnID == null) 971 { 972 throw new LDAPException(ResultCode.DECODING_ERROR, 973 ERR_DELIVER_OTP_REQ_NO_AUTHN_ID.get()); 974 } 975 else 976 { 977 authenticationID = authnID; 978 } 979 980 staticPassword = password; 981 messageSubject = subject; 982 fullTextBeforeOTP = fullBefore; 983 fullTextAfterOTP = fullAfter; 984 compactTextBeforeOTP = compactBefore; 985 compactTextAfterOTP = compactAfter; 986 987 if ((pdmList == null) || pdmList.isEmpty()) 988 { 989 preferredDeliveryMechanisms = Collections.emptyList(); 990 } 991 else 992 { 993 preferredDeliveryMechanisms = Collections.unmodifiableList(pdmList); 994 } 995 } 996 997 998 999 /** 1000 * Encodes the provided information into an ASN.1 octet string suitable for 1001 * use as the value of this extended request. 1002 * 1003 * @param authenticationID The authentication ID for the user to 1004 * whom the one-time password should be 1005 * delivered. It must not be 1006 * {@code null}. 1007 * @param staticPassword The static password for the user to 1008 * whom the one-time password should be 1009 * delivered. 1010 * @param preferredDeliveryMechanisms The names of the preferred delivery 1011 * mechanisms for the one-time password. 1012 * It may be {@code null} or empty if the 1013 * server should select an appropriate 1014 * delivery mechanism. If it is 1015 * non-{@code null} and non-empty, then 1016 * only the listed mechanisms will be 1017 * considered for use, even if the server 1018 * supports alternate mechanisms not 1019 * included in this list. 1020 * 1021 * @return An ASN.1 octet string suitable for use as the value of this 1022 * extended request. 1023 */ 1024 @NotNull() 1025 private static ASN1OctetString encodeValue( 1026 @NotNull final String authenticationID, 1027 @Nullable final ASN1OctetString staticPassword, 1028 @Nullable final List<String> preferredDeliveryMechanisms) 1029 { 1030 final ArrayList<ASN1Element> elements = new ArrayList<>(3); 1031 1032 elements.add(new ASN1OctetString(TYPE_AUTHN_ID, authenticationID)); 1033 1034 if (staticPassword != null) 1035 { 1036 elements.add(staticPassword); 1037 } 1038 1039 if ((preferredDeliveryMechanisms != null) && 1040 (! preferredDeliveryMechanisms.isEmpty())) 1041 { 1042 final ArrayList<ASN1Element> dmElements = 1043 new ArrayList<>(preferredDeliveryMechanisms.size()); 1044 for (final String s : preferredDeliveryMechanisms) 1045 { 1046 dmElements.add(new ASN1OctetString(s)); 1047 } 1048 elements.add(new ASN1Sequence(TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES, 1049 dmElements)); 1050 } 1051 1052 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 1053 } 1054 1055 1056 1057 /** 1058 * Encodes the provided information into an ASN.1 octet string suitable for 1059 * use as the value of this extended request. 1060 * 1061 * @param authenticationID The authentication ID for the user to 1062 * whom the one-time password should be 1063 * delivered. It must not be 1064 * {@code null}. 1065 * @param staticPassword The static password for the user to 1066 * whom the one-time password should be 1067 * delivered. It may be {@code null} if 1068 * this request is intended to be used 1069 * to step-up an existing authentication 1070 * rather than perform a new 1071 * authentication (in which case the 1072 * provided authentication ID must match 1073 * the operation's authorization ID). 1074 * @param messageSubject The text (if any) that should be used 1075 * as the message subject if the delivery 1076 * mechanism accepts a subject. This may 1077 * be {@code null} if no subject is 1078 * required or a subject should be 1079 * automatically generated. 1080 * @param fullTextBeforeOTP The text (if any) that should appear 1081 * before the generated one-time password 1082 * in the message delivered to the user 1083 * via a delivery mechanism that does not 1084 * impose significant constraints on 1085 * message size. This may be 1086 * {@code null} if no text is required 1087 * before the one-time password. 1088 * @param fullTextAfterOTP The text (if any) that should appear 1089 * after the one-time password in the 1090 * message delivered to the user via a 1091 * delivery mechanism that does not 1092 * impose significant constraints on 1093 * message size. This may be 1094 * {@code null} if no text is required 1095 * after the one-time password. 1096 * @param compactTextBeforeOTP The text (if any) that should appear 1097 * before the generated one-time password 1098 * in the message delivered to the user 1099 * via a delivery mechanism that imposes 1100 * significant constraints on message 1101 * size. This may be {@code null} if no 1102 * text is required before the one-time 1103 * password. 1104 * @param compactTextAfterOTP The text (if any) that should appear 1105 * after the generated one-time password 1106 * in the message delivered to the user 1107 * via a delivery mechanism that imposes 1108 * significant constraints on message 1109 * size. This may be {@code null} if no 1110 * text is required after the one-time 1111 * password. 1112 * @param preferredDeliveryMechanisms An optional ordered list of preferred 1113 * delivery mechanisms that should be 1114 * used to deliver the one-time password 1115 * to the user. It may be {@code null} 1116 * or empty to allow the server to select 1117 * an appropriate delivery mechanism. If 1118 * it is non-{@code null} and non-empty, 1119 * then only the listed mechanisms will 1120 * be considered for use, even if the 1121 * server supports alternate mechanisms 1122 * not included in this list. Each 1123 * {@code ObjectPair} item must have 1124 * a non-{@code null} value for the first 1125 * element, which is the name of the 1126 * target delivery mechanism. It may 1127 * optionally have a non-{@code null} 1128 * value for the second element, which is 1129 * a recipient ID to use for that 1130 * mechanism (e.g., the target mobile 1131 * phone number for SMS delivery, an 1132 * email address for email delivery, 1133 * etc.). If no recipient ID is provided 1134 * for a mechanism, then the server will 1135 * attempt to select a value for the 1136 * user. 1137 * 1138 * @return An ASN.1 octet string suitable for use as the value of this 1139 * extended request. 1140 */ 1141 @NotNull() 1142 private static ASN1OctetString encodeValue( 1143 @NotNull final String authenticationID, 1144 @Nullable final ASN1OctetString staticPassword, 1145 @Nullable final String messageSubject, 1146 @Nullable final String fullTextBeforeOTP, 1147 @Nullable final String fullTextAfterOTP, 1148 @Nullable final String compactTextBeforeOTP, 1149 @Nullable final String compactTextAfterOTP, 1150 @Nullable final List<ObjectPair<String,String>> 1151 preferredDeliveryMechanisms) 1152 { 1153 final ArrayList<ASN1Element> elements = new ArrayList<>(8); 1154 1155 elements.add(new ASN1OctetString(TYPE_AUTHN_ID, authenticationID)); 1156 1157 if (staticPassword != null) 1158 { 1159 elements.add(staticPassword); 1160 } 1161 1162 if (messageSubject != null) 1163 { 1164 elements.add(new ASN1OctetString(MESSAGE_SUBJECT_BER_TYPE, 1165 messageSubject)); 1166 } 1167 1168 if (fullTextBeforeOTP != null) 1169 { 1170 elements.add(new ASN1OctetString(FULL_TEXT_BEFORE_OTP_BER_TYPE, 1171 fullTextBeforeOTP)); 1172 } 1173 1174 if (fullTextAfterOTP != null) 1175 { 1176 elements.add(new ASN1OctetString(FULL_TEXT_AFTER_OTP_BER_TYPE, 1177 fullTextAfterOTP)); 1178 } 1179 1180 if (compactTextBeforeOTP != null) 1181 { 1182 elements.add(new ASN1OctetString(COMPACT_TEXT_BEFORE_OTP_BER_TYPE, 1183 compactTextBeforeOTP)); 1184 } 1185 1186 if (compactTextAfterOTP != null) 1187 { 1188 elements.add(new ASN1OctetString(COMPACT_TEXT_AFTER_OTP_BER_TYPE, 1189 compactTextAfterOTP)); 1190 } 1191 1192 if ((preferredDeliveryMechanisms != null) && 1193 (! preferredDeliveryMechanisms.isEmpty())) 1194 { 1195 final ArrayList<ASN1Element> pdmElements = 1196 new ArrayList<>(preferredDeliveryMechanisms.size()); 1197 for (final ObjectPair<String,String> p : preferredDeliveryMechanisms) 1198 { 1199 if (p.getSecond() == null) 1200 { 1201 pdmElements.add(new ASN1Sequence( 1202 new ASN1OctetString(p.getFirst()))); 1203 } 1204 else 1205 { 1206 pdmElements.add(new ASN1Sequence( 1207 new ASN1OctetString(p.getFirst()), 1208 new ASN1OctetString(p.getSecond()))); 1209 } 1210 } 1211 1212 elements.add(new ASN1Sequence( 1213 TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES_AND_IDS, pdmElements)); 1214 } 1215 1216 return new ASN1OctetString(new ASN1Sequence(elements).encode()); 1217 } 1218 1219 1220 1221 /** 1222 * Retrieves the authentication ID for the user to whom the one-time password 1223 * should be delivered. 1224 * 1225 * @return The authentication ID for the user to whom the one-time password 1226 * should be delivered. 1227 */ 1228 @NotNull() 1229 public String getAuthenticationID() 1230 { 1231 return authenticationID; 1232 } 1233 1234 1235 1236 /** 1237 * Retrieves the static password for the user to whom the one-time password 1238 * should be delivered. The returned password may be {@code null} if no 1239 * 1240 * 1241 * @return The static password for the user to whom the one-time password 1242 * should be delivered, or {@code null} if no static password should 1243 * be included in the request. 1244 */ 1245 @Nullable() 1246 public ASN1OctetString getStaticPassword() 1247 { 1248 return staticPassword; 1249 } 1250 1251 1252 1253 /** 1254 * Retrieves an ordered list of the names of the preferred delivery mechanisms 1255 * for the one-time password, if provided. 1256 * 1257 * @return An ordered list of the names of the preferred delivery mechanisms 1258 * for the one-time password, or {@code null} if this was not 1259 * provided. 1260 */ 1261 @Nullable() 1262 public List<String> getPreferredDeliveryMechanisms() 1263 { 1264 if (preferredDeliveryMechanisms.isEmpty()) 1265 { 1266 return null; 1267 } 1268 else 1269 { 1270 final LinkedHashSet<String> s = new LinkedHashSet<>( 1271 StaticUtils.computeMapCapacity(preferredDeliveryMechanisms.size())); 1272 for (final ObjectPair<String,String> p : preferredDeliveryMechanisms) 1273 { 1274 s.add(p.getFirst()); 1275 } 1276 1277 return Collections.unmodifiableList(new ArrayList<>(s)); 1278 } 1279 } 1280 1281 1282 1283 /** 1284 * Retrieves an ordered list of the preferred delivery mechanisms that should 1285 * be used to provide the one-time password to the user, optionally paired 1286 * with a mechanism-specific recipient ID (e.g., a mobile phone number for SMS 1287 * delivery, or an email address for email delivery) that can be used in the 1288 * delivery. If this list is non-empty, then the server will use the first 1289 * mechanism in the list that the server supports and is available for the 1290 * target user, and the server will only consider mechanisms in the provided 1291 * list even if the server supports alternate mechanisms that are not 1292 * included. If this list is empty, then the server will attempt to select an 1293 * appropriate delivery mechanism for the user. 1294 * 1295 * @return An ordered list of the preferred delivery mechanisms for the 1296 * one-time password, or an empty list if none were provided. 1297 */ 1298 @NotNull() 1299 public List<ObjectPair<String,String>> 1300 getPreferredDeliveryMechanismNamesAndIDs() 1301 { 1302 return preferredDeliveryMechanisms; 1303 } 1304 1305 1306 1307 /** 1308 * Retrieves the text (if any) that should be used as the message subject for 1309 * delivery mechanisms that can make use of a subject. 1310 * 1311 * @return The text that should be used as the message subject for delivery 1312 * mechanisms that can make use of a subject, or {@code null} if no 1313 * subject should be used, or if the delivery mechanism should 1314 * attempt to automatically determine a subject. 1315 */ 1316 @Nullable() 1317 public String getMessageSubject() 1318 { 1319 return messageSubject; 1320 } 1321 1322 1323 1324 /** 1325 * Retrieves the text (if any) that should appear before the one-time password 1326 * in the message delivered to the user via a mechanism that does not impose 1327 * significant constraints on message size. 1328 * 1329 * @return The text that should appear before the one-time password in the 1330 * message delivered to the user via a mechanism that does not impose 1331 * significant constraints on message size, or {@code null} if there 1332 * should not be any text before the one-time password. 1333 */ 1334 @Nullable() 1335 public String getFullTextBeforeOTP() 1336 { 1337 return fullTextBeforeOTP; 1338 } 1339 1340 1341 1342 /** 1343 * Retrieves the text (if any) that should appear after the one-time password 1344 * in the message delivered to the user via a mechanism that does not impose 1345 * significant constraints on message size. 1346 * 1347 * @return The text that should appear after the one-time password in the 1348 * message delivered to the user via a mechanism that does not impose 1349 * significant constraints on message size, or {@code null} if there 1350 * should not be any text after the one-time password. 1351 */ 1352 @Nullable() 1353 public String getFullTextAfterOTP() 1354 { 1355 return fullTextAfterOTP; 1356 } 1357 1358 1359 1360 /** 1361 * Retrieves the text (if any) that should appear before the one-time password 1362 * in the message delivered to the user via a mechanism that imposes 1363 * significant constraints on message size. 1364 * 1365 * @return The text that should appear before the one-time password in the 1366 * message delivered to the user via a mechanism that imposes 1367 * significant constraints on message size, or {@code null} if there 1368 * should not be any text before the one-time password. 1369 */ 1370 @Nullable() 1371 public String getCompactTextBeforeOTP() 1372 { 1373 return compactTextBeforeOTP; 1374 } 1375 1376 1377 1378 /** 1379 * Retrieves the text (if any) that should appear after the one-time password 1380 * in the message delivered to the user via a mechanism that imposes 1381 * significant constraints on message size. 1382 * 1383 * @return The text that should appear after the one-time password in the 1384 * message delivered to the user via a mechanism that imposes 1385 * significant constraints on message size, or {@code null} if there 1386 * should not be any text after the one-time password. 1387 */ 1388 @Nullable() 1389 public String getCompactTextAfterOTP() 1390 { 1391 return compactTextAfterOTP; 1392 } 1393 1394 1395 1396 /** 1397 * {@inheritDoc} 1398 */ 1399 @Override() 1400 @NotNull() 1401 public DeliverOneTimePasswordExtendedResult process( 1402 @NotNull final LDAPConnection connection, final int depth) 1403 throws LDAPException 1404 { 1405 final ExtendedResult extendedResponse = super.process(connection, depth); 1406 return new DeliverOneTimePasswordExtendedResult(extendedResponse); 1407 } 1408 1409 1410 1411 /** 1412 * {@inheritDoc}. 1413 */ 1414 @Override() 1415 @NotNull() 1416 public DeliverOneTimePasswordExtendedRequest duplicate() 1417 { 1418 return duplicate(getControls()); 1419 } 1420 1421 1422 1423 /** 1424 * {@inheritDoc}. 1425 */ 1426 @Override() 1427 @NotNull() 1428 public DeliverOneTimePasswordExtendedRequest duplicate( 1429 @Nullable final Control[] controls) 1430 { 1431 final DeliverOneTimePasswordExtendedRequest r = 1432 new DeliverOneTimePasswordExtendedRequest(authenticationID, 1433 staticPassword, messageSubject, fullTextBeforeOTP, 1434 fullTextAfterOTP, compactTextBeforeOTP, compactTextAfterOTP, 1435 preferredDeliveryMechanisms, controls); 1436 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null)); 1437 r.setIntermediateResponseListener(getIntermediateResponseListener()); 1438 r.setReferralDepth(getReferralDepth()); 1439 r.setReferralConnector(getReferralConnectorInternal()); 1440 return r; 1441 } 1442 1443 1444 1445 /** 1446 * {@inheritDoc} 1447 */ 1448 @Override() 1449 @NotNull() 1450 public String getExtendedRequestName() 1451 { 1452 return INFO_DELIVER_OTP_REQ_NAME.get(); 1453 } 1454 1455 1456 1457 /** 1458 * {@inheritDoc} 1459 */ 1460 @Override() 1461 public void toString(@NotNull final StringBuilder buffer) 1462 { 1463 buffer.append("DeliverOneTimePasswordExtendedRequest(authenticationID="); 1464 buffer.append(authenticationID); 1465 1466 if (messageSubject != null) 1467 { 1468 buffer.append(", messageSubject='"); 1469 buffer.append(messageSubject); 1470 buffer.append('\''); 1471 } 1472 1473 if (fullTextBeforeOTP != null) 1474 { 1475 buffer.append(", fullTextBeforeOTP='"); 1476 buffer.append(fullTextBeforeOTP); 1477 buffer.append('\''); 1478 } 1479 1480 if (fullTextAfterOTP != null) 1481 { 1482 buffer.append(", fullTextAfterOTP='"); 1483 buffer.append(fullTextAfterOTP); 1484 buffer.append('\''); 1485 } 1486 1487 if (compactTextBeforeOTP != null) 1488 { 1489 buffer.append(", compactTextBeforeOTP='"); 1490 buffer.append(compactTextBeforeOTP); 1491 buffer.append('\''); 1492 } 1493 1494 if (compactTextAfterOTP != null) 1495 { 1496 buffer.append(", compactTextAfterOTP='"); 1497 buffer.append(compactTextAfterOTP); 1498 buffer.append('\''); 1499 } 1500 1501 if (preferredDeliveryMechanisms != null) 1502 { 1503 buffer.append(", preferredDeliveryMechanisms={"); 1504 1505 final Iterator<ObjectPair<String,String>> iterator = 1506 preferredDeliveryMechanisms.iterator(); 1507 while (iterator.hasNext()) 1508 { 1509 final ObjectPair<String,String> p = iterator.next(); 1510 buffer.append('\''); 1511 buffer.append(p.getFirst()); 1512 if (p.getSecond() != null) 1513 { 1514 buffer.append('('); 1515 buffer.append(p.getSecond()); 1516 buffer.append(')'); 1517 } 1518 buffer.append('\''); 1519 if (iterator.hasNext()) 1520 { 1521 buffer.append(','); 1522 } 1523 } 1524 } 1525 1526 final Control[] controls = getControls(); 1527 if (controls.length > 0) 1528 { 1529 buffer.append(", controls={"); 1530 for (int i=0; i < controls.length; i++) 1531 { 1532 if (i > 0) 1533 { 1534 buffer.append(", "); 1535 } 1536 1537 buffer.append(controls[i]); 1538 } 1539 buffer.append('}'); 1540 } 1541 1542 buffer.append(')'); 1543 } 1544}