Skip to content

Commit

Permalink
Merge pull request #23 from partior-3p/feature/set559_db_credsin_vaul…
Browse files Browse the repository at this point in the history
…t_uat

Added Environment Variables for Authentication to Vault DB Secret Engine
  • Loading branch information
john-sobrepena-partior authored Aug 27, 2024
2 parents 6ea1849 + c1e1dfb commit 2f54f27
Show file tree
Hide file tree
Showing 7 changed files with 107 additions and 20 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,12 @@ public final class EnvironmentVariables {

public static final String HASHICORP_TOKEN = "HASHICORP_TOKEN";

public static final String HASHICORP_DSE_ROLE_ID = "HASHICORP_DSE_ROLE_ID";

public static final String HASHICORP_DSE_SECRET_ID = "HASHICORP_DSE_SECRET_ID";

public static final String HASHICORP_DSE_TOKEN = "HASHICORP_DSE_TOKEN";

public static final String HASHICORP_CLIENT_KEYSTORE_PWD = "HASHICORP_CLIENT_KEYSTORE_PWD";

public static final String HASHICORP_CLIENT_TRUSTSTORE_PWD = "HASHICORP_CLIENT_TRUSTSTORE_PWD";
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
package com.quorum.tessera.key.vault.hashicorp;

import static com.quorum.tessera.config.util.EnvironmentVariables.*;

import com.quorum.tessera.config.Config;
import com.quorum.tessera.config.ConfigException;
import com.quorum.tessera.config.KeyVaultConfig;
Expand Down Expand Up @@ -32,7 +34,10 @@ HashicorpDbCredentialsVaultService create(
envProvider,
util,
this::getKeyVaultConfig,
HashicorpDbCredentialsVaultService::new);
HashicorpDbCredentialsVaultService::new,
HASHICORP_DSE_ROLE_ID,
HASHICORP_DSE_SECRET_ID,
HASHICORP_DSE_TOKEN);
}

private KeyVaultConfig getKeyVaultConfig(Config config) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,10 +77,28 @@ ClientAuthentication configureClientAuthentication(
EnvironmentVariableProvider envProvider,
ClientHttpRequestFactory clientHttpRequestFactory,
VaultEndpoint vaultEndpoint) {
return configureClientAuthentication(
keyVaultConfig,
envProvider,
clientHttpRequestFactory,
vaultEndpoint,
HASHICORP_ROLE_ID,
HASHICORP_SECRET_ID,
HASHICORP_TOKEN);
}

