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