1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package credentials
16
17 import (
18 "bytes"
19 "context"
20 "crypto/rand"
21 "crypto/rsa"
22 "crypto/x509"
23 "encoding/base64"
24 "encoding/json"
25 "encoding/pem"
26 "strings"
27 "testing"
28 "time"
29
30 "cloud.google.com/go/auth/internal/jwt"
31 )
32
33 var jwtJSONKey = []byte(`{
34 "private_key_id": "268f54e43a1af97cfc71731688434f45aca15c8b",
35 "private_key": "super secret key",
36 "client_email": "gopher@developer.gserviceaccount.com",
37 "client_id": "gopher.apps.googleusercontent.com",
38 "token_uri": "https://accountp.google.com/o/gophers/token",
39 "type": "service_account",
40 "audience": "https://testpervice.googleapis.com/"
41 }`)
42
43 func TestDefaultCredentials_SelfSignedJSON(t *testing.T) {
44 privateKey, jsonKey, err := setupFakeKey()
45 if err != nil {
46 t.Fatal(err)
47 }
48 tp, err := DetectDefault(&DetectOptions{
49 CredentialsJSON: jsonKey,
50 Audience: "audience",
51 UseSelfSignedJWT: true,
52 })
53 if err != nil {
54 t.Fatalf("DefaultCredentials(%s): %v", jsonKey, err)
55 }
56
57 tok, err := tp.Token(context.Background())
58 if err != nil {
59 t.Fatalf("Token(): %v", err)
60 }
61
62 if got, want := tok.Type, "Bearer"; got != want {
63 t.Errorf("Type = %q, want %q", got, want)
64 }
65 if got := tok.Expiry; tok.Expiry.Before(time.Now()) {
66 t.Errorf("Expiry = %v, should not be expired", got)
67 }
68
69 err = jwt.VerifyJWS(tok.Value, &privateKey.PublicKey)
70 if err != nil {
71 t.Errorf("jwt.Verify(%q): %v", tok.Value, err)
72 }
73
74 claim, err := jwt.DecodeJWS(tok.Value)
75 if err != nil {
76 t.Fatalf("jwt.Decode(%q): %v", tok.Value, err)
77 }
78
79 if got, want := claim.Iss, "gopher@developer.gserviceaccount.com"; got != want {
80 t.Errorf("Iss = %q, want %q", got, want)
81 }
82 if got, want := claim.Sub, "gopher@developer.gserviceaccount.com"; got != want {
83 t.Errorf("Sub = %q, want %q", got, want)
84 }
85 if got, want := claim.Aud, "audience"; got != want {
86 t.Errorf("Aud = %q, want %q", got, want)
87 }
88
89
90 tokParts := strings.Split(tok.Value, ".")
91 hdrJSON, err := base64.RawURLEncoding.DecodeString(tokParts[0])
92 if err != nil {
93 t.Fatalf("DecodeString(%q): %v", tokParts[0], err)
94 }
95 var hdr jwt.Header
96 if err := json.Unmarshal(hdrJSON, &hdr); err != nil {
97 t.Fatalf("json.Unmarshal(%q): %v", hdrJSON, err)
98 }
99
100 if got, want := hdr.KeyID, "268f54e43a1af97cfc71731688434f45aca15c8b"; got != want {
101 t.Errorf("KeyID = %q, want %q", got, want)
102 }
103 }
104
105 func TestDefaultCredentials_SelfSignedWithScope(t *testing.T) {
106 privateKey, jsonKey, err := setupFakeKey()
107 if err != nil {
108 t.Fatal(err)
109 }
110 tp, err := DetectDefault(&DetectOptions{
111 CredentialsJSON: jsonKey,
112 Scopes: []string{"scope1", "scope2"},
113 UseSelfSignedJWT: true,
114 })
115 if err != nil {
116 t.Fatalf("DefaultCredentials(%s): %v", jsonKey, err)
117 }
118
119 tok, err := tp.Token(context.Background())
120 if err != nil {
121 t.Fatalf("Token(): %v", err)
122 }
123
124 if got, want := tok.Type, "Bearer"; got != want {
125 t.Errorf("TokenType = %q, want %q", got, want)
126 }
127 if got := tok.Expiry; tok.Expiry.Before(time.Now()) {
128 t.Errorf("Expiry = %v, should not be expired", got)
129 }
130
131 err = jwt.VerifyJWS(tok.Value, &privateKey.PublicKey)
132 if err != nil {
133 t.Errorf("jwt.Verify(%q): %v", tok.Value, err)
134 }
135
136 claim, err := jwt.DecodeJWS(tok.Value)
137 if err != nil {
138 t.Fatalf("jwt.Decode(%q): %v", tok.Value, err)
139 }
140
141 if got, want := claim.Iss, "gopher@developer.gserviceaccount.com"; got != want {
142 t.Errorf("Iss = %q, want %q", got, want)
143 }
144 if got, want := claim.Sub, "gopher@developer.gserviceaccount.com"; got != want {
145 t.Errorf("Sub = %q, want %q", got, want)
146 }
147 if got, want := claim.Scope, "scope1 scope2"; got != want {
148 t.Errorf("Aud = %q, want %q", got, want)
149 }
150
151
152 tokParts := strings.Split(tok.Value, ".")
153 hdrJSON, err := base64.RawURLEncoding.DecodeString(tokParts[0])
154 if err != nil {
155 t.Fatalf("DecodeString(%q): %v", tokParts[0], err)
156 }
157 var hdr jwt.Header
158 if err := json.Unmarshal(hdrJSON, &hdr); err != nil {
159 t.Fatalf("json.Unmarshal(%q): %v", hdrJSON, err)
160 }
161
162 if got, want := hdr.KeyID, "268f54e43a1af97cfc71731688434f45aca15c8b"; got != want {
163 t.Errorf("KeyID = %q, want %q", got, want)
164 }
165 }
166
167
168 func setupFakeKey() (*rsa.PrivateKey, []byte, error) {
169
170 pk, err := rsa.GenerateKey(rand.Reader, 2048)
171 if err != nil {
172 return nil, nil, err
173 }
174
175 enc := pem.EncodeToMemory(&pem.Block{
176 Type: "PRIVATE KEY",
177 Bytes: x509.MarshalPKCS1PrivateKey(pk),
178 })
179 enc, err = json.Marshal(string(enc))
180 if err != nil {
181 return nil, nil, err
182 }
183 return pk, bytes.Replace(jwtJSONKey, []byte(`"super secret key"`), enc, 1), nil
184 }
185
View as plain text