...
1
2
3
4
5 package externalaccount
6
7 import (
8 "context"
9 "encoding/json"
10 "errors"
11 "fmt"
12 "io"
13 "io/ioutil"
14 "net/http"
15
16 "golang.org/x/oauth2"
17 )
18
19 type urlCredentialSource struct {
20 URL string
21 Headers map[string]string
22 Format Format
23 ctx context.Context
24 }
25
26 func (cs urlCredentialSource) credentialSourceType() string {
27 return "url"
28 }
29
30 func (cs urlCredentialSource) subjectToken() (string, error) {
31 client := oauth2.NewClient(cs.ctx, nil)
32 req, err := http.NewRequest("GET", cs.URL, nil)
33 if err != nil {
34 return "", fmt.Errorf("oauth2/google/externalaccount: HTTP request for URL-sourced credential failed: %v", err)
35 }
36 req = req.WithContext(cs.ctx)
37
38 for key, val := range cs.Headers {
39 req.Header.Add(key, val)
40 }
41 resp, err := client.Do(req)
42 if err != nil {
43 return "", fmt.Errorf("oauth2/google/externalaccount: invalid response when retrieving subject token: %v", err)
44 }
45 defer resp.Body.Close()
46
47 respBody, err := ioutil.ReadAll(io.LimitReader(resp.Body, 1<<20))
48 if err != nil {
49 return "", fmt.Errorf("oauth2/google/externalaccount: invalid body in subject token URL query: %v", err)
50 }
51 if c := resp.StatusCode; c < 200 || c > 299 {
52 return "", fmt.Errorf("oauth2/google/externalaccount: status code %d: %s", c, respBody)
53 }
54
55 switch cs.Format.Type {
56 case "json":
57 jsonData := make(map[string]interface{})
58 err = json.Unmarshal(respBody, &jsonData)
59 if err != nil {
60 return "", fmt.Errorf("oauth2/google/externalaccount: failed to unmarshal subject token file: %v", err)
61 }
62 val, ok := jsonData[cs.Format.SubjectTokenFieldName]
63 if !ok {
64 return "", errors.New("oauth2/google/externalaccount: provided subject_token_field_name not found in credentials")
65 }
66 token, ok := val.(string)
67 if !ok {
68 return "", errors.New("oauth2/google/externalaccount: improperly formatted subject token")
69 }
70 return token, nil
71 case "text":
72 return string(respBody), nil
73 case "":
74 return string(respBody), nil
75 default:
76 return "", errors.New("oauth2/google/externalaccount: invalid credential_source file format type")
77 }
78
79 }
80
View as plain text