vendor: google.golang.org/api v0.160.0

Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
Sebastiaan van Stijn
2025-06-12 14:03:05 +02:00
parent d2954c4e05
commit 5fb6604642
10 changed files with 147 additions and 55 deletions

View File

@@ -237,7 +237,7 @@ require (
golang.org/x/crypto v0.37.0 // indirect
golang.org/x/oauth2 v0.29.0 // indirect
golang.org/x/tools v0.32.0 // indirect
google.golang.org/api v0.155.0 // indirect
google.golang.org/api v0.160.0 // indirect
google.golang.org/genproto v0.0.0-20240123012728-ef4313101c80 // indirect; TODO(thaJeztah): should we keep this one aligned with the other google.golang.org/genproto/xxx modules?
google.golang.org/genproto/googleapis/rpc v0.0.0-20250218202821-56aae31c358a // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect

View File

@@ -777,8 +777,8 @@ golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8T
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
google.golang.org/api v0.155.0 h1:vBmGhCYs0djJttDNynWo44zosHlPvHmA0XiN2zP2DtA=
google.golang.org/api v0.155.0/go.mod h1:GI5qK5f40kCpHfPn6+YzGAByIKWv8ujFnmoWm7Igduk=
google.golang.org/api v0.160.0 h1:SEspjXHVqE1m5a1fRy8JFB+5jSu+V0GEDKDghF3ttO4=
google.golang.org/api v0.160.0/go.mod h1:0mu0TpK33qnydLvWqbImq2b1eQ5FHRSDCBzAxX9ZHyw=
google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=

View File

@@ -35,6 +35,7 @@ package internal
import (
"context"
"crypto/tls"
"errors"
"net"
"net/url"
"os"
@@ -53,6 +54,12 @@ const (
// Experimental: if true, the code will try MTLS with S2A as the default for transport security. Default value is false.
googleAPIUseS2AEnv = "EXPERIMENTAL_GOOGLE_API_USE_S2A"
universeDomainPlaceholder = "UNIVERSE_DOMAIN"
)
var (
errUniverseNotSupportedMTLS = errors.New("mTLS is not supported in any universe other than googleapis.com")
)
// getClientCertificateSourceAndEndpoint is a convenience function that invokes
@@ -67,6 +74,14 @@ func getClientCertificateSourceAndEndpoint(settings *DialSettings) (cert.Source,
if err != nil {
return nil, "", err
}
// TODO(chrisdsmith): https://github.com/googleapis/google-api-go-client/issues/2359
if settings.Endpoint == "" && !settings.IsUniverseDomainGDU() && settings.DefaultEndpointTemplate != "" {
// TODO(chrisdsmith): https://github.com/googleapis/google-api-go-client/issues/2359
// if settings.DefaultEndpointTemplate == "" {
// return nil, "", errors.New("internaloption.WithDefaultEndpointTemplate is required if option.WithUniverseDomain is not googleapis.com")
// }
endpoint = resolvedDefaultEndpoint(settings)
}
return clientCertSource, endpoint, nil
}
@@ -80,9 +95,7 @@ type transportConfig struct {
func getTransportConfig(settings *DialSettings) (*transportConfig, error) {
clientCertSource, endpoint, err := getClientCertificateSourceAndEndpoint(settings)
if err != nil {
return &transportConfig{
clientCertSource: nil, endpoint: "", s2aAddress: "", s2aMTLSEndpoint: "",
}, err
return nil, err
}
defaultTransportConfig := transportConfig{
clientCertSource: clientCertSource,
@@ -94,12 +107,10 @@ func getTransportConfig(settings *DialSettings) (*transportConfig, error) {
if !shouldUseS2A(clientCertSource, settings) {
return &defaultTransportConfig, nil
}
s2aMTLSEndpoint := settings.DefaultMTLSEndpoint
// If there is endpoint override, honor it.
if settings.Endpoint != "" {
s2aMTLSEndpoint = endpoint
if !settings.IsUniverseDomainGDU() {
return nil, errUniverseNotSupportedMTLS
}
s2aAddress := GetS2AAddress()
if s2aAddress == "" {
return &defaultTransportConfig, nil
@@ -108,7 +119,7 @@ func getTransportConfig(settings *DialSettings) (*transportConfig, error) {
clientCertSource: clientCertSource,
endpoint: endpoint,
s2aAddress: s2aAddress,
s2aMTLSEndpoint: s2aMTLSEndpoint,
s2aMTLSEndpoint: settings.DefaultMTLSEndpoint,
}, nil
}
@@ -153,24 +164,41 @@ func isClientCertificateEnabled() bool {
// WithDefaultEndpoint("https://foo.com/bar/baz") will return "https://myhost:8080/bar/baz"
func getEndpoint(settings *DialSettings, clientCertSource cert.Source) (string, error) {
if settings.Endpoint == "" {
mtlsMode := getMTLSMode()
if mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto) {
if isMTLS(clientCertSource) {
if !settings.IsUniverseDomainGDU() {
return "", errUniverseNotSupportedMTLS
}
return settings.DefaultMTLSEndpoint, nil
}
return settings.DefaultEndpoint, nil
return resolvedDefaultEndpoint(settings), nil
}
if strings.Contains(settings.Endpoint, "://") {
// User passed in a full URL path, use it verbatim.
return settings.Endpoint, nil
}
if settings.DefaultEndpoint == "" {
if resolvedDefaultEndpoint(settings) == "" {
// If DefaultEndpoint is not configured, use the user provided endpoint verbatim.
// This allows a naked "host[:port]" URL to be used with GRPC Direct Path.
return settings.Endpoint, nil
}
// Assume user-provided endpoint is host[:port], merge it with the default endpoint.
return mergeEndpoints(settings.DefaultEndpoint, settings.Endpoint)
return mergeEndpoints(resolvedDefaultEndpoint(settings), settings.Endpoint)
}
func isMTLS(clientCertSource cert.Source) bool {
mtlsMode := getMTLSMode()
return mtlsMode == mTLSModeAlways || (clientCertSource != nil && mtlsMode == mTLSModeAuto)
}
// resolvedDefaultEndpoint returns the DefaultEndpointTemplate merged with the
// Universe Domain if the DefaultEndpointTemplate is set, otherwise returns the
// deprecated DefaultEndpoint value.
func resolvedDefaultEndpoint(settings *DialSettings) string {
if settings.DefaultEndpointTemplate == "" {
return settings.DefaultEndpoint
}
return strings.Replace(settings.DefaultEndpointTemplate, universeDomainPlaceholder, settings.GetUniverseDomain(), 1)
}
func getMTLSMode() string {
@@ -274,12 +302,8 @@ func shouldUseS2A(clientCertSource cert.Source, settings *DialSettings) bool {
if !isGoogleS2AEnabled() {
return false
}
// If DefaultMTLSEndpoint is not set and no endpoint override, skip S2A.
if settings.DefaultMTLSEndpoint == "" && settings.Endpoint == "" {
return false
}
// If MTLS is not enabled for this endpoint, skip S2A.
if !mtlsEndpointEnabledForS2A() {
// If DefaultMTLSEndpoint is not set or has endpoint override, skip S2A.
if settings.DefaultMTLSEndpoint == "" || settings.Endpoint != "" {
return false
}
// If custom HTTP client is provided, skip S2A.
@@ -289,12 +313,6 @@ func shouldUseS2A(clientCertSource cert.Source, settings *DialSettings) bool {
return true
}
// mtlsEndpointEnabledForS2A checks if the endpoint is indeed MTLS-enabled, so that we can use S2A for MTLS connection.
var mtlsEndpointEnabledForS2A = func() bool {
// TODO(xmenxk): determine this via discovery config.
return true
}
func isGoogleS2AEnabled() bool {
return strings.ToLower(os.Getenv(googleAPIUseS2AEnv)) == "true"
}

View File

@@ -16,6 +16,7 @@ import (
"time"
"golang.org/x/oauth2"
"google.golang.org/api/internal/cert"
"google.golang.org/api/internal/impersonate"
"golang.org/x/oauth2/google"
@@ -90,11 +91,11 @@ func credentialsFromJSON(ctx context.Context, data []byte, ds *DialSettings) (*g
// Determine configurations for the OAuth2 transport, which is separate from the API transport.
// The OAuth2 transport and endpoint will be configured for mTLS if applicable.
clientCertSource, oauth2Endpoint, err := getClientCertificateSourceAndEndpoint(oauth2DialSettings(ds))
clientCertSource, err := getClientCertificateSource(ds)
if err != nil {
return nil, err
}
params.TokenURL = oauth2Endpoint
params.TokenURL = oAuth2Endpoint(clientCertSource)
if clientCertSource != nil {
tlsConfig := &tls.Config{
GetClientCertificate: clientCertSource,
@@ -124,22 +125,37 @@ func credentialsFromJSON(ctx context.Context, data []byte, ds *DialSettings) (*g
return cred, err
}
func oAuth2Endpoint(clientCertSource cert.Source) string {
if isMTLS(clientCertSource) {
return google.MTLSTokenURL
}
return google.Endpoint.TokenURL
}
func isSelfSignedJWTFlow(data []byte, ds *DialSettings) (bool, error) {
if (ds.EnableJwtWithScope || ds.HasCustomAudience()) &&
ds.ImpersonationConfig == nil {
// Check if JSON is a service account and if so create a self-signed JWT.
var f struct {
Type string `json:"type"`
// The rest JSON fields are omitted because they are not used.
}
if err := json.Unmarshal(data, &f); err != nil {
return false, err
}
return f.Type == serviceAccountKey, nil
// For non-GDU universe domains, token exchange is impossible and services
// must support self-signed JWTs with scopes.
if !ds.IsUniverseDomainGDU() {
return typeServiceAccount(data)
}
if (ds.EnableJwtWithScope || ds.HasCustomAudience()) && ds.ImpersonationConfig == nil {
return typeServiceAccount(data)
}
return false, nil
}
// typeServiceAccount checks if JSON data is for a service account.
func typeServiceAccount(data []byte) (bool, error) {
var f struct {
Type string `json:"type"`
// The remaining JSON fields are omitted because they are not used.
}
if err := json.Unmarshal(data, &f); err != nil {
return false, err
}
return f.Type == serviceAccountKey, nil
}
func selfSignedJWTTokenSource(data []byte, ds *DialSettings) (oauth2.TokenSource, error) {
if len(ds.GetScopes()) > 0 && !ds.HasCustomAudience() {
// Scopes are preferred in self-signed JWT unless the scope is not available
@@ -188,15 +204,6 @@ func impersonateCredentials(ctx context.Context, creds *google.Credentials, ds *
}, nil
}
// oauth2DialSettings returns the settings to be used by the OAuth2 transport, which is separate from the API transport.
func oauth2DialSettings(ds *DialSettings) *DialSettings {
var ods DialSettings
ods.DefaultEndpoint = google.Endpoint.TokenURL
ods.DefaultMTLSEndpoint = google.MTLSTokenURL
ods.ClientCertSource = ds.ClientCertSource
return &ods
}
// customHTTPClient constructs an HTTPClient using the provided tlsConfig, to support mTLS.
func customHTTPClient(tlsConfig *tls.Config) *http.Client {
trans := baseTransport()
@@ -219,3 +226,14 @@ func baseTransport() *http.Transport {
ExpectContinueTimeout: 1 * time.Second,
}
}
// ErrUniverseNotMatch composes an error string from the provided universe
// domain sources (DialSettings and Credentials, respectively).
func ErrUniverseNotMatch(settingsUD, credsUD string) error {
return fmt.Errorf(
"the configured universe domain (%q) does not match the universe "+
"domain found in the credentials (%q). If you haven't configured "+
"WithUniverseDomain explicitly, \"googleapis.com\" is the default",
settingsUD,
credsUD)
}

View File

@@ -19,7 +19,8 @@ import (
)
const (
newAuthLibEnVar = "GOOGLE_API_GO_EXPERIMENTAL_USE_NEW_AUTH_LIB"
newAuthLibEnVar = "GOOGLE_API_GO_EXPERIMENTAL_USE_NEW_AUTH_LIB"
universeDomainDefault = "googleapis.com"
)
// DialSettings holds information needed to establish a connection with a
@@ -161,3 +162,28 @@ func (ds *DialSettings) Validate() error {
}
return nil
}
// GetDefaultUniverseDomain returns the default service domain for a given Cloud
// universe, as configured with internaloption.WithDefaultUniverseDomain.
// The default value is "googleapis.com".
func (ds *DialSettings) GetDefaultUniverseDomain() string {
if ds.DefaultUniverseDomain == "" {
return universeDomainDefault
}
return ds.DefaultUniverseDomain
}
// GetUniverseDomain returns the default service domain for a given Cloud
// universe, as configured with option.WithUniverseDomain.
// The default value is the value of GetDefaultUniverseDomain, as configured
// with internaloption.WithDefaultUniverseDomain.
func (ds *DialSettings) GetUniverseDomain() string {
if ds.UniverseDomain == "" {
return ds.GetDefaultUniverseDomain()
}
return ds.UniverseDomain
}
func (ds *DialSettings) IsUniverseDomainGDU() bool {
return ds.GetUniverseDomain() == ds.GetDefaultUniverseDomain()
}

View File

@@ -5,4 +5,4 @@
package internal
// Version is the current tagged release of the library.
const Version = "0.155.0"
const Version = "0.160.0"

View File

@@ -38,7 +38,10 @@ func (o defaultEndpointTemplateOption) Apply(settings *internal.DialSettings) {
// WithDefaultEndpointTemplate provides a template for creating the endpoint
// using a universe domain. See also WithDefaultUniverseDomain and
// option.WithUniverseDomain.
// option.WithUniverseDomain. The placeholder UNIVERSE_DOMAIN should be used
// instead of a concrete universe domain such as "googleapis.com".
//
// Example: WithDefaultEndpointTemplate("https://logging.UNIVERSE_DOMAIN/")
//
// It should only be used internally by generated clients.
func WithDefaultEndpointTemplate(url string) option.ClientOption {
@@ -163,6 +166,11 @@ func (w withDefaultUniverseDomain) Apply(o *internal.DialSettings) {
// EnableJwtWithScope returns a ClientOption that specifies if scope can be used
// with self-signed JWT.
//
// EnableJwtWithScope is ignored when option.WithUniverseDomain is set
// to a value other than the Google Default Universe (GDU) of "googleapis.com".
// For non-GDU domains, token exchange is impossible and services must
// support self-signed JWTs with scopes.
func EnableJwtWithScope() option.ClientOption {
return enableJwtWithScope(true)
}

View File

@@ -177,6 +177,17 @@ func dial(ctx context.Context, insecure bool, o *internal.DialSettings) (*grpc.C
if err != nil {
return nil, err
}
credsUniverseDomain, err := creds.GetUniverseDomain()
if err != nil {
return nil, err
}
if o.TokenSource == nil {
// We only validate non-tokensource creds, as TokenSource-based credentials
// don't propagate universe.
if o.GetUniverseDomain() != credsUniverseDomain {
return nil, internal.ErrUniverseNotMatch(o.GetUniverseDomain(), credsUniverseDomain)
}
}
grpcOpts = append(grpcOpts, grpc.WithPerRPCCredentials(grpcTokenSource{
TokenSource: oauth.TokenSource{TokenSource: creds.TokenSource},
quotaProject: internal.GetQuotaProject(creds, o.QuotaProject),

View File

@@ -88,6 +88,17 @@ func newTransport(ctx context.Context, base http.RoundTripper, settings *interna
if err != nil {
return nil, err
}
credsUniverseDomain, err := creds.GetUniverseDomain()
if err != nil {
return nil, err
}
if settings.TokenSource == nil {
// We only validate non-tokensource creds, as TokenSource-based credentials
// don't propagate universe.
if settings.GetUniverseDomain() != credsUniverseDomain {
return nil, internal.ErrUniverseNotMatch(settings.GetUniverseDomain(), credsUniverseDomain)
}
}
paramTransport.quotaProject = internal.GetQuotaProject(creds, settings.QuotaProject)
ts := creds.TokenSource
if settings.ImpersonationConfig == nil && settings.TokenSource != nil {

2
vendor/modules.txt vendored
View File

@@ -1519,7 +1519,7 @@ golang.org/x/tools/internal/stdlib
golang.org/x/tools/internal/typeparams
golang.org/x/tools/internal/typesinternal
golang.org/x/tools/internal/versions
# google.golang.org/api v0.155.0
# google.golang.org/api v0.160.0
## explicit; go 1.19
google.golang.org/api/googleapi
google.golang.org/api/googleapi/transport