Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(220)

Side by Side Diff: appengine/gaeauth/client/client.go

Issue 2951393002: [errors] de-specialize Transient in favor of Tags. (Closed)
Patch Set: more refactor Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2015 The LUCI Authors. All rights reserved. 1 // Copyright 2015 The LUCI Authors. All rights reserved.
2 // Use of this source code is governed under the Apache License, Version 2.0 2 // Use of this source code is governed under the Apache License, Version 2.0
3 // that can be found in the LICENSE file. 3 // that can be found in the LICENSE file.
4 4
5 // Package client implements OAuth2 authentication for outbound connections 5 // Package client implements OAuth2 authentication for outbound connections
6 // from Appengine using the application services account. 6 // from Appengine using the application services account.
7 package client 7 package client
8 8
9 import ( 9 import (
10 "fmt" 10 "fmt"
11 "sort" 11 "sort"
12 "strings" 12 "strings"
13 "time" 13 "time"
14 14
15 "golang.org/x/net/context" 15 "golang.org/x/net/context"
16 "golang.org/x/oauth2" 16 "golang.org/x/oauth2"
17 17
18 "github.com/luci/gae/service/info" 18 "github.com/luci/gae/service/info"
19 19
20 "github.com/luci/luci-go/common/auth" 20 "github.com/luci/luci-go/common/auth"
21 "github.com/luci/luci-go/common/clock" 21 "github.com/luci/luci-go/common/clock"
22 "github.com/luci/luci-go/common/data/caching/proccache" 22 "github.com/luci/luci-go/common/data/caching/proccache"
23 "github.com/luci/luci-go/common/data/rand/mathrand" 23 "github.com/luci/luci-go/common/data/rand/mathrand"
24 "github.com/luci/luci-go/common/data/stringset" 24 "github.com/luci/luci-go/common/data/stringset"
25 "github.com/luci/luci-go/common/errors"
26 "github.com/luci/luci-go/common/logging" 25 "github.com/luci/luci-go/common/logging"
26 "github.com/luci/luci-go/common/retry/transient"
27 ) 27 )
28 28
29 // GetAccessToken returns an OAuth access token representing app's service 29 // GetAccessToken returns an OAuth access token representing app's service
30 // account. 30 // account.
31 // 31 //
32 // If scopes is empty, uses auth.OAuthScopeEmail scope. 32 // If scopes is empty, uses auth.OAuthScopeEmail scope.
33 // 33 //
34 // Implements a caching layer on top of GAE's GetAccessToken RPC. May return 34 // Implements a caching layer on top of GAE's GetAccessToken RPC. May return
35 // transient errors. 35 // transient errors.
36 func GetAccessToken(c context.Context, scopes []string) (*oauth2.Token, error) { 36 func GetAccessToken(c context.Context, scopes []string) (*oauth2.Token, error) {
37 scopes, cacheKey := normalizeScopes(scopes) 37 scopes, cacheKey := normalizeScopes(scopes)
38 38
39 // Try to find the token in the local memory first. If it expires soon, 39 // Try to find the token in the local memory first. If it expires soon,
40 // refresh it earlier with some probability. That avoids a situation whe n 40 // refresh it earlier with some probability. That avoids a situation whe n
41 // parallel requests that use access tokens suddenly see the cache expir ed 41 // parallel requests that use access tokens suddenly see the cache expir ed
42 // and rush to refresh the token all at once. 42 // and rush to refresh the token all at once.
43 pcache := proccache.GetCache(c) 43 pcache := proccache.GetCache(c)
44 if entry := pcache.Get(cacheKey); entry != nil && !closeToExpRandomized( c, entry.Exp) { 44 if entry := pcache.Get(cacheKey); entry != nil && !closeToExpRandomized( c, entry.Exp) {
45 return entry.Value.(*oauth2.Token), nil 45 return entry.Value.(*oauth2.Token), nil
46 } 46 }
47 47
48 // The token needs to be refreshed. 48 // The token needs to be refreshed.
49 logging.Debugf(c, "Getting an access token for scopes %q", strings.Join( scopes, ", ")) 49 logging.Debugf(c, "Getting an access token for scopes %q", strings.Join( scopes, ", "))
50 accessToken, exp, err := info.AccessToken(c, scopes...) 50 accessToken, exp, err := info.AccessToken(c, scopes...)
51 if err != nil { 51 if err != nil {
52 » » return nil, errors.WrapTransient(err) 52 » » return nil, transient.Tag.Apply(err)
53 } 53 }
54 logging.Debugf(c, "The token expires in %s", exp.Sub(clock.Now(c))) 54 logging.Debugf(c, "The token expires in %s", exp.Sub(clock.Now(c)))
55 55
56 // Prematurely expire it to guarantee all returned token live for at lea st 56 // Prematurely expire it to guarantee all returned token live for at lea st
57 // 'expirationMinLifetime'. 57 // 'expirationMinLifetime'.
58 tok := &oauth2.Token{ 58 tok := &oauth2.Token{
59 AccessToken: accessToken, 59 AccessToken: accessToken,
60 Expiry: exp.Add(-expirationMinLifetime), 60 Expiry: exp.Add(-expirationMinLifetime),
61 TokenType: "Bearer", 61 TokenType: "Bearer",
62 } 62 }
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after
116 case now.After(exp): 116 case now.After(exp):
117 return true // expired already 117 return true // expired already
118 case now.Add(expirationRandomization).Before(exp): 118 case now.Add(expirationRandomization).Before(exp):
119 return false // far from expiration 119 return false // far from expiration
120 default: 120 default:
121 // The expiration is close enough. Do the randomization. 121 // The expiration is close enough. Do the randomization.
122 rnd := time.Duration(mathrand.Int63n(c, int64(expirationRandomiz ation))) 122 rnd := time.Duration(mathrand.Int63n(c, int64(expirationRandomiz ation)))
123 return now.Add(rnd).After(exp) 123 return now.Add(rnd).After(exp)
124 } 124 }
125 } 125 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698