com.unboundid.ldap.sdk.unboundidds.extensions.GeneratedPassword Maven / Gradle / Ivy
/*
* Copyright 2019 Ping Identity Corporation
* All Rights Reserved.
*/
/*
* Copyright (C) 2019 Ping Identity Corporation
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License (GPLv2 only)
* or the terms of the GNU Lesser General Public License (LGPLv2.1 only)
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, see .
*/
package com.unboundid.ldap.sdk.unboundidds.extensions;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import com.unboundid.asn1.ASN1Boolean;
import com.unboundid.asn1.ASN1Element;
import com.unboundid.asn1.ASN1OctetString;
import com.unboundid.asn1.ASN1Sequence;
import com.unboundid.ldap.sdk.LDAPException;
import com.unboundid.ldap.sdk.ResultCode;
import com.unboundid.util.Debug;
import com.unboundid.util.NotMutable;
import com.unboundid.util.StaticUtils;
import com.unboundid.util.ThreadSafety;
import com.unboundid.util.ThreadSafetyLevel;
import com.unboundid.util.Validator;
import static com.unboundid.ldap.sdk.unboundidds.extensions.ExtOpMessages.*;
/**
* This class defines a data structure that holds information about a password
* generated by the server and returned to the client in a
* {@link GeneratePasswordExtendedResult}.
*
*
* NOTE: This class, and other classes within the
* {@code com.unboundid.ldap.sdk.unboundidds} package structure, are only
* supported for use against Ping Identity, UnboundID, and
* Nokia/Alcatel-Lucent 8661 server products. These classes provide support
* for proprietary functionality or for external specifications that are not
* considered stable or mature enough to be guaranteed to work in an
* interoperable way with other types of LDAP servers.
*
*/
@NotMutable()
@ThreadSafety(level=ThreadSafetyLevel.COMPLETELY_THREADSAFE)
public final class GeneratedPassword
implements Serializable
{
/**
* The BER type for the element that provides a list of validation errors for
* the generated password.
*/
private static final byte TYPE_VALIDATION_ERRORS = (byte) 0xA0;
/**
* The serial version UID for this serializable class.
*/
private static final long serialVersionUID = -240847847799966594L;
// The password that was generated.
private final ASN1OctetString password;
// Indicates whether the server attempted to perform any validation on the
// provided password.
private final boolean validationAttempted;
// A list of messages with information about any problems identified while the
// server was validating the quality of the generated password.
private final List validationErrors;
/**
* Creates a generated password object with the provided information.
*
* @param password The password that was generated. It must not
* be @code null} or empty.
* @param validationAttempted Indicates whether the server attempted to
* validate the quality of the generated
* password.
* @param validationErrors An optional list of messages with information
* about any problems identified while the
* server was validating the quality of the
* generated password.
*/
public GeneratedPassword(final String password,
final boolean validationAttempted,
final List validationErrors)
{
this(new ASN1OctetString(password), validationAttempted, validationErrors);
}
/**
* Creates a generated password object with the provided information.
*
* @param password The password that was generated. It must not
* be @code null} or empty.
* @param validationAttempted Indicates whether the server attempted to
* validate the quality of the generated
* password.
* @param validationErrors An optional list of messages with information
* about any problems identified while the
* server was validating the quality of the
* generated password.
*/
public GeneratedPassword(final byte[] password,
final boolean validationAttempted,
final List validationErrors)
{
this(new ASN1OctetString(password), validationAttempted, validationErrors);
}
/**
* Creates a generated password object with the provided information.
*
* @param password The password that was generated. It must not
* be @code null} or empty.
* @param validationAttempted Indicates whether the server attempted to
* validate the quality of the generated
* password.
* @param validationErrors An optional list of messages with information
* about any problems identified while the
* server was validating the quality of the
* generated password.
*/
private GeneratedPassword(final ASN1OctetString password,
final boolean validationAttempted,
final List validationErrors)
{
Validator.ensureTrue(
((password != null) && (password.getValueLength() > 0)),
"GeneratedPassword.password must not be null or empty.");
this.password = password;
this.validationAttempted = validationAttempted;
if (validationErrors == null)
{
this.validationErrors = Collections.emptyList();
}
else
{
this.validationErrors = Collections.unmodifiableList(
new ArrayList<>(validationErrors));
}
}
/**
* Retrieves a string representation of the server-generated password.
*
* @return A string representation of the server-generated password.
*/
public String getPasswordString()
{
return password.stringValue();
}
/**
* Retrieves the bytes that comprise the server-generated password.
*
* @return The bytes that comprise the server-generated password.
*/
public byte[] getPasswordBytes()
{
return password.getValue();
}
/**
* Indicates whether the server attempted to validate the quality of the
* generated password.
*
* @return {@code true} if the server attempted to validate the quality of
* the generated password, or {@code false} if not.
*/
public boolean validationAttempted()
{
return validationAttempted;
}
/**
* Retrieves a list of problems identified while the server was validating the
* quality of the generated password.
*
* @return A list of problems identified while the server was validating the
* quality of the generated password, or an empty list if no
* validation was attempted or if the generated password satisfied
* all of the requirements for all of the appropriate password
* validators.
*/
public List getValidationErrors()
{
return validationErrors;
}
/**
* Encodes this generated password to a sequence suitable for inclusion in the
* value of a {@link GeneratePasswordExtendedResult}.
*
* @return An ASN.1 sequence containing an encoded representation of this
* generated password object.
*/
public ASN1Sequence encode()
{
final List elements = new ArrayList<>(3);
elements.add(password);
elements.add(new ASN1Boolean(validationAttempted));
if (! validationErrors.isEmpty())
{
final List validationErrorElements =
new ArrayList<>(validationErrors.size());
for (final String error : validationErrors)
{
validationErrorElements.add(new ASN1OctetString(error));
}
elements.add(new ASN1Sequence(TYPE_VALIDATION_ERRORS,
validationErrorElements));
}
return new ASN1Sequence(elements);
}
/**
* Decodes the provided ASN.1 element as a generated password object.
*
* @param element The ASN.1 element to be decoded. It must not be
* {@code null}.
*
* @return The generated password object that was decoded.
*
* @throws LDAPException If a problem is encountered while decoding the
* provided element as a generated password.
*/
public static GeneratedPassword decode(final ASN1Element element)
throws LDAPException
{
try
{
final ASN1Element[] elements =
ASN1Sequence.decodeAsSequence(element).elements();
final ASN1OctetString password = elements[0].decodeAsOctetString();
final boolean validationAttempted =
elements[1].decodeAsBoolean().booleanValue();
final List validationErrors = new ArrayList<>(5);
for (int i=2; i < elements.length; i++)
{
if (elements[i].getType() == TYPE_VALIDATION_ERRORS)
{
for (final ASN1Element errorElement :
elements[i].decodeAsSequence().elements())
{
validationErrors.add(
errorElement.decodeAsOctetString().stringValue());
}
}
}
return new GeneratedPassword(password, validationAttempted,
validationErrors);
}
catch (final Exception e)
{
Debug.debugException(e);
throw new LDAPException(ResultCode.DECODING_ERROR,
ERR_GENERATED_PASSWORD_DECODING_ERROR.get(
StaticUtils.getExceptionMessage(e)),
e);
}
}
/**
* Retrieves a string representation of this generated password object.
*
* @return A string representation of this generated password object.
*/
@Override()
public String toString()
{
final StringBuilder buffer = new StringBuilder();
toString(buffer);
return buffer.toString();
}
/**
* Appends a string representation of this generated password object to the
* provided buffer.
*
* @param buffer The buffer to which the information should be appended.
*/
public void toString(final StringBuilder buffer)
{
buffer.append("GeneratedPassword(passwordLength=");
buffer.append(password.getValueLength());
buffer.append(", validationAttempted=");
buffer.append(validationAttempted);
if (! validationErrors.isEmpty())
{
buffer.append(", validationErrors={");
buffer.append('}');
}
buffer.append(')');
}
}