mirror of
https://github.com/golang/oauth2.git
synced 2025-07-21 00:00:09 +08:00
oauth2/google: use the metadata package, cleanups
Verified it compiles on Go 1.2 now too. Fixes golang/oauth2#70 Change-Id: I099a86676d2464b3840f1798bbca914a202eb195 Reviewed-on: https://go-review.googlesource.com/2372 Reviewed-by: Burcu Dogan <jbd@google.com>
This commit is contained in:
parent
685f9f8718
commit
5361962df4
@ -15,13 +15,14 @@ package google // import "golang.org/x/oauth2/google"
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"net"
|
"strings"
|
||||||
"net/http"
|
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"golang.org/x/oauth2"
|
"golang.org/x/oauth2"
|
||||||
"golang.org/x/oauth2/jwt"
|
"golang.org/x/oauth2/jwt"
|
||||||
|
"google.golang.org/cloud/compute/metadata"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TODO(bradfitz,jbd): import "google.golang.org/cloud/compute/metadata" instead of
|
// TODO(bradfitz,jbd): import "google.golang.org/cloud/compute/metadata" instead of
|
||||||
@ -56,12 +57,6 @@ func JWTConfigFromJSON(ctx oauth2.Context, jsonKey []byte, scope ...string) (*jw
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
type metaTokenRespBody struct {
|
|
||||||
AccessToken string `json:"access_token"`
|
|
||||||
ExpiresIn time.Duration `json:"expires_in"`
|
|
||||||
TokenType string `json:"token_type"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ComputeTokenSource returns a token source that fetches access tokens
|
// ComputeTokenSource returns a token source that fetches access tokens
|
||||||
// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
|
// from Google Compute Engine (GCE)'s metadata server. It's only valid to use
|
||||||
// this token source if your program is running on a GCE instance.
|
// this token source if your program is running on a GCE instance.
|
||||||
@ -69,50 +64,40 @@ type metaTokenRespBody struct {
|
|||||||
// Further information about retrieving access tokens from the GCE metadata
|
// Further information about retrieving access tokens from the GCE metadata
|
||||||
// server can be found at https://cloud.google.com/compute/docs/authentication.
|
// server can be found at https://cloud.google.com/compute/docs/authentication.
|
||||||
func ComputeTokenSource(account string) oauth2.TokenSource {
|
func ComputeTokenSource(account string) oauth2.TokenSource {
|
||||||
return oauth2.ReuseTokenSource(nil, &computeSource{account: account})
|
return oauth2.ReuseTokenSource(nil, computeSource{account: account})
|
||||||
}
|
}
|
||||||
|
|
||||||
type computeSource struct {
|
type computeSource struct {
|
||||||
account string
|
account string
|
||||||
}
|
}
|
||||||
|
|
||||||
var metaClient = &http.Client{
|
func (cs computeSource) Token() (*oauth2.Token, error) {
|
||||||
Transport: &http.Transport{
|
if !metadata.OnGCE() {
|
||||||
Dial: (&net.Dialer{
|
return nil, errors.New("oauth2/google: can't get a token from the metadata service; not running on GCE")
|
||||||
Timeout: 750 * time.Millisecond,
|
}
|
||||||
KeepAlive: 30 * time.Second,
|
|
||||||
}).Dial,
|
|
||||||
ResponseHeaderTimeout: 750 * time.Millisecond,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
func (cs *computeSource) Token() (*oauth2.Token, error) {
|
|
||||||
acct := cs.account
|
acct := cs.account
|
||||||
if acct == "" {
|
if acct == "" {
|
||||||
acct = "default"
|
acct = "default"
|
||||||
}
|
}
|
||||||
u := "http://metadata.google.internal/computeMetadata/v1/instance/service-accounts/" + acct + "/token"
|
tokenJSON, err := metadata.Get("instance/service-accounts/" + acct + "/token")
|
||||||
req, err := http.NewRequest("GET", u, nil)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
req.Header.Add("X-Google-Metadata-Request", "True")
|
var res struct {
|
||||||
resp, err := metaClient.Do(req)
|
AccessToken string `json:"access_token"`
|
||||||
if err != nil {
|
ExpiresInSec int `json:"expires_in"`
|
||||||
return nil, err
|
TokenType string `json:"token_type"`
|
||||||
}
|
}
|
||||||
defer resp.Body.Close()
|
err = json.NewDecoder(strings.NewReader(tokenJSON)).Decode(&res)
|
||||||
if resp.StatusCode < 200 || resp.StatusCode > 299 {
|
|
||||||
return nil, fmt.Errorf("oauth2: can't retrieve a token from metadata server, status code: %d", resp.StatusCode)
|
|
||||||
}
|
|
||||||
var tokenResp metaTokenRespBody
|
|
||||||
err = json.NewDecoder(resp.Body).Decode(&tokenResp)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("oauth2/google: invalid token JSON from metadata: %v", err)
|
||||||
|
}
|
||||||
|
if res.ExpiresInSec == 0 || res.AccessToken == "" {
|
||||||
|
return nil, fmt.Errorf("oauth2/google: incomplete token received from metadata")
|
||||||
}
|
}
|
||||||
return &oauth2.Token{
|
return &oauth2.Token{
|
||||||
AccessToken: tokenResp.AccessToken,
|
AccessToken: res.AccessToken,
|
||||||
TokenType: tokenResp.TokenType,
|
TokenType: res.TokenType,
|
||||||
Expiry: time.Now().Add(tokenResp.ExpiresIn * time.Second),
|
Expiry: time.Now().Add(time.Duration(res.ExpiresInSec) * time.Second),
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user