golang.org/x/oauth2@v0.18.0/google/appengine_gen1.go (about) 1 // Copyright 2018 The Go Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 //go:build appengine 6 7 // This file applies to App Engine first generation runtimes (<= Go 1.9). 8 9 package google 10 11 import ( 12 "context" 13 "sort" 14 "strings" 15 "sync" 16 17 "golang.org/x/oauth2" 18 "google.golang.org/appengine" 19 ) 20 21 func init() { 22 appengineTokenFunc = appengine.AccessToken 23 appengineAppIDFunc = appengine.AppID 24 } 25 26 // See comment on AppEngineTokenSource in appengine.go. 27 func appEngineTokenSource(ctx context.Context, scope ...string) oauth2.TokenSource { 28 scopes := append([]string{}, scope...) 29 sort.Strings(scopes) 30 return &gaeTokenSource{ 31 ctx: ctx, 32 scopes: scopes, 33 key: strings.Join(scopes, " "), 34 } 35 } 36 37 // aeTokens helps the fetched tokens to be reused until their expiration. 38 var ( 39 aeTokensMu sync.Mutex 40 aeTokens = make(map[string]*tokenLock) // key is space-separated scopes 41 ) 42 43 type tokenLock struct { 44 mu sync.Mutex // guards t; held while fetching or updating t 45 t *oauth2.Token 46 } 47 48 type gaeTokenSource struct { 49 ctx context.Context 50 scopes []string 51 key string // to aeTokens map; space-separated scopes 52 } 53 54 func (ts *gaeTokenSource) Token() (*oauth2.Token, error) { 55 aeTokensMu.Lock() 56 tok, ok := aeTokens[ts.key] 57 if !ok { 58 tok = &tokenLock{} 59 aeTokens[ts.key] = tok 60 } 61 aeTokensMu.Unlock() 62 63 tok.mu.Lock() 64 defer tok.mu.Unlock() 65 if tok.t.Valid() { 66 return tok.t, nil 67 } 68 access, exp, err := appengineTokenFunc(ts.ctx, ts.scopes...) 69 if err != nil { 70 return nil, err 71 } 72 tok.t = &oauth2.Token{ 73 AccessToken: access, 74 Expiry: exp, 75 } 76 return tok.t, nil 77 }