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