ClientAuthentication configureClientAuthentication(
KeyVaultConfig keyVaultConfig,
EnvironmentVariableProvider envProvider,
ClientHttpRequestFactory clientHttpRequestFactory,
VaultEndpoint vaultEndpoint,
String envVarHashicorpRoleId,
String envVarHashicorpSecretId,
String envVarHashicorpToken) {

final String roleId = envProvider.getEnv(HASHICORP_ROLE_ID);
final String secretId = envProvider.getEnv(HASHICORP_SECRET_ID);
final String authToken = envProvider.getEnv(HASHICORP_TOKEN);
final String roleId = envProvider.getEnv(envVarHashicorpRoleId);
final String secretId = envProvider.getEnv(envVarHashicorpSecretId);
final String authToken = envProvider.getEnv(envVarHashicorpToken);

if (roleId != null && secretId != null) {

Expand Down Expand Up @@ -110,20 +128,20 @@ ClientAuthentication configureClientAuthentication(

throw new HashicorpCredentialNotSetException(
"Both "
+ HASHICORP_ROLE_ID
+ envVarHashicorpRoleId
+ " and "
+ HASHICORP_SECRET_ID
+ envVarHashicorpSecretId
+ " environment variables must be set to use the AppRole authentication method");

} else if (authToken == null) {

throw new HashicorpCredentialNotSetException(
"Both "
+ HASHICORP_ROLE_ID
+ envVarHashicorpRoleId
+ " and "
+ HASHICORP_SECRET_ID
+ envVarHashicorpSecretId
+ " environment variables must be set to use the AppRole authentication method. Alternatively set "
+ HASHICORP_TOKEN
+ envVarHashicorpToken
+ " to authenticate using the Token method");
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,32 +36,52 @@ <R> R create(
HashicorpKeyVaultServiceFactoryUtil util,
Function<Config, KeyVaultConfig> keyVaultConfigProvider,
BiFunction<VaultOperations, KeyVaultConfig, R> keyVaultServiceProvider) {
return create(
config,
envProvider,
util,
keyVaultConfigProvider,
keyVaultServiceProvider,
HASHICORP_ROLE_ID,
HASHICORP_SECRET_ID,
HASHICORP_TOKEN);
}

<R> R create(
Config config,
EnvironmentVariableProvider envProvider,
HashicorpKeyVaultServiceFactoryUtil util,
Function<Config, KeyVaultConfig> keyVaultConfigProvider,
BiFunction<VaultOperations, KeyVaultConfig, R> keyVaultServiceProvider,
String envVarHashicorpRoleId,
String envVarHashicorpSecretId,
String envVarHashicorpToken) {

Objects.requireNonNull(config);
Objects.requireNonNull(envProvider);
Objects.requireNonNull(util);
Objects.requireNonNull(keyVaultConfigProvider);
Objects.requireNonNull(keyVaultServiceProvider);

final String roleId = envProvider.getEnv(HASHICORP_ROLE_ID);
final String secretId = envProvider.getEnv(HASHICORP_SECRET_ID);
final String authToken = envProvider.getEnv(HASHICORP_TOKEN);
final String roleId = envProvider.getEnv(envVarHashicorpRoleId);
final String secretId = envProvider.getEnv(envVarHashicorpSecretId);
final String authToken = envProvider.getEnv(envVarHashicorpToken);

if (roleId == null && secretId == null && authToken == null) {
throw new HashicorpCredentialNotSetException(
"Environment variables must be set to authenticate with Hashicorp Vault. Set the "
+ HASHICORP_ROLE_ID
+ envVarHashicorpRoleId
+ " and "
+ HASHICORP_SECRET_ID
+ envVarHashicorpSecretId
+ " environment variables if using the AppRole authentication method. Set the "
+ HASHICORP_TOKEN
+ envVarHashicorpToken
+ " environment variable if using another authentication method.");
} else if (isOnlyOneInputNull(roleId, secretId)) {
throw new HashicorpCredentialNotSetException(
"Only one of the "
+ HASHICORP_ROLE_ID
+ envVarHashicorpRoleId
+ " and "
+ HASHICORP_SECRET_ID
+ envVarHashicorpSecretId
+ " environment variables to authenticate with Hashicorp Vault using the AppRole method has been set");
}

Expand All @@ -87,7 +107,13 @@ <R> R create(

ClientAuthentication clientAuthentication =
util.configureClientAuthentication(
keyVaultConfig, envProvider, clientHttpRequestFactory, vaultEndpoint);
keyVaultConfig,
envProvider,
clientHttpRequestFactory,
vaultEndpoint,
envVarHashicorpRoleId,
envVarHashicorpSecretId,
envVarHashicorpToken);

SessionManager sessionManager = new SimpleSessionManager(clientAuthentication);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -268,6 +268,15 @@ private void setUpUtilMocks(KeyVaultConfig keyVaultConfig) {
eq(clientHttpRequestFactory),
any(VaultEndpoint.class)))
.thenReturn(clientAuthentication);
when(keyVaultServiceFactoryUtil.configureClientAuthentication(
eq(keyVaultConfig),
eq(envProvider),
eq(clientHttpRequestFactory),
any(VaultEndpoint.class),
anyString(),
anyString(),
anyString()))
.thenReturn(clientAuthentication);
when(keyVaultServiceFactoryUtil.getRestTemplateWithVaultNamespace(
anyString(), eq(clientHttpRequestFactory), any(VaultEndpoint.class)))
.thenReturn(restTemplateBuilder);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -786,6 +786,21 @@ public HashicorpStepDefs() {
startTessera(args, jvmArgs, null, authMethod);
});

Then(
"Tessera will fetch a missing transaction and successfully get a response of not found",
() -> {
var response =
makeHttpRequestAndGetResponse(
"http://localhost:18080",
"/transaction/c2FtcGxldGVzc2VyYWtleQ==",
"GET",
null,
Map.of());
assertThat(response.getResponseCode()).isEqualTo(HttpsURLConnection.HTTP_NOT_FOUND);
assertThat(response.getResponseBody())
.startsWith("Message with hash c2FtcGxldGVzc2VyYWtleQ== was not found");
});

Then(
"Tessera will retrieve the key pair from the vault",
() -> {
Expand Down Expand Up @@ -974,7 +989,7 @@ private TestHttpReponse makeHttpRequestAndGetResponse(
private TestHttpReponse makeHttpRequestAndGetResponse(
URL url, String method, String data, Map<String, String> headers) {
try {
HttpsURLConnection urlConnection = (HttpsURLConnection) url.openConnection();
HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();

urlConnection.setDoOutput(true);
urlConnection.setRequestMethod(method);
Expand All @@ -992,7 +1007,11 @@ private TestHttpReponse makeHttpRequestAndGetResponse(

StringBuilder stringBodyContent = new StringBuilder();
try (BufferedReader reader =
new BufferedReader(new InputStreamReader(urlConnection.getInputStream()))) {
new BufferedReader(
new InputStreamReader(
urlConnection.getResponseCode() == HttpURLConnection.HTTP_NOT_FOUND
? urlConnection.getErrorStream()
: urlConnection.getInputStream()))) {
String line;
while ((line = reader.readLine()) != null) {
stringBodyContent.append(line);
Expand Down Expand Up @@ -1041,11 +1060,14 @@ private void startTessera(
if ("token".equals(authMethod)) {
Objects.requireNonNull(vaultToken);
tesseraEnvironment.put(HASHICORP_TOKEN, vaultToken);
tesseraEnvironment.put(HASHICORP_DSE_TOKEN, vaultToken);
} else {
Objects.requireNonNull(approleRoleId);
Objects.requireNonNull(approleSecretId);
tesseraEnvironment.put(HASHICORP_ROLE_ID, approleRoleId);
tesseraEnvironment.put(HASHICORP_SECRET_ID, approleSecretId);
tesseraEnvironment.put(HASHICORP_DSE_ROLE_ID, approleRoleId);
tesseraEnvironment.put(HASHICORP_DSE_SECRET_ID, approleSecretId);
}

try {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,4 @@ Feature: Hashicorp Vault support with DB Secret Engine
-configfile %s -pidfile %s -o jdbc.autoCreateTables=true
"""
Then Tessera will retrieve the key pair from the vault
Then Tessera will fetch a missing transaction and successfully get a response of not found

0 comments on commit 2f54f27

Please sign in to comment.