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 }