...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package externalaccountuser
16
17 import (
18 "context"
19 "errors"
20 "net/http"
21 "time"
22
23 "cloud.google.com/go/auth"
24 "cloud.google.com/go/auth/credentials/internal/stsexchange"
25 "cloud.google.com/go/auth/internal"
26 )
27
28
29
30 type Options struct {
31
32
33
34 Audience string
35
36 RefreshToken string
37
38 TokenURL string
39
40 TokenInfoURL string
41
42
43 ClientID string
44
45
46
47
48 ClientSecret string
49
50 Scopes []string
51
52
53 Client *http.Client
54 }
55
56 func (c *Options) validate() bool {
57 return c.ClientID != "" && c.ClientSecret != "" && c.RefreshToken != "" && c.TokenURL != ""
58 }
59
60
61
62 func NewTokenProvider(opts *Options) (auth.TokenProvider, error) {
63 if !opts.validate() {
64 return nil, errors.New("credentials: invalid external_account_authorized_user configuration")
65 }
66
67 tp := &tokenProvider{
68 o: opts,
69 }
70 return auth.NewCachedTokenProvider(tp, nil), nil
71 }
72
73 type tokenProvider struct {
74 o *Options
75 }
76
77 func (tp *tokenProvider) Token(ctx context.Context) (*auth.Token, error) {
78 opts := tp.o
79
80 clientAuth := stsexchange.ClientAuthentication{
81 AuthStyle: auth.StyleInHeader,
82 ClientID: opts.ClientID,
83 ClientSecret: opts.ClientSecret,
84 }
85 headers := make(http.Header)
86 headers.Set("Content-Type", "application/x-www-form-urlencoded")
87 stsResponse, err := stsexchange.RefreshAccessToken(ctx, &stsexchange.Options{
88 Client: opts.Client,
89 Endpoint: opts.TokenURL,
90 RefreshToken: opts.RefreshToken,
91 Authentication: clientAuth,
92 Headers: headers,
93 })
94 if err != nil {
95 return nil, err
96 }
97 if stsResponse.ExpiresIn < 0 {
98 return nil, errors.New("credentials: invalid expiry from security token service")
99 }
100
101
102 if stsResponse.RefreshToken != "" {
103 opts.RefreshToken = stsResponse.RefreshToken
104 }
105 return &auth.Token{
106 Value: stsResponse.AccessToken,
107 Expiry: time.Now().UTC().Add(time.Duration(stsResponse.ExpiresIn) * time.Second),
108 Type: internal.TokenTypeBearer,
109 }, nil
110 }
111
View as plain text