package at.gv.egiz.eaaf.core.impl.http;
import java.text.MessageFormat;
import java.util.UUID;
import javax.annotation.Nonnull;
import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException;
import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration;
import org.apache.commons.lang3.StringUtils;
import lombok.Getter;
import lombok.Setter;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Getter
public class HttpClientConfiguration {
private static final String MSG_KEYSTORE_NAME = "KeyStore for httpClient: {0}";
private static final String ERROR_00 = "internal.httpclient.00";
private static final String ERROR_01 = "internal.httpclient.01";
private static final String ERROR_02 = "internal.httpclient.02";
@Nonnull
private final String friendlyName;
@Nonnull
private final String uuid;
@Nonnull
private ClientAuthMode authMode = ClientAuthMode.NONE;
@Setter
private String username;
@Setter
private String password;
@Setter
boolean disableHostnameValidation = false;
@Setter
boolean disableTlsHostCertificateValidation = false;
private KeyStoreConfiguration keyStoreConfig;
@Setter
private String sslKeyAlias;
@Setter
private String sslKeyPassword;
@Setter
private boolean followHttpRedirects = true;
/**
* Get a new HTTP-client configuration object.
*
* @param name FriendlyName of this http client for logging purposes.
*/
public HttpClientConfiguration(String name) {
this.friendlyName = name;
this.uuid = UUID.randomUUID().toString();
}
/**
* Set Client authentication-mode from configuration property.
*
*
If the mode is unknown than the {@link ClientAuthMode} is set to NONE
*
* @param authModeString Modes from {@link ClientAuthMode}
*/
public void setAuthMode(String authModeString) {
final ClientAuthMode configAuthMode = HttpClientConfiguration.ClientAuthMode.fromString(authModeString);
if (configAuthMode != null) {
authMode = configAuthMode;
} else {
log.warn("Can Not parse ClientAuthMode for client: {}! Set mode to default value",
friendlyName);
}
}
/**
* Validate the internal state of this configuration object.
*
* @throws EaafConfigurationException In case of a configuration error
*/
public void validate() throws EaafConfigurationException {
log.trace("Validating http-client: {}", this.friendlyName);
if (this.authMode.equals(ClientAuthMode.PASSWORD)) {
if (StringUtils.isEmpty(this.username)) {
throw new EaafConfigurationException(ERROR_00, new Object[] {this.friendlyName});
}
if (StringUtils.isEmpty(this.password)) {
log.warn("Http basic authentication was activated but NOT username was set!");
}
} else if (this.authMode.equals(ClientAuthMode.SSL)) {
if (this.keyStoreConfig == null) {
throw new EaafConfigurationException(ERROR_01, new Object[] {this.friendlyName});
} else {
log.trace("Validating KeyStore: {} for http-client: {} ...",
this.keyStoreConfig.getFriendlyName(), this.friendlyName);
this.keyStoreConfig.validate();
}
if (StringUtils.isEmpty(this.sslKeyPassword)) {
throw new EaafConfigurationException(ERROR_02, new Object[] {
this.friendlyName, this.keyStoreConfig.getFriendlyName()});
}
}
}
/**
* Build a {@link KeyStoreConfiguration} object from configuration parameters.
*
* @param keyStoreType String based KeyStore type
* @param keyStorePath Path to KeyStore in case of a software based KeyStore
* @param keyStorePassword Password in case of a software based KeyStore
* @param keyStoreName Name of the KeyStore in case of a named KeyStore like HSM-Facade
* @throws EaafConfigurationException In case of a configuration error
*/
public void buildKeyStoreConfig(String keyStoreType, String keyStorePath,
String keyStorePassword, String keyStoreName) throws EaafConfigurationException {
final KeyStoreConfiguration config = new KeyStoreConfiguration();
config.setKeyStoreType(keyStoreType);
config.setFriendlyName(MessageFormat.format(MSG_KEYSTORE_NAME, friendlyName));
config.setSoftKeyStoreFilePath(keyStorePath);
config.setSoftKeyStorePassword(keyStorePassword);
config.setKeyStoreName(keyStoreName);
this.keyStoreConfig = config;
}
public enum ClientAuthMode {
NONE("none"), PASSWORD("password"), SSL("ssl");
private final String mode;
ClientAuthMode(final String mode) {
this.mode = mode;
}
/**
* Get the PVP mode.
*
* @return
*/
public String getMode() {
return this.mode;
}
/**
* Get http-client authentication mode from String representation.
*
* @param s Config parameter
* @return
*/
public static ClientAuthMode fromString(final String s) {
try {
return ClientAuthMode.valueOf(s.toUpperCase());
} catch (IllegalArgumentException | NullPointerException e) {
return null;
}
}
@Override
public String toString() {
return getMode();
}
}
}