From 57856c092fdecf3cd3b2bf6f5296a60547657a86 Mon Sep 17 00:00:00 2001 From: Brad Fitzpatrick Date: Wed, 13 Aug 2014 17:17:21 -0700 Subject: [PATCH] Make Google oauth2 support work again. Change-Id: I7f5f3c714c7385685c283fec5362db5ca1c31f81 --- .../code.google.com/p/goauth2/oauth/oauth.go | 30 ++++++++++++++----- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/third_party/code.google.com/p/goauth2/oauth/oauth.go b/third_party/code.google.com/p/goauth2/oauth/oauth.go index 317d88e91..ecdbd157f 100644 --- a/third_party/code.google.com/p/goauth2/oauth/oauth.go +++ b/third_party/code.google.com/p/goauth2/oauth/oauth.go @@ -367,23 +367,37 @@ func (t *Transport) AuthenticateClient() error { return t.updateToken(t.Token, url.Values{"grant_type": {"client_credentials"}}) } +// providerAuthHeaderWorks reports whether the OAuth2 server identified by the tokenURL +// implements the OAuth2 spec correctly +// See https://code.google.com/p/goauth2/issues/detail?id=31 for background. +// In summary: +// - Reddit only accepts client_secret in Authorization header. +// - Dropbox accepts either, but not both. +// - Google only accepts client_secret (not spec compliant?) +func providerAuthHeaderWorks(tokenURL string) bool { + if strings.HasPrefix(tokenURL, "https://accounts.google.com/") { + // Google fails to implement the OAuth2 spec fully? + return false + } + return true +} + // updateToken mutates both tok and v. func (t *Transport) updateToken(tok *Token, v url.Values) error { v.Set("client_id", t.ClientId) - // Note that we're not setting v's client_secret to t.ClientSecret, due - // to https://code.google.com/p/goauth2/issues/detail?id=31 - // Reddit only accepts client_secret in Authorization header. - // Dropbox accepts either, but not both. - // The spec requires servers to always support the Authorization header, - // so that's all we use. - + bustedAuth := !providerAuthHeaderWorks(t.TokenURL) + if bustedAuth { + v.Set("client_secret", t.ClientSecret) + } client := &http.Client{Transport: t.transport()} req, err := http.NewRequest("POST", t.TokenURL, strings.NewReader(v.Encode())) if err != nil { return err } req.Header.Set("Content-Type", "application/x-www-form-urlencoded") - req.SetBasicAuth(t.ClientId, t.ClientSecret) + if !bustedAuth { + req.SetBasicAuth(t.ClientId, t.ClientSecret) + } r, err := client.Do(req) if err != nil { return err