001 /*
002 * Copyright 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
027 import com.unboundid.asn1.ASN1Element;
028 import com.unboundid.asn1.ASN1OctetString;
029 import com.unboundid.asn1.ASN1Sequence;
030 import com.unboundid.ldap.sdk.Control;
031 import com.unboundid.ldap.sdk.ExtendedResult;
032 import com.unboundid.ldap.sdk.LDAPException;
033 import com.unboundid.ldap.sdk.ResultCode;
034 import com.unboundid.util.Debug;
035 import com.unboundid.util.NotMutable;
036 import com.unboundid.util.StaticUtils;
037 import com.unboundid.util.ThreadSafety;
038 import com.unboundid.util.ThreadSafetyLevel;
039 import com.unboundid.util.Validator;
040
041 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
042
043
044
045 /**
046 * <BLOCKQUOTE>
047 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
048 * LDAP SDK for Java. It is not available for use in applications that
049 * include only the Standard Edition of the LDAP SDK, and is not supported for
050 * use in conjunction with non-UnboundID products.
051 * </BLOCKQUOTE>
052 * This class provides an implementation of an extended result that may be used
053 * to provide information about the result of processing for a deliver
054 * single-use token extended request. If the token was delivered successfully,
055 * then this result will include information about the mechanism through which
056 * the token was delivered.
057 * <BR><BR>
058 * If the request was processed successfully, then the extended result will have
059 * an OID of 1.3.6.1.4.1.30221.2.6.50 and a value with the following encoding:
060 * <BR><BR>
061 * <PRE>
062 * DeliverSingleUseTokenResult ::= SEQUENCE {
063 * deliveryMechanism OCTET STRING,
064 * recipientID [0] OCTET STRING OPTIONAL,
065 * message [1] OCTET STRING OPTIONAL,
066 * ... }
067 * </PRE>
068 *
069 * @see DeliverSingleUseTokenExtendedRequest
070 * @see ConsumeSingleUseTokenExtendedRequest
071 */
072 @NotMutable()
073 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
074 public final class DeliverSingleUseTokenExtendedResult
075 extends ExtendedResult
076 {
077 /**
078 * The OID (1.3.6.1.4.1.30221.2.6.50) for the deliver single-use token
079 * extended result.
080 */
081 public static final String DELIVER_SINGLE_USE_TOKEN_RESULT_OID =
082 "1.3.6.1.4.1.30221.2.6.50";
083
084
085
086 /**
087 * The BER type for the recipient ID element of the value sequence.
088 */
089 private static final byte RECIPIENT_ID_BER_TYPE = (byte) 0x80;
090
091
092
093 /**
094 * The BER type for the message element of the value sequence.
095 */
096 private static final byte DELIVERY_MESSAGE_BER_TYPE = (byte) 0x81;
097
098
099
100 /**
101 * The serial version UID for this serializable class.
102 */
103 private static final long serialVersionUID = 8874679715973086041L;
104
105
106
107 // The name of the mechanism by which the single-use token was delivered.
108 private final String deliveryMechanism;
109
110 // An message providing additional information about the delivery of the
111 // single-use token.
112 private final String deliveryMessage;
113
114 // An identifier for the recipient of the single-use token.
115 private final String recipientID;
116
117
118
119 /**
120 * Creates a new deliver single-use token extended result with the provided
121 * information.
122 *
123 * @param messageID The message ID for the LDAP message that is
124 * associated with this LDAP result.
125 * @param resultCode The result code from the response. It must not
126 * be {@code null}.
127 * @param diagnosticMessage The diagnostic message from the response, if
128 * available.
129 * @param matchedDN The matched DN from the response, if available.
130 * @param referralURLs The set of referral URLs from the response, if
131 * available.
132 * @param deliveryMechanism The name of the mechanism by which the token was
133 * delivered, if available. This should be
134 * non-{@code null} for a success result.
135 * @param recipientID An identifier for the user to whom the token was
136 * delivered. It may be {@code null} if no token
137 * was delivered or there is no appropriate
138 * identifier, but if a value is provided then it
139 * should appropriate for the delivery mechanism
140 * (e.g., the user's e-mail address if delivered
141 * via e-mail, a phone number if delivered via SMS
142 * or voice call, etc.).
143 * @param deliveryMessage An optional message providing additional
144 * information about the token delivery, if
145 * available. If this is non-{@code null}, then
146 * the delivery mechanism must also be
147 * non-{@code null}.
148 * @param responseControls The set of controls for the response, if
149 * available.
150 */
151 public DeliverSingleUseTokenExtendedResult(final int messageID,
152 final ResultCode resultCode, final String diagnosticMessage,
153 final String matchedDN, final String[] referralURLs,
154 final String deliveryMechanism, final String recipientID,
155 final String deliveryMessage, final Control... responseControls)
156 {
157 super(messageID, resultCode, diagnosticMessage, matchedDN, referralURLs,
158 ((deliveryMechanism == null)
159 ? null : DELIVER_SINGLE_USE_TOKEN_RESULT_OID),
160 encodeValue(deliveryMechanism, recipientID, deliveryMessage),
161 responseControls);
162
163 this.deliveryMechanism = deliveryMechanism;
164 this.recipientID = recipientID;
165 this.deliveryMessage = deliveryMessage;
166 }
167
168
169
170 /**
171 * Creates a new deliver single-use token result from the provided generic
172 * extended result.
173 *
174 * @param result The generic extended result to be parsed as a deliver
175 * single-use token result.
176 *
177 * @throws LDAPException If the provided extended result cannot be parsed as
178 * a deliver single-use token result.
179 */
180 public DeliverSingleUseTokenExtendedResult(final ExtendedResult result)
181 throws LDAPException
182 {
183 super(result);
184
185 final ASN1OctetString value = result.getValue();
186 if (value == null)
187 {
188 deliveryMechanism = null;
189 recipientID = null;
190 deliveryMessage = null;
191 return;
192 }
193
194 try
195 {
196 final ASN1Element[] elements =
197 ASN1Sequence.decodeAsSequence(value.getValue()).elements();
198 deliveryMechanism =
199 ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
200
201 String id = null;
202 String msg = null;
203 for (int i=1; i < elements.length; i++)
204 {
205 switch (elements[i].getType())
206 {
207 case RECIPIENT_ID_BER_TYPE:
208 id = ASN1OctetString.decodeAsOctetString(elements[i]).stringValue();
209 break;
210
211 case DELIVERY_MESSAGE_BER_TYPE:
212 msg = ASN1OctetString.decodeAsOctetString(
213 elements[i]).stringValue();
214 break;
215
216 default:
217 throw new LDAPException(ResultCode.DECODING_ERROR,
218 ERR_DELIVER_SINGLE_USE_TOKEN_RESULT_UNEXPECTED_TYPE.get(
219 StaticUtils.toHex(elements[i].getType())));
220 }
221 }
222
223 recipientID = id;
224 deliveryMessage = msg;
225 }
226 catch (final LDAPException le)
227 {
228 Debug.debugException(le);
229 throw le;
230 }
231 catch (final Exception e)
232 {
233 Debug.debugException(e);
234 throw new LDAPException(ResultCode.DECODING_ERROR,
235 ERR_DELIVER_SINGLE_USE_TOKEN_RESULT_ERROR_DECODING_VALUE.get(
236 StaticUtils.getExceptionMessage(e)),
237 e);
238 }
239 }
240
241
242
243 /**
244 * Encodes the provided information into an ASN.1 octet string suitable for
245 * use as the value of this extended result.
246 *
247 * @param deliveryMechanism The name of the mechanism by which the token was
248 * delivered, if available. This should be
249 * non-{@code null} for a success result.
250 * @param recipientID An identifier for the user to whom the token was
251 * delivered. It may be {@code null} if no token
252 * was delivered or there is no appropriate
253 * identifier, but if a value is provided then it
254 * should appropriate for the delivery mechanism
255 * (e.g., the user's e-mail address if delivered
256 * via e-mail, a phone number if delivered via SMS
257 * or voice call, etc.).
258 * @param deliveryMessage An optional message providing additional
259 * information about the token delivery, if
260 * available. If this is non-{@code null}, then
261 * the delivery mechanism must also be
262 * non-{@code null}.
263 *
264 * @return An ASN.1 octet string containing the encoded value, or
265 * {@code null} if the extended result should not have a value.
266 */
267 private static ASN1OctetString encodeValue(final String deliveryMechanism,
268 final String recipientID,
269 final String deliveryMessage)
270 {
271 if (deliveryMechanism == null)
272 {
273 Validator.ensureTrue((recipientID == null),
274 "The delivery mechanism must be non-null if the recipient ID " +
275 "is non-null.");
276 Validator.ensureTrue((deliveryMessage == null),
277 "The delivery mechanism must be non-null if the delivery message " +
278 "is non-null.");
279 return null;
280 }
281
282 final ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(3);
283 elements.add(new ASN1OctetString(deliveryMechanism));
284
285 if (recipientID != null)
286 {
287 elements.add(new ASN1OctetString(RECIPIENT_ID_BER_TYPE, recipientID));
288 }
289
290 if (deliveryMessage != null)
291 {
292 elements.add(new ASN1OctetString(DELIVERY_MESSAGE_BER_TYPE,
293 deliveryMessage));
294 }
295
296 return new ASN1OctetString(new ASN1Sequence(elements).encode());
297 }
298
299
300
301 /**
302 * Retrieves the name of the mechanism by which the single-use token was
303 * delivered to the user, if available.
304 *
305 * @return The name of the mechanism by which the single-use token was
306 * delivered to the user, or {@code null} if this is not available.
307 */
308 public String getDeliveryMechanism()
309 {
310 return deliveryMechanism;
311 }
312
313
314
315 /**
316 * Retrieves an identifier for the user to whom the single-use token was
317 * delivered, if available. If a recipient ID is provided, then it should be
318 * in a form appropriate to the delivery mechanism (e.g., an e-mail address
319 * if the token was delivered by e-mail, a phone number if it was delivered
320 * by SMS or a voice call, etc.).
321 *
322 * @return An identifier for the user to whom the single-use token was
323 * delivered, or {@code null} if this is not available.
324 */
325 public String getRecipientID()
326 {
327 return recipientID;
328 }
329
330
331
332 /**
333 * Retrieves a message providing additional information about the single-use
334 * token delivery, if available.
335 *
336 * @return A message providing additional information about the single-use
337 * token delivery, or {@code null} if this is not available.
338 */
339 public String getDeliveryMessage()
340 {
341 return deliveryMessage;
342 }
343
344
345
346 /**
347 * {@inheritDoc}
348 */
349 @Override()
350 public String getExtendedResultName()
351 {
352 return INFO_EXTENDED_RESULT_NAME_DELIVER_SINGLE_USE_TOKEN.get();
353 }
354
355
356
357 /**
358 * Appends a string representation of this extended result to the provided
359 * buffer.
360 *
361 * @param buffer The buffer to which a string representation of this
362 * extended result will be appended.
363 */
364 @Override()
365 public void toString(final StringBuilder buffer)
366 {
367 buffer.append("DeliverSingleUseTokenExtendedResult(resultCode=");
368 buffer.append(getResultCode());
369
370 final int messageID = getMessageID();
371 if (messageID >= 0)
372 {
373 buffer.append(", messageID=");
374 buffer.append(messageID);
375 }
376
377 if (deliveryMechanism != null)
378 {
379 buffer.append(", deliveryMechanism='");
380 buffer.append(deliveryMechanism);
381 buffer.append('\'');
382 }
383
384 if (recipientID != null)
385 {
386 buffer.append(", recipientID='");
387 buffer.append(recipientID);
388 buffer.append('\'');
389 }
390
391 if (deliveryMessage != null)
392 {
393 buffer.append(", deliveryMessage='");
394 buffer.append(deliveryMessage);
395 buffer.append('\'');
396 }
397
398 final String diagnosticMessage = getDiagnosticMessage();
399 if (diagnosticMessage != null)
400 {
401 buffer.append(", diagnosticMessage='");
402 buffer.append(diagnosticMessage);
403 buffer.append('\'');
404 }
405
406 final String matchedDN = getMatchedDN();
407 if (matchedDN != null)
408 {
409 buffer.append(", matchedDN='");
410 buffer.append(matchedDN);
411 buffer.append('\'');
412 }
413
414 final String[] referralURLs = getReferralURLs();
415 if (referralURLs.length > 0)
416 {
417 buffer.append(", referralURLs={");
418 for (int i=0; i < referralURLs.length; i++)
419 {
420 if (i > 0)
421 {
422 buffer.append(", ");
423 }
424
425 buffer.append('\'');
426 buffer.append(referralURLs[i]);
427 buffer.append('\'');
428 }
429 buffer.append('}');
430 }
431
432 final Control[] responseControls = getResponseControls();
433 if (responseControls.length > 0)
434 {
435 buffer.append(", responseControls={");
436 for (int i=0; i < responseControls.length; i++)
437 {
438 if (i > 0)
439 {
440 buffer.append(", ");
441 }
442
443 buffer.append(responseControls[i]);
444 }
445 buffer.append('}');
446 }
447
448 buffer.append(')');
449 }
450 }