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.controls;
022
023
024
025 import java.io.Serializable;
026 import java.util.ArrayList;
027
028 import com.unboundid.asn1.ASN1Boolean;
029 import com.unboundid.asn1.ASN1Element;
030 import com.unboundid.asn1.ASN1OctetString;
031 import com.unboundid.asn1.ASN1Sequence;
032 import com.unboundid.ldap.sdk.LDAPException;
033 import com.unboundid.ldap.sdk.ResultCode;
034 import com.unboundid.ldap.sdk.unboundidds.extensions.PasswordQualityRequirement;
035 import com.unboundid.util.Debug;
036 import com.unboundid.util.NotMutable;
037 import com.unboundid.util.StaticUtils;
038 import com.unboundid.util.ThreadSafety;
039 import com.unboundid.util.ThreadSafetyLevel;
040 import com.unboundid.util.Validator;
041
042 import static com.unboundid.ldap.sdk.unboundidds.controls.ControlMessages.*;
043
044
045
046 /**
047 * <BLOCKQUOTE>
048 * <B>NOTE:</B> This class is part of the Commercial Edition of the UnboundID
049 * LDAP SDK for Java. It is not available for use in applications that
050 * include only the Standard Edition of the LDAP SDK, and is not supported for
051 * use in conjunction with non-UnboundID products.
052 * </BLOCKQUOTE>
053 * This class provides a data structure that holds information about the result
054 * of attempting validation with a proposed password against a password quality
055 * requirement.
056 * <BR><BR>
057 * If it appears in an LDAP protocol element (e.g., in a password validation
058 * details response control), then the password quality validation result object
059 * should have the following ASN.1 encoding:
060 * <PRE>
061 * PasswordQualityRequirementValidationResult ::= SEQUENCE {
062 * passwordRequirement PasswordQualityRequirement,
063 * requirementSatisfied BOOLEAN,
064 * additionalInfo [0] OCTET STRING OPTIONAL }
065 * </PRE>
066 */
067 @NotMutable()
068 @ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
069 public final class PasswordQualityRequirementValidationResult
070 implements Serializable
071 {
072 /**
073 * The BER type for the additional info element of the value sequence.
074 */
075 private static final byte TYPE_ADDITIONAL_INFO = (byte) 0x80;
076
077
078
079 /**
080 * The serial version UID for this serializable class.
081 */
082 private static final long serialVersionUID = -8048878239770726375L;
083
084
085
086 // Indicates whether the proposed password satisfied the constraints of the
087 // associated password quality requirement.
088 private final boolean requirementSatisfied;
089
090 // The password quality requirement to which this validation result applies.
091 private final PasswordQualityRequirement passwordRequirement;
092
093 // An optional message with additional information about the result of the
094 // validation for the proposed password with respect to the associated
095 // password quality requirement.
096 private final String additionalInfo;
097
098
099
100 /**
101 * Creates a new password quality requirement validation result object with
102 * the provided information.
103 *
104 * @param passwordRequirement The password quality requirement to which
105 * this validation result applies. This must
106 * not be {@code null}.
107 * @param requirementSatisfied Indicates whether the proposed password
108 * satisfied the constraints of the associated
109 * password quality requirement.
110 * @param additionalInfo An optional message with additional
111 * information about the result of the
112 * validation for the proposed password with
113 * respect to the associated password quality
114 * requirement.
115 */
116 public PasswordQualityRequirementValidationResult(
117 final PasswordQualityRequirement passwordRequirement,
118 final boolean requirementSatisfied, final String additionalInfo)
119 {
120 Validator.ensureNotNull(passwordRequirement);
121
122 this.passwordRequirement = passwordRequirement;
123 this.requirementSatisfied = requirementSatisfied;
124 this.additionalInfo = additionalInfo;
125 }
126
127
128
129 /**
130 * Retrieves the password quality requirement to which this validation result
131 * applies.
132 *
133 * @return The password quality requirement to which this validation result
134 * applies.
135 */
136 public PasswordQualityRequirement getPasswordRequirement()
137 {
138 return passwordRequirement;
139 }
140
141
142
143 /**
144 * Indicates whether the proposed password satisfied the constraints of the
145 * associated password quality requirement.
146 *
147 * @return {@code true} if the proposed password satisfied the constraints of
148 * the associated password quality requirement, or {@code false} if
149 * not.
150 */
151 public boolean requirementSatisfied()
152 {
153 return requirementSatisfied;
154 }
155
156
157
158 /**
159 * Retrieves a message with additional information about the result of the
160 * validation of the proposed password with respect to the associated
161 * password quality requirement.
162 *
163 * @return A message with additional information about the result of the
164 * validation, or {@code null} if no additional information is
165 * available.
166 */
167 public String getAdditionalInfo()
168 {
169 return additionalInfo;
170 }
171
172
173
174 /**
175 * Encodes this password quality requirement validation result object to an
176 * ASN.1 element.
177 *
178 * @return The ASN.1 element that provides an encoded representation of this
179 * object.
180 */
181 public ASN1Element encode()
182 {
183 final ArrayList<ASN1Element> elements = new ArrayList<ASN1Element>(3);
184 elements.add(passwordRequirement.encode());
185 elements.add(new ASN1Boolean(requirementSatisfied));
186
187 if (additionalInfo != null)
188 {
189 elements.add(new ASN1OctetString(TYPE_ADDITIONAL_INFO, additionalInfo));
190 }
191
192 return new ASN1Sequence(elements);
193 }
194
195
196
197 /**
198 * Decodes the provided ASN.1 element as a password quality requirement
199 * validation result.
200 *
201 * @param element The ASN.1 element to be decoded as a password quality
202 * requirement validation result.
203 *
204 * @return The ASN.1 element containing the encoded password quality
205 * requirement validation result.
206 *
207 * @throws LDAPException If a problem is encountered while attempting to
208 * decode the provided ASN.1 element.
209 */
210 public static PasswordQualityRequirementValidationResult decode(
211 final ASN1Element element)
212 throws LDAPException
213 {
214 try
215 {
216 final ASN1Element[] elements =
217 ASN1Sequence.decodeAsSequence(element).elements();
218 final PasswordQualityRequirement passwordRequirement =
219 PasswordQualityRequirement.decode(elements[0]);
220 final boolean requirementSatisfied =
221 ASN1Boolean.decodeAsBoolean(elements[1]).booleanValue();
222
223 String additionalInfo = null;
224 for (int i=2; i < elements.length; i++)
225 {
226 switch (elements[i].getType())
227 {
228 case TYPE_ADDITIONAL_INFO:
229 additionalInfo =
230 ASN1OctetString.decodeAsOctetString(elements[i]).stringValue();
231 break;
232
233 default:
234 throw new LDAPException(ResultCode.DECODING_ERROR,
235 ERR_PW_REQ_VALIDATION_RESULT_INVALID_ELEMENT_TYPE.get(
236 StaticUtils.toHex(elements[i].getType())));
237 }
238 }
239
240 return new PasswordQualityRequirementValidationResult(passwordRequirement,
241 requirementSatisfied, additionalInfo);
242 }
243 catch (final LDAPException le)
244 {
245 Debug.debugException(le);
246 throw le;
247 }
248 catch (final Exception e)
249 {
250 Debug.debugException(e);
251 throw new LDAPException(ResultCode.DECODING_ERROR,
252 ERR_PW_REQ_VALIDATION_RESULT_CANNOT_DECODE.get(
253 StaticUtils.getExceptionMessage(e)),
254 e);
255 }
256 }
257
258
259
260 /**
261 * Retrieves a string representation of this password quality requirement
262 * validation result.
263 *
264 * @return A string representation of this password quality requirement
265 * validation result.
266 */
267 @Override()
268 public String toString()
269 {
270 final StringBuilder buffer = new StringBuilder();
271 toString(buffer);
272 return buffer.toString();
273 }
274
275
276
277 /**
278 * Appends a string representation of this password quality requirement
279 * validation result to the provided buffer.
280 *
281 * @param buffer The buffer to which the information should be appended.
282 */
283 public void toString(final StringBuilder buffer)
284 {
285 buffer.append("PasswordQualityRequirementValidationResult(requirement=");
286 passwordRequirement.toString(buffer);
287 buffer.append(", requirementSatisfied=");
288 buffer.append(requirementSatisfied);
289
290 if (additionalInfo != null)
291 {
292 buffer.append(", additionalInfo='");
293 buffer.append(additionalInfo);
294 buffer.append('\'');
295 }
296
297 buffer.append(')');
298 }
299 }