vendor: golang.org/x/oauth2@latest

go get golang.org/x/oauth2@latest
go mod tidy
go mod vendor
This commit is contained in:
Radek Simko 2019-02-20 18:59:25 +00:00
parent df089ee2fb
commit 876d548bc1
No known key found for this signature in database
GPG Key ID: 1F1C84FE689A88D7
17 changed files with 248 additions and 171 deletions

2
go.mod
View File

@ -125,7 +125,7 @@ require (
go.uber.org/zap v1.9.1 // indirect go.uber.org/zap v1.9.1 // indirect
golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85 golang.org/x/crypto v0.0.0-20181127143415-eb0de9b17e85
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd golang.org/x/net v0.0.0-20190213061140-3a22650c66bd
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9
google.golang.org/api v0.1.0 google.golang.org/api v0.1.0
google.golang.org/grpc v1.18.0 google.golang.org/grpc v1.18.0
gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect gopkg.in/vmihailenco/msgpack.v2 v2.9.1 // indirect

6
go.sum
View File

@ -1,6 +1,7 @@
cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ= cloud.google.com/go v0.26.0 h1:e0WKqKTd5BnrG8aKH3J3h+QvEIQtSUcf2n5UZ5ZgLtQ=
cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.26.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw= cloud.google.com/go v0.31.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8= cloud.google.com/go v0.36.0 h1:+aCSj7tOo2LODWVEuZDZeGCckdt6MlSF+X/rB3wUiS8=
cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40= cloud.google.com/go v0.36.0/go.mod h1:RUoy9p/M4ge0HzT8L+SDZ8jg+Q6fth0CiBuhFJpSV40=
dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU= dmitri.shuralyov.com/app/changes v0.0.0-20180602232624-0a106ad413e3/go.mod h1:Yl+fi1br7+Rr3LqpNJf1/uxUdtRUV+Tnj0o93V2B9MU=
@ -403,12 +404,15 @@ golang.org/x/net v0.0.0-20181029044818-c44066c5c816/go.mod h1:mL1N/T3taQHkDXs73r
golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181106065722-10aee1819953/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76 h1:xx5MUFyRQRbPk6VjWjIE1epE/K5AoDD8QUN116NCy8k= golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76 h1:xx5MUFyRQRbPk6VjWjIE1epE/K5AoDD8QUN116NCy8k=
golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181129055619-fae4c4e3ad76/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd h1:HuTn7WObtcDo9uEEU7rEqL0jYthdXAmZ6PP+meazmaU=
golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181017192945-9dcd33a902f4/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 h1:uESlIz09WIHT2I+pasSXcpLYqYK8wHcdCetU3VuMBJE=
golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9 h1:pfyU+l9dEu0vZzDDMsdAKa1gZbJYEn6urYXj/+Xkz7s=
golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw= golang.org/x/perf v0.0.0-20180704124530-6e6d33e29852/go.mod h1:JLpeXjPJfIyPr5TlbXLkXWLhP8nz10XfvxElABhCtcw=
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=
@ -437,6 +441,8 @@ google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9Ywl
google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.2.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk= google.golang.org/appengine v1.3.0 h1:FBSsiFRMz3LBeXIomRnVzrQwSDj4ibvcRexLG0LZGQk=
google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4= google.golang.org/appengine v1.3.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
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= google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b h1:lohp5blsw53GBXtLyLNaTXPXS9pJ1tiTw61ZHUoE9Qw=
google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc= google.golang.org/genproto v0.0.0-20180831171423-11092d34479b/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=

51
vendor/golang.org/x/oauth2/README.md generated vendored
View File

@ -19,57 +19,6 @@ See godoc for further documentation and examples.
* [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2) * [godoc.org/golang.org/x/oauth2](http://godoc.org/golang.org/x/oauth2)
* [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google) * [godoc.org/golang.org/x/oauth2/google](http://godoc.org/golang.org/x/oauth2/google)
## App Engine
In change 96e89be (March 2015), we removed the `oauth2.Context2` type in favor
of the [`context.Context`](https://golang.org/x/net/context#Context) type from
the `golang.org/x/net/context` package. Later replaced by the standard `context` package
of the [`context.Context`](https://golang.org/pkg/context#Context) type.
This means it's no longer possible to use the "Classic App Engine"
`appengine.Context` type with the `oauth2` package. (You're using
Classic App Engine if you import the package `"appengine"`.)
To work around this, you may use the new `"google.golang.org/appengine"`
package. This package has almost the same API as the `"appengine"` package,
but it can be fetched with `go get` and used on "Managed VMs" and well as
Classic App Engine.
See the [new `appengine` package's readme](https://github.com/golang/appengine#updating-a-go-app-engine-app)
for information on updating your app.
If you don't want to update your entire app to use the new App Engine packages,
you may use both sets of packages in parallel, using only the new packages
with the `oauth2` package.
```go
import (
"context"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
newappengine "google.golang.org/appengine"
newurlfetch "google.golang.org/appengine/urlfetch"
"appengine"
)
func handler(w http.ResponseWriter, r *http.Request) {
var c appengine.Context = appengine.NewContext(r)
c.Infof("Logging a message with the old package")
var ctx context.Context = newappengine.NewContext(r)
client := &http.Client{
Transport: &oauth2.Transport{
Source: google.AppEngineTokenSource(ctx, "scope"),
Base: &newurlfetch.Transport{Context: ctx},
},
}
client.Get("...")
}
```
## Policy for new packages ## Policy for new packages
We no longer accept new provider-specific packages in this repo. For We no longer accept new provider-specific packages in this repo. For

10
vendor/golang.org/x/oauth2/go.mod generated vendored Normal file
View File

@ -0,0 +1,10 @@
module golang.org/x/oauth2
go 1.11
require (
cloud.google.com/go v0.34.0
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 // indirect
google.golang.org/appengine v1.4.0
)

12
vendor/golang.org/x/oauth2/go.sum generated vendored Normal file
View File

@ -0,0 +1,12 @@
cloud.google.com/go v0.34.0 h1:eOI3/cP2VTU6uZLDYAoic+eyzzB9YyGmJ7eIjl8rOPg=
cloud.google.com/go v0.34.0/go.mod h1:aQUYkXzVsufM+DwF1aE+0xfcU+56JwCaLick0ClmMTw=
github.com/golang/protobuf v1.2.0 h1:P3YflyNX/ehuJFLhxviNdFxQPkGK5cDcApsge1SqnvM=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e h1:bRhVy7zSSasaqNksaRZiA5EEI+Ei4I1nO5Jh72wfHlg=
golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4 h1:YUO/7uOKsKeq9UokNS62b8FYywz3ker1l1vDZRCRefw=
golang.org/x/sync v0.0.0-20181221193216-37e7f081c4d4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
google.golang.org/appengine v1.4.0 h1:/wp5JvzpHIxhs/dumFmF7BXTf3Z+dd4uXta4kVyO508=
google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=

View File

@ -21,6 +21,7 @@ import (
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://accounts.google.com/o/oauth2/token", TokenURL: "https://accounts.google.com/o/oauth2/token",
AuthStyle: oauth2.AuthStyleInParams,
} }
// JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow. // JWTTokenURL is Google's OAuth 2.0 token URL to use with the JWT flow.

View File

@ -16,6 +16,7 @@ import (
"net/url" "net/url"
"strconv" "strconv"
"strings" "strings"
"sync"
"time" "time"
"golang.org/x/net/context/ctxhttp" "golang.org/x/net/context/ctxhttp"
@ -77,6 +78,9 @@ func (e *tokenJSON) expiry() (t time.Time) {
type expirationTime int32 type expirationTime int32
func (e *expirationTime) UnmarshalJSON(b []byte) error { func (e *expirationTime) UnmarshalJSON(b []byte) error {
if len(b) == 0 || string(b) == "null" {
return nil
}
var n json.Number var n json.Number
err := json.Unmarshal(b, &n) err := json.Unmarshal(b, &n)
if err != nil { if err != nil {
@ -90,102 +94,71 @@ func (e *expirationTime) UnmarshalJSON(b []byte) error {
return nil return nil
} }
var brokenAuthHeaderProviders = []string{ // RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
"https://accounts.google.com/", //
"https://api.codeswholesale.com/oauth/token", // Deprecated: this function no longer does anything. Caller code that
"https://api.dropbox.com/", // wants to avoid potential extra HTTP requests made during
"https://api.dropboxapi.com/", // auto-probing of the provider's auth style should set
"https://api.instagram.com/", // Endpoint.AuthStyle.
"https://api.netatmo.net/", func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
"https://api.odnoklassniki.ru/",
"https://api.pushbullet.com/", // AuthStyle is a copy of the golang.org/x/oauth2 package's AuthStyle type.
"https://api.soundcloud.com/", type AuthStyle int
"https://api.twitch.tv/",
"https://id.twitch.tv/", const (
"https://app.box.com/", AuthStyleUnknown AuthStyle = 0
"https://api.box.com/", AuthStyleInParams AuthStyle = 1
"https://connect.stripe.com/", AuthStyleInHeader AuthStyle = 2
"https://login.mailchimp.com/", )
"https://login.microsoftonline.com/",
"https://login.salesforce.com/", // authStyleCache is the set of tokenURLs we've successfully used via
"https://login.windows.net", // RetrieveToken and which style auth we ended up using.
"https://login.live.com/", // It's called a cache, but it doesn't (yet?) shrink. It's expected that
"https://login.live-int.com/", // the set of OAuth2 servers a program contacts over time is fixed and
"https://oauth.sandbox.trainingpeaks.com/", // small.
"https://oauth.trainingpeaks.com/", var authStyleCache struct {
"https://oauth.vk.com/", sync.Mutex
"https://openapi.baidu.com/", m map[string]AuthStyle // keyed by tokenURL
"https://slack.com/",
"https://test-sandbox.auth.corp.google.com",
"https://test.salesforce.com/",
"https://user.gini.net/",
"https://www.douban.com/",
"https://www.googleapis.com/",
"https://www.linkedin.com/",
"https://www.strava.com/oauth/",
"https://www.wunderlist.com/oauth/",
"https://api.patreon.com/",
"https://sandbox.codeswholesale.com/oauth/token",
"https://api.sipgate.com/v1/authorization/oauth",
"https://api.medium.com/v1/tokens",
"https://log.finalsurge.com/oauth/token",
"https://multisport.todaysplan.com.au/rest/oauth/access_token",
"https://whats.todaysplan.com.au/rest/oauth/access_token",
"https://stackoverflow.com/oauth/access_token",
"https://account.health.nokia.com",
"https://accounts.zoho.com",
"https://gitter.im/login/oauth/token",
"https://openid-connect.onelogin.com/oidc",
"https://api.dailymotion.com/oauth/token",
} }
// brokenAuthHeaderDomains lists broken providers that issue dynamic endpoints. // ResetAuthCache resets the global authentication style cache used
var brokenAuthHeaderDomains = []string{ // for AuthStyleUnknown token requests.
".auth0.com", func ResetAuthCache() {
".force.com", authStyleCache.Lock()
".myshopify.com", defer authStyleCache.Unlock()
".okta.com", authStyleCache.m = nil
".oktapreview.com",
} }
func RegisterBrokenAuthHeaderProvider(tokenURL string) { // lookupAuthStyle reports which auth style we last used with tokenURL
brokenAuthHeaderProviders = append(brokenAuthHeaderProviders, tokenURL) // when calling RetrieveToken and whether we have ever done so.
func lookupAuthStyle(tokenURL string) (style AuthStyle, ok bool) {
authStyleCache.Lock()
defer authStyleCache.Unlock()
style, ok = authStyleCache.m[tokenURL]
return
} }
// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL // setAuthStyle adds an entry to authStyleCache, documented above.
// implements the OAuth2 spec correctly func setAuthStyle(tokenURL string, v AuthStyle) {
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background. authStyleCache.Lock()
// In summary: defer authStyleCache.Unlock()
// - Reddit only accepts client secret in the Authorization header if authStyleCache.m == nil {
// - Dropbox accepts either it in URL param or Auth header, but not both. authStyleCache.m = make(map[string]AuthStyle)
// - Google only accepts URL param (not spec compliant?), not Auth header
// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
func providerAuthHeaderWorks(tokenURL string) bool {
for _, s := range brokenAuthHeaderProviders {
if strings.HasPrefix(tokenURL, s) {
// Some sites fail to implement the OAuth2 spec fully.
return false
} }
} authStyleCache.m[tokenURL] = v
if u, err := url.Parse(tokenURL); err == nil {
for _, s := range brokenAuthHeaderDomains {
if strings.HasSuffix(u.Host, s) {
return false
}
}
}
// Assume the provider implements the spec properly
// otherwise. We can add more exceptions as they're
// discovered. We will _not_ be adding configurable hooks
// to this package to let users select server bugs.
return true
} }
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values) (*Token, error) { // newTokenRequest returns a new *http.Request to retrieve a new token
bustedAuth := !providerAuthHeaderWorks(tokenURL) // from tokenURL using the provided clientID, clientSecret, and POST
if bustedAuth { // body parameters.
//
// inParams is whether the clientID & clientSecret should be encoded
// as the POST body. An 'inParams' value of true means to send it in
// the POST body (along with any values in v); false means to send it
// in the Authorization header.
func newTokenRequest(tokenURL, clientID, clientSecret string, v url.Values, authStyle AuthStyle) (*http.Request, error) {
if authStyle == AuthStyleInParams {
v = cloneURLValues(v)
if clientID != "" { if clientID != "" {
v.Set("client_id", clientID) v.Set("client_id", clientID)
} }
@ -198,15 +171,70 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
return nil, err return nil, err
} }
req.Header.Set("Content-Type", "application/x-www-form-urlencoded") req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
if !bustedAuth { if authStyle == AuthStyleInHeader {
req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret)) req.SetBasicAuth(url.QueryEscape(clientID), url.QueryEscape(clientSecret))
} }
return req, nil
}
func cloneURLValues(v url.Values) url.Values {
v2 := make(url.Values, len(v))
for k, vv := range v {
v2[k] = append([]string(nil), vv...)
}
return v2
}
func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string, v url.Values, authStyle AuthStyle) (*Token, error) {
needsAuthStyleProbe := authStyle == 0
if needsAuthStyleProbe {
if style, ok := lookupAuthStyle(tokenURL); ok {
authStyle = style
needsAuthStyleProbe = false
} else {
authStyle = AuthStyleInHeader // the first way we'll try
}
}
req, err := newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
if err != nil {
return nil, err
}
token, err := doTokenRoundTrip(ctx, req)
if err != nil && needsAuthStyleProbe {
// If we get an error, assume the server wants the
// clientID & clientSecret in a different form.
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
// In summary:
// - Reddit only accepts client secret in the Authorization header
// - Dropbox accepts either it in URL param or Auth header, but not both.
// - Google only accepts URL param (not spec compliant?), not Auth header
// - Stripe only accepts client secret in Auth header with Bearer method, not Basic
//
// We used to maintain a big table in this code of all the sites and which way
// they went, but maintaining it didn't scale & got annoying.
// So just try both ways.
authStyle = AuthStyleInParams // the second way we'll try
req, _ = newTokenRequest(tokenURL, clientID, clientSecret, v, authStyle)
token, err = doTokenRoundTrip(ctx, req)
}
if needsAuthStyleProbe && err == nil {
setAuthStyle(tokenURL, authStyle)
}
// Don't overwrite `RefreshToken` with an empty value
// if this was a token refreshing request.
if token != nil && token.RefreshToken == "" {
token.RefreshToken = v.Get("refresh_token")
}
return token, err
}
func doTokenRoundTrip(ctx context.Context, req *http.Request) (*Token, error) {
r, err := ctxhttp.Do(ctx, ContextClient(ctx), req) r, err := ctxhttp.Do(ctx, ContextClient(ctx), req)
if err != nil { if err != nil {
return nil, err return nil, err
} }
defer r.Body.Close()
body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20)) body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1<<20))
r.Body.Close()
if err != nil { if err != nil {
return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err) return nil, fmt.Errorf("oauth2: cannot fetch token: %v", err)
} }
@ -232,7 +260,7 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
Raw: vals, Raw: vals,
} }
e := vals.Get("expires_in") e := vals.Get("expires_in")
if e == "" { if e == "" || e == "null" {
// TODO(jbd): Facebook's OAuth2 implementation is broken and // TODO(jbd): Facebook's OAuth2 implementation is broken and
// returns expires_in field in expires. Remove the fallback to expires, // returns expires_in field in expires. Remove the fallback to expires,
// when Facebook fixes their implementation. // when Facebook fixes their implementation.
@ -256,13 +284,8 @@ func RetrieveToken(ctx context.Context, clientID, clientSecret, tokenURL string,
} }
json.Unmarshal(body, &token.Raw) // no error checks for optional fields json.Unmarshal(body, &token.Raw) // no error checks for optional fields
} }
// Don't overwrite `RefreshToken` with an empty value
// if this was a token refreshing request.
if token.RefreshToken == "" {
token.RefreshToken = v.Get("refresh_token")
}
if token.AccessToken == "" { if token.AccessToken == "" {
return token, errors.New("oauth2: server response missing access_token") return nil, errors.New("oauth2: server response missing access_token")
} }
return token, nil return token, nil
} }

