Skip to content

Commit c8c764d

Browse files
feat: update with latest from main (#1860)
* chore: Only enable renovate bot for CVE PRs (#1819) * fix: Simplify call to directly retrieve the default service account from MDS (#1844) * fix: Simplify call to directly retrieve the default service account from MDS * chore: Make getDefaultServiceAccountUrl package-private * fix: Add configurable connect and read timeouts for IdentityPoolCredentials requests (#1847) * fix: Add configurable connect and read timeouts to STS requests * chore: Fix lint issues * chore: Add connect and read timeout to identity pool creds * chore: Propogate connect and read timeouts to all calls * chore: set base branch last release to 1.41.0 --------- Co-authored-by: Lawrence Qiu <[email protected]>
1 parent b60b292 commit c8c764d

File tree

8 files changed

+119
-45
lines changed

8 files changed

+119
-45
lines changed

.release-please-manifest.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
{
2-
".": "1.41.0-rc1"
2+
".": "1.41.0"
33
}

oauth2_http/java/com/google/auth/oauth2/ComputeEngineCredentials.java

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,6 @@
6969
import java.util.Collections;
7070
import java.util.Date;
7171
import java.util.List;
72-
import java.util.Map;
7372
import java.util.Objects;
7473
import java.util.logging.Level;
7574
import java.util.logging.Logger;
@@ -632,6 +631,12 @@ public static String getServiceAccountsUrl() {
632631
+ "/computeMetadata/v1/instance/service-accounts/?recursive=true";
633632
}
634633

634+
/** Url to retrieve the default service account entry from the Metadata Server. */
635+
static String getDefaultServiceAccountUrl() {
636+
return getMetadataServerUrl(DefaultCredentialsProvider.DEFAULT)
637+
+ "/computeMetadata/v1/instance/service-accounts/default/email";
638+
}
639+
635640
public static String getIdentityDocumentUrl() {
636641
return getMetadataServerUrl(DefaultCredentialsProvider.DEFAULT)
637642
+ "/computeMetadata/v1/instance/service-accounts/default/identity";
@@ -733,7 +738,7 @@ public byte[] sign(byte[] toSign) {
733738

734739
private String getDefaultServiceAccount() throws IOException {
735740
HttpResponse response =
736-
getMetadataResponse(getServiceAccountsUrl(), RequestType.UNTRACKED, false);
741+
getMetadataResponse(getDefaultServiceAccountUrl(), RequestType.UNTRACKED, false);
737742
int statusCode = response.getStatusCode();
738743
if (statusCode == HttpStatusCodes.STATUS_CODE_NOT_FOUND) {
739744
throw new IOException(
@@ -756,12 +761,7 @@ private String getDefaultServiceAccount() throws IOException {
756761
// Mock transports will have success code with empty content by default.
757762
throw new IOException(METADATA_RESPONSE_EMPTY_CONTENT_ERROR_MESSAGE);
758763
}
759-
GenericData responseData = response.parseAs(GenericData.class);
760-
LoggingUtils.logResponsePayload(
761-
responseData, LOGGER_PROVIDER, "Received default service account payload");
762-
Map<String, Object> defaultAccount =
763-
OAuth2Utils.validateMap(responseData, "default", PARSE_ERROR_ACCOUNT);
764-
return OAuth2Utils.validateString(defaultAccount, "email", PARSE_ERROR_ACCOUNT);
764+
return response.parseAsString();
765765
}
766766

767767
public static class Builder extends GoogleCredentials.Builder {

oauth2_http/java/com/google/auth/oauth2/ExternalAccountCredentials.java

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
import com.google.api.client.http.HttpHeaders;
3737
import com.google.api.client.json.GenericJson;
3838
import com.google.api.client.util.Data;
39+
import com.google.api.core.InternalApi;
3940
import com.google.auth.RequestMetadataCallback;
4041
import com.google.auth.http.HttpTransportFactory;
4142
import com.google.common.base.MoreObjects;
@@ -97,6 +98,9 @@ public abstract class ExternalAccountCredentials extends GoogleCredentials {
9798

9899
private EnvironmentProvider environmentProvider;
99100

101+
private int connectTimeout;
102+
private int readTimeout;
103+
100104
/**
101105
* Constructor with minimum identifying information and custom HTTP transport. Does not support
102106
* workforce credentials.
@@ -271,6 +275,8 @@ protected ExternalAccountCredentials(ExternalAccountCredentials.Builder builder)
271275
: builder.metricsHandler;
272276

273277
this.name = GoogleCredentialsInfo.EXTERNAL_ACCOUNT_CREDENTIALS.getCredentialName();
278+
this.connectTimeout = builder.connectTimeout;
279+
this.readTimeout = builder.readTimeout;
274280
}
275281

276282
ImpersonatedCredentials buildImpersonatedCredentials() {
@@ -305,6 +311,8 @@ ImpersonatedCredentials buildImpersonatedCredentials() {
305311
.setScopes(new ArrayList<>(scopes))
306312
.setLifetime(this.serviceAccountImpersonationOptions.lifetime)
307313
.setIamEndpointOverride(serviceAccountImpersonationUrl)
314+
.setConnectTimeout(connectTimeout)
315+
.setReadTimeout(readTimeout)
308316
.build();
309317
}
310318

@@ -533,7 +541,9 @@ protected AccessToken exchangeExternalCredentialForAccessToken(
533541

534542
StsRequestHandler.Builder requestHandler =
535543
StsRequestHandler.newBuilder(
536-
tokenUrl, stsTokenExchangeRequest, transportFactory.create().createRequestFactory());
544+
tokenUrl, stsTokenExchangeRequest, transportFactory.create().createRequestFactory())
545+
.setConnectTimeout(connectTimeout)
546+
.setReadTimeout(readTimeout);
537547

538548
// If this credential was initialized with a Workforce configuration then the
539549
// workforcePoolUserProject must be passed to the Security Token Service via the internal
@@ -771,6 +781,9 @@ public abstract static class Builder extends GoogleCredentials.Builder {
771781
@Nullable protected String workforcePoolUserProject;
772782
@Nullable protected ServiceAccountImpersonationOptions serviceAccountImpersonationOptions;
773783

784+
protected int connectTimeout = 20000; // Default to 20000ms = 20s
785+
protected int readTimeout = 20000; // Default to 20000ms = 20s
786+
774787
/* The field is not being used and value not set. Superseded by the same field in the
775788
{@link GoogleCredentials.Builder}.
776789
*/
@@ -796,6 +809,8 @@ protected Builder(ExternalAccountCredentials credentials) {
796809
this.workforcePoolUserProject = credentials.workforcePoolUserProject;
797810
this.serviceAccountImpersonationOptions = credentials.serviceAccountImpersonationOptions;
798811
this.metricsHandler = credentials.metricsHandler;
812+
this.connectTimeout = credentials.connectTimeout;
813+
this.readTimeout = credentials.readTimeout;
799814
}
800815

801816
/**
@@ -988,6 +1003,20 @@ public Builder setUniverseDomain(String universeDomain) {
9881003
return this;
9891004
}
9901005

1006+
/** Warning: Not for public use and can be removed at any time. */
1007+
@InternalApi
1008+
public Builder setConnectTimeout(int connectTimeout) {
1009+
this.connectTimeout = connectTimeout;
1010+
return this;
1011+
}
1012+
1013+
/** Warning: Not for public use and can be removed at any time. */
1014+
@InternalApi
1015+
public Builder setReadTimeout(int readTimeout) {
1016+
this.readTimeout = readTimeout;
1017+
return this;
1018+
}
1019+
9911020
/**
9921021
* Sets the optional Environment Provider.
9931022
*

oauth2_http/java/com/google/auth/oauth2/ImpersonatedCredentials.java

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
import com.google.api.client.json.GenericJson;
4545
import com.google.api.client.json.JsonObjectParser;
4646
import com.google.api.client.util.GenericData;
47+
import com.google.api.core.InternalApi;
4748
import com.google.auth.CredentialTypeForMetrics;
4849
import com.google.auth.ServiceAccountSigner;
4950
import com.google.auth.http.HttpCredentialsAdapter;
@@ -117,6 +118,9 @@ public class ImpersonatedCredentials extends GoogleCredentials
117118

118119
private transient Calendar calendar;
119120

121+
private int connectTimeout;
122+
private int readTimeout;
123+
120124
/**
121125
* @param sourceCredentials the source credential used to acquire the impersonated credentials. It
122126
* should be either a user account credential or a service account credential.
@@ -559,6 +563,8 @@ private ImpersonatedCredentials(Builder builder) throws IOException {
559563
+ "does not match %s universe domain set for impersonated credentials.",
560564
this.sourceCredentials.getUniverseDomain(), builder.getUniverseDomain()));
561565
}
566+
this.connectTimeout = builder.connectTimeout;
567+
this.readTimeout = builder.readTimeout;
562568
}
563569

564570
/**
@@ -587,6 +593,12 @@ public AccessToken refreshAccessToken() throws IOException {
587593
|| (isDefaultUniverseDomain()
588594
&& ((ServiceAccountCredentials) this.sourceCredentials)
589595
.shouldUseAssertionFlowForGdu())) {
596+
if (this.sourceCredentials instanceof IdentityPoolCredentials) {
597+
this.sourceCredentials =
598+
((IdentityPoolCredentials) this.sourceCredentials)
599+
.toBuilder().setConnectTimeout(connectTimeout).setReadTimeout(readTimeout).build();
600+
}
601+
590602
try {
591603
this.sourceCredentials.refreshIfExpired();
592604
} catch (IOException e) {
@@ -616,6 +628,8 @@ public AccessToken refreshAccessToken() throws IOException {
616628

617629
HttpContent requestContent = new JsonHttpContent(parser.getJsonFactory(), body);
618630
HttpRequest request = requestFactory.buildPostRequest(url, requestContent);
631+
request.setConnectTimeout(connectTimeout);
632+
request.setReadTimeout(readTimeout);
619633
adapter.initialize(request);
620634
request.setParser(parser);
621635
MetricsUtils.setMetricsHeader(
@@ -746,6 +760,9 @@ public static class Builder extends GoogleCredentials.Builder {
746760
private String iamEndpointOverride;
747761
private Calendar calendar = Calendar.getInstance();
748762

763+
private int connectTimeout = 20000; // Default to 20000ms = 20s
764+
private int readTimeout = 20000; // Default to 20000ms = 20s
765+
749766
protected Builder() {}
750767

751768
/**
@@ -769,6 +786,8 @@ protected Builder(ImpersonatedCredentials credentials) {
769786
this.lifetime = credentials.lifetime;
770787
this.transportFactory = credentials.transportFactory;
771788
this.iamEndpointOverride = credentials.iamEndpointOverride;
789+
this.connectTimeout = credentials.connectTimeout;
790+
this.readTimeout = credentials.readTimeout;
772791
}
773792

774793
@CanIgnoreReturnValue
@@ -860,6 +879,20 @@ public Builder setCalendar(Calendar calendar) {
860879
return this;
861880
}
862881

882+
/** Warning: Not for public use and can be removed at any time. */
883+
@InternalApi
884+
public Builder setConnectTimeout(int connectTimeout) {
885+
this.connectTimeout = connectTimeout;
886+
return this;
887+
}
888+
889+
/** Warning: Not for public use and can be removed at any time. */
890+
@InternalApi
891+
public Builder setReadTimeout(int readTimeout) {
892+
this.readTimeout = readTimeout;
893+
return this;
894+
}
895+
863896
public Calendar getCalendar() {
864897
return this.calendar;
865898
}

oauth2_http/java/com/google/auth/oauth2/StsRequestHandler.java

Lines changed: 32 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@
4242
import com.google.api.client.json.JsonObjectParser;
4343
import com.google.api.client.json.JsonParser;
4444
import com.google.api.client.util.GenericData;
45+
import com.google.api.core.InternalApi;
4546
import com.google.common.base.Joiner;
4647
import com.google.errorprone.annotations.CanIgnoreReturnValue;
4748
import java.io.IOException;
@@ -73,26 +74,22 @@ public final class StsRequestHandler {
7374
@Nullable private final HttpHeaders headers;
7475
@Nullable private final String internalOptions;
7576

77+
private final int connectTimeout;
78+
private final int readTimeout;
79+
7680
/**
7781
* Internal constructor.
7882
*
79-
* @param tokenExchangeEndpoint the token exchange endpoint
80-
* @param request the token exchange request
81-
* @param headers optional additional headers to pass along the request
82-
* @param internalOptions optional GCP specific STS options
8383
* @return an StsTokenExchangeResponse instance if the request was successful
8484
*/
85-
private StsRequestHandler(
86-
String tokenExchangeEndpoint,
87-
StsTokenExchangeRequest request,
88-
HttpRequestFactory httpRequestFactory,
89-
@Nullable HttpHeaders headers,
90-
@Nullable String internalOptions) {
91-
this.tokenExchangeEndpoint = tokenExchangeEndpoint;
92-
this.request = request;
93-
this.httpRequestFactory = httpRequestFactory;
94-
this.headers = headers;
95-
this.internalOptions = internalOptions;
85+
private StsRequestHandler(Builder builder) {
86+
this.tokenExchangeEndpoint = builder.tokenExchangeEndpoint;
87+
this.request = builder.request;
88+
this.httpRequestFactory = builder.httpRequestFactory;
89+
this.headers = builder.headers;
90+
this.internalOptions = builder.internalOptions;
91+
this.connectTimeout = builder.connectTimeout;
92+
this.readTimeout = builder.readTimeout;
9693
}
9794

9895
/**
@@ -120,6 +117,8 @@ public StsTokenExchangeResponse exchangeToken() throws IOException {
120117
if (headers != null) {
121118
httpRequest.setHeaders(headers);
122119
}
120+
httpRequest.setConnectTimeout(connectTimeout);
121+
httpRequest.setReadTimeout(readTimeout);
123122

124123
try {
125124
HttpResponse response = httpRequest.execute();
@@ -214,6 +213,9 @@ public static class Builder {
214213
@Nullable private HttpHeaders headers;
215214
@Nullable private String internalOptions;
216215

216+
private int connectTimeout = 20000; // Default to 20000ms = 20s
217+
private int readTimeout = 20000; // Default to 20000ms = 20s
218+
217219
private Builder(
218220
String tokenExchangeEndpoint,
219221
StsTokenExchangeRequest stsTokenExchangeRequest,
@@ -235,9 +237,22 @@ public StsRequestHandler.Builder setInternalOptions(String internalOptions) {
235237
return this;
236238
}
237239

240+
/** Warning: Not for public use and can be removed at any time. */
241+
@InternalApi
242+
public StsRequestHandler.Builder setConnectTimeout(int connectTimeout) {
243+
this.connectTimeout = connectTimeout;
244+
return this;
245+
}
246+
247+
/** Warning: Not for public use and can be removed at any time. */
248+
@InternalApi
249+
public StsRequestHandler.Builder setReadTimeout(int readTimeout) {
250+
this.readTimeout = readTimeout;
251+
return this;
252+
}
253+
238254
public StsRequestHandler build() {
239-
return new StsRequestHandler(
240-
tokenExchangeEndpoint, request, httpRequestFactory, headers, internalOptions);
255+
return new StsRequestHandler(this);
241256
}
242257
}
243258
}

oauth2_http/javatests/com/google/auth/oauth2/ComputeEngineCredentialsTest.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -590,7 +590,7 @@ public void getAccount_missing_throws() {
590590
new MockMetadataServerTransport() {
591591
@Override
592592
public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
593-
if (isGetServiceAccountsUrl(url)) {
593+
if (isGetDefaultServiceAccountsUrl(url)) {
594594
return new MockLowLevelHttpRequest(url) {
595595
@Override
596596
public LowLevelHttpResponse execute() throws IOException {
@@ -626,7 +626,7 @@ public void getAccount_emptyContent_throws() {
626626
new MockMetadataServerTransport() {
627627
@Override
628628
public LowLevelHttpRequest buildRequest(String method, String url) throws IOException {
629-
if (isGetServiceAccountsUrl(url)) {
629+
if (isGetDefaultServiceAccountsUrl(url)) {
630630
return new MockLowLevelHttpRequest(url) {
631631
@Override
632632
public LowLevelHttpResponse execute() throws IOException {

oauth2_http/javatests/com/google/auth/oauth2/MockMetadataServerTransport.java

Lines changed: 7 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ public LowLevelHttpRequest buildRequest(String method, String url) throws IOExce
129129
if (url.startsWith(ComputeEngineCredentials.getTokenServerEncodedUrl())) {
130130
this.request = getMockRequestForTokenEndpoint(url);
131131
return this.request;
132-
} else if (isGetServiceAccountsUrl(url)) {
133-
this.request = getMockRequestForServiceAccount(url);
132+
} else if (isGetDefaultServiceAccountsUrl(url)) {
133+
this.request = getMockRequestForDefaultServiceAccount(url);
134134
return this.request;
135135
} else if (isSignRequestUrl(url)) {
136136
this.request = getMockRequestForSign(url);
@@ -176,22 +176,13 @@ public LowLevelHttpResponse execute() throws IOException {
176176
};
177177
}
178178

179-
private MockLowLevelHttpRequest getMockRequestForServiceAccount(String url) {
179+
private MockLowLevelHttpRequest getMockRequestForDefaultServiceAccount(String url) {
180180
return new MockLowLevelHttpRequest(url) {
181181
@Override
182-
public LowLevelHttpResponse execute() throws IOException {
183-
// Create the JSON response
184-
GenericJson serviceAccountsContents = new GenericJson();
185-
serviceAccountsContents.setFactory(OAuth2Utils.JSON_FACTORY);
186-
GenericJson defaultAccount = new GenericJson();
187-
defaultAccount.put("email", serviceAccountEmail);
188-
serviceAccountsContents.put("default", defaultAccount);
189-
190-
String serviceAccounts = serviceAccountsContents.toPrettyString();
191-
182+
public LowLevelHttpResponse execute() {
192183
return new MockLowLevelHttpResponse()
193184
.setContentType(Json.MEDIA_TYPE)
194-
.setContent(serviceAccounts);
185+
.setContent(serviceAccountEmail);
195186
}
196187
};
197188
}
@@ -341,8 +332,8 @@ public LowLevelHttpResponse execute() throws IOException {
341332
};
342333
}
343334

344-
protected boolean isGetServiceAccountsUrl(String url) {
345-
return url.equals(ComputeEngineCredentials.getServiceAccountsUrl());
335+
protected boolean isGetDefaultServiceAccountsUrl(String url) {
336+
return url.equals(ComputeEngineCredentials.getDefaultServiceAccountUrl());
346337
}
347338

348339
protected boolean isSignRequestUrl(String url) {

renovate.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@
1313
"ignorePaths": [
1414
".kokoro/requirements.txt"
1515
],
16+
"vulnerabilityAlerts": {
17+
"enabled": true
18+
},
19+
"maven": {
20+
"enabled": false
21+
},
1622
"customManagers": [
1723
{
1824
"customType": "regex",

0 commit comments

Comments
 (0)