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