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