oauth2/google: fix decode error in Cloud SDK config

google.NewCloudSDK fails to decode credentials file if it contains
service account.
NOTE: the private key in testdata is generated only for this test.

Fixes #86 (https://github.com/golang/oauth2/issues/86).

Change-Id: I9e9e8e10763723d1bf1f953b491aa6e6f3ee760c
Reviewed-on: https://go-review.googlesource.com/4220
Reviewed-by: Andrew Gerrand <adg@golang.org>
This commit is contained in:
Yuki Yugui Sonoda 2015-02-09 18:18:20 +09:00 committed by Andrew Gerrand
parent d838a7d6be
commit 721c86aedb
3 changed files with 53 additions and 9 deletions

View File

@ -23,11 +23,11 @@ import (
type sdkCredentials struct { type sdkCredentials struct {
Data []struct { Data []struct {
Credential struct { Credential struct {
ClientID string `json:"client_id"` ClientID string `json:"client_id"`
ClientSecret string `json:"client_secret"` ClientSecret string `json:"client_secret"`
AccessToken string `json:"access_token"` AccessToken string `json:"access_token"`
RefreshToken string `json:"refresh_token"` RefreshToken string `json:"refresh_token"`
TokenExpiry time.Time `json:"token_expiry"` TokenExpiry *time.Time `json:"token_expiry"`
} `json:"credential"` } `json:"credential"`
Key struct { Key struct {
Account string `json:"account"` Account string `json:"account"`
@ -92,6 +92,13 @@ func NewSDKConfig(account string) (*SDKConfig, error) {
for _, d := range c.Data { for _, d := range c.Data {
if account == "" || d.Key.Account == account { if account == "" || d.Key.Account == account {
if d.Credential.AccessToken == "" && d.Credential.RefreshToken == "" {
return nil, fmt.Errorf("oauth2/google: no token available for account %q", account)
}
var expiry time.Time
if d.Credential.TokenExpiry != nil {
expiry = *d.Credential.TokenExpiry
}
return &SDKConfig{ return &SDKConfig{
conf: oauth2.Config{ conf: oauth2.Config{
ClientID: d.Credential.ClientID, ClientID: d.Credential.ClientID,
@ -103,7 +110,7 @@ func NewSDKConfig(account string) (*SDKConfig, error) {
initialToken: &oauth2.Token{ initialToken: &oauth2.Token{
AccessToken: d.Credential.AccessToken, AccessToken: d.Credential.AccessToken,
RefreshToken: d.Credential.RefreshToken, RefreshToken: d.Credential.RefreshToken,
Expiry: d.Credential.TokenExpiry, Expiry: expiry,
}, },
}, nil }, nil
} }

View File

@ -19,17 +19,21 @@ func TestSDKConfig(t *testing.T) {
{"", "bar_access_token", false}, {"", "bar_access_token", false},
{"foo@example.com", "foo_access_token", false}, {"foo@example.com", "foo_access_token", false},
{"bar@example.com", "bar_access_token", false}, {"bar@example.com", "bar_access_token", false},
{"baz@serviceaccount.example.com", "", true},
} }
for _, tt := range tests { for _, tt := range tests {
c, err := NewSDKConfig(tt.account) c, err := NewSDKConfig(tt.account)
if (err != nil) != tt.err { if got, want := err != nil, tt.err; got != want {
if !tt.err { if !tt.err {
t.Errorf("expected no error, got error: %v", tt.err, err) t.Errorf("expected no error, got error: %v", tt.err, err)
} else { } else {
t.Errorf("execcted error, got none") t.Errorf("expected error, got none")
} }
continue continue
} }
if err != nil {
continue
}
tok := c.initialToken tok := c.initialToken
if tok == nil { if tok == nil {
t.Errorf("expected token %q, got: nil", tt.accessToken) t.Errorf("expected token %q, got: nil", tt.accessToken)

View File

@ -83,7 +83,40 @@
"scope": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting", "scope": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
"type": "google-cloud-sdk" "type": "google-cloud-sdk"
} }
},
{
"credential": {
"_class": "ServiceAccountCredentials",
"_kwargs": {},
"_module": "oauth2client.client",
"_private_key_id": "00000000000000000000000000000000",
"_private_key_pkcs8_text": "-----BEGIN RSA PRIVATE KEY-----\nMIICWwIBAAKBgQCt3fpiynPSaUhWSIKMGV331zudwJ6GkGmvQtwsoK2S2LbvnSwU\nNxgj4fp08kIDR5p26wF4+t/HrKydMwzftXBfZ9UmLVJgRdSswmS5SmChCrfDS5OE\nvFFcN5+6w1w8/Nu657PF/dse8T0bV95YrqyoR0Osy8WHrUOMSIIbC3hRuwIDAQAB\nAoGAJrGE/KFjn0sQ7yrZ6sXmdLawrM3mObo/2uI9T60+k7SpGbBX0/Pi6nFrJMWZ\nTVONG7P3Mu5aCPzzuVRYJB0j8aldSfzABTY3HKoWCczqw1OztJiEseXGiYz4QOyr\nYU3qDyEpdhS6q6wcoLKGH+hqRmz6pcSEsc8XzOOu7s4xW8kCQQDkc75HjhbarCnd\nJJGMe3U76+6UGmdK67ltZj6k6xoB5WbTNChY9TAyI2JC+ppYV89zv3ssj4L+02u3\nHIHFGxsHAkEAwtU1qYb1tScpchPobnYUFiVKJ7KA8EZaHVaJJODW/cghTCV7BxcJ\nbgVvlmk4lFKn3lPKAgWw7PdQsBTVBUcCrQJATPwoIirizrv3u5soJUQxZIkENAqV\nxmybZx9uetrzP7JTrVbFRf0SScMcyN90hdLJiQL8+i4+gaszgFht7sNMnwJAAbfj\nq0UXcauQwALQ7/h2oONfTg5S+MuGC/AxcXPSMZbMRGGoPh3D5YaCv27aIuS/ukQ+\n6dmm/9AGlCb64fsIWQJAPaokbjIifo+LwC5gyK73Mc4t8nAOSZDenzd/2f6TCq76\nS1dcnKiPxaED7W/y6LJiuBT2rbZiQ2L93NJpFZD/UA==\n-----END RSA PRIVATE KEY-----\n",
"_revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
"_scopes": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
"_service_account_email": "baz@serviceaccount.example.com",
"_service_account_id": "baz.serviceaccount.example.com",
"_token_uri": "https://accounts.google.com/o/oauth2/token",
"_user_agent": "Cloud SDK Command Line Tool",
"access_token": null,
"assertion_type": null,
"client_id": null,
"client_secret": null,
"id_token": null,
"invalid": false,
"refresh_token": null,
"revoke_uri": "https://accounts.google.com/o/oauth2/revoke",
"service_account_name": "baz@serviceaccount.example.com",
"token_expiry": null,
"token_response": null,
"user_agent": "Cloud SDK Command Line Tool"
},
"key": {
"account": "baz@serviceaccount.example.com",
"clientId": "baz_client_id",
"scope": "https://www.googleapis.com/auth/appengine.admin https://www.googleapis.com/auth/bigquery https://www.googleapis.com/auth/compute https://www.googleapis.com/auth/devstorage.full_control https://www.googleapis.com/auth/userinfo.email https://www.googleapis.com/auth/ndev.cloudman https://www.googleapis.com/auth/cloud-platform https://www.googleapis.com/auth/sqlservice.admin https://www.googleapis.com/auth/prediction https://www.googleapis.com/auth/projecthosting",
"type": "google-cloud-sdk"
}
} }
], ],
"file_version": 1 "file_version": 1
} }