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