OLD | NEW |
1 // Copyright 2017 The LUCI Authors. All rights reserved. | 1 // Copyright 2017 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 internal | 5 package internal |
6 | 6 |
7 import ( | 7 import ( |
8 "bytes" | 8 "bytes" |
9 "crypto/sha1" | 9 "crypto/sha1" |
10 "encoding/hex" | 10 "encoding/hex" |
11 "encoding/json" | 11 "encoding/json" |
12 "fmt" | 12 "fmt" |
13 "io/ioutil" | 13 "io/ioutil" |
14 "net/http" | 14 "net/http" |
15 "strings" | 15 "strings" |
16 "time" | 16 "time" |
17 | 17 |
18 "golang.org/x/net/context" | 18 "golang.org/x/net/context" |
19 "golang.org/x/net/context/ctxhttp" | 19 "golang.org/x/net/context/ctxhttp" |
20 "golang.org/x/oauth2" | 20 "golang.org/x/oauth2" |
21 | 21 |
22 "github.com/luci/luci-go/common/auth/localauth/rpcs" | 22 "github.com/luci/luci-go/common/auth/localauth/rpcs" |
23 "github.com/luci/luci-go/common/errors" | |
24 "github.com/luci/luci-go/common/logging" | 23 "github.com/luci/luci-go/common/logging" |
| 24 "github.com/luci/luci-go/common/retry/transient" |
25 "github.com/luci/luci-go/lucictx" | 25 "github.com/luci/luci-go/lucictx" |
26 ) | 26 ) |
27 | 27 |
28 type luciContextTokenProvider struct { | 28 type luciContextTokenProvider struct { |
29 localAuth *lucictx.LocalAuth | 29 localAuth *lucictx.LocalAuth |
30 scopes []string | 30 scopes []string |
31 transport http.RoundTripper | 31 transport http.RoundTripper |
32 cacheKey CacheKey // used only for in-memory cache | 32 cacheKey CacheKey // used only for in-memory cache |
33 } | 33 } |
34 | 34 |
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
112 url := fmt.Sprintf("http://127.0.0.1:%d/rpc/LuciLocalAuthService.GetOAut
hToken", p.localAuth.RPCPort) | 112 url := fmt.Sprintf("http://127.0.0.1:%d/rpc/LuciLocalAuthService.GetOAut
hToken", p.localAuth.RPCPort) |
113 logging.Debugf(ctx, "POST %s", url) | 113 logging.Debugf(ctx, "POST %s", url) |
114 httpReq, err := http.NewRequest("POST", url, bytes.NewReader(body)) | 114 httpReq, err := http.NewRequest("POST", url, bytes.NewReader(body)) |
115 if err != nil { | 115 if err != nil { |
116 return nil, err | 116 return nil, err |
117 } | 117 } |
118 httpReq.Header.Set("Content-Type", "application/json") | 118 httpReq.Header.Set("Content-Type", "application/json") |
119 | 119 |
120 httpResp, err := ctxhttp.Do(ctx, &http.Client{Transport: p.transport}, h
ttpReq) | 120 httpResp, err := ctxhttp.Do(ctx, &http.Client{Transport: p.transport}, h
ttpReq) |
121 if err != nil { | 121 if err != nil { |
122 » » return nil, errors.WrapTransient(err) | 122 » » return nil, transient.Tag.Apply(err) |
123 } | 123 } |
124 defer httpResp.Body.Close() | 124 defer httpResp.Body.Close() |
125 respBody, err := ioutil.ReadAll(httpResp.Body) | 125 respBody, err := ioutil.ReadAll(httpResp.Body) |
126 if err != nil { | 126 if err != nil { |
127 » » return nil, errors.WrapTransient(err) | 127 » » return nil, transient.Tag.Apply(err) |
128 } | 128 } |
129 | 129 |
130 if httpResp.StatusCode != 200 { | 130 if httpResp.StatusCode != 200 { |
131 err := fmt.Errorf("local auth - HTTP %d: %s", httpResp.StatusCod
e, strings.TrimSpace(string(respBody))) | 131 err := fmt.Errorf("local auth - HTTP %d: %s", httpResp.StatusCod
e, strings.TrimSpace(string(respBody))) |
132 if httpResp.StatusCode >= 500 { | 132 if httpResp.StatusCode >= 500 { |
133 » » » return nil, errors.WrapTransient(err) | 133 » » » return nil, transient.Tag.Apply(err) |
134 } | 134 } |
135 return nil, err | 135 return nil, err |
136 } | 136 } |
137 | 137 |
138 response := rpcs.GetOAuthTokenResponse{} | 138 response := rpcs.GetOAuthTokenResponse{} |
139 if err := json.Unmarshal(respBody, &response); err != nil { | 139 if err := json.Unmarshal(respBody, &response); err != nil { |
140 return nil, err | 140 return nil, err |
141 } | 141 } |
142 if response.ErrorMessage != "" || response.ErrorCode != 0 { | 142 if response.ErrorMessage != "" || response.ErrorCode != 0 { |
143 msg := response.ErrorMessage | 143 msg := response.ErrorMessage |
144 if msg == "" { | 144 if msg == "" { |
145 msg = "unknown error" | 145 msg = "unknown error" |
146 } | 146 } |
147 return nil, fmt.Errorf("local auth - RPC code %d: %s", response.
ErrorCode, msg) | 147 return nil, fmt.Errorf("local auth - RPC code %d: %s", response.
ErrorCode, msg) |
148 } | 148 } |
149 | 149 |
150 return &oauth2.Token{ | 150 return &oauth2.Token{ |
151 AccessToken: response.AccessToken, | 151 AccessToken: response.AccessToken, |
152 Expiry: time.Unix(response.Expiry, 0).UTC(), | 152 Expiry: time.Unix(response.Expiry, 0).UTC(), |
153 TokenType: "Bearer", | 153 TokenType: "Bearer", |
154 }, nil | 154 }, nil |
155 } | 155 } |
156 | 156 |
157 func (p *luciContextTokenProvider) RefreshToken(ctx context.Context, prev, base
*oauth2.Token) (*oauth2.Token, error) { | 157 func (p *luciContextTokenProvider) RefreshToken(ctx context.Context, prev, base
*oauth2.Token) (*oauth2.Token, error) { |
158 // Minting and refreshing is the same thing: a call to local auth server
. | 158 // Minting and refreshing is the same thing: a call to local auth server
. |
159 return p.MintToken(ctx, base) | 159 return p.MintToken(ctx, base) |
160 } | 160 } |
OLD | NEW |