From 721c86aedbb404bcb5a439cd05c1e0a6bf7d8923 Mon Sep 17 00:00:00 2001 From: Yuki Yugui Sonoda Date: Mon, 9 Feb 2015 18:18:20 +0900 Subject: [PATCH] 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 --- google/sdk.go | 19 +++++++++++----- google/sdk_test.go | 8 +++++-- google/testdata/gcloud/credentials | 35 +++++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 9 deletions(-) diff --git a/google/sdk.go b/google/sdk.go index d83df14..9d2e71a 100644 --- a/google/sdk.go +++ b/google/sdk.go @@ -23,11 +23,11 @@ import ( type sdkCredentials struct { Data []struct { Credential struct { - ClientID string `json:"client_id"` - ClientSecret string `json:"client_secret"` - AccessToken string `json:"access_token"` - RefreshToken string `json:"refresh_token"` - TokenExpiry time.Time `json:"token_expiry"` + ClientID string `json:"client_id"` + ClientSecret string `json:"client_secret"` + AccessToken string `json:"access_token"` + RefreshToken string `json:"refresh_token"` + TokenExpiry *time.Time `json:"token_expiry"` } `json:"credential"` Key struct { Account string `json:"account"` @@ -92,6 +92,13 @@ func NewSDKConfig(account string) (*SDKConfig, error) { for _, d := range c.Data { 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{ conf: oauth2.Config{ ClientID: d.Credential.ClientID, @@ -103,7 +110,7 @@ func NewSDKConfig(account string) (*SDKConfig, error) { initialToken: &oauth2.Token{ AccessToken: d.Credential.AccessToken, RefreshToken: d.Credential.RefreshToken, - Expiry: d.Credential.TokenExpiry, + Expiry: expiry, }, }, nil } diff --git a/google/sdk_test.go b/google/sdk_test.go index f05a75a..79df889 100644 --- a/google/sdk_test.go +++ b/google/sdk_test.go @@ -19,17 +19,21 @@ func TestSDKConfig(t *testing.T) { {"", "bar_access_token", false}, {"foo@example.com", "foo_access_token", false}, {"bar@example.com", "bar_access_token", false}, + {"baz@serviceaccount.example.com", "", true}, } for _, tt := range tests { c, err := NewSDKConfig(tt.account) - if (err != nil) != tt.err { + if got, want := err != nil, tt.err; got != want { if !tt.err { t.Errorf("expected no error, got error: %v", tt.err, err) } else { - t.Errorf("execcted error, got none") + t.Errorf("expected error, got none") } continue } + if err != nil { + continue + } tok := c.initialToken if tok == nil { t.Errorf("expected token %q, got: nil", tt.accessToken) diff --git a/google/testdata/gcloud/credentials b/google/testdata/gcloud/credentials index fd0a798..ff5eefb 100644 --- a/google/testdata/gcloud/credentials +++ b/google/testdata/gcloud/credentials @@ -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", "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 -} \ No newline at end of file +}