mirror of
https://github.com/moby/moby.git
synced 2022-11-09 12:21:53 -05:00
vendor: golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
Remove the replace rule, and use the version as specified by (indirect) dependencies:
full diff: bf48bf16ab...f6687ab280
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
parent
42d2f0bbc7
commit
3ddf696a2d
19 changed files with 1246 additions and 33 deletions
|
@ -166,7 +166,6 @@ replace (
|
||||||
github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.11
|
github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.11
|
||||||
github.com/vishvananda/netlink => github.com/vishvananda/netlink v1.1.0
|
github.com/vishvananda/netlink => github.com/vishvananda/netlink v1.1.0
|
||||||
go.opencensus.io => go.opencensus.io v0.22.3
|
go.opencensus.io => go.opencensus.io v0.22.3
|
||||||
golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
|
||||||
google.golang.org/api => google.golang.org/api v0.8.0
|
google.golang.org/api => google.golang.org/api v0.8.0
|
||||||
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200227132054-3f1135a288c9
|
google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200227132054-3f1135a288c9
|
||||||
google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
||||||
|
|
|
@ -795,6 +795,7 @@ golang.org/x/net v0.0.0-20200324143707-d3edc9973b7e/go.mod h1:qpuaurCH72eLCgpAm/
|
||||||
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200506145744-7e3656a0809f/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
golang.org/x/net v0.0.0-20200520182314-0ba52f642ac2/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A=
|
||||||
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
|
golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA=
|
||||||
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201006153459-a7d1128ccaa0/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
|
||||||
|
@ -802,8 +803,11 @@ golang.org/x/net v0.0.0-20201224014010-6772e930b67b/go.mod h1:m0MpNAwzfU5UDzcl9v
|
||||||
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2 h1:CIJ76btIcR3eFI5EgSo6k1qKw9KJexJuRLI9G7Hp5wE=
|
||||||
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d h1:TzXSXBo42m9gQenoE3b9BGiEpg5IG2JkU5FkPIawgtw=
|
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c h1:pkQiBZBvdos9qq4wBAHqlzuZHEXo07pqV06ef90u1WI=
|
||||||
|
golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c/go.mod h1:KelEdhl1UZF7XfJ4dDtk6s++YSgaE7mD/BuKKDLBl4A=
|
||||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181108010431-42b317875d0f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||||
|
@ -931,6 +935,7 @@ google.golang.org/api v0.8.0 h1:VGGbLNyPF7dvYHhcUGYBBGCRDDK0RRJAI6KCvo0CL+E=
|
||||||
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
google.golang.org/api v0.8.0/go.mod h1:o4eAsZoiT+ibD93RtjEohWalFOjRDx6CVaqeizhEnKg=
|
||||||
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
|
||||||
|
google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
google.golang.org/appengine v1.6.7 h1:FZR1q0exgwxzPzp/aF+VccGrSfxfPpkBqjIIEq3ru6c=
|
||||||
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
google.golang.org/appengine v1.6.7/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
|
||||||
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
|
||||||
|
|
10
vendor/golang.org/x/oauth2/README.md
generated
vendored
10
vendor/golang.org/x/oauth2/README.md
generated
vendored
|
@ -1,7 +1,7 @@
|
||||||
# OAuth2 for Go
|
# OAuth2 for Go
|
||||||
|
|
||||||
|
[![Go Reference](https://pkg.go.dev/badge/golang.org/x/oauth2.svg)](https://pkg.go.dev/golang.org/x/oauth2)
|
||||||
[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2)
|
[![Build Status](https://travis-ci.org/golang/oauth2.svg?branch=master)](https://travis-ci.org/golang/oauth2)
|
||||||
[![GoDoc](https://godoc.org/golang.org/x/oauth2?status.svg)](https://godoc.org/golang.org/x/oauth2)
|
|
||||||
|
|
||||||
oauth2 package contains a client implementation for OAuth 2.0 spec.
|
oauth2 package contains a client implementation for OAuth 2.0 spec.
|
||||||
|
|
||||||
|
@ -14,17 +14,17 @@ go get golang.org/x/oauth2
|
||||||
Or you can manually git clone the repository to
|
Or you can manually git clone the repository to
|
||||||
`$(go env GOPATH)/src/golang.org/x/oauth2`.
|
`$(go env GOPATH)/src/golang.org/x/oauth2`.
|
||||||
|
|
||||||
See godoc for further documentation and examples.
|
See pkg.go.dev for further documentation and examples.
|
||||||
|
|
||||||
* [godoc.org/golang.org/x/oauth2](https://godoc.org/golang.org/x/oauth2)
|
* [pkg.go.dev/golang.org/x/oauth2](https://pkg.go.dev/golang.org/x/oauth2)
|
||||||
* [godoc.org/golang.org/x/oauth2/google](https://godoc.org/golang.org/x/oauth2/google)
|
* [pkg.go.dev/golang.org/x/oauth2/google](https://pkg.go.dev/golang.org/x/oauth2/google)
|
||||||
|
|
||||||
## Policy for new packages
|
## Policy for new packages
|
||||||
|
|
||||||
We no longer accept new provider-specific packages in this repo if all
|
We no longer accept new provider-specific packages in this repo if all
|
||||||
they do is add a single endpoint variable. If you just want to add a
|
they do is add a single endpoint variable. If you just want to add a
|
||||||
single endpoint, add it to the
|
single endpoint, add it to the
|
||||||
[godoc.org/golang.org/x/oauth2/endpoints](https://godoc.org/golang.org/x/oauth2/endpoints)
|
[pkg.go.dev/golang.org/x/oauth2/endpoints](https://pkg.go.dev/golang.org/x/oauth2/endpoints)
|
||||||
package.
|
package.
|
||||||
|
|
||||||
## Report Issues / Send Patches
|
## Report Issues / Send Patches
|
||||||
|
|
56
vendor/golang.org/x/oauth2/authhandler/authhandler.go
generated
vendored
Normal file
56
vendor/golang.org/x/oauth2/authhandler/authhandler.go
generated
vendored
Normal file
|
@ -0,0 +1,56 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
// Package authhandler implements a TokenSource to support
|
||||||
|
// "three-legged OAuth 2.0" via a custom AuthorizationHandler.
|
||||||
|
package authhandler
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// AuthorizationHandler is a 3-legged-OAuth helper that prompts
|
||||||
|
// the user for OAuth consent at the specified auth code URL
|
||||||
|
// and returns an auth code and state upon approval.
|
||||||
|
type AuthorizationHandler func(authCodeURL string) (code string, state string, err error)
|
||||||
|
|
||||||
|
// TokenSource returns an oauth2.TokenSource that fetches access tokens
|
||||||
|
// using 3-legged-OAuth flow.
|
||||||
|
//
|
||||||
|
// The provided context.Context is used for oauth2 Exchange operation.
|
||||||
|
//
|
||||||
|
// The provided oauth2.Config should be a full configuration containing AuthURL,
|
||||||
|
// TokenURL, and Scope.
|
||||||
|
//
|
||||||
|
// An environment-specific AuthorizationHandler is used to obtain user consent.
|
||||||
|
//
|
||||||
|
// Per the OAuth protocol, a unique "state" string should be specified here.
|
||||||
|
// This token source will verify that the "state" is identical in the request
|
||||||
|
// and response before exchanging the auth code for OAuth token to prevent CSRF
|
||||||
|
// attacks.
|
||||||
|
func TokenSource(ctx context.Context, config *oauth2.Config, state string, authHandler AuthorizationHandler) oauth2.TokenSource {
|
||||||
|
return oauth2.ReuseTokenSource(nil, authHandlerSource{config: config, ctx: ctx, authHandler: authHandler, state: state})
|
||||||
|
}
|
||||||
|
|
||||||
|
type authHandlerSource struct {
|
||||||
|
ctx context.Context
|
||||||
|
config *oauth2.Config
|
||||||
|
authHandler AuthorizationHandler
|
||||||
|
state string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (source authHandlerSource) Token() (*oauth2.Token, error) {
|
||||||
|
url := source.config.AuthCodeURL(source.state)
|
||||||
|
code, state, err := source.authHandler(url)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if state != source.state {
|
||||||
|
return nil, errors.New("state mismatch in 3-legged-OAuth flow")
|
||||||
|
}
|
||||||
|
return source.config.Exchange(source.ctx, code)
|
||||||
|
}
|
1
vendor/golang.org/x/oauth2/google/appengine_gen1.go
generated
vendored
1
vendor/golang.org/x/oauth2/google/appengine_gen1.go
generated
vendored
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build appengine
|
||||||
// +build appengine
|
// +build appengine
|
||||||
|
|
||||||
// This file applies to App Engine first generation runtimes (<= Go 1.9).
|
// This file applies to App Engine first generation runtimes (<= Go 1.9).
|
||||||
|
|
1
vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go
generated
vendored
1
vendor/golang.org/x/oauth2/google/appengine_gen2_flex.go
generated
vendored
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build !appengine
|
||||||
// +build !appengine
|
// +build !appengine
|
||||||
|
|
||||||
// This file applies to App Engine second generation runtimes (>= Go 1.11) and App Engine flexible.
|
// This file applies to App Engine second generation runtimes (>= Go 1.11) and App Engine flexible.
|
||||||
|
|
95
vendor/golang.org/x/oauth2/google/default.go
generated
vendored
95
vendor/golang.org/x/oauth2/google/default.go
generated
vendored
|
@ -16,11 +16,16 @@ import (
|
||||||
|
|
||||||
"cloud.google.com/go/compute/metadata"
|
"cloud.google.com/go/compute/metadata"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
"golang.org/x/oauth2/authhandler"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Credentials holds Google credentials, including "Application Default Credentials".
|
// Credentials holds Google credentials, including "Application Default Credentials".
|
||||||
// For more details, see:
|
// For more details, see:
|
||||||
// https://developers.google.com/accounts/docs/application-default-credentials
|
// https://developers.google.com/accounts/docs/application-default-credentials
|
||||||
|
// Credentials from external accounts (workload identity federation) are used to
|
||||||
|
// identify a particular application from an on-prem or non-Google Cloud platform
|
||||||
|
// including Amazon Web Services (AWS), Microsoft Azure or any identity provider
|
||||||
|
// that supports OpenID Connect (OIDC).
|
||||||
type Credentials struct {
|
type Credentials struct {
|
||||||
ProjectID string // may be empty
|
ProjectID string // may be empty
|
||||||
TokenSource oauth2.TokenSource
|
TokenSource oauth2.TokenSource
|
||||||
|
@ -37,6 +42,32 @@ type Credentials struct {
|
||||||
// Deprecated: use Credentials instead.
|
// Deprecated: use Credentials instead.
|
||||||
type DefaultCredentials = Credentials
|
type DefaultCredentials = Credentials
|
||||||
|
|
||||||
|
// CredentialsParams holds user supplied parameters that are used together
|
||||||
|
// with a credentials file for building a Credentials object.
|
||||||
|
type CredentialsParams struct {
|
||||||
|
// Scopes is the list OAuth scopes. Required.
|
||||||
|
// Example: https://www.googleapis.com/auth/cloud-platform
|
||||||
|
Scopes []string
|
||||||
|
|
||||||
|
// Subject is the user email used for domain wide delegation (see
|
||||||
|
// https://developers.google.com/identity/protocols/oauth2/service-account#delegatingauthority).
|
||||||
|
// Optional.
|
||||||
|
Subject string
|
||||||
|
|
||||||
|
// AuthHandler is the AuthorizationHandler used for 3-legged OAuth flow. Optional.
|
||||||
|
AuthHandler authhandler.AuthorizationHandler
|
||||||
|
|
||||||
|
// State is a unique string used with AuthHandler. Optional.
|
||||||
|
State string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (params CredentialsParams) deepCopy() CredentialsParams {
|
||||||
|
paramsCopy := params
|
||||||
|
paramsCopy.Scopes = make([]string, len(params.Scopes))
|
||||||
|
copy(paramsCopy.Scopes, params.Scopes)
|
||||||
|
return paramsCopy
|
||||||
|
}
|
||||||
|
|
||||||
// DefaultClient returns an HTTP Client that uses the
|
// DefaultClient returns an HTTP Client that uses the
|
||||||
// DefaultTokenSource to obtain authentication credentials.
|
// DefaultTokenSource to obtain authentication credentials.
|
||||||
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
|
func DefaultClient(ctx context.Context, scope ...string) (*http.Client, error) {
|
||||||
|
@ -58,13 +89,17 @@ func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSourc
|
||||||
return creds.TokenSource, nil
|
return creds.TokenSource, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// FindDefaultCredentials searches for "Application Default Credentials".
|
// FindDefaultCredentialsWithParams searches for "Application Default Credentials".
|
||||||
//
|
//
|
||||||
// It looks for credentials in the following places,
|
// It looks for credentials in the following places,
|
||||||
// preferring the first location found:
|
// preferring the first location found:
|
||||||
//
|
//
|
||||||
// 1. A JSON file whose path is specified by the
|
// 1. A JSON file whose path is specified by the
|
||||||
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
|
// GOOGLE_APPLICATION_CREDENTIALS environment variable.
|
||||||
|
// For workload identity federation, refer to
|
||||||
|
// https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation on
|
||||||
|
// how to generate the JSON configuration file for on-prem/non-Google cloud
|
||||||
|
// platforms.
|
||||||
// 2. A JSON file in a location known to the gcloud command-line tool.
|
// 2. A JSON file in a location known to the gcloud command-line tool.
|
||||||
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
|
// On Windows, this is %APPDATA%/gcloud/application_default_credentials.json.
|
||||||
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
|
// On other systems, $HOME/.config/gcloud/application_default_credentials.json.
|
||||||
|
@ -73,11 +108,14 @@ func DefaultTokenSource(ctx context.Context, scope ...string) (oauth2.TokenSourc
|
||||||
// 4. On Google Compute Engine, Google App Engine standard second generation runtimes
|
// 4. On Google Compute Engine, Google App Engine standard second generation runtimes
|
||||||
// (>= Go 1.11), and Google App Engine flexible environment, it fetches
|
// (>= Go 1.11), and Google App Engine flexible environment, it fetches
|
||||||
// credentials from the metadata server.
|
// credentials from the metadata server.
|
||||||
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
|
func FindDefaultCredentialsWithParams(ctx context.Context, params CredentialsParams) (*Credentials, error) {
|
||||||
|
// Make defensive copy of the slices in params.
|
||||||
|
params = params.deepCopy()
|
||||||
|
|
||||||
// First, try the environment variable.
|
// First, try the environment variable.
|
||||||
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
|
const envVar = "GOOGLE_APPLICATION_CREDENTIALS"
|
||||||
if filename := os.Getenv(envVar); filename != "" {
|
if filename := os.Getenv(envVar); filename != "" {
|
||||||
creds, err := readCredentialsFile(ctx, filename, scopes)
|
creds, err := readCredentialsFile(ctx, filename, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
|
return nil, fmt.Errorf("google: error getting credentials using %v environment variable: %v", envVar, err)
|
||||||
}
|
}
|
||||||
|
@ -86,7 +124,7 @@ func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials
|
||||||
|
|
||||||
// Second, try a well-known file.
|
// Second, try a well-known file.
|
||||||
filename := wellKnownFile()
|
filename := wellKnownFile()
|
||||||
if creds, err := readCredentialsFile(ctx, filename, scopes); err == nil {
|
if creds, err := readCredentialsFile(ctx, filename, params); err == nil {
|
||||||
return creds, nil
|
return creds, nil
|
||||||
} else if !os.IsNotExist(err) {
|
} else if !os.IsNotExist(err) {
|
||||||
return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
|
return nil, fmt.Errorf("google: error getting credentials using well-known file (%v): %v", filename, err)
|
||||||
|
@ -98,7 +136,7 @@ func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials
|
||||||
if appengineTokenFunc != nil {
|
if appengineTokenFunc != nil {
|
||||||
return &DefaultCredentials{
|
return &DefaultCredentials{
|
||||||
ProjectID: appengineAppIDFunc(ctx),
|
ProjectID: appengineAppIDFunc(ctx),
|
||||||
TokenSource: AppEngineTokenSource(ctx, scopes...),
|
TokenSource: AppEngineTokenSource(ctx, params.Scopes...),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -108,7 +146,7 @@ func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials
|
||||||
id, _ := metadata.ProjectID()
|
id, _ := metadata.ProjectID()
|
||||||
return &DefaultCredentials{
|
return &DefaultCredentials{
|
||||||
ProjectID: id,
|
ProjectID: id,
|
||||||
TokenSource: ComputeTokenSource("", scopes...),
|
TokenSource: ComputeTokenSource("", params.Scopes...),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -117,16 +155,38 @@ func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials
|
||||||
return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
|
return nil, fmt.Errorf("google: could not find default credentials. See %v for more information.", url)
|
||||||
}
|
}
|
||||||
|
|
||||||
// CredentialsFromJSON obtains Google credentials from a JSON value. The JSON can
|
// FindDefaultCredentials invokes FindDefaultCredentialsWithParams with the specified scopes.
|
||||||
// represent either a Google Developers Console client_credentials.json file (as in
|
func FindDefaultCredentials(ctx context.Context, scopes ...string) (*Credentials, error) {
|
||||||
// ConfigFromJSON) or a Google Developers service account key file (as in
|
var params CredentialsParams
|
||||||
// JWTConfigFromJSON).
|
params.Scopes = scopes
|
||||||
func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
|
return FindDefaultCredentialsWithParams(ctx, params)
|
||||||
|
}
|
||||||
|
|
||||||
|
// CredentialsFromJSONWithParams obtains Google credentials from a JSON value. The JSON can
|
||||||
|
// represent either a Google Developers Console client_credentials.json file (as in ConfigFromJSON),
|
||||||
|
// a Google Developers service account key file, a gcloud user credentials file (a.k.a. refresh
|
||||||
|
// token JSON), or the JSON configuration file for workload identity federation in non-Google cloud
|
||||||
|
// platforms (see https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation).
|
||||||
|
func CredentialsFromJSONWithParams(ctx context.Context, jsonData []byte, params CredentialsParams) (*Credentials, error) {
|
||||||
|
// Make defensive copy of the slices in params.
|
||||||
|
params = params.deepCopy()
|
||||||
|
|
||||||
|
// First, attempt to parse jsonData as a Google Developers Console client_credentials.json.
|
||||||
|
config, _ := ConfigFromJSON(jsonData, params.Scopes...)
|
||||||
|
if config != nil {
|
||||||
|
return &Credentials{
|
||||||
|
ProjectID: "",
|
||||||
|
TokenSource: authhandler.TokenSource(ctx, config, params.State, params.AuthHandler),
|
||||||
|
JSON: jsonData,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// Otherwise, parse jsonData as one of the other supported credentials files.
|
||||||
var f credentialsFile
|
var f credentialsFile
|
||||||
if err := json.Unmarshal(jsonData, &f); err != nil {
|
if err := json.Unmarshal(jsonData, &f); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ts, err := f.tokenSource(ctx, append([]string(nil), scopes...))
|
ts, err := f.tokenSource(ctx, params)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -137,6 +197,13 @@ func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string)
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// CredentialsFromJSON invokes CredentialsFromJSONWithParams with the specified scopes.
|
||||||
|
func CredentialsFromJSON(ctx context.Context, jsonData []byte, scopes ...string) (*Credentials, error) {
|
||||||
|
var params CredentialsParams
|
||||||
|
params.Scopes = scopes
|
||||||
|
return CredentialsFromJSONWithParams(ctx, jsonData, params)
|
||||||
|
}
|
||||||
|
|
||||||
func wellKnownFile() string {
|
func wellKnownFile() string {
|
||||||
const f = "application_default_credentials.json"
|
const f = "application_default_credentials.json"
|
||||||
if runtime.GOOS == "windows" {
|
if runtime.GOOS == "windows" {
|
||||||
|
@ -145,10 +212,10 @@ func wellKnownFile() string {
|
||||||
return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
|
return filepath.Join(guessUnixHomeDir(), ".config", "gcloud", f)
|
||||||
}
|
}
|
||||||
|
|
||||||
func readCredentialsFile(ctx context.Context, filename string, scopes []string) (*DefaultCredentials, error) {
|
func readCredentialsFile(ctx context.Context, filename string, params CredentialsParams) (*DefaultCredentials, error) {
|
||||||
b, err := ioutil.ReadFile(filename)
|
b, err := ioutil.ReadFile(filename)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
return CredentialsFromJSON(ctx, b, scopes...)
|
return CredentialsFromJSONWithParams(ctx, b, params)
|
||||||
}
|
}
|
||||||
|
|
43
vendor/golang.org/x/oauth2/google/doc.go
generated
vendored
43
vendor/golang.org/x/oauth2/google/doc.go
generated
vendored
|
@ -4,13 +4,16 @@
|
||||||
|
|
||||||
// Package google provides support for making OAuth2 authorized and authenticated
|
// Package google provides support for making OAuth2 authorized and authenticated
|
||||||
// HTTP requests to Google APIs. It supports the Web server flow, client-side
|
// HTTP requests to Google APIs. It supports the Web server flow, client-side
|
||||||
// credentials, service accounts, Google Compute Engine service accounts, and Google
|
// credentials, service accounts, Google Compute Engine service accounts, Google
|
||||||
// App Engine service accounts.
|
// App Engine service accounts and workload identity federation from non-Google
|
||||||
|
// cloud platforms.
|
||||||
//
|
//
|
||||||
// A brief overview of the package follows. For more information, please read
|
// A brief overview of the package follows. For more information, please read
|
||||||
// https://developers.google.com/accounts/docs/OAuth2
|
// https://developers.google.com/accounts/docs/OAuth2
|
||||||
// and
|
// and
|
||||||
// https://developers.google.com/accounts/docs/application-default-credentials.
|
// https://developers.google.com/accounts/docs/application-default-credentials.
|
||||||
|
// For more information on using workload identity federation, refer to
|
||||||
|
// https://cloud.google.com/iam/docs/how-to#using-workload-identity-federation.
|
||||||
//
|
//
|
||||||
// OAuth2 Configs
|
// OAuth2 Configs
|
||||||
//
|
//
|
||||||
|
@ -19,6 +22,35 @@
|
||||||
// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or
|
// the other by JWTConfigFromJSON. The returned Config can be used to obtain a TokenSource or
|
||||||
// create an http.Client.
|
// create an http.Client.
|
||||||
//
|
//
|
||||||
|
// Workload Identity Federation
|
||||||
|
//
|
||||||
|
// Using workload identity federation, your application can access Google Cloud
|
||||||
|
// resources from Amazon Web Services (AWS), Microsoft Azure or any identity
|
||||||
|
// provider that supports OpenID Connect (OIDC).
|
||||||
|
// Traditionally, applications running outside Google Cloud have used service
|
||||||
|
// account keys to access Google Cloud resources. Using identity federation,
|
||||||
|
// you can allow your workload to impersonate a service account.
|
||||||
|
// This lets you access Google Cloud resources directly, eliminating the
|
||||||
|
// maintenance and security burden associated with service account keys.
|
||||||
|
//
|
||||||
|
// Follow the detailed instructions on how to configure Workload Identity Federation
|
||||||
|
// in various platforms:
|
||||||
|
//
|
||||||
|
// Amazon Web Services (AWS): https://cloud.google.com/iam/docs/access-resources-aws
|
||||||
|
// Microsoft Azure: https://cloud.google.com/iam/docs/access-resources-azure
|
||||||
|
// OIDC identity provider: https://cloud.google.com/iam/docs/access-resources-oidc
|
||||||
|
//
|
||||||
|
// For OIDC providers, the library can retrieve OIDC tokens either from a
|
||||||
|
// local file location (file-sourced credentials) or from a local server
|
||||||
|
// (URL-sourced credentials).
|
||||||
|
// For file-sourced credentials, a background process needs to be continuously
|
||||||
|
// refreshing the file location with a new OIDC token prior to expiration.
|
||||||
|
// For tokens with one hour lifetimes, the token needs to be updated in the file
|
||||||
|
// every hour. The token can be stored directly as plain text or in JSON format.
|
||||||
|
// For URL-sourced credentials, a local server needs to host a GET endpoint to
|
||||||
|
// return the OIDC token. The response can be in plain text or JSON.
|
||||||
|
// Additional required request headers can also be specified.
|
||||||
|
//
|
||||||
//
|
//
|
||||||
// Credentials
|
// Credentials
|
||||||
//
|
//
|
||||||
|
@ -29,6 +61,13 @@
|
||||||
// FindDefaultCredentials looks in some well-known places for a credentials file, and
|
// FindDefaultCredentials looks in some well-known places for a credentials file, and
|
||||||
// will call AppEngineTokenSource or ComputeTokenSource as needed.
|
// will call AppEngineTokenSource or ComputeTokenSource as needed.
|
||||||
//
|
//
|
||||||
|
// Application Default Credentials also support workload identity federation to
|
||||||
|
// access Google Cloud resources from non-Google Cloud platforms including Amazon
|
||||||
|
// Web Services (AWS), Microsoft Azure or any identity provider that supports
|
||||||
|
// OpenID Connect (OIDC). Workload identity federation is recommended for
|
||||||
|
// non-Google Cloud environments as it avoids the need to download, manage and
|
||||||
|
// store service account private keys locally.
|
||||||
|
//
|
||||||
// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials,
|
// DefaultClient and DefaultTokenSource are convenience methods. They first call FindDefaultCredentials,
|
||||||
// then use the credentials to construct an http.Client or an oauth2.TokenSource.
|
// then use the credentials to construct an http.Client or an oauth2.TokenSource.
|
||||||
//
|
//
|
||||||
|
|
53
vendor/golang.org/x/oauth2/google/google.go
generated
vendored
53
vendor/golang.org/x/oauth2/google/google.go
generated
vendored
|
@ -15,10 +15,11 @@ import (
|
||||||
|
|
||||||
"cloud.google.com/go/compute/metadata"
|
"cloud.google.com/go/compute/metadata"
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
|
"golang.org/x/oauth2/google/internal/externalaccount"
|
||||||
"golang.org/x/oauth2/jwt"
|
"golang.org/x/oauth2/jwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Endpoint is Google's OAuth 2.0 endpoint.
|
// Endpoint is Google's OAuth 2.0 default endpoint.
|
||||||
var Endpoint = oauth2.Endpoint{
|
var Endpoint = oauth2.Endpoint{
|
||||||
AuthURL: "https://accounts.google.com/o/oauth2/auth",
|
AuthURL: "https://accounts.google.com/o/oauth2/auth",
|
||||||
TokenURL: "https://oauth2.googleapis.com/token",
|
TokenURL: "https://oauth2.googleapis.com/token",
|
||||||
|
@ -86,23 +87,25 @@ func JWTConfigFromJSON(jsonKey []byte, scope ...string) (*jwt.Config, error) {
|
||||||
return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey)
|
return nil, fmt.Errorf("google: read JWT from JSON credentials: 'type' field is %q (expected %q)", f.Type, serviceAccountKey)
|
||||||
}
|
}
|
||||||
scope = append([]string(nil), scope...) // copy
|
scope = append([]string(nil), scope...) // copy
|
||||||
return f.jwtConfig(scope), nil
|
return f.jwtConfig(scope, ""), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// JSON key file types.
|
// JSON key file types.
|
||||||
const (
|
const (
|
||||||
serviceAccountKey = "service_account"
|
serviceAccountKey = "service_account"
|
||||||
userCredentialsKey = "authorized_user"
|
userCredentialsKey = "authorized_user"
|
||||||
|
externalAccountKey = "external_account"
|
||||||
)
|
)
|
||||||
|
|
||||||
// credentialsFile is the unmarshalled representation of a credentials file.
|
// credentialsFile is the unmarshalled representation of a credentials file.
|
||||||
type credentialsFile struct {
|
type credentialsFile struct {
|
||||||
Type string `json:"type"` // serviceAccountKey or userCredentialsKey
|
Type string `json:"type"`
|
||||||
|
|
||||||
// Service Account fields
|
// Service Account fields
|
||||||
ClientEmail string `json:"client_email"`
|
ClientEmail string `json:"client_email"`
|
||||||
PrivateKeyID string `json:"private_key_id"`
|
PrivateKeyID string `json:"private_key_id"`
|
||||||
PrivateKey string `json:"private_key"`
|
PrivateKey string `json:"private_key"`
|
||||||
|
AuthURL string `json:"auth_uri"`
|
||||||
TokenURL string `json:"token_uri"`
|
TokenURL string `json:"token_uri"`
|
||||||
ProjectID string `json:"project_id"`
|
ProjectID string `json:"project_id"`
|
||||||
|
|
||||||
|
@ -111,15 +114,25 @@ type credentialsFile struct {
|
||||||
ClientSecret string `json:"client_secret"`
|
ClientSecret string `json:"client_secret"`
|
||||||
ClientID string `json:"client_id"`
|
ClientID string `json:"client_id"`
|
||||||
RefreshToken string `json:"refresh_token"`
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
|
||||||
|
// External Account fields
|
||||||
|
Audience string `json:"audience"`
|
||||||
|
SubjectTokenType string `json:"subject_token_type"`
|
||||||
|
TokenURLExternal string `json:"token_url"`
|
||||||
|
TokenInfoURL string `json:"token_info_url"`
|
||||||
|
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
|
||||||
|
CredentialSource externalaccount.CredentialSource `json:"credential_source"`
|
||||||
|
QuotaProjectID string `json:"quota_project_id"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config {
|
func (f *credentialsFile) jwtConfig(scopes []string, subject string) *jwt.Config {
|
||||||
cfg := &jwt.Config{
|
cfg := &jwt.Config{
|
||||||
Email: f.ClientEmail,
|
Email: f.ClientEmail,
|
||||||
PrivateKey: []byte(f.PrivateKey),
|
PrivateKey: []byte(f.PrivateKey),
|
||||||
PrivateKeyID: f.PrivateKeyID,
|
PrivateKeyID: f.PrivateKeyID,
|
||||||
Scopes: scopes,
|
Scopes: scopes,
|
||||||
TokenURL: f.TokenURL,
|
TokenURL: f.TokenURL,
|
||||||
|
Subject: subject, // This is the user email to impersonate
|
||||||
}
|
}
|
||||||
if cfg.TokenURL == "" {
|
if cfg.TokenURL == "" {
|
||||||
cfg.TokenURL = JWTTokenURL
|
cfg.TokenURL = JWTTokenURL
|
||||||
|
@ -127,20 +140,44 @@ func (f *credentialsFile) jwtConfig(scopes []string) *jwt.Config {
|
||||||
return cfg
|
return cfg
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *credentialsFile) tokenSource(ctx context.Context, scopes []string) (oauth2.TokenSource, error) {
|
func (f *credentialsFile) tokenSource(ctx context.Context, params CredentialsParams) (oauth2.TokenSource, error) {
|
||||||
switch f.Type {
|
switch f.Type {
|
||||||
case serviceAccountKey:
|
case serviceAccountKey:
|
||||||
cfg := f.jwtConfig(scopes)
|
cfg := f.jwtConfig(params.Scopes, params.Subject)
|
||||||
return cfg.TokenSource(ctx), nil
|
return cfg.TokenSource(ctx), nil
|
||||||
case userCredentialsKey:
|
case userCredentialsKey:
|
||||||
cfg := &oauth2.Config{
|
cfg := &oauth2.Config{
|
||||||
ClientID: f.ClientID,
|
ClientID: f.ClientID,
|
||||||
ClientSecret: f.ClientSecret,
|
ClientSecret: f.ClientSecret,
|
||||||
Scopes: scopes,
|
Scopes: params.Scopes,
|
||||||
Endpoint: Endpoint,
|
Endpoint: oauth2.Endpoint{
|
||||||
|
AuthURL: f.AuthURL,
|
||||||
|
TokenURL: f.TokenURL,
|
||||||
|
AuthStyle: oauth2.AuthStyleInParams,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
if cfg.Endpoint.AuthURL == "" {
|
||||||
|
cfg.Endpoint.AuthURL = Endpoint.AuthURL
|
||||||
|
}
|
||||||
|
if cfg.Endpoint.TokenURL == "" {
|
||||||
|
cfg.Endpoint.TokenURL = Endpoint.TokenURL
|
||||||
}
|
}
|
||||||
tok := &oauth2.Token{RefreshToken: f.RefreshToken}
|
tok := &oauth2.Token{RefreshToken: f.RefreshToken}
|
||||||
return cfg.TokenSource(ctx, tok), nil
|
return cfg.TokenSource(ctx, tok), nil
|
||||||
|
case externalAccountKey:
|
||||||
|
cfg := &externalaccount.Config{
|
||||||
|
Audience: f.Audience,
|
||||||
|
SubjectTokenType: f.SubjectTokenType,
|
||||||
|
TokenURL: f.TokenURLExternal,
|
||||||
|
TokenInfoURL: f.TokenInfoURL,
|
||||||
|
ServiceAccountImpersonationURL: f.ServiceAccountImpersonationURL,
|
||||||
|
ClientSecret: f.ClientSecret,
|
||||||
|
ClientID: f.ClientID,
|
||||||
|
CredentialSource: f.CredentialSource,
|
||||||
|
QuotaProjectID: f.QuotaProjectID,
|
||||||
|
Scopes: params.Scopes,
|
||||||
|
}
|
||||||
|
return cfg.TokenSource(ctx), nil
|
||||||
case "":
|
case "":
|
||||||
return nil, errors.New("missing 'type' field in credentials")
|
return nil, errors.New("missing 'type' field in credentials")
|
||||||
default:
|
default:
|
||||||
|
|
466
vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go
generated
vendored
Normal file
466
vendor/golang.org/x/oauth2/google/internal/externalaccount/aws.go
generated
vendored
Normal file
|
@ -0,0 +1,466 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"crypto/hmac"
|
||||||
|
"crypto/sha256"
|
||||||
|
"encoding/hex"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"os"
|
||||||
|
"path"
|
||||||
|
"sort"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
type awsSecurityCredentials struct {
|
||||||
|
AccessKeyID string `json:"AccessKeyID"`
|
||||||
|
SecretAccessKey string `json:"SecretAccessKey"`
|
||||||
|
SecurityToken string `json:"Token"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// awsRequestSigner is a utility class to sign http requests using a AWS V4 signature.
|
||||||
|
type awsRequestSigner struct {
|
||||||
|
RegionName string
|
||||||
|
AwsSecurityCredentials awsSecurityCredentials
|
||||||
|
}
|
||||||
|
|
||||||
|
// getenv aliases os.Getenv for testing
|
||||||
|
var getenv = os.Getenv
|
||||||
|
|
||||||
|
const (
|
||||||
|
// AWS Signature Version 4 signing algorithm identifier.
|
||||||
|
awsAlgorithm = "AWS4-HMAC-SHA256"
|
||||||
|
|
||||||
|
// The termination string for the AWS credential scope value as defined in
|
||||||
|
// https://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
|
||||||
|
awsRequestType = "aws4_request"
|
||||||
|
|
||||||
|
// The AWS authorization header name for the security session token if available.
|
||||||
|
awsSecurityTokenHeader = "x-amz-security-token"
|
||||||
|
|
||||||
|
// The AWS authorization header name for the auto-generated date.
|
||||||
|
awsDateHeader = "x-amz-date"
|
||||||
|
|
||||||
|
awsTimeFormatLong = "20060102T150405Z"
|
||||||
|
awsTimeFormatShort = "20060102"
|
||||||
|
)
|
||||||
|
|
||||||
|
func getSha256(input []byte) (string, error) {
|
||||||
|
hash := sha256.New()
|
||||||
|
if _, err := hash.Write(input); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return hex.EncodeToString(hash.Sum(nil)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getHmacSha256(key, input []byte) ([]byte, error) {
|
||||||
|
hash := hmac.New(sha256.New, key)
|
||||||
|
if _, err := hash.Write(input); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
return hash.Sum(nil), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func cloneRequest(r *http.Request) *http.Request {
|
||||||
|
r2 := new(http.Request)
|
||||||
|
*r2 = *r
|
||||||
|
if r.Header != nil {
|
||||||
|
r2.Header = make(http.Header, len(r.Header))
|
||||||
|
|
||||||
|
// Find total number of values.
|
||||||
|
headerCount := 0
|
||||||
|
for _, headerValues := range r.Header {
|
||||||
|
headerCount += len(headerValues)
|
||||||
|
}
|
||||||
|
copiedHeaders := make([]string, headerCount) // shared backing array for headers' values
|
||||||
|
|
||||||
|
for headerKey, headerValues := range r.Header {
|
||||||
|
headerCount = copy(copiedHeaders, headerValues)
|
||||||
|
r2.Header[headerKey] = copiedHeaders[:headerCount:headerCount]
|
||||||
|
copiedHeaders = copiedHeaders[headerCount:]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return r2
|
||||||
|
}
|
||||||
|
|
||||||
|
func canonicalPath(req *http.Request) string {
|
||||||
|
result := req.URL.EscapedPath()
|
||||||
|
if result == "" {
|
||||||
|
return "/"
|
||||||
|
}
|
||||||
|
return path.Clean(result)
|
||||||
|
}
|
||||||
|
|
||||||
|
func canonicalQuery(req *http.Request) string {
|
||||||
|
queryValues := req.URL.Query()
|
||||||
|
for queryKey := range queryValues {
|
||||||
|
sort.Strings(queryValues[queryKey])
|
||||||
|
}
|
||||||
|
return queryValues.Encode()
|
||||||
|
}
|
||||||
|
|
||||||
|
func canonicalHeaders(req *http.Request) (string, string) {
|
||||||
|
// Header keys need to be sorted alphabetically.
|
||||||
|
var headers []string
|
||||||
|
lowerCaseHeaders := make(http.Header)
|
||||||
|
for k, v := range req.Header {
|
||||||
|
k := strings.ToLower(k)
|
||||||
|
if _, ok := lowerCaseHeaders[k]; ok {
|
||||||
|
// include additional values
|
||||||
|
lowerCaseHeaders[k] = append(lowerCaseHeaders[k], v...)
|
||||||
|
} else {
|
||||||
|
headers = append(headers, k)
|
||||||
|
lowerCaseHeaders[k] = v
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Strings(headers)
|
||||||
|
|
||||||
|
var fullHeaders bytes.Buffer
|
||||||
|
for _, header := range headers {
|
||||||
|
headerValue := strings.Join(lowerCaseHeaders[header], ",")
|
||||||
|
fullHeaders.WriteString(header)
|
||||||
|
fullHeaders.WriteRune(':')
|
||||||
|
fullHeaders.WriteString(headerValue)
|
||||||
|
fullHeaders.WriteRune('\n')
|
||||||
|
}
|
||||||
|
|
||||||
|
return strings.Join(headers, ";"), fullHeaders.String()
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestDataHash(req *http.Request) (string, error) {
|
||||||
|
var requestData []byte
|
||||||
|
if req.Body != nil {
|
||||||
|
requestBody, err := req.GetBody()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer requestBody.Close()
|
||||||
|
|
||||||
|
requestData, err = ioutil.ReadAll(io.LimitReader(requestBody, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return getSha256(requestData)
|
||||||
|
}
|
||||||
|
|
||||||
|
func requestHost(req *http.Request) string {
|
||||||
|
if req.Host != "" {
|
||||||
|
return req.Host
|
||||||
|
}
|
||||||
|
return req.URL.Host
|
||||||
|
}
|
||||||
|
|
||||||
|
func canonicalRequest(req *http.Request, canonicalHeaderColumns, canonicalHeaderData string) (string, error) {
|
||||||
|
dataHash, err := requestDataHash(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s\n%s\n%s\n%s\n%s\n%s", req.Method, canonicalPath(req), canonicalQuery(req), canonicalHeaderData, canonicalHeaderColumns, dataHash), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// SignRequest adds the appropriate headers to an http.Request
|
||||||
|
// or returns an error if something prevented this.
|
||||||
|
func (rs *awsRequestSigner) SignRequest(req *http.Request) error {
|
||||||
|
signedRequest := cloneRequest(req)
|
||||||
|
timestamp := now()
|
||||||
|
|
||||||
|
signedRequest.Header.Add("host", requestHost(req))
|
||||||
|
|
||||||
|
if rs.AwsSecurityCredentials.SecurityToken != "" {
|
||||||
|
signedRequest.Header.Add(awsSecurityTokenHeader, rs.AwsSecurityCredentials.SecurityToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
if signedRequest.Header.Get("date") == "" {
|
||||||
|
signedRequest.Header.Add(awsDateHeader, timestamp.Format(awsTimeFormatLong))
|
||||||
|
}
|
||||||
|
|
||||||
|
authorizationCode, err := rs.generateAuthentication(signedRequest, timestamp)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
signedRequest.Header.Set("Authorization", authorizationCode)
|
||||||
|
|
||||||
|
req.Header = signedRequest.Header
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (rs *awsRequestSigner) generateAuthentication(req *http.Request, timestamp time.Time) (string, error) {
|
||||||
|
canonicalHeaderColumns, canonicalHeaderData := canonicalHeaders(req)
|
||||||
|
|
||||||
|
dateStamp := timestamp.Format(awsTimeFormatShort)
|
||||||
|
serviceName := ""
|
||||||
|
if splitHost := strings.Split(requestHost(req), "."); len(splitHost) > 0 {
|
||||||
|
serviceName = splitHost[0]
|
||||||
|
}
|
||||||
|
|
||||||
|
credentialScope := fmt.Sprintf("%s/%s/%s/%s", dateStamp, rs.RegionName, serviceName, awsRequestType)
|
||||||
|
|
||||||
|
requestString, err := canonicalRequest(req, canonicalHeaderColumns, canonicalHeaderData)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
requestHash, err := getSha256([]byte(requestString))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
stringToSign := fmt.Sprintf("%s\n%s\n%s\n%s", awsAlgorithm, timestamp.Format(awsTimeFormatLong), credentialScope, requestHash)
|
||||||
|
|
||||||
|
signingKey := []byte("AWS4" + rs.AwsSecurityCredentials.SecretAccessKey)
|
||||||
|
for _, signingInput := range []string{
|
||||||
|
dateStamp, rs.RegionName, serviceName, awsRequestType, stringToSign,
|
||||||
|
} {
|
||||||
|
signingKey, err = getHmacSha256(signingKey, []byte(signingInput))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return fmt.Sprintf("%s Credential=%s/%s, SignedHeaders=%s, Signature=%s", awsAlgorithm, rs.AwsSecurityCredentials.AccessKeyID, credentialScope, canonicalHeaderColumns, hex.EncodeToString(signingKey)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
type awsCredentialSource struct {
|
||||||
|
EnvironmentID string
|
||||||
|
RegionURL string
|
||||||
|
RegionalCredVerificationURL string
|
||||||
|
CredVerificationURL string
|
||||||
|
TargetResource string
|
||||||
|
requestSigner *awsRequestSigner
|
||||||
|
region string
|
||||||
|
ctx context.Context
|
||||||
|
client *http.Client
|
||||||
|
}
|
||||||
|
|
||||||
|
type awsRequestHeader struct {
|
||||||
|
Key string `json:"key"`
|
||||||
|
Value string `json:"value"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type awsRequest struct {
|
||||||
|
URL string `json:"url"`
|
||||||
|
Method string `json:"method"`
|
||||||
|
Headers []awsRequestHeader `json:"headers"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs awsCredentialSource) doRequest(req *http.Request) (*http.Response, error) {
|
||||||
|
if cs.client == nil {
|
||||||
|
cs.client = oauth2.NewClient(cs.ctx, nil)
|
||||||
|
}
|
||||||
|
return cs.client.Do(req.WithContext(cs.ctx))
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs awsCredentialSource) subjectToken() (string, error) {
|
||||||
|
if cs.requestSigner == nil {
|
||||||
|
awsSecurityCredentials, err := cs.getSecurityCredentials()
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if cs.region, err = cs.getRegion(); err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
cs.requestSigner = &awsRequestSigner{
|
||||||
|
RegionName: cs.region,
|
||||||
|
AwsSecurityCredentials: awsSecurityCredentials,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generate the signed request to AWS STS GetCallerIdentity API.
|
||||||
|
// Use the required regional endpoint. Otherwise, the request will fail.
|
||||||
|
req, err := http.NewRequest("POST", strings.Replace(cs.RegionalCredVerificationURL, "{region}", cs.region, 1), nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
// The full, canonical resource name of the workload identity pool
|
||||||
|
// provider, with or without the HTTPS prefix.
|
||||||
|
// Including this header as part of the signature is recommended to
|
||||||
|
// ensure data integrity.
|
||||||
|
if cs.TargetResource != "" {
|
||||||
|
req.Header.Add("x-goog-cloud-target-resource", cs.TargetResource)
|
||||||
|
}
|
||||||
|
cs.requestSigner.SignRequest(req)
|
||||||
|
|
||||||
|
/*
|
||||||
|
The GCP STS endpoint expects the headers to be formatted as:
|
||||||
|
# [
|
||||||
|
# {key: 'x-amz-date', value: '...'},
|
||||||
|
# {key: 'Authorization', value: '...'},
|
||||||
|
# ...
|
||||||
|
# ]
|
||||||
|
# And then serialized as:
|
||||||
|
# quote(json.dumps({
|
||||||
|
# url: '...',
|
||||||
|
# method: 'POST',
|
||||||
|
# headers: [{key: 'x-amz-date', value: '...'}, ...]
|
||||||
|
# }))
|
||||||
|
*/
|
||||||
|
|
||||||
|
awsSignedReq := awsRequest{
|
||||||
|
URL: req.URL.String(),
|
||||||
|
Method: "POST",
|
||||||
|
}
|
||||||
|
for headerKey, headerList := range req.Header {
|
||||||
|
for _, headerValue := range headerList {
|
||||||
|
awsSignedReq.Headers = append(awsSignedReq.Headers, awsRequestHeader{
|
||||||
|
Key: headerKey,
|
||||||
|
Value: headerValue,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
sort.Slice(awsSignedReq.Headers, func(i, j int) bool {
|
||||||
|
headerCompare := strings.Compare(awsSignedReq.Headers[i].Key, awsSignedReq.Headers[j].Key)
|
||||||
|
if headerCompare == 0 {
|
||||||
|
return strings.Compare(awsSignedReq.Headers[i].Value, awsSignedReq.Headers[j].Value) < 0
|
||||||
|
}
|
||||||
|
return headerCompare < 0
|
||||||
|
})
|
||||||
|
|
||||||
|
result, err := json.Marshal(awsSignedReq)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
return url.QueryEscape(string(result)), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *awsCredentialSource) getRegion() (string, error) {
|
||||||
|
if envAwsRegion := getenv("AWS_REGION"); envAwsRegion != "" {
|
||||||
|
return envAwsRegion, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
if cs.RegionURL == "" {
|
||||||
|
return "", errors.New("oauth2/google: unable to determine AWS region")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", cs.RegionURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := cs.doRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return "", fmt.Errorf("oauth2/google: unable to retrieve AWS region - %s", string(respBody))
|
||||||
|
}
|
||||||
|
|
||||||
|
// This endpoint will return the region in format: us-east-2b.
|
||||||
|
// Only the us-east-2 part should be used.
|
||||||
|
respBodyEnd := 0
|
||||||
|
if len(respBody) > 1 {
|
||||||
|
respBodyEnd = len(respBody) - 1
|
||||||
|
}
|
||||||
|
return string(respBody[:respBodyEnd]), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *awsCredentialSource) getSecurityCredentials() (result awsSecurityCredentials, err error) {
|
||||||
|
if accessKeyID := getenv("AWS_ACCESS_KEY_ID"); accessKeyID != "" {
|
||||||
|
if secretAccessKey := getenv("AWS_SECRET_ACCESS_KEY"); secretAccessKey != "" {
|
||||||
|
return awsSecurityCredentials{
|
||||||
|
AccessKeyID: accessKeyID,
|
||||||
|
SecretAccessKey: secretAccessKey,
|
||||||
|
SecurityToken: getenv("AWS_SESSION_TOKEN"),
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
roleName, err := cs.getMetadataRoleName()
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
credentials, err := cs.getMetadataSecurityCredentials(roleName)
|
||||||
|
if err != nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
if credentials.AccessKeyID == "" {
|
||||||
|
return result, errors.New("oauth2/google: missing AccessKeyId credential")
|
||||||
|
}
|
||||||
|
|
||||||
|
if credentials.SecretAccessKey == "" {
|
||||||
|
return result, errors.New("oauth2/google: missing SecretAccessKey credential")
|
||||||
|
}
|
||||||
|
|
||||||
|
return credentials, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *awsCredentialSource) getMetadataSecurityCredentials(roleName string) (awsSecurityCredentials, error) {
|
||||||
|
var result awsSecurityCredentials
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", fmt.Sprintf("%s/%s", cs.CredVerificationURL, roleName), nil)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := cs.doRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return result, fmt.Errorf("oauth2/google: unable to retrieve AWS security credentials - %s", string(respBody))
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(respBody, &result)
|
||||||
|
return result, err
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs *awsCredentialSource) getMetadataRoleName() (string, error) {
|
||||||
|
if cs.CredVerificationURL == "" {
|
||||||
|
return "", errors.New("oauth2/google: unable to determine the AWS metadata server security credentials endpoint")
|
||||||
|
}
|
||||||
|
|
||||||
|
req, err := http.NewRequest("GET", cs.CredVerificationURL, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
resp, err := cs.doRequest(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
if resp.StatusCode != 200 {
|
||||||
|
return "", fmt.Errorf("oauth2/google: unable to retrieve AWS role name - %s", string(respBody))
|
||||||
|
}
|
||||||
|
|
||||||
|
return string(respBody), nil
|
||||||
|
}
|
163
vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
generated
vendored
Normal file
163
vendor/golang.org/x/oauth2/google/internal/externalaccount/basecredentials.go
generated
vendored
Normal file
|
@ -0,0 +1,163 @@
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"net/http"
|
||||||
|
"strconv"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// now aliases time.Now for testing
|
||||||
|
var now = func() time.Time {
|
||||||
|
return time.Now().UTC()
|
||||||
|
}
|
||||||
|
|
||||||
|
// Config stores the configuration for fetching tokens with external credentials.
|
||||||
|
type Config struct {
|
||||||
|
Audience string
|
||||||
|
SubjectTokenType string
|
||||||
|
TokenURL string
|
||||||
|
TokenInfoURL string
|
||||||
|
ServiceAccountImpersonationURL string
|
||||||
|
ClientSecret string
|
||||||
|
ClientID string
|
||||||
|
CredentialSource CredentialSource
|
||||||
|
QuotaProjectID string
|
||||||
|
Scopes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// TokenSource Returns an external account TokenSource struct. This is to be called by package google to construct a google.Credentials.
|
||||||
|
func (c *Config) TokenSource(ctx context.Context) oauth2.TokenSource {
|
||||||
|
ts := tokenSource{
|
||||||
|
ctx: ctx,
|
||||||
|
conf: c,
|
||||||
|
}
|
||||||
|
if c.ServiceAccountImpersonationURL == "" {
|
||||||
|
return oauth2.ReuseTokenSource(nil, ts)
|
||||||
|
}
|
||||||
|
scopes := c.Scopes
|
||||||
|
ts.conf.Scopes = []string{"https://www.googleapis.com/auth/cloud-platform"}
|
||||||
|
imp := impersonateTokenSource{
|
||||||
|
ctx: ctx,
|
||||||
|
url: c.ServiceAccountImpersonationURL,
|
||||||
|
scopes: scopes,
|
||||||
|
ts: oauth2.ReuseTokenSource(nil, ts),
|
||||||
|
}
|
||||||
|
return oauth2.ReuseTokenSource(nil, imp)
|
||||||
|
}
|
||||||
|
|
||||||
|
// Subject token file types.
|
||||||
|
const (
|
||||||
|
fileTypeText = "text"
|
||||||
|
fileTypeJSON = "json"
|
||||||
|
)
|
||||||
|
|
||||||
|
type format struct {
|
||||||
|
// Type is either "text" or "json". When not provided "text" type is assumed.
|
||||||
|
Type string `json:"type"`
|
||||||
|
// SubjectTokenFieldName is only required for JSON format. This would be "access_token" for azure.
|
||||||
|
SubjectTokenFieldName string `json:"subject_token_field_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// CredentialSource stores the information necessary to retrieve the credentials for the STS exchange.
|
||||||
|
type CredentialSource struct {
|
||||||
|
File string `json:"file"`
|
||||||
|
|
||||||
|
URL string `json:"url"`
|
||||||
|
Headers map[string]string `json:"headers"`
|
||||||
|
|
||||||
|
EnvironmentID string `json:"environment_id"`
|
||||||
|
RegionURL string `json:"region_url"`
|
||||||
|
RegionalCredVerificationURL string `json:"regional_cred_verification_url"`
|
||||||
|
CredVerificationURL string `json:"cred_verification_url"`
|
||||||
|
Format format `json:"format"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// parse determines the type of CredentialSource needed
|
||||||
|
func (c *Config) parse(ctx context.Context) (baseCredentialSource, error) {
|
||||||
|
if len(c.CredentialSource.EnvironmentID) > 3 && c.CredentialSource.EnvironmentID[:3] == "aws" {
|
||||||
|
if awsVersion, err := strconv.Atoi(c.CredentialSource.EnvironmentID[3:]); err == nil {
|
||||||
|
if awsVersion != 1 {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: aws version '%d' is not supported in the current build", awsVersion)
|
||||||
|
}
|
||||||
|
return awsCredentialSource{
|
||||||
|
EnvironmentID: c.CredentialSource.EnvironmentID,
|
||||||
|
RegionURL: c.CredentialSource.RegionURL,
|
||||||
|
RegionalCredVerificationURL: c.CredentialSource.RegionalCredVerificationURL,
|
||||||
|
CredVerificationURL: c.CredentialSource.URL,
|
||||||
|
TargetResource: c.Audience,
|
||||||
|
ctx: ctx,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
} else if c.CredentialSource.File != "" {
|
||||||
|
return fileCredentialSource{File: c.CredentialSource.File, Format: c.CredentialSource.Format}, nil
|
||||||
|
} else if c.CredentialSource.URL != "" {
|
||||||
|
return urlCredentialSource{URL: c.CredentialSource.URL, Headers: c.CredentialSource.Headers, Format: c.CredentialSource.Format, ctx: ctx}, nil
|
||||||
|
}
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to parse credential source")
|
||||||
|
}
|
||||||
|
|
||||||
|
type baseCredentialSource interface {
|
||||||
|
subjectToken() (string, error)
|
||||||
|
}
|
||||||
|
|
||||||
|
// tokenSource is the source that handles external credentials.
|
||||||
|
type tokenSource struct {
|
||||||
|
ctx context.Context
|
||||||
|
conf *Config
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token allows tokenSource to conform to the oauth2.TokenSource interface.
|
||||||
|
func (ts tokenSource) Token() (*oauth2.Token, error) {
|
||||||
|
conf := ts.conf
|
||||||
|
|
||||||
|
credSource, err := conf.parse(ts.ctx)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
subjectToken, err := credSource.subjectToken()
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
stsRequest := stsTokenExchangeRequest{
|
||||||
|
GrantType: "urn:ietf:params:oauth:grant-type:token-exchange",
|
||||||
|
Audience: conf.Audience,
|
||||||
|
Scope: conf.Scopes,
|
||||||
|
RequestedTokenType: "urn:ietf:params:oauth:token-type:access_token",
|
||||||
|
SubjectToken: subjectToken,
|
||||||
|
SubjectTokenType: conf.SubjectTokenType,
|
||||||
|
}
|
||||||
|
header := make(http.Header)
|
||||||
|
header.Add("Content-Type", "application/x-www-form-urlencoded")
|
||||||
|
clientAuth := clientAuthentication{
|
||||||
|
AuthStyle: oauth2.AuthStyleInHeader,
|
||||||
|
ClientID: conf.ClientID,
|
||||||
|
ClientSecret: conf.ClientSecret,
|
||||||
|
}
|
||||||
|
stsResp, err := exchangeToken(ts.ctx, conf.TokenURL, &stsRequest, clientAuth, header, nil)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
accessToken := &oauth2.Token{
|
||||||
|
AccessToken: stsResp.AccessToken,
|
||||||
|
TokenType: stsResp.TokenType,
|
||||||
|
}
|
||||||
|
if stsResp.ExpiresIn < 0 {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: got invalid expiry from security token service")
|
||||||
|
} else if stsResp.ExpiresIn >= 0 {
|
||||||
|
accessToken.Expiry = now().Add(time.Duration(stsResp.ExpiresIn) * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
if stsResp.RefreshToken != "" {
|
||||||
|
accessToken.RefreshToken = stsResp.RefreshToken
|
||||||
|
}
|
||||||
|
return accessToken, nil
|
||||||
|
}
|
41
vendor/golang.org/x/oauth2/google/internal/externalaccount/clientauth.go
generated
vendored
Normal file
41
vendor/golang.org/x/oauth2/google/internal/externalaccount/clientauth.go
generated
vendored
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/base64"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
)
|
||||||
|
|
||||||
|
// clientAuthentication represents an OAuth client ID and secret and the mechanism for passing these credentials as stated in rfc6749#2.3.1.
|
||||||
|
type clientAuthentication struct {
|
||||||
|
// AuthStyle can be either basic or request-body
|
||||||
|
AuthStyle oauth2.AuthStyle
|
||||||
|
ClientID string
|
||||||
|
ClientSecret string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *clientAuthentication) InjectAuthentication(values url.Values, headers http.Header) {
|
||||||
|
if c.ClientID == "" || c.ClientSecret == "" || values == nil || headers == nil {
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
switch c.AuthStyle {
|
||||||
|
case oauth2.AuthStyleInHeader: // AuthStyleInHeader corresponds to basic authentication as defined in rfc7617#2
|
||||||
|
plainHeader := c.ClientID + ":" + c.ClientSecret
|
||||||
|
headers.Add("Authorization", "Basic "+base64.StdEncoding.EncodeToString([]byte(plainHeader)))
|
||||||
|
case oauth2.AuthStyleInParams: // AuthStyleInParams corresponds to request-body authentication with ClientID and ClientSecret in the message body.
|
||||||
|
values.Set("client_id", c.ClientID)
|
||||||
|
values.Set("client_secret", c.ClientSecret)
|
||||||
|
case oauth2.AuthStyleAutoDetect:
|
||||||
|
values.Set("client_id", c.ClientID)
|
||||||
|
values.Set("client_secret", c.ClientSecret)
|
||||||
|
default:
|
||||||
|
values.Set("client_id", c.ClientID)
|
||||||
|
values.Set("client_secret", c.ClientSecret)
|
||||||
|
}
|
||||||
|
}
|
18
vendor/golang.org/x/oauth2/google/internal/externalaccount/err.go
generated
vendored
Normal file
18
vendor/golang.org/x/oauth2/google/internal/externalaccount/err.go
generated
vendored
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
// Error for handling OAuth related error responses as stated in rfc6749#5.2.
|
||||||
|
type Error struct {
|
||||||
|
Code string
|
||||||
|
URI string
|
||||||
|
Description string
|
||||||
|
}
|
||||||
|
|
||||||
|
func (err *Error) Error() string {
|
||||||
|
return fmt.Sprintf("got error code %s from %s: %s", err.Code, err.URI, err.Description)
|
||||||
|
}
|
57
vendor/golang.org/x/oauth2/google/internal/externalaccount/filecredsource.go
generated
vendored
Normal file
57
vendor/golang.org/x/oauth2/google/internal/externalaccount/filecredsource.go
generated
vendored
Normal file
|
@ -0,0 +1,57 @@
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
type fileCredentialSource struct {
|
||||||
|
File string
|
||||||
|
Format format
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs fileCredentialSource) subjectToken() (string, error) {
|
||||||
|
tokenFile, err := os.Open(cs.File)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: failed to open credential file %q", cs.File)
|
||||||
|
}
|
||||||
|
defer tokenFile.Close()
|
||||||
|
tokenBytes, err := ioutil.ReadAll(io.LimitReader(tokenFile, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: failed to read credential file: %v", err)
|
||||||
|
}
|
||||||
|
tokenBytes = bytes.TrimSpace(tokenBytes)
|
||||||
|
switch cs.Format.Type {
|
||||||
|
case "json":
|
||||||
|
jsonData := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(tokenBytes, &jsonData)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: failed to unmarshal subject token file: %v", err)
|
||||||
|
}
|
||||||
|
val, ok := jsonData[cs.Format.SubjectTokenFieldName]
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("oauth2/google: provided subject_token_field_name not found in credentials")
|
||||||
|
}
|
||||||
|
token, ok := val.(string)
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("oauth2/google: improperly formatted subject token")
|
||||||
|
}
|
||||||
|
return token, nil
|
||||||
|
case "text":
|
||||||
|
return string(tokenBytes), nil
|
||||||
|
case "":
|
||||||
|
return string(tokenBytes), nil
|
||||||
|
default:
|
||||||
|
return "", errors.New("oauth2/google: invalid credential_source file format type")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
83
vendor/golang.org/x/oauth2/google/internal/externalaccount/impersonate.go
generated
vendored
Normal file
83
vendor/golang.org/x/oauth2/google/internal/externalaccount/impersonate.go
generated
vendored
Normal file
|
@ -0,0 +1,83 @@
|
||||||
|
// Copyright 2021 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bytes"
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
// generateAccesstokenReq is used for service account impersonation
|
||||||
|
type generateAccessTokenReq struct {
|
||||||
|
Delegates []string `json:"delegates,omitempty"`
|
||||||
|
Lifetime string `json:"lifetime,omitempty"`
|
||||||
|
Scope []string `json:"scope,omitempty"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type impersonateTokenResponse struct {
|
||||||
|
AccessToken string `json:"accessToken"`
|
||||||
|
ExpireTime string `json:"expireTime"`
|
||||||
|
}
|
||||||
|
|
||||||
|
type impersonateTokenSource struct {
|
||||||
|
ctx context.Context
|
||||||
|
ts oauth2.TokenSource
|
||||||
|
|
||||||
|
url string
|
||||||
|
scopes []string
|
||||||
|
}
|
||||||
|
|
||||||
|
// Token performs the exchange to get a temporary service account
|
||||||
|
func (its impersonateTokenSource) Token() (*oauth2.Token, error) {
|
||||||
|
reqBody := generateAccessTokenReq{
|
||||||
|
Lifetime: "3600s",
|
||||||
|
Scope: its.scopes,
|
||||||
|
}
|
||||||
|
b, err := json.Marshal(reqBody)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to marshal request: %v", err)
|
||||||
|
}
|
||||||
|
client := oauth2.NewClient(its.ctx, its.ts)
|
||||||
|
req, err := http.NewRequest("POST", its.url, bytes.NewReader(b))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to create impersonation request: %v", err)
|
||||||
|
}
|
||||||
|
req = req.WithContext(its.ctx)
|
||||||
|
req.Header.Set("Content-Type", "application/json")
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to generate access token: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to read body: %v", err)
|
||||||
|
}
|
||||||
|
if c := resp.StatusCode; c < 200 || c > 299 {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: status code %d: %s", c, body)
|
||||||
|
}
|
||||||
|
|
||||||
|
var accessTokenResp impersonateTokenResponse
|
||||||
|
if err := json.Unmarshal(body, &accessTokenResp); err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to parse response: %v", err)
|
||||||
|
}
|
||||||
|
expiry, err := time.Parse(time.RFC3339, accessTokenResp.ExpireTime)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: unable to parse expiry: %v", err)
|
||||||
|
}
|
||||||
|
return &oauth2.Token{
|
||||||
|
AccessToken: accessTokenResp.AccessToken,
|
||||||
|
Expiry: expiry,
|
||||||
|
TokenType: "Bearer",
|
||||||
|
}, nil
|
||||||
|
}
|
104
vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go
generated
vendored
Normal file
104
vendor/golang.org/x/oauth2/google/internal/externalaccount/sts_exchange.go
generated
vendored
Normal file
|
@ -0,0 +1,104 @@
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
"net/url"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
)
|
||||||
|
|
||||||
|
// exchangeToken performs an oauth2 token exchange with the provided endpoint.
|
||||||
|
// The first 4 fields are all mandatory. headers can be used to pass additional
|
||||||
|
// headers beyond the bare minimum required by the token exchange. options can
|
||||||
|
// be used to pass additional JSON-structured options to the remote server.
|
||||||
|
func exchangeToken(ctx context.Context, endpoint string, request *stsTokenExchangeRequest, authentication clientAuthentication, headers http.Header, options map[string]interface{}) (*stsTokenExchangeResponse, error) {
|
||||||
|
|
||||||
|
client := oauth2.NewClient(ctx, nil)
|
||||||
|
|
||||||
|
data := url.Values{}
|
||||||
|
data.Set("audience", request.Audience)
|
||||||
|
data.Set("grant_type", "urn:ietf:params:oauth:grant-type:token-exchange")
|
||||||
|
data.Set("requested_token_type", "urn:ietf:params:oauth:token-type:access_token")
|
||||||
|
data.Set("subject_token_type", request.SubjectTokenType)
|
||||||
|
data.Set("subject_token", request.SubjectToken)
|
||||||
|
data.Set("scope", strings.Join(request.Scope, " "))
|
||||||
|
if options != nil {
|
||||||
|
opts, err := json.Marshal(options)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: failed to marshal additional options: %v", err)
|
||||||
|
}
|
||||||
|
data.Set("options", string(opts))
|
||||||
|
}
|
||||||
|
|
||||||
|
authentication.InjectAuthentication(data, headers)
|
||||||
|
encodedData := data.Encode()
|
||||||
|
|
||||||
|
req, err := http.NewRequest("POST", endpoint, strings.NewReader(encodedData))
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: failed to properly build http request: %v", err)
|
||||||
|
|
||||||
|
}
|
||||||
|
req = req.WithContext(ctx)
|
||||||
|
for key, list := range headers {
|
||||||
|
for _, val := range list {
|
||||||
|
req.Header.Add(key, val)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
req.Header.Add("Content-Length", strconv.Itoa(len(encodedData)))
|
||||||
|
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: invalid response from Secure Token Server: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
body, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
if c := resp.StatusCode; c < 200 || c > 299 {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: status code %d: %s", c, body)
|
||||||
|
}
|
||||||
|
var stsResp stsTokenExchangeResponse
|
||||||
|
err = json.Unmarshal(body, &stsResp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: failed to unmarshal response body from Secure Token Server: %v", err)
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
return &stsResp, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
// stsTokenExchangeRequest contains fields necessary to make an oauth2 token exchange.
|
||||||
|
type stsTokenExchangeRequest struct {
|
||||||
|
ActingParty struct {
|
||||||
|
ActorToken string
|
||||||
|
ActorTokenType string
|
||||||
|
}
|
||||||
|
GrantType string
|
||||||
|
Resource string
|
||||||
|
Audience string
|
||||||
|
Scope []string
|
||||||
|
RequestedTokenType string
|
||||||
|
SubjectToken string
|
||||||
|
SubjectTokenType string
|
||||||
|
}
|
||||||
|
|
||||||
|
// stsTokenExchangeResponse is used to decode the remote server response during an oauth2 token exchange.
|
||||||
|
type stsTokenExchangeResponse struct {
|
||||||
|
AccessToken string `json:"access_token"`
|
||||||
|
IssuedTokenType string `json:"issued_token_type"`
|
||||||
|
TokenType string `json:"token_type"`
|
||||||
|
ExpiresIn int `json:"expires_in"`
|
||||||
|
Scope string `json:"scope"`
|
||||||
|
RefreshToken string `json:"refresh_token"`
|
||||||
|
}
|
74
vendor/golang.org/x/oauth2/google/internal/externalaccount/urlcredsource.go
generated
vendored
Normal file
74
vendor/golang.org/x/oauth2/google/internal/externalaccount/urlcredsource.go
generated
vendored
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
// Copyright 2020 The Go Authors. All rights reserved.
|
||||||
|
// Use of this source code is governed by a BSD-style
|
||||||
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
package externalaccount
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/oauth2"
|
||||||
|
"io"
|
||||||
|
"io/ioutil"
|
||||||
|
"net/http"
|
||||||
|
)
|
||||||
|
|
||||||
|
type urlCredentialSource struct {
|
||||||
|
URL string
|
||||||
|
Headers map[string]string
|
||||||
|
Format format
|
||||||
|
ctx context.Context
|
||||||
|
}
|
||||||
|
|
||||||
|
func (cs urlCredentialSource) subjectToken() (string, error) {
|
||||||
|
client := oauth2.NewClient(cs.ctx, nil)
|
||||||
|
req, err := http.NewRequest("GET", cs.URL, nil)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: HTTP request for URL-sourced credential failed: %v", err)
|
||||||
|
}
|
||||||
|
req = req.WithContext(cs.ctx)
|
||||||
|
|
||||||
|
for key, val := range cs.Headers {
|
||||||
|
req.Header.Add(key, val)
|
||||||
|
}
|
||||||
|
resp, err := client.Do(req)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: invalid response when retrieving subject token: %v", err)
|
||||||
|
}
|
||||||
|
defer resp.Body.Close()
|
||||||
|
|
||||||
|
respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: invalid body in subject token URL query: %v", err)
|
||||||
|
}
|
||||||
|
if c := resp.StatusCode; c < 200 || c > 299 {
|
||||||
|
return "", fmt.Errorf("oauth2/google: status code %d: %s", c, respBody)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch cs.Format.Type {
|
||||||
|
case "json":
|
||||||
|
jsonData := make(map[string]interface{})
|
||||||
|
err = json.Unmarshal(respBody, &jsonData)
|
||||||
|
if err != nil {
|
||||||
|
return "", fmt.Errorf("oauth2/google: failed to unmarshal subject token file: %v", err)
|
||||||
|
}
|
||||||
|
val, ok := jsonData[cs.Format.SubjectTokenFieldName]
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("oauth2/google: provided subject_token_field_name not found in credentials")
|
||||||
|
}
|
||||||
|
token, ok := val.(string)
|
||||||
|
if !ok {
|
||||||
|
return "", errors.New("oauth2/google: improperly formatted subject token")
|
||||||
|
}
|
||||||
|
return token, nil
|
||||||
|
case "text":
|
||||||
|
return string(respBody), nil
|
||||||
|
case "":
|
||||||
|
return string(respBody), nil
|
||||||
|
default:
|
||||||
|
return "", errors.New("oauth2/google: invalid credential_source file format type")
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
1
vendor/golang.org/x/oauth2/internal/client_appengine.go
generated
vendored
1
vendor/golang.org/x/oauth2/internal/client_appengine.go
generated
vendored
|
@ -2,6 +2,7 @@
|
||||||
// Use of this source code is governed by a BSD-style
|
// Use of this source code is governed by a BSD-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
|
//go:build appengine
|
||||||
// +build appengine
|
// +build appengine
|
||||||
|
|
||||||
package internal
|
package internal
|
||||||
|
|
5
vendor/modules.txt
vendored
5
vendor/modules.txt
vendored
|
@ -828,10 +828,12 @@ golang.org/x/net/ipv6
|
||||||
golang.org/x/net/proxy
|
golang.org/x/net/proxy
|
||||||
golang.org/x/net/trace
|
golang.org/x/net/trace
|
||||||
golang.org/x/net/websocket
|
golang.org/x/net/websocket
|
||||||
# golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c => golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
# golang.org/x/oauth2 v0.0.0-20210514164344-f6687ab2804c
|
||||||
## explicit; go 1.11
|
## explicit; go 1.11
|
||||||
golang.org/x/oauth2
|
golang.org/x/oauth2
|
||||||
|
golang.org/x/oauth2/authhandler
|
||||||
golang.org/x/oauth2/google
|
golang.org/x/oauth2/google
|
||||||
|
golang.org/x/oauth2/google/internal/externalaccount
|
||||||
golang.org/x/oauth2/internal
|
golang.org/x/oauth2/internal
|
||||||
golang.org/x/oauth2/jws
|
golang.org/x/oauth2/jws
|
||||||
golang.org/x/oauth2/jwt
|
golang.org/x/oauth2/jwt
|
||||||
|
@ -1002,7 +1004,6 @@ gotest.tools/v3/skip
|
||||||
# github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.11
|
# github.com/prometheus/procfs => github.com/prometheus/procfs v0.0.11
|
||||||
# github.com/vishvananda/netlink => github.com/vishvananda/netlink v1.1.0
|
# github.com/vishvananda/netlink => github.com/vishvananda/netlink v1.1.0
|
||||||
# go.opencensus.io => go.opencensus.io v0.22.3
|
# go.opencensus.io => go.opencensus.io v0.22.3
|
||||||
# golang.org/x/oauth2 => golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d
|
|
||||||
# google.golang.org/api => google.golang.org/api v0.8.0
|
# google.golang.org/api => google.golang.org/api v0.8.0
|
||||||
# google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200227132054-3f1135a288c9
|
# google.golang.org/genproto => google.golang.org/genproto v0.0.0-20200227132054-3f1135a288c9
|
||||||
# google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
# google.golang.org/grpc => google.golang.org/grpc v1.27.1
|
||||||
|
|
Loading…
Reference in a new issue