Skip to content

Commit e9ce2de

Browse files
Enhance Vault Secrets Manager Implementation with KEY Feature
1 parent 56e27e1 commit e9ce2de

File tree

3 files changed

+64
-81
lines changed

3 files changed

+64
-81
lines changed

ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/dedicated/configuration/HashiJsonVaultProvider.java

+5-5
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import oracle.jdbc.provider.hashicorp.dedicated.secrets.HashiVaultSecretsManagerFactory;
55
import oracle.jdbc.provider.parameter.ParameterSet;
66
import oracle.jdbc.spi.OracleConfigurationJsonSecretProvider;
7+
import oracle.sql.json.OracleJsonFactory;
78
import oracle.sql.json.OracleJsonObject;
89

910
import java.io.ByteArrayInputStream;
@@ -31,18 +32,17 @@ public char[] getSecret(OracleJsonObject jsonObject) {
3132

3233
ByteArrayInputStream inputStream = new ByteArrayInputStream(secretString.getBytes(StandardCharsets.UTF_8));
3334

34-
3535
OracleJsonObject secretJsonObj =
36-
new oracle.sql.json.OracleJsonFactory()
36+
new OracleJsonFactory()
3737
.createJsonTextValue(inputStream)
3838
.asJsonObject();
3939

40-
String myPasswordValue = parameterSet.getOptional(FIELD_NAME);
41-
String a = String.valueOf(secretJsonObj.get(myPasswordValue));
40+
String fieldName = parameterSet.getOptional(FIELD_NAME);
41+
String extractedPassword = String.valueOf(secretJsonObj.get(fieldName));
4242

4343
// 5) Base64-encode just that field
4444
return Base64.getEncoder()
45-
.encodeToString(a.getBytes())
45+
.encodeToString(extractedPassword.getBytes())
4646
.toCharArray();
4747
}
4848

ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/dedicated/configuration/HashiVaultSecretsManagerConfigurationProvider.java