View File

@ -61,6 +61,11 @@ type Config struct {
// Expires optionally specifies how long the token is valid for. // Expires optionally specifies how long the token is valid for.
Expires time.Duration Expires time.Duration
// Audience optionally specifies the intended audience of the
// request. If empty, the value of TokenURL is used as the
// intended audience.
Audience string
} }
// TokenSource returns a JWT TokenSource using the configuration // TokenSource returns a JWT TokenSource using the configuration
@ -105,6 +110,9 @@ func (js jwtSource) Token() (*oauth2.Token, error) {
if t := js.conf.Expires; t > 0 { if t := js.conf.Expires; t > 0 {
claimSet.Exp = time.Now().Add(t).Unix() claimSet.Exp = time.Now().Add(t).Unix()
} }
if aud := js.conf.Audience; aud != "" {
claimSet.Aud = aud
}
h := *defaultHeader h := *defaultHeader
h.KeyID = js.conf.PrivateKeyID h.KeyID = js.conf.PrivateKeyID
payload, err := jws.Encode(&h, claimSet, pk) payload, err := jws.Encode(&h, claimSet, pk)

47
vendor/golang.org/x/oauth2/oauth2.go generated vendored
View File

@ -26,17 +26,13 @@ import (
// Deprecated: Use context.Background() or context.TODO() instead. // Deprecated: Use context.Background() or context.TODO() instead.
var NoContext = context.TODO() var NoContext = context.TODO()
// RegisterBrokenAuthHeaderProvider registers an OAuth2 server // RegisterBrokenAuthHeaderProvider previously did something. It is now a no-op.
// identified by the tokenURL prefix as an OAuth2 implementation //
// which doesn't support the HTTP Basic authentication // Deprecated: this function no longer does anything. Caller code that
// scheme to authenticate with the authorization server. // wants to avoid potential extra HTTP requests made during
// Once a server is registered, credentials (client_id and client_secret) // auto-probing of the provider's auth style should set
// will be passed as query parameters rather than being present // Endpoint.AuthStyle.
// in the Authorization header. func RegisterBrokenAuthHeaderProvider(tokenURL string) {}
// See https://code.google.com/p/goauth2/issues/detail?id=31 for background.
func RegisterBrokenAuthHeaderProvider(tokenURL string) {
internal.RegisterBrokenAuthHeaderProvider(tokenURL)
}
// Config describes a typical 3-legged OAuth2 flow, with both the // Config describes a typical 3-legged OAuth2 flow, with both the
// client application information and the server's endpoint URLs. // client application information and the server's endpoint URLs.
@ -71,13 +67,38 @@ type TokenSource interface {
Token() (*Token, error) Token() (*Token, error)
} }
// Endpoint contains the OAuth 2.0 provider's authorization and token // Endpoint represents an OAuth 2.0 provider's authorization and token
// endpoint URLs. // endpoint URLs.
type Endpoint struct { type Endpoint struct {
AuthURL string AuthURL string
TokenURL string TokenURL string
// AuthStyle optionally specifies how the endpoint wants the
// client ID & client secret sent. The zero value means to
// auto-detect.
AuthStyle AuthStyle
} }
// AuthStyle represents how requests for tokens are authenticated
// to the server.
type AuthStyle int
const (
// AuthStyleAutoDetect means to auto-detect which authentication
// style the provider wants by trying both ways and caching
// the successful way for the future.
AuthStyleAutoDetect AuthStyle = 0
// AuthStyleInParams sends the "client_id" and "client_secret"
// in the POST body as application/x-www-form-urlencoded parameters.
AuthStyleInParams AuthStyle = 1
// AuthStyleInHeader sends the client_id and client_password
// using HTTP Basic Authorization. This is an optional style
// described in the OAuth2 RFC 6749 section 2.3.1.
AuthStyleInHeader AuthStyle = 2
)
var ( var (
// AccessTypeOnline and AccessTypeOffline are options passed // AccessTypeOnline and AccessTypeOffline are options passed
// to the Options.AuthCodeURL method. They modify the // to the Options.AuthCodeURL method. They modify the
@ -124,7 +145,7 @@ func SetAuthURLParam(key, value string) AuthCodeOption {
// //
// Opts may include AccessTypeOnline or AccessTypeOffline, as well // Opts may include AccessTypeOnline or AccessTypeOffline, as well
// as ApprovalForce. // as ApprovalForce.
// It can also be used to pass the PKCE challange. // It can also be used to pass the PKCE challenge.
// See https://www.oauth.com/oauth2-servers/pkce/ for more info. // See https://www.oauth.com/oauth2-servers/pkce/ for more info.
func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string { func (c *Config) AuthCodeURL(state string, opts ...AuthCodeOption) string {
var buf bytes.Buffer var buf bytes.Buffer

View File

@ -118,13 +118,16 @@ func (t *Token) Extra(key string) interface{} {
return v return v
} }
// timeNow is time.Now but pulled out as a variable for tests.
var timeNow = time.Now
// expired reports whether the token is expired. // expired reports whether the token is expired.
// t must be non-nil. // t must be non-nil.
func (t *Token) expired() bool { func (t *Token) expired() bool {
if t.Expiry.IsZero() { if t.Expiry.IsZero() {
return false return false
} }
return t.Expiry.Round(0).Add(-expiryDelta).Before(time.Now()) return t.Expiry.Round(0).Add(-expiryDelta).Before(timeNow())
} }
// Valid reports whether t is non-nil, has an AccessToken, and is not expired. // Valid reports whether t is non-nil, has an AccessToken, and is not expired.
@ -151,7 +154,7 @@ func tokenFromInternal(t *internal.Token) *Token {
// This token is then mapped from *internal.Token into an *oauth2.Token which is returned along // This token is then mapped from *internal.Token into an *oauth2.Token which is returned along
// with an error.. // with an error..
func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) { func retrieveToken(ctx context.Context, c *Config, v url.Values) (*Token, error) {
tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v) tk, err := internal.RetrieveToken(ctx, c.ClientID, c.ClientSecret, c.Endpoint.TokenURL, v, internal.AuthStyle(c.Endpoint.AuthStyle))
if err != nil { if err != nil {
if rErr, ok := err.(*internal.RetrieveError); ok { if rErr, ok := err.(*internal.RetrieveError); ok {
return nil, (*RetrieveError)(rErr) return nil, (*RetrieveError)(rErr)

View File

@ -78,6 +78,12 @@ func IsAppEngine() bool {
return internal.IsAppEngine() return internal.IsAppEngine()
} }
// IsSecondGen reports whether the App Engine app is running on the second generation
// runtimes (>= Go 1.11).
func IsSecondGen() bool {
return internal.IsSecondGen()
}
// NewContext returns a context for an in-flight HTTP request. // NewContext returns a context for an in-flight HTTP request.
// This function is cheap. // This function is cheap.
func NewContext(req *http.Request) context.Context { func NewContext(req *http.Request) context.Context {

View File

@ -579,7 +579,10 @@ func logf(c *context, level int64, format string, args ...interface{}) {
Level: &level, Level: &level,
Message: &s, Message: &s,
}) })
// Only duplicate log to stderr if not running on App Engine second generation
if !IsSecondGen() {
log.Print(logLevelName[level] + ": " + s) log.Print(logLevelName[level] + ": " + s)
}
} }
// flushLog attempts to flush any pending logs to the appserver. // flushLog attempts to flush any pending logs to the appserver.

View File

@ -31,9 +31,15 @@ func AppID(c netcontext.Context) string {
// ../appengine.go. See that file for commentary. // ../appengine.go. See that file for commentary.
func IsStandard() bool { func IsStandard() bool {
// appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not // appengineStandard will be true for first-gen runtimes (<= Go 1.9) but not
// second-gen (>= Go 1.11). Second-gen runtimes set $GAE_ENV so we use that // second-gen (>= Go 1.11).
// to check if we're on a second-gen runtime. return appengineStandard || IsSecondGen()
return appengineStandard || os.Getenv("GAE_ENV") == "standard" }
// IsStandard is the implementation of the wrapper function of the same name in
// ../appengine.go. See that file for commentary.
func IsSecondGen() bool {
// Second-gen runtimes set $GAE_ENV so we use that to check if we're on a second-gen runtime.
return os.Getenv("GAE_ENV") == "standard"
} }
// IsFlex is the implementation of the wrapper function of the same name in // IsFlex is the implementation of the wrapper function of the same name in

View File

@ -11,5 +11,6 @@ import (
) )
func Main() { func Main() {
MainPath = ""
appengine_internal.Main() appengine_internal.Main()
} }

View File

@ -0,0 +1,7 @@
package internal
// MainPath stores the file path of the main package. On App Engine Standard
// using Go version 1.9 and below, this will be unset. On App Engine Flex and
// App Engine Standard second-gen (Go 1.11 and above), this will be the
// filepath to package main.
var MainPath string

View File

@ -12,9 +12,12 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"path/filepath"
"runtime"
) )
func Main() { func Main() {
MainPath = filepath.Dir(findMainPath())
installHealthChecker(http.DefaultServeMux) installHealthChecker(http.DefaultServeMux)
port := "8080" port := "8080"
@ -31,6 +34,24 @@ func Main() {
} }
} }
// Find the path to package main by looking at the root Caller.
func findMainPath() string {
pc := make([]uintptr, 100)
n := runtime.Callers(2, pc)
frames := runtime.CallersFrames(pc[:n])
for {
frame, more := frames.Next()
// Tests won't have package main, instead they have testing.tRunner
if frame.Function == "main.main" || frame.Function == "testing.tRunner" {
return frame.File
}
if !more {
break
}
}
return ""
}
func installHealthChecker(mux *http.ServeMux) { func installHealthChecker(mux *http.ServeMux) {
// If no health check handler has been installed by this point, add a trivial one. // If no health check handler has been installed by this point, add a trivial one.
const healthPath = "/_ah/health" const healthPath = "/_ah/health"

4
vendor/modules.txt vendored
View File

@ -490,7 +490,7 @@ golang.org/x/net/http2/hpack
golang.org/x/net/html golang.org/x/net/html
golang.org/x/net/http/httpguts golang.org/x/net/http/httpguts
golang.org/x/net/html/atom golang.org/x/net/html/atom
# golang.org/x/oauth2 v0.0.0-20181203162652-d668ce993890 # golang.org/x/oauth2 v0.0.0-20190220154721-9b3c75971fc9
golang.org/x/oauth2/jwt golang.org/x/oauth2/jwt
golang.org/x/oauth2 golang.org/x/oauth2
golang.org/x/oauth2/internal golang.org/x/oauth2/internal
@ -532,7 +532,7 @@ google.golang.org/api/googleapi/internal/uritemplates
google.golang.org/api/gensupport google.golang.org/api/gensupport
google.golang.org/api/googleapi/transport google.golang.org/api/googleapi/transport
google.golang.org/api/transport/http/internal/propagation google.golang.org/api/transport/http/internal/propagation
# google.golang.org/appengine v1.3.0 # google.golang.org/appengine v1.4.0
google.golang.org/appengine/urlfetch google.golang.org/appengine/urlfetch
google.golang.org/appengine google.golang.org/appengine
google.golang.org/appengine/datastore google.golang.org/appengine/datastore