001/*
002 * Copyright 2013-2019 Ping Identity Corporation
003 * All Rights Reserved.
004 */
005/*
006 * Copyright (C) 2015-2019 Ping Identity Corporation
007 *
008 * This program is free software; you can redistribute it and/or modify
009 * it under the terms of the GNU General Public License (GPLv2 only)
010 * or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
011 * as published by the Free Software Foundation.
012 *
013 * This program is distributed in the hope that it will be useful,
014 * but WITHOUT ANY WARRANTY; without even the implied warranty of
015 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
016 * GNU General Public License for more details.
017 *
018 * You should have received a copy of the GNU General Public License
019 * along with this program; if not, see <http://www.gnu.org/licenses>.
020 */
021package com.unboundid.ldap.sdk.unboundidds.extensions;
022
023
024
025import 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
061 *   Nokia/Alcatel-Lucent 8661 server products.  These classes provide support
062 *   for proprietary functionality or for external specifications that are not
063 *   considered stable or mature enough to be guaranteed to work in an
064 *   interoperable way with 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<>(preferredDeliveryMechanisms.size());
456      for (final String s : preferredDeliveryMechanisms)
457      {
458        l.add(new ObjectPair<String,String>(s, null));
459      }
460      this.preferredDeliveryMechanisms = Collections.unmodifiableList(l);
461    }
462
463    messageSubject       = null;
464    fullTextBeforeOTP    = null;
465    fullTextAfterOTP     = null;
466    compactTextBeforeOTP = null;
467    compactTextAfterOTP  = null;
468  }
469
470
471
472  /**
473   * Creates a new deliver one-time password extended request with the provided
474   * information.
475   *
476   * @param  authenticationID             The authentication ID for the user to
477   *                                      whom the one-time password should be
478   *                                      delivered.  It must not be
479   *                                      {@code null}.
480   * @param  staticPassword               The static password for the user to
481   *                                      whom the one-time password should be
482   *                                      delivered.  It may be {@code null} if
483   *                                      this request is intended to be used
484   *                                      to step-up an existing authentication
485   *                                      rather than perform a new
486   *                                      authentication (in which case the
487   *                                      provided authentication ID must match
488   *                                      the operation's authorization ID).
489   * @param  messageSubject               The text (if any) that should be used
490   *                                      as the message subject if the delivery
491   *                                      mechanism accepts a subject.  This may
492   *                                      be {@code null} if no subject is
493   *                                      required or a subject should be
494   *                                      automatically generated.
495   * @param  fullTextBeforeOTP            The text (if any) that should appear
496   *                                      before the generated one-time password
497   *                                      in the message delivered to the user
498   *                                      via a delivery mechanism that does not
499   *                                      impose significant constraints on
500   *                                      message size.  This may be
501   *                                      {@code null} if no text is required
502   *                                      before the one-time password.
503   * @param  fullTextAfterOTP             The text (if any) that should appear
504   *                                      after the one-time password in the
505   *                                      message delivered to the user via a
506   *                                      delivery mechanism that does not
507   *                                      impose significant constraints on
508   *                                      message size.  This may be
509   *                                      {@code null} if no text is required
510   *                                      after the one-time password.
511   * @param  compactTextBeforeOTP         The text (if any) that should appear
512   *                                      before the generated one-time password
513   *                                      in the message delivered to the user
514   *                                      via a delivery mechanism that imposes
515   *                                      significant constraints on message
516   *                                      size.  This may be {@code null} if no
517   *                                      text is required before the one-time
518   *                                      password.
519   * @param  compactTextAfterOTP          The text (if any) that should appear
520   *                                      after the generated one-time password
521   *                                      in the message delivered to the user
522   *                                      via a delivery mechanism that imposes
523   *                                      significant constraints on message
524   *                                      size.  This may be {@code null} if no
525   *                                      text is required after the one-time
526   *                                      password.
527   * @param  preferredDeliveryMechanisms  An optional ordered list of preferred
528   *                                      delivery mechanisms that should be
529   *                                      used to deliver the one-time password
530   *                                      to the user.  It may be {@code null}
531   *                                      or empty to allow the server to select
532   *                                      an appropriate delivery mechanism.  If
533   *                                      it is non-{@code null} and non-empty,
534   *                                      then only the listed mechanisms will
535   *                                      be considered for use, even if the
536   *                                      server supports alternate mechanisms
537   *                                      not included in this list.  Each
538   *                                      {@code ObjectPair} item must have
539   *                                      a non-{@code null} value for the first
540   *                                      element, which is the name of the
541   *                                      target delivery mechanism.  It may
542   *                                      optionally have a non-{@code null}
543   *                                      value for the second element, which is
544   *                                      a recipient ID to use for that
545   *                                      mechanism (e.g., the target  mobile
546   *                                      phone number for SMS delivery, an
547   *                                      email address for email delivery,
548   *                                      etc.).  If no recipient ID is provided
549   *                                      for a mechanism, then the server will
550   *                                      attempt to select a value for the
551   *                                      user.
552   * @param  controls                     The set of controls to include in the
553   *                                      request.  It may be {@code null} or
554   *                                      empty if no controls should be
555   *                                      included.
556   */
557  public DeliverOneTimePasswordExtendedRequest(final String authenticationID,
558       final String staticPassword, final String messageSubject,
559       final String fullTextBeforeOTP, final String fullTextAfterOTP,
560       final String compactTextBeforeOTP, final String compactTextAfterOTP,
561       final List<ObjectPair<String,String>> preferredDeliveryMechanisms,
562       final Control... controls)
563  {
564    this(authenticationID,
565         (staticPassword == null
566              ? null
567              : new ASN1OctetString(TYPE_PASSWORD, staticPassword)),
568         messageSubject, fullTextBeforeOTP, fullTextAfterOTP,
569         compactTextBeforeOTP, compactTextAfterOTP, preferredDeliveryMechanisms,
570         controls);
571  }
572
573
574
575  /**
576   * Creates a new deliver one-time password extended request with the provided
577   * information.
578   *
579   * @param  authenticationID             The authentication ID for the user to
580   *                                      whom the one-time password should be
581   *                                      delivered.  It must not be
582   *                                      {@code null}.
583   * @param  staticPassword               The static password for the user to
584   *                                      whom the one-time password should be
585   *                                      delivered.  It may be {@code null} if
586   *                                      this request is intended to be used
587   *                                      to step-up an existing authentication
588   *                                      rather than perform a new
589   *                                      authentication (in which case the
590   *                                      provided authentication ID must match
591   *                                      the operation's authorization ID).
592   * @param  messageSubject               The text (if any) that should be used
593   *                                      as the message subject if the delivery
594   *                                      mechanism accepts a subject.  This may
595   *                                      be {@code null} if no subject is
596   *                                      required or a subject should be
597   *                                      automatically generated.
598   * @param  fullTextBeforeOTP            The text (if any) that should appear
599   *                                      before the generated one-time password
600   *                                      in the message delivered to the user
601   *                                      via a delivery mechanism that does not
602   *                                      impose significant constraints on
603   *                                      message size.  This may be
604   *                                      {@code null} if no text is required
605   *                                      before the one-time password.
606   * @param  fullTextAfterOTP             The text (if any) that should appear
607   *                                      after the one-time password in the
608   *                                      message delivered to the user via a
609   *                                      delivery mechanism that does not
610   *                                      impose significant constraints on
611   *                                      message size.  This may be
612   *                                      {@code null} if no text is required
613   *                                      after the one-time password.
614   * @param  compactTextBeforeOTP         The text (if any) that should appear
615   *                                      before the generated one-time password
616   *                                      in the message delivered to the user
617   *                                      via a delivery mechanism that imposes
618   *                                      significant constraints on message
619   *                                      size.  This may be {@code null} if no
620   *                                      text is required before the one-time
621   *                                      password.
622   * @param  compactTextAfterOTP          The text (if any) that should appear
623   *                                      after the generated one-time password
624   *                                      in the message delivered to the user
625   *                                      via a delivery mechanism that imposes
626   *                                      significant constraints on message
627   *                                      size.  This may be {@code null} if no
628   *                                      text is required after the one-time
629   *                                      password.
630   * @param  preferredDeliveryMechanisms  An optional ordered list of preferred
631   *                                      delivery mechanisms that should be
632   *                                      used to deliver the one-time password
633   *                                      to the user.  It may be {@code null}
634   *                                      or empty to allow the server to select
635   *                                      an appropriate delivery mechanism.  If
636   *                                      it is non-{@code null} and non-empty,
637   *                                      then only the listed mechanisms will
638   *                                      be considered for use, even if the
639   *                                      server supports alternate mechanisms
640   *                                      not included in this list.  Each
641   *                                      {@code ObjectPair} item must have
642   *                                      a non-{@code null} value for the first
643   *                                      element, which is the name of the
644   *                                      target delivery mechanism.  It may
645   *                                      optionally have a non-{@code null}
646   *                                      value for the second element, which is
647   *                                      a recipient ID to use for that
648   *                                      mechanism (e.g., the target  mobile
649   *                                      phone number for SMS delivery, an
650   *                                      email address for email delivery,
651   *                                      etc.).  If no recipient ID is provided
652   *                                      for a mechanism, then the server will
653   *                                      attempt to select a value for the
654   *                                      user.
655   * @param  controls                     The set of controls to include in the
656   *                                      request.  It may be {@code null} or
657   *                                      empty if no controls should be
658   *                                      included.
659   */
660  public DeliverOneTimePasswordExtendedRequest(final String authenticationID,
661       final byte[] staticPassword, final String messageSubject,
662       final String fullTextBeforeOTP, final String fullTextAfterOTP,
663       final String compactTextBeforeOTP, final String compactTextAfterOTP,
664       final List<ObjectPair<String,String>> preferredDeliveryMechanisms,
665       final Control... controls)
666  {
667    this(authenticationID,
668         (staticPassword == null
669              ? null
670              : new ASN1OctetString(TYPE_PASSWORD, staticPassword)),
671         messageSubject, fullTextBeforeOTP, fullTextAfterOTP,
672         compactTextBeforeOTP, compactTextAfterOTP, preferredDeliveryMechanisms,
673         controls);
674  }
675
676
677
678  /**
679   * Creates a new deliver one-time password extended request with the provided
680   * information.
681   *
682   * @param  authenticationID             The authentication ID for the user to
683   *                                      whom the one-time password should be
684   *                                      delivered.  It must not be
685   *                                      {@code null}.
686   * @param  staticPassword               The static password for the user to
687   *                                      whom the one-time password should be
688   *                                      delivered.  It may be {@code null} if
689   *                                      this request is intended to be used
690   *                                      to step-up an existing authentication
691   *                                      rather than perform a new
692   *                                      authentication (in which case the
693   *                                      provided authentication ID must match
694   *                                      the operation's authorization ID).
695   * @param  messageSubject               The text (if any) that should be used
696   *                                      as the message subject if the delivery
697   *                                      mechanism accepts a subject.  This may
698   *                                      be {@code null} if no subject is
699   *                                      required or a subject should be
700   *                                      automatically generated.
701   * @param  fullTextBeforeOTP            The text (if any) that should appear
702   *                                      before the generated one-time password
703   *                                      in the message delivered to the user
704   *                                      via a delivery mechanism that does not
705   *                                      impose significant constraints on
706   *                                      message size.  This may be
707   *                                      {@code null} if no text is required
708   *                                      before the one-time password.
709   * @param  fullTextAfterOTP             The text (if any) that should appear
710   *                                      after the one-time password in the
711   *                                      message delivered to the user via a
712   *                                      delivery mechanism that does not
713   *                                      impose significant constraints on
714   *                                      message size.  This may be
715   *                                      {@code null} if no text is required
716   *                                      after the one-time password.
717   * @param  compactTextBeforeOTP         The text (if any) that should appear
718   *                                      before the generated one-time password
719   *                                      in the message delivered to the user
720   *                                      via a delivery mechanism that imposes
721   *                                      significant constraints on message
722   *                                      size.  This may be {@code null} if no
723   *                                      text is required before the one-time
724   *                                      password.
725   * @param  compactTextAfterOTP          The text (if any) that should appear
726   *                                      after the generated one-time password
727   *                                      in the message delivered to the user
728   *                                      via a delivery mechanism that imposes
729   *                                      significant constraints on message
730   *                                      size.  This may be {@code null} if no
731   *                                      text is required after the one-time
732   *                                      password.
733   * @param  preferredDeliveryMechanisms  An optional ordered list of preferred
734   *                                      delivery mechanisms that should be
735   *                                      used to deliver the one-time password
736   *                                      to the user.  It may be {@code null}
737   *                                      or empty to allow the server to select
738   *                                      an appropriate delivery mechanism.  If
739   *                                      it is non-{@code null} and non-empty,
740   *                                      then only the listed mechanisms will
741   *                                      be considered for use, even if the
742   *                                      server supports alternate mechanisms
743   *                                      not included in this list.  Each
744   *                                      {@code ObjectPair} item must have
745   *                                      a non-{@code null} value for the first
746   *                                      element, which is the name of the
747   *                                      target delivery mechanism.  It may
748   *                                      optionally have a non-{@code null}
749   *                                      value for the second element, which is
750   *                                      a recipient ID to use for that
751   *                                      mechanism (e.g., the target  mobile
752   *                                      phone number for SMS delivery, an
753   *                                      email address for email delivery,
754   *                                      etc.).  If no recipient ID is provided
755   *                                      for a mechanism, then the server will
756   *                                      attempt to select a value for the
757   *                                      user.
758   * @param  controls                     The set of controls to include in the
759   *                                      request.  It may be {@code null} or
760   *                                      empty if no controls should be
761   *                                      included.
762   */
763  private DeliverOneTimePasswordExtendedRequest(final String authenticationID,
764       final ASN1OctetString staticPassword, final String messageSubject,
765       final String fullTextBeforeOTP, final String fullTextAfterOTP,
766       final String compactTextBeforeOTP, final String compactTextAfterOTP,
767       final List<ObjectPair<String,String>> preferredDeliveryMechanisms,
768       final Control... controls)
769  {
770    super(DELIVER_OTP_REQUEST_OID,
771         encodeValue(authenticationID, staticPassword, messageSubject,
772              fullTextBeforeOTP, fullTextAfterOTP, compactTextBeforeOTP,
773              compactTextAfterOTP, preferredDeliveryMechanisms),
774         controls);
775
776    this.authenticationID     = authenticationID;
777    this.staticPassword       = staticPassword;
778    this.messageSubject       = messageSubject;
779    this.fullTextBeforeOTP    = fullTextBeforeOTP;
780    this.fullTextAfterOTP     = fullTextAfterOTP;
781    this.compactTextBeforeOTP = compactTextBeforeOTP;
782    this.compactTextAfterOTP  = compactTextAfterOTP;
783
784    if ((preferredDeliveryMechanisms == null) ||
785        preferredDeliveryMechanisms.isEmpty())
786    {
787      this.preferredDeliveryMechanisms = Collections.emptyList();
788    }
789    else
790    {
791      this.preferredDeliveryMechanisms =
792           Collections.unmodifiableList(preferredDeliveryMechanisms);
793    }
794  }
795
796
797
798  /**
799   * Creates a new deliver one-time password extended request from the
800   * information contained in the provided generic extended request.
801   *
802   * @param  request  The generic extended request to be decoded as a deliver
803   *                  one-time password extended request.
804   *
805   * @throws  LDAPException  If a problem is encountered while attempting to
806   *                         decode the provided generic extended request as a
807   *                         deliver one-time password extended request.
808   */
809  public DeliverOneTimePasswordExtendedRequest(final ExtendedRequest request)
810         throws LDAPException
811  {
812    super(request);
813
814    // The request must have a value.
815    final ASN1OctetString value = request.getValue();
816    if (value == null)
817    {
818      throw new LDAPException(ResultCode.DECODING_ERROR,
819           ERR_DELIVER_OTP_REQ_NO_VALUE.get());
820    }
821
822
823    //  Parse the value.
824    ASN1OctetString password = null;
825    String authnID = null;
826    String subject = null;
827    String fullBefore = null;
828    String fullAfter = null;
829    String compactBefore = null;
830    String compactAfter = null;
831    final ArrayList<ObjectPair<String,String>> pdmList = new ArrayList<>(10);
832    try
833    {
834      for (final ASN1Element e :
835           ASN1Sequence.decodeAsSequence(value.getValue()).elements())
836      {
837        switch (e.getType())
838        {
839          case TYPE_AUTHN_ID:
840            authnID = ASN1OctetString.decodeAsOctetString(e).stringValue();
841            break;
842
843          case TYPE_PASSWORD:
844            password = ASN1OctetString.decodeAsOctetString(e);
845            break;
846
847          case TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES:
848            final ASN1Element[] mechNameElements =
849                 ASN1Sequence.decodeAsSequence(e).elements();
850            for (final ASN1Element mechElement : mechNameElements)
851            {
852              pdmList.add(new ObjectPair<String,String>(
853                   ASN1OctetString.decodeAsOctetString(mechElement).
854                        stringValue(),
855                   null));
856            }
857            break;
858
859          case TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES_AND_IDS:
860            final ASN1Element[] pdmElements =
861                 ASN1Sequence.decodeAsSequence(e).elements();
862            for (final ASN1Element pdmElement : pdmElements)
863            {
864              final ASN1Element[] mechElements =
865                   ASN1Sequence.decodeAsSequence(pdmElement).elements();
866              final String mech = ASN1OctetString.decodeAsOctetString(
867                   mechElements[0]).stringValue();
868
869              final String recipientID;
870              if (mechElements.length > 1)
871              {
872                recipientID = ASN1OctetString.decodeAsOctetString(
873                     mechElements[1]).stringValue();
874              }
875              else
876              {
877                recipientID = null;
878              }
879
880              pdmList.add(new ObjectPair<>(mech, recipientID));
881            }
882            break;
883
884          case MESSAGE_SUBJECT_BER_TYPE:
885            subject =
886                 ASN1OctetString.decodeAsOctetString(e).stringValue();
887            break;
888
889          case FULL_TEXT_BEFORE_OTP_BER_TYPE:
890            fullBefore =
891                 ASN1OctetString.decodeAsOctetString(e).stringValue();
892            break;
893
894          case FULL_TEXT_AFTER_OTP_BER_TYPE:
895            fullAfter =
896                 ASN1OctetString.decodeAsOctetString(e).stringValue();
897            break;
898
899          case COMPACT_TEXT_BEFORE_OTP_BER_TYPE:
900            compactBefore =
901                 ASN1OctetString.decodeAsOctetString(e).stringValue();
902            break;
903
904          case COMPACT_TEXT_AFTER_OTP_BER_TYPE:
905            compactAfter =
906                 ASN1OctetString.decodeAsOctetString(e).stringValue();
907            break;
908
909          default:
910            throw new LDAPException(ResultCode.DECODING_ERROR,
911                 ERR_DELIVER_OTP_REQ_UNEXPECTED_ELEMENT_TYPE.get(
912                      StaticUtils.toHex(e.getType())));
913
914        }
915      }
916    }
917    catch (final LDAPException le)
918    {
919      Debug.debugException(le);
920      throw le;
921    }
922    catch (final Exception e)
923    {
924      Debug.debugException(e);
925      throw new LDAPException(ResultCode.DECODING_ERROR,
926           ERR_DELIVER_OTP_REQ_ERROR_PARSING_VALUE.get(
927                StaticUtils.getExceptionMessage(e)),
928           e);
929    }
930
931    if (authnID == null)
932    {
933      throw new LDAPException(ResultCode.DECODING_ERROR,
934           ERR_DELIVER_OTP_REQ_NO_AUTHN_ID.get());
935    }
936    else
937    {
938      authenticationID = authnID;
939    }
940
941    staticPassword       = password;
942    messageSubject       = subject;
943    fullTextBeforeOTP    = fullBefore;
944    fullTextAfterOTP     = fullAfter;
945    compactTextBeforeOTP = compactBefore;
946    compactTextAfterOTP  = compactAfter;
947
948    if ((pdmList == null) || pdmList.isEmpty())
949    {
950      preferredDeliveryMechanisms = Collections.emptyList();
951    }
952    else
953    {
954      preferredDeliveryMechanisms = Collections.unmodifiableList(pdmList);
955    }
956  }
957
958
959
960  /**
961   * Encodes the provided information into an ASN.1 octet string suitable for
962   * use as the value of this extended request.
963   *
964   * @param  authenticationID             The authentication ID for the user to
965   *                                      whom the one-time password should be
966   *                                      delivered.  It must not be
967   *                                      {@code null}.
968   * @param  staticPassword               The static password for the user to
969   *                                      whom the one-time password should be
970   *                                      delivered.
971   * @param  preferredDeliveryMechanisms  The names of the preferred delivery
972   *                                      mechanisms for the one-time password.
973   *                                      It may be {@code null} or empty if the
974   *                                      server should select an appropriate
975   *                                      delivery mechanism.  If it is
976   *                                      non-{@code null} and non-empty, then
977   *                                      only the listed mechanisms will be
978   *                                      considered for use, even if the server
979   *                                      supports alternate mechanisms not
980   *                                      included in this list.
981   *
982   * @return  An ASN.1 octet string suitable for use as the value of this
983   *          extended request.
984   */
985  private static ASN1OctetString encodeValue(final String authenticationID,
986                      final ASN1OctetString staticPassword,
987                      final List<String> preferredDeliveryMechanisms)
988  {
989    final ArrayList<ASN1Element> elements = new ArrayList<>(3);
990
991    elements.add(new ASN1OctetString(TYPE_AUTHN_ID, authenticationID));
992
993    if (staticPassword != null)
994    {
995      elements.add(staticPassword);
996    }
997
998    if ((preferredDeliveryMechanisms != null) &&
999        (! preferredDeliveryMechanisms.isEmpty()))
1000    {
1001      final ArrayList<ASN1Element> dmElements =
1002           new ArrayList<>(preferredDeliveryMechanisms.size());
1003      for (final String s : preferredDeliveryMechanisms)
1004      {
1005        dmElements.add(new ASN1OctetString(s));
1006      }
1007      elements.add(new ASN1Sequence(TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES,
1008           dmElements));
1009    }
1010
1011    return new ASN1OctetString(new ASN1Sequence(elements).encode());
1012  }
1013
1014
1015
1016  /**
1017   * Encodes the provided information into an ASN.1 octet string suitable for
1018   * use as the value of this extended request.
1019   *
1020   * @param  authenticationID             The authentication ID for the user to
1021   *                                      whom the one-time password should be
1022   *                                      delivered.  It must not be
1023   *                                      {@code null}.
1024   * @param  staticPassword               The static password for the user to
1025   *                                      whom the one-time password should be
1026   *                                      delivered.  It may be {@code null} if
1027   *                                      this request is intended to be used
1028   *                                      to step-up an existing authentication
1029   *                                      rather than perform a new
1030   *                                      authentication (in which case the
1031   *                                      provided authentication ID must match
1032   *                                      the operation's authorization ID).
1033   * @param  messageSubject               The text (if any) that should be used
1034   *                                      as the message subject if the delivery
1035   *                                      mechanism accepts a subject.  This may
1036   *                                      be {@code null} if no subject is
1037   *                                      required or a subject should be
1038   *                                      automatically generated.
1039   * @param  fullTextBeforeOTP            The text (if any) that should appear
1040   *                                      before the generated one-time password
1041   *                                      in the message delivered to the user
1042   *                                      via a delivery mechanism that does not
1043   *                                      impose significant constraints on
1044   *                                      message size.  This may be
1045   *                                      {@code null} if no text is required
1046   *                                      before the one-time password.
1047   * @param  fullTextAfterOTP             The text (if any) that should appear
1048   *                                      after the one-time password in the
1049   *                                      message delivered to the user via a
1050   *                                      delivery mechanism that does not
1051   *                                      impose significant constraints on
1052   *                                      message size.  This may be
1053   *                                      {@code null} if no text is required
1054   *                                      after the one-time password.
1055   * @param  compactTextBeforeOTP         The text (if any) that should appear
1056   *                                      before the generated one-time password
1057   *                                      in the message delivered to the user
1058   *                                      via a delivery mechanism that imposes
1059   *                                      significant constraints on message
1060   *                                      size.  This may be {@code null} if no
1061   *                                      text is required before the one-time
1062   *                                      password.
1063   * @param  compactTextAfterOTP          The text (if any) that should appear
1064   *                                      after the generated one-time password
1065   *                                      in the message delivered to the user
1066   *                                      via a delivery mechanism that imposes
1067   *                                      significant constraints on message
1068   *                                      size.  This may be {@code null} if no
1069   *                                      text is required after the one-time
1070   *                                      password.
1071   * @param  preferredDeliveryMechanisms  An optional ordered list of preferred
1072   *                                      delivery mechanisms that should be
1073   *                                      used to deliver the one-time password
1074   *                                      to the user.  It may be {@code null}
1075   *                                      or empty to allow the server to select
1076   *                                      an appropriate delivery mechanism.  If
1077   *                                      it is non-{@code null} and non-empty,
1078   *                                      then only the listed mechanisms will
1079   *                                      be considered for use, even if the
1080   *                                      server supports alternate mechanisms
1081   *                                      not included in this list.  Each
1082   *                                      {@code ObjectPair} item must have
1083   *                                      a non-{@code null} value for the first
1084   *                                      element, which is the name of the
1085   *                                      target delivery mechanism.  It may
1086   *                                      optionally have a non-{@code null}
1087   *                                      value for the second element, which is
1088   *                                      a recipient ID to use for that
1089   *                                      mechanism (e.g., the target  mobile
1090   *                                      phone number for SMS delivery, an
1091   *                                      email address for email delivery,
1092   *                                      etc.).  If no recipient ID is provided
1093   *                                      for a mechanism, then the server will
1094   *                                      attempt to select a value for the
1095   *                                      user.
1096   *
1097   * @return  An ASN.1 octet string suitable for use as the value of this
1098   *          extended request.
1099   */
1100  private static ASN1OctetString encodeValue(final String authenticationID,
1101       final ASN1OctetString staticPassword, final String messageSubject,
1102       final String fullTextBeforeOTP, final String fullTextAfterOTP,
1103       final String compactTextBeforeOTP, final String compactTextAfterOTP,
1104       final List<ObjectPair<String,String>> preferredDeliveryMechanisms)
1105  {
1106    final ArrayList<ASN1Element> elements = new ArrayList<>(8);
1107
1108    elements.add(new ASN1OctetString(TYPE_AUTHN_ID, authenticationID));
1109
1110    if (staticPassword != null)
1111    {
1112      elements.add(staticPassword);
1113    }
1114
1115    if (messageSubject != null)
1116    {
1117      elements.add(new ASN1OctetString(MESSAGE_SUBJECT_BER_TYPE,
1118           messageSubject));
1119    }
1120
1121    if (fullTextBeforeOTP != null)
1122    {
1123      elements.add(new ASN1OctetString(FULL_TEXT_BEFORE_OTP_BER_TYPE,
1124           fullTextBeforeOTP));
1125    }
1126
1127    if (fullTextAfterOTP != null)
1128    {
1129      elements.add(new ASN1OctetString(FULL_TEXT_AFTER_OTP_BER_TYPE,
1130           fullTextAfterOTP));
1131    }
1132
1133    if (compactTextBeforeOTP != null)
1134    {
1135      elements.add(new ASN1OctetString(COMPACT_TEXT_BEFORE_OTP_BER_TYPE,
1136           compactTextBeforeOTP));
1137    }
1138
1139    if (compactTextAfterOTP != null)
1140    {
1141      elements.add(new ASN1OctetString(COMPACT_TEXT_AFTER_OTP_BER_TYPE,
1142           compactTextAfterOTP));
1143    }
1144
1145    if ((preferredDeliveryMechanisms != null) &&
1146        (! preferredDeliveryMechanisms.isEmpty()))
1147    {
1148      final ArrayList<ASN1Element> pdmElements =
1149           new ArrayList<>(preferredDeliveryMechanisms.size());
1150      for (final ObjectPair<String,String> p : preferredDeliveryMechanisms)
1151      {
1152        if (p.getSecond() == null)
1153        {
1154          pdmElements.add(new ASN1Sequence(
1155               new ASN1OctetString(p.getFirst())));
1156        }
1157        else
1158        {
1159          pdmElements.add(new ASN1Sequence(
1160               new ASN1OctetString(p.getFirst()),
1161               new ASN1OctetString(p.getSecond())));
1162        }
1163      }
1164
1165      elements.add(new ASN1Sequence(
1166           TYPE_PREFERRED_DELIVERY_MECHANISM_NAMES_AND_IDS, pdmElements));
1167    }
1168
1169    return new ASN1OctetString(new ASN1Sequence(elements).encode());
1170  }
1171
1172
1173
1174  /**
1175   * Retrieves the authentication ID for the user to whom the one-time password
1176   * should be delivered.
1177   *
1178   * @return  The authentication ID for the user to whom the one-time password
1179   *          should be delivered.
1180   */
1181  public String getAuthenticationID()
1182  {
1183    return authenticationID;
1184  }
1185
1186
1187
1188  /**
1189   * Retrieves the static password for the user to whom the one-time password
1190   * should be delivered.  The returned password may be {@code null} if no
1191   *
1192   *
1193   * @return  The static password for the user to whom the one-time password
1194   *          should be delivered, or {@code null} if no static password should
1195   *          be included in the request.
1196   */
1197  public ASN1OctetString getStaticPassword()
1198  {
1199    return staticPassword;
1200  }
1201
1202
1203
1204  /**
1205   * Retrieves an ordered list of the names of the preferred delivery mechanisms
1206   * for the one-time password, if provided.
1207   *
1208   * @return  An ordered list of the names of the preferred delivery mechanisms
1209   *          for the one-time password, or {@code null} if this was not
1210   *          provided.
1211   */
1212  public List<String> getPreferredDeliveryMechanisms()
1213  {
1214    if (preferredDeliveryMechanisms.isEmpty())
1215    {
1216      return null;
1217    }
1218    else
1219    {
1220      final LinkedHashSet<String> s = new LinkedHashSet<>(
1221           StaticUtils.computeMapCapacity(preferredDeliveryMechanisms.size()));
1222      for (final ObjectPair<String,String> p : preferredDeliveryMechanisms)
1223      {
1224        s.add(p.getFirst());
1225      }
1226
1227      return Collections.unmodifiableList(new ArrayList<>(s));
1228    }
1229  }
1230
1231
1232
1233  /**
1234   * Retrieves an ordered list of the preferred delivery mechanisms that should
1235   * be used to provide the one-time password to the user, optionally paired
1236   * with a mechanism-specific recipient ID (e.g., a mobile phone number for SMS
1237   * delivery, or an email address for email delivery) that can be used in the
1238   * delivery.  If this list is non-empty, then the server will use the first
1239   * mechanism in the list that the server supports and is available for the
1240   * target user, and the server will only consider mechanisms in the provided
1241   * list even if the server supports alternate mechanisms that are not
1242   * included.  If this list is empty, then the server will attempt to select an
1243   * appropriate delivery mechanism for the user.
1244   *
1245   * @return  An ordered list of the preferred delivery mechanisms for the
1246   *          one-time password, or an empty list if none were provided.
1247   */
1248  public List<ObjectPair<String,String>>
1249              getPreferredDeliveryMechanismNamesAndIDs()
1250  {
1251    return preferredDeliveryMechanisms;
1252  }
1253
1254
1255
1256  /**
1257   * Retrieves the text (if any) that should be used as the message subject for
1258   * delivery mechanisms that can make use of a subject.
1259   *
1260   * @return  The text that should be used as the message subject for delivery
1261   *          mechanisms that can make use of a subject, or {@code null} if no
1262   *          subject should be used, or if the delivery mechanism should
1263   *          attempt to automatically determine a subject.
1264   */
1265  public String getMessageSubject()
1266  {
1267    return messageSubject;
1268  }
1269
1270
1271
1272  /**
1273   * Retrieves the text (if any) that should appear before the one-time password
1274   * in the message delivered to the user via a mechanism that does not impose
1275   * significant constraints on message size.
1276   *
1277   * @return  The text that should appear before the one-time password in the
1278   *          message delivered to the user via a mechanism that does not impose
1279   *          significant constraints on message size, or {@code null} if there
1280   *          should not be any text before the one-time password.
1281   */
1282  public String getFullTextBeforeOTP()
1283  {
1284    return fullTextBeforeOTP;
1285  }
1286
1287
1288
1289  /**
1290   * Retrieves the text (if any) that should appear after the one-time password
1291   * in the message delivered to the user via a mechanism that does not impose
1292   * significant constraints on message size.
1293   *
1294   * @return  The text that should appear after the one-time password in the
1295   *          message delivered to the user via a mechanism that does not impose
1296   *          significant constraints on message size, or {@code null} if there
1297   *          should not be any text after the one-time password.
1298   */
1299  public String getFullTextAfterOTP()
1300  {
1301    return fullTextAfterOTP;
1302  }
1303
1304
1305
1306  /**
1307   * Retrieves the text (if any) that should appear before the one-time password
1308   * in the message delivered to the user via a mechanism that imposes
1309   * significant constraints on message size.
1310   *
1311   * @return  The text that should appear before the one-time password in the
1312   *          message delivered to the user via a mechanism that imposes
1313   *          significant constraints on message size, or {@code null} if there
1314   *          should not be any text before the one-time password.
1315   */
1316  public String getCompactTextBeforeOTP()
1317  {
1318    return compactTextBeforeOTP;
1319  }
1320
1321
1322
1323  /**
1324   * Retrieves the text (if any) that should appear after the one-time password
1325   * in the message delivered to the user via a mechanism that imposes
1326   * significant constraints on message size.
1327   *
1328   * @return  The text that should appear after the one-time password in the
1329   *          message delivered to the user via a mechanism that imposes
1330   *          significant constraints on message size, or {@code null} if there
1331   *          should not be any text after the one-time password.
1332   */
1333  public String getCompactTextAfterOTP()
1334  {
1335    return compactTextAfterOTP;
1336  }
1337
1338
1339
1340  /**
1341   * {@inheritDoc}
1342   */
1343  @Override()
1344  public DeliverOneTimePasswordExtendedResult process(
1345              final LDAPConnection connection, final int depth)
1346         throws LDAPException
1347  {
1348    final ExtendedResult extendedResponse = super.process(connection, depth);
1349    return new DeliverOneTimePasswordExtendedResult(extendedResponse);
1350  }
1351
1352
1353
1354  /**
1355   * {@inheritDoc}.
1356   */
1357  @Override()
1358  public DeliverOneTimePasswordExtendedRequest duplicate()
1359  {
1360    return duplicate(getControls());
1361  }
1362
1363
1364
1365  /**
1366   * {@inheritDoc}.
1367   */
1368  @Override()
1369  public DeliverOneTimePasswordExtendedRequest duplicate(
1370                                                    final Control[] controls)
1371  {
1372    final DeliverOneTimePasswordExtendedRequest r =
1373         new DeliverOneTimePasswordExtendedRequest(authenticationID,
1374              staticPassword, messageSubject, fullTextBeforeOTP,
1375              fullTextAfterOTP, compactTextBeforeOTP, compactTextAfterOTP,
1376              preferredDeliveryMechanisms, controls);
1377    r.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
1378    return r;
1379  }
1380
1381
1382
1383  /**
1384   * {@inheritDoc}
1385   */
1386  @Override()
1387  public String getExtendedRequestName()
1388  {
1389    return INFO_DELIVER_OTP_REQ_NAME.get();
1390  }
1391
1392
1393
1394  /**
1395   * {@inheritDoc}
1396   */
1397  @Override()
1398  public void toString(final StringBuilder buffer)
1399  {
1400    buffer.append("DeliverOneTimePasswordExtendedRequest(authenticationID=");
1401    buffer.append(authenticationID);
1402
1403    if (messageSubject != null)
1404    {
1405      buffer.append(", messageSubject='");
1406      buffer.append(messageSubject);
1407      buffer.append('\'');
1408    }
1409
1410    if (fullTextBeforeOTP != null)
1411    {
1412      buffer.append(", fullTextBeforeOTP='");
1413      buffer.append(fullTextBeforeOTP);
1414      buffer.append('\'');
1415    }
1416
1417    if (fullTextAfterOTP != null)
1418    {
1419      buffer.append(", fullTextAfterOTP='");
1420      buffer.append(fullTextAfterOTP);
1421      buffer.append('\'');
1422    }
1423
1424    if (compactTextBeforeOTP != null)
1425    {
1426      buffer.append(", compactTextBeforeOTP='");
1427      buffer.append(compactTextBeforeOTP);
1428      buffer.append('\'');
1429    }
1430
1431    if (compactTextAfterOTP != null)
1432    {
1433      buffer.append(", compactTextAfterOTP='");
1434      buffer.append(compactTextAfterOTP);
1435      buffer.append('\'');
1436    }
1437
1438    if (preferredDeliveryMechanisms != null)
1439    {
1440      buffer.append(", preferredDeliveryMechanisms={");
1441
1442      final Iterator<ObjectPair<String,String>> iterator =
1443           preferredDeliveryMechanisms.iterator();
1444      while (iterator.hasNext())
1445      {
1446        final ObjectPair<String,String> p = iterator.next();
1447        buffer.append('\'');
1448        buffer.append(p.getFirst());
1449        if (p.getSecond() != null)
1450        {
1451          buffer.append('(');
1452          buffer.append(p.getSecond());
1453          buffer.append(')');
1454        }
1455        buffer.append('\'');
1456        if (iterator.hasNext())
1457        {
1458          buffer.append(',');
1459        }
1460      }
1461    }
1462
1463    final Control[] controls = getControls();
1464    if (controls.length > 0)
1465    {
1466      buffer.append(", controls={");
1467      for (int i=0; i < controls.length; i++)
1468      {
1469        if (i > 0)
1470        {
1471          buffer.append(", ");
1472        }
1473
1474        buffer.append(controls[i]);
1475      }
1476      buffer.append('}');
1477    }
1478
1479    buffer.append(')');
1480  }
1481}