package at.gv.egiz.eaaf.core.impl.http; import java.text.MessageFormat; import java.util.UUID; import javax.annotation.Nonnull; import org.apache.commons.lang3.StringUtils; import at.gv.egiz.eaaf.core.exceptions.EaafConfigurationException; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration; import at.gv.egiz.eaaf.core.impl.credential.KeyStoreConfiguration.KeyStoreType; 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; @Setter private int httpErrorRetryCount = 3; @Setter private boolean httpErrorRetryPost = false; /** * 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) && (KeyStoreType.JKS.equals(keyStoreConfig.getKeyStoreType()) || KeyStoreType.PKCS12.equals(keyStoreConfig.getKeyStoreType()))) { 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(); } } }