+1-2
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ public class HashiVaultSecretsManagerConfigurationProvider extends OracleConfigu
1717
HashicorpConfigurationParameters.configureBuilder(
1818
ParameterSetParser.builder()
1919
.addParameter("value", HashiVaultSecretsManagerFactory.SECRET_PATH)
20-
.addParameter("key_name", HashiVaultSecretsManagerFactory.KEY_NAME)
20+
.addParameter("key", HashiVaultSecretsManagerFactory.KEY)
2121
.addParameter(
2222
"VAULT_ADDR",
2323
HashiVaultSecretsManagerFactory.VAULT_ADDR
@@ -47,7 +47,6 @@ public InputStream getJson(String secretPath) {
4747
.request(parameters)
4848
.getContent();
4949

50-
// Return the JSON as an InputStream
5150
return new ByteArrayInputStream(secretString.getBytes());
5251
}
5352

ojdbc-provider-hashicorp/src/main/java/oracle/jdbc/provider/hashicorp/dedicated/secrets/HashiVaultSecretsManagerFactory.java

+58-74
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import oracle.jdbc.provider.parameter.ParameterSet;
1010
import oracle.sql.json.OracleJsonFactory;
1111
import oracle.sql.json.OracleJsonObject;
12+
import oracle.sql.json.OracleJsonValue;
1213

1314
import java.io.ByteArrayInputStream;
1415
import java.io.ByteArrayOutputStream;
1516
import java.io.IOException;
1617
import java.io.InputStream;
1718
import java.net.HttpURLConnection;
1819
import java.net.URL;
20+
import java.util.Optional;
1921

2022
import static java.nio.charset.StandardCharsets.UTF_8;
2123
import static oracle.jdbc.provider.parameter.Parameter.CommonAttribute.REQUIRED;
@@ -29,7 +31,7 @@ public final class HashiVaultSecretsManagerFactory extends HashiVaultResourceFac
2931
* The name of the key if the secret is a JSON with multiple fields.
3032
* This is optional.
3133
*/
32-
public static final Parameter<String> KEY_NAME = Parameter.create();
34+
public static final Parameter<String> KEY = Parameter.create();
3335

3436
/**
3537
* (Optional) The Vault address. If not specified, fallback to system property or environment var.
@@ -45,6 +47,10 @@ public final class HashiVaultSecretsManagerFactory extends HashiVaultResourceFac
4547

4648
private static final OracleJsonFactory JSON_FACTORY = new OracleJsonFactory();
4749

50+
private static final String ERROR_VAULT_ADDR = "Vault address not found in parameters, system properties, or environment variables";
51+
private static final String ERROR_VAULT_TOKEN = "Vault token not found in parameters, system properties, or environment variables";
52+
53+
4854
/**
4955
* The single instance of this factory, cached for performance.
5056
*/
@@ -60,35 +66,30 @@ public static ResourceFactory<String> getInstance() {
6066
@Override
6167
public Resource<String> request(HashiCredentials credentials, ParameterSet parameterSet) {
6268
String secretPath = parameterSet.getRequired(SECRET_PATH);
63-
String key = parameterSet.getOptional(KEY_NAME);
64-
String vaultAddrParam = parameterSet.getOptional(VAULT_ADDR);
65-
String vaultTokenParam = parameterSet.getOptional(VAULT_TOKEN);
69+
// Get required parameters with fallback
70+
String vaultAddr = getRequiredOrFallback(parameterSet, VAULT_ADDR, "VAULT_ADDR");
71+
String vaultToken = getRequiredOrFallback(parameterSet, VAULT_TOKEN, "VAULT_TOKEN");
72+
String key = parameterSet.getOptional(KEY);
6673

67-
String vaultAddr = (vaultAddrParam != null)
68-
? vaultAddrParam
69-
: System.getProperty("VAULT_ADDR", System.getenv("VAULT_ADDR"));
74+
System.out.println("secretPath: " + secretPath + ", vaultAddr: " + vaultAddr + ", vaultToken: " + vaultToken + ", key: " + key);
7075

71-
String vaultToken = (vaultTokenParam != null)
72-
? vaultTokenParam
73-
: System.getProperty("VAULT_TOKEN", System.getenv("VAULT_TOKEN"));
7476

7577
if (vaultAddr == null || vaultAddr.isEmpty()) {
76-
throw new IllegalStateException(
77-
"Vault address not found in URL parameters, system properties, or environment variables");
78+
throw new IllegalStateException(ERROR_VAULT_ADDR);
7879
}
7980
if (vaultToken == null || vaultToken.isEmpty()) {
80-
throw new IllegalStateException(
81-
"Vault token not found in URL parameters, system properties, or environment variables");
81+
throw new IllegalStateException(ERROR_VAULT_TOKEN);
8282
}
8383

84+
8485
String vaultUrl = vaultAddr + secretPath;
8586

8687
// Make the REST call
8788
String secretString = fetchSecretFromVault(vaultUrl, vaultToken);
8889

8990
/*
90-
* If KEY_NAME is specified, we only want a single field from the nested JSON.
91-
* If KEY_NAME is not specified, we return the entire
91+
* If KEY is specified, we only want a single field from the nested JSON.
92+
* If KEY is not specified, we return the entire
9293
* {
9394
* "data": { ...all fields... }
9495
* }
@@ -100,28 +101,28 @@ public Resource<String> request(HashiCredentials credentials, ParameterSet param
100101
}
101102

102103
private static String fetchSecretFromVault(String vaultUrl, String token) {
103-
HttpURLConnection conn = null;
104104
try {
105105
URL url = new URL(vaultUrl);
106-
conn = (HttpURLConnection) url.openConnection();
106+
HttpURLConnection conn = (HttpURLConnection) url.openConnection();
107107
conn.setRequestMethod("GET");
108108
conn.setRequestProperty("X-Vault-Token", token);
109109
conn.setRequestProperty("Accept", "application/json");
110110

111-
if (conn.getResponseCode() != 200) {
111+
if (conn.getResponseCode() != HttpURLConnection.HTTP_OK) {
112112
throw new IllegalStateException(
113113
"Failed to fetch secret. HTTP error code: " + conn.getResponseCode());
114114
}
115+
116+
// Use try-with-resources for the InputStream
115117
try (InputStream in = conn.getInputStream()) {
116118
return readStream(in);
119+
} finally {
120+
// Explicitly disconnect the connection
121+
conn.disconnect();
117122
}
118123
} catch (IOException e) {
119124
throw new IllegalArgumentException(
120125
"Failed to read secret from Vault at " + vaultUrl, e);
121-
} finally {
122-
if (conn != null) {
123-
conn.disconnect();
124-
}
125126
}
126127
}
127128

@@ -135,6 +136,7 @@ private static String readStream(InputStream in) throws IOException {
135136
return new String(baos.toByteArray(), UTF_8);
136137
}
137138

139+
138140
/**
139141
* If {@code key} is non-null, parse the JSON from Vault and return only that key's value.
140142
* Otherwise, return just the nested JSON:
@@ -149,61 +151,43 @@ private static String readStream(InputStream in) throws IOException {
149151
* }
150152
*/
151153
private static String extractValueFromJson(String secretJson, String key, String secretPath) {
152-
InputStream is = null;
153-
try {
154-
is = new ByteArrayInputStream(secretJson.getBytes(UTF_8));
154+
try (InputStream is = new ByteArrayInputStream(secretJson.getBytes(UTF_8))) {
155155
OracleJsonObject rootObject = JSON_FACTORY.createJsonTextValue(is).asJsonObject();
156+
OracleJsonObject dataNode = rootObject.getObject("data");
157+
OracleJsonObject nestedData = dataNode.getObject("data");
156158

157-
// Navigate to the second-level "data" object: rootObject.data.data
158-
// Example root:
159-
// {
160-
// "request_id": "...",
161-
// "data": {
162-
// "data": {
163-
// "connect_descriptor": "...",
164-
// "jdbc": {...},
165-
// "password": {...},
166-
// "user": "ADMIN"
167-
// },
168-
// "metadata": {...}
169-
// },
170-
// ...
171-
// }
172-
173-
OracleJsonObject dataNode = rootObject.getObject("data"); // top-level "data"
174-
175-
OracleJsonObject dataData = dataNode.getObject("data"); // nested "data"
176-
177-
178-
if (key != null) {
179-
// Return only that key's value
180-
if (!dataData.containsKey(key)) {
181-
throw new IllegalArgumentException(
182-
"Failed to find key " + key + " in secret: " + secretPath);
183-
}
184-
return dataData.getString(key);
185-
186-
} else {
187-
// Return just the nested data as:
188-
// {
189-
// "data": {
190-
// "connect_descriptor": "...",
191-
// "jdbc": {...},
192-
// "password": {...},
193-
// "user": "ADMIN"
194-
// }
195-
// }
196-
197-
return dataData.toString();
159+
if (key == null) {
160+
return nestedData.toString();
198161
}
199-
} finally {
200-
if (is != null) {
201-
try {
202-
is.close();
203-
} catch (IOException ignore) {
204-
// ignore
205-
}
162+
163+
OracleJsonValue value = nestedData.get(key);
164+
if (value == null) {
165+
throw new IllegalArgumentException(
166+
"Key \"" + key + "\" not found in secret at path: " + secretPath);
206167
}
168+
169+
return value.toString();
170+
} catch (IOException e) {
171+
throw new IllegalArgumentException(
172+
"Failed to parse JSON for secret at path: " + secretPath, e);
207173
}
208174
}
175+
176+
private static String getEnvOrProperty(String key) {
177+
return System.getProperty(key, System.getenv(key));
178+
}
179+
180+
private static String getRequiredOrFallback(ParameterSet parameterSet, Parameter<String> parameter, String envKey) {
181+
// Try to get the required parameter value
182+
String value = parameterSet.getOptional(parameter);
183+
if (value != null) {
184+
return value;
185+
}
186+
187+
// Fallback to environment variables or system properties
188+
return getEnvOrProperty(envKey);
189+
}
190+
191+
192+
209193
}

0 commit comments

Comments
 (0)