Skip to content

Commit 74aaca6

Browse files
committed
Responding to comments and updating tests
1 parent 3756021 commit 74aaca6

File tree

4 files changed

+285
-39
lines changed

4 files changed

+285
-39
lines changed

oauth2_http/java/com/google/auth/mtls/WorkloadCertificateConfiguration.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,10 +36,28 @@ public static WorkloadCertificateConfiguration fromCertificateConfigurationStrea
3636
parser.parseAndClose(certConfigStream, StandardCharsets.UTF_8, GenericJson.class);
3737

3838
Map<String, Object> certConfigs = (Map<String, Object>) fileContents.get("cert_configs");
39+
if (certConfigs == null) {
40+
throw new IllegalArgumentException(
41+
"The cert_configs object must be provided in the certificate configuration file.");
42+
}
43+
3944
Map<String, Object> workloadConfig = (Map<String, Object>) certConfigs.get("workload");
45+
if (workloadConfig == null) {
46+
throw new IllegalArgumentException(
47+
"A workload certificate configuration must be provided in the cert_configs object.");
48+
}
4049

4150
String certPath = (String) workloadConfig.get("cert_path");
51+
if (certPath.isEmpty() || certPath == null) {
52+
throw new IllegalArgumentException(
53+
"The cert_path field must be provided in the workload certificate configuration.");
54+
}
55+
4256
String privateKeyPath = (String) workloadConfig.get("key_path");
57+
if (privateKeyPath.isEmpty() || privateKeyPath == null) {
58+
throw new IllegalArgumentException(
59+
"The key_path field must be provided in the workload certificate configuration.");
60+
}
4361

4462
return new WorkloadCertificateConfiguration(certPath, privateKeyPath);
4563
}

oauth2_http/java/com/google/auth/mtls/X509Provider.java

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.google.auth.mtls;
22

