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 com.unboundid.asn1.ASN1Element;
026 import com.unboundid.asn1.ASN1OctetString;
027 import com.unboundid.asn1.ASN1Sequence;
028 import com.unboundid.ldap.sdk.Control;
029 import com.unboundid.ldap.sdk.ExtendedRequest;
030 import com.unboundid.ldap.sdk.LDAPException;
031 import com.unboundid.ldap.sdk.ResultCode;
032 import com.unboundid.util.Debug;
033 import com.unboundid.util.NotMutable;
034 import com.unboundid.util.StaticUtils;
035 import com.unboundid.util.ThreadSafety;
036 import com.unboundid.util.ThreadSafetyLevel;
037 import com.unboundid.util.Validator;
038
039 import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
040
041
042
043 /**
044 * <BLOCKQUOTE>
045 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
046 * LDAP SDK for Java. It is not available for use in applications that
047 * include only the Standard Edition of the LDAP SDK, and is not supported for
048 * use in conjunction with non-UnboundID products.
049 * </BLOCKQUOTE>
050 * This class provides an implementation of an extended request that can be used
051 * to consume a single-use token that was generated and provided to the user
052 * through the deliver single-use token extended operation. Once a token has
053 * been consumed, it cannot be used again, although a new token can be generated
054 * and delivered to the user if necessary.
055 * <BR><BR>
056 * This extended request has an OID of "1.3.6.1.4.1.30221.2.6.51" and it must
057 * have a value with the following encoding:
058 * <PRE>
059 * ConsumeSingleUseTokenRequestValue ::= SEQUENCE {
060 * userDN LDAPDN,
061 * tokenID OCTET STRING,
062 * tokenValue OCTET STRING
063 * ... }
064 * </PRE>
065 *
066 * @see DeliverSingleUseTokenExtendedResult
067 */
068 @NotMutable()
069 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
070 public final class ConsumeSingleUseTokenExtendedRequest
071 extends ExtendedRequest
072 {
073 /**
074 * The OID (1.3.6.1.4.1.30221.2.6.51) for the consume single-use token
075 * extended request.
076 */
077 public static final String CONSUME_SINGLE_USE_TOKEN_REQUEST_OID =
078 "1.3.6.1.4.1.30221.2.6.51";
079
080
081
082 /**
083 * The serial version UID for this serializable class.
084 */
085 private static final long serialVersionUID = -3162206445662323272L;
086
087
088
089 // The identifier for the token to consume.
090 private final String tokenID;
091
092 // The value for the single-use token to consume.
093 private final String tokenValue;
094
095 // The DN of the user whose account contains the token to consume.
096 private final String userDN;
097
098
099
100 /**
101 * Creates a new consume single-use token extended request with the provided
102 * information.
103 *
104 * @param userDN The DN of the user whose account contains the token to
105 * consume. It must not be {@code null}.
106 * @param tokenID The identifier for the token to consume. It must not
107 * be {@code null}.
108 * @param tokenValue The value for the single-use token to consume. It
109 * must not be {@code null}.
110 * @param controls An optional set of controls to include in the request.
111 * It may be {@code null} or empty if no controls are
112 * required.
113 */
114 public ConsumeSingleUseTokenExtendedRequest(final String userDN,
115 final String tokenID,
116 final String tokenValue,
117 final Control... controls)
118 {
119 super(CONSUME_SINGLE_USE_TOKEN_REQUEST_OID,
120 encodeValue(userDN, tokenID, tokenValue),
121 controls);
122
123 this.userDN = userDN;
124 this.tokenID = tokenID;
125 this.tokenValue = tokenValue;
126 }
127
128
129
130 /**
131 * Decodes the provided extended request as a consume single-use token
132 * extended request.
133 *
134 * @param request The extended request to decode as a consume single-use
135 * token extended request.
136 *
137 * @throws LDAPException If the provided extended request cannot be decoded
138 * as a consume single-use token request.
139 */
140 public ConsumeSingleUseTokenExtendedRequest(final ExtendedRequest request)
141 throws LDAPException
142 {
143 super(request);
144
145 final ASN1OctetString value = request.getValue();
146 if (value == null)
147 {
148 throw new LDAPException(ResultCode.DECODING_ERROR,
149 ERR_CONSUME_SINGLE_USE_TOKEN_REQUEST_NO_VALUE.get());
150 }
151
152 try
153 {
154 final ASN1Element[] elements =
155 ASN1Sequence.decodeAsSequence(value.getValue()).elements();
156 userDN = ASN1OctetString.decodeAsOctetString(elements[0]).stringValue();
157 tokenID = ASN1OctetString.decodeAsOctetString(elements[1]).stringValue();
158 tokenValue =
159 ASN1OctetString.decodeAsOctetString(elements[2]).stringValue();
160 }
161 catch (final Exception e)
162 {
163 Debug.debugException(e);
164 throw new LDAPException(ResultCode.DECODING_ERROR,
165 ERR_CONSUME_SINGLE_USE_TOKEN_REQUEST_CANNOT_DECODE.get(
166 StaticUtils.getExceptionMessage(e)),
167 e);
168 }
169 }
170
171
172
173 /**
174 * Encodes the provided information into an ASN.1 octet string suitable for
175 * use as the value of the extended request.
176 *
177 * @param userDN The DN of the user whose account contains the token to
178 * consume. It must not be {@code null}.
179 * @param tokenID The identifier for the token to consume. It must not
180 * be {@code null}.
181 * @param tokenValue The value for the single-use token to consume. It
182 * must not be {@code null}.
183 *
184 * @return An ASN.1 octet string containing the encoded value.
185 */
186 private static ASN1OctetString encodeValue(final String userDN,
187 final String tokenID, final String tokenValue)
188 {
189 Validator.ensureNotNull(userDN);
190 Validator.ensureNotNull(tokenID);
191 Validator.ensureNotNull(tokenValue);
192
193 final ASN1Sequence valueSequence = new ASN1Sequence(
194 new ASN1OctetString(userDN),
195 new ASN1OctetString(tokenID),
196 new ASN1OctetString(tokenValue));
197 return new ASN1OctetString(valueSequence.encode());
198 }
199
200
201
202 /**
203 * Retrieves the DN of the user whose account contains the token to consume.
204 *
205 * @return The DN of the user whose account contains the token to consume.
206 */
207 public String getUserDN()
208 {
209 return userDN;
210 }
211
212
213
214 /**
215 * Retrieves the identifier for the token to consume.
216 *
217 * @return The identifier for the token to consume.
218 */
219 public String getTokenID()
220 {
221 return tokenID;
222 }
223
224
225
226 /**
227 * Retrieves the value for the token to consume.
228 *
229 * @return The value for the token to consume.
230 */
231 public String getTokenValue()
232 {
233 return tokenValue;
234 }
235
236
237
238 /**
239 * {@inheritDoc}.
240 */
241 @Override()
242 public ConsumeSingleUseTokenExtendedRequest duplicate()
243 {
244 return duplicate(getControls());
245 }
246
247
248
249 /**
250 * {@inheritDoc}.
251 */
252 @Override()
253 public ConsumeSingleUseTokenExtendedRequest duplicate(
254 final Control[] controls)
255 {
256 final ConsumeSingleUseTokenExtendedRequest r =
257 new ConsumeSingleUseTokenExtendedRequest(userDN, tokenID, tokenValue,
258 controls);
259 r.setResponseTimeoutMillis(getResponseTimeoutMillis(null));
260 return r;
261 }
262
263
264
265 /**
266 * {@inheritDoc}
267 */
268 @Override()
269 public String getExtendedRequestName()
270 {
271 return INFO_EXTENDED_REQUEST_NAME_CONSUME_SINGLE_USE_TOKEN.get();
272 }
273
274
275
276 /**
277 * {@inheritDoc}
278 */
279 @Override()
280 public void toString(final StringBuilder buffer)
281 {
282 buffer.append("ConsumeSingleUseTokenExtendedRequest(userDN='");
283 buffer.append(userDN);
284 buffer.append("', tokenID='");
285 buffer.append(tokenID);
286 buffer.append('\'');
287
288 final Control[] controls = getControls();
289 if (controls.length > 0)
290 {
291 buffer.append(", controls={");
292 for (int i=0; i < controls.length; i++)
293 {
294 if (i > 0)
295 {
296 buffer.append(", ");
297 }
298
299 buffer.append(controls[i]);
300 }
301 buffer.append('}');
302 }
303
304 buffer.append(')');
305 }
306 }