33
import com.google.api.client.util.SecurityUtils;
4+
import com.google.common.annotations.VisibleForTesting;
45
import java.io.File;
56
import java.io.FileInputStream;
67
import java.io.FileNotFoundException;
@@ -49,14 +50,16 @@ public KeyStore getKeyStore() throws IOException {
4950

5051
private WorkloadCertificateConfiguration getWorkloadCertificateConfiguration()
5152
throws IOException {
52-
String envCredentialsPath = getEnv(CERTIFICATE_CONFIGURATION_ENV_VARIABLE);
5353
File certConfig;
5454
if (this.certConfigPathOverride != null) {
5555
certConfig = new File(certConfigPathOverride);
56-
} else if (envCredentialsPath != null && envCredentialsPath.length() > 0) {
57-
certConfig = new File(envCredentialsPath);
5856
} else {
59-
certConfig = getWellKnownCertificateConfigFile();
57+
String envCredentialsPath = getEnv(CERTIFICATE_CONFIGURATION_ENV_VARIABLE);
58+
if (envCredentialsPath != null && !envCredentialsPath.isEmpty()) {
59+
certConfig = new File(envCredentialsPath);
60+
} else {
61+
certConfig = getWellKnownCertificateConfigFile();
62+
}
6063
}
6164
InputStream certConfigStream = null;
6265
try {
@@ -82,6 +85,9 @@ private WorkloadCertificateConfiguration getWorkloadCertificateConfiguration()
8285
}
8386
}
8487

88+
/*
89+
* Start of methods to allow overriding in the test code to isolate from the environment.
90+
*/
8591
boolean isFile(File file) {
8692
return file.isFile();
8793
}
@@ -101,8 +107,11 @@ String getOsName() {
101107
String getProperty(String property, String def) {
102108
return System.getProperty(property, def);
103109
}
104-
105-
File getWellKnownCertificateConfigFile() {
110+
/*
111+
* End of methods to allow overriding in the test code to isolate from the environment.
112+
*/
113+
114+
private File getWellKnownCertificateConfigFile() {
106115
File cloudConfigPath;
107116
String envPath = getEnv("CLOUDSDK_CONFIG");
108117
if (envPath != null) {
Lines changed: 146 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,146 @@
1+
/*
2+
* Copyright 2025, Google Inc. All rights reserved.
3+
*
4+
* Redistribution and use in source and binary forms, with or without
5+
* modification, are permitted provided that the following conditions are
6+
* met:
7+
*
8+
* * Redistributions of source code must retain the above copyright
9+
* notice, this list of conditions and the following disclaimer.
10+
* * Redistributions in binary form must reproduce the above
11+
* copyright notice, this list of conditions and the following disclaimer
12+
* in the documentation and/or other materials provided with the
13+
* distribution.
14+
*
15+
* * Neither the name of Google Inc. nor the names of its
16+
* contributors may be used to endorse or promote products derived from
17+
* this software without specific prior written permission.
18+
*
19+
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
20+
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
21+
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
22+
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
23+
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24+
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25+
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
26+
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
27+
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28+
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
29+
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30+
*/
31+
32+
package com.google.auth.mtls;
33+
34+
import static org.junit.Assert.assertEquals;
35+
import static org.junit.Assert.assertNotNull;
36+
import static org.junit.Assert.fail;
37+
38+
import com.google.api.client.json.GenericJson;
39+
import com.google.auth.TestUtils;
40+
import java.io.IOException;
41+
import java.io.InputStream;
42+
import org.junit.Test;
43+
44+
public class WorkloadCertificateConfigurationTest {
45+
46+
@Test
47+
public void workloadCertificateConfig_fromStream_Succeeds() throws IOException {
48+
String certPath = "cert.crt";
49+
String privateKeyPath = "key.crt";
50+
InputStream configStream = writeWorkloadCertificateConfigStream(certPath, privateKeyPath);
51+
52+
WorkloadCertificateConfiguration config =
53+
WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream);
54+
assertNotNull(config);
55+
}
56+
57+
@Test
58+
public void workloadCertificateConfig_fromStreamMissingCertPath_Fails() throws IOException {
59+
String certPath = "";
60+
String privateKeyPath = "key.crt";
61+
InputStream configStream = writeWorkloadCertificateConfigStream(certPath, privateKeyPath);
62+
63+
try {
64+
WorkloadCertificateConfiguration config =
65+
WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream);
66+
fail("Expected an error due to missing the certificate path field.");
67+
} catch (IllegalArgumentException e) {
68+
assertEquals(
69+
"The cert_path field must be provided in the workload certificate configuration.",
70+
e.getMessage());
71+
}
72+
}
73+
74+
@Test
75+
public void workloadCertificateConfig_fromStreamMissingPrivateKeyPath_Fails() throws IOException {
76+
String certPath = "cert.crt";
77+
String privateKeyPath = "";
78+
InputStream configStream = writeWorkloadCertificateConfigStream(certPath, privateKeyPath);
79+
80+
try {
81+
WorkloadCertificateConfiguration config =
82+
WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream);
83+
fail("Expected an error due to missing the private key path field.");
84+
} catch (IllegalArgumentException e) {
85+
assertEquals(
86+
"The key_path field must be provided in the workload certificate configuration.",
87+
e.getMessage());
88+
}
89+
}
90+
91+
@Test
92+
public void workloadCertificateConfig_fromStreamMissingWorkload_Fails() throws IOException {
93+
GenericJson json = new GenericJson();
94+
json.put("cert_configs", new GenericJson());
95+
InputStream configStream = TestUtils.jsonToInputStream(json);
96+
97+
try {
98+
WorkloadCertificateConfiguration config =
99+
WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream);
100+
fail("Expected an error due to missing the workload field.");
101+
} catch (IllegalArgumentException e) {
102+
assertEquals(
103+
"A workload certificate configuration must be provided in the cert_configs object.",
104+
e.getMessage());
105+
}
106+
}
107+
108+
@Test
109+
public void workloadCertificateConfig_fromStreamMissingCertConfig_Fails() throws IOException {
110+
GenericJson json = new GenericJson();
111+
InputStream configStream = TestUtils.jsonToInputStream(json);
112+
113+
try {
114+
WorkloadCertificateConfiguration config =
115+
WorkloadCertificateConfiguration.fromCertificateConfigurationStream(configStream);
116+
fail("Expected an error due to missing the cert_config field.");
117+
} catch (IllegalArgumentException e) {
118+
assertEquals(
119+
"The cert_configs object must be provided in the certificate configuration file.",
120+
e.getMessage());
121+
}
122+
}
123+
124+
static InputStream writeWorkloadCertificateConfigStream(String certPath, String privateKeyPath)
125+
throws IOException {
126+
GenericJson json = writeWorkloadCertificateConfigJson(certPath, privateKeyPath);
127+
return TestUtils.jsonToInputStream(json);
128+
}
129+
130+
private static GenericJson writeWorkloadCertificateConfigJson(
131+
String certPath, String privateKeyPath) {
132+
GenericJson json = new GenericJson();
133+
json.put("version", 1);
134+
GenericJson certConfigs = new GenericJson();
135+
GenericJson workloadConfig = new GenericJson();
136+
if (certPath != null) {
137+
workloadConfig.put("cert_path", certPath);
138+
}
139+
if (privateKeyPath != null) {
140+
workloadConfig.put("key_path", privateKeyPath);
141+
}
142+
certConfigs.put("workload", workloadConfig);
143+
json.put("cert_configs", certConfigs);
144+
return json;
145+
}
146+
}

0 commit comments

Comments
 (0)