1
2
3
4
5 package internal
6
7 import (
8 "context"
9 "os"
10 "testing"
11
12 "golang.org/x/oauth2"
13 "golang.org/x/oauth2/google"
14 )
15
16 func TestDefaultServiceAccount(t *testing.T) {
17 ctx := context.Background()
18
19
20
21 ds := &DialSettings{
22 CredentialsFile: "testdata/service-account.json",
23 DefaultScopes: []string{"foo"},
24 }
25 if _, err := Creds(ctx, ds); err != nil {
26 t.Errorf("got %v, wanted no error", err)
27 }
28
29
30
31 ds = &DialSettings{
32 CredentialsJSON: []byte(validServiceAccountJSON),
33 DefaultScopes: []string{"foo"},
34 }
35 if _, err := Creds(ctx, ds); err != nil {
36 t.Errorf("got %v, wanted no error", err)
37 }
38 }
39
40 func TestJWTWithAudience(t *testing.T) {
41 ctx := context.Background()
42
43
44
45 ds := &DialSettings{CredentialsFile: "testdata/service-account.json", Audiences: []string{"foo"}}
46 if _, err := Creds(ctx, ds); err != nil {
47 t.Errorf("got %v, wanted no error", err)
48 }
49
50
51
52 ds = &DialSettings{CredentialsJSON: []byte(validServiceAccountJSON), Audiences: []string{"foo"}}
53 if _, err := Creds(ctx, ds); err != nil {
54 t.Errorf("got %v, wanted no error", err)
55 }
56 }
57
58 func TestJWTWithScope(t *testing.T) {
59 ctx := context.Background()
60
61
62
63 ds := &DialSettings{
64 CredentialsFile: "testdata/service-account.json",
65 Scopes: []string{"foo"},
66 EnableJwtWithScope: true,
67 }
68 if _, err := Creds(ctx, ds); err != nil {
69 t.Errorf("got %v, wanted no error", err)
70 }
71
72
73
74 ds = &DialSettings{
75 CredentialsJSON: []byte(validServiceAccountJSON),
76 Scopes: []string{"foo"},
77 EnableJwtWithScope: true,
78 }
79 if _, err := Creds(ctx, ds); err != nil {
80 t.Errorf("got %v, wanted no error", err)
81 }
82 }
83
84 func TestJWTWithScopeAndUniverseDomain(t *testing.T) {
85 ctx := context.Background()
86
87
88
89 ds := &DialSettings{
90 CredentialsFile: "testdata/service-account.json",
91 Scopes: []string{"foo"},
92 EnableJwtWithScope: true,
93 UniverseDomain: "example.com",
94 }
95 if _, err := Creds(ctx, ds); err != nil {
96 t.Errorf("got %v, wanted no error", err)
97 }
98
99
100
101 ds = &DialSettings{
102 CredentialsJSON: []byte(validServiceAccountJSON),
103 Scopes: []string{"foo"},
104 EnableJwtWithScope: true,
105 UniverseDomain: "example.com",
106 }
107 if _, err := Creds(ctx, ds); err != nil {
108 t.Errorf("got %v, wanted no error", err)
109 }
110 }
111
112 func TestJWTWithDefaultScopes(t *testing.T) {
113 ctx := context.Background()
114
115
116
117 ds := &DialSettings{
118 CredentialsFile: "testdata/service-account.json",
119 DefaultScopes: []string{"foo"},
120 EnableJwtWithScope: true,
121 }
122 if _, err := Creds(ctx, ds); err != nil {
123 t.Errorf("got %v, wanted no error", err)
124 }
125
126
127
128 ds = &DialSettings{
129 CredentialsJSON: []byte(validServiceAccountJSON),
130 DefaultScopes: []string{"foo"},
131 EnableJwtWithScope: true,
132 }
133 if _, err := Creds(ctx, ds); err != nil {
134 t.Errorf("got %v, wanted no error", err)
135 }
136 }
137
138 func TestJWTWithDefaultAudience(t *testing.T) {
139 ctx := context.Background()
140
141
142
143 ds := &DialSettings{
144 CredentialsFile: "testdata/service-account.json",
145 DefaultAudience: "foo",
146 }
147 if _, err := Creds(ctx, ds); err != nil {
148 t.Errorf("got %v, wanted no error", err)
149 }
150
151
152
153 ds = &DialSettings{
154 CredentialsJSON: []byte(validServiceAccountJSON),
155 DefaultAudience: "foo",
156 }
157 if _, err := Creds(ctx, ds); err != nil {
158 t.Errorf("got %v, wanted no error", err)
159 }
160 }
161
162 func TestOAuth(t *testing.T) {
163 ctx := context.Background()
164
165
166
167 ds := &DialSettings{CredentialsFile: "testdata/service-account.json", Scopes: []string{"foo"}}
168 if _, err := Creds(ctx, ds); err != nil {
169 t.Errorf("got %v, wanted no error", err)
170 }
171
172
173
174 ds = &DialSettings{CredentialsJSON: []byte(validServiceAccountJSON), Scopes: []string{"foo"}}
175 if _, err := Creds(ctx, ds); err != nil {
176 t.Errorf("got %v, wanted no error", err)
177 }
178 }
179
180 const validServiceAccountJSON = `{
181 "type": "service_account",
182 "project_id": "dumba-504",
183 "private_key_id": "adsfsdd",
184 "private_key": "-----BEGIN PRIVATE KEY-----\nMIIEvgIBADANBgkqhkiG9w0BAQEFAASCBKgwggSkAgEAAoIBAQDczcmZh9zhcDjd\nc+a1bcNu06QA+PGwjAZygTy9ays8qTLi4J8zWSjxgb18ZgYnv1gwVenmSBRuj+kg\nG03NPOxGmPrC/fTnZVBZpQRwBccBrPnRMvEM94egVrHKvPgqbifkyn2VR+ouWZvv\nwigR2PbjcvrSNkPE0QpLnRV0stilgCIYXR17lFrOPoiMra3N//1J0IPIFl3qZHxB\nsiejdi7zUiqLkqjYrNRHKulAGcJjqdCsNjAdjxgbRHgTjXSyuJh8bdKBgAMhetKj\nvU2OM431a9MQq77q/kvuJuCDRe6WqHs7JEFICUymTSSauANXowTUz63jfoSMMwmL\nBNcoePAZAgMBAAECggEAFxpkJe+YjbERjiBOqzybJok3/48MsOGR2iDKI3KncT8t\n7x28IqIJXe2qjy3YpoeHmXUf1mPD2YauyJh6xUcC3OcsU8NBQQXxiJOy2WrNVhBM\nilZXcPkkZIM1sqYfnEbu3ypNxhUifGuNXKKW0Tk/qfBRrLWXVSxfNKawxEdjUjua\ncknCwOBuZYkp8tTO5py5+RcoxHjAoNGaajep3yvNTIZ0WOLSjpAxLh0XCL5PRqKe\nfOrxL7ZY5Xl+yhc7/9PnVcdVOyUrry6I3byx8Yu46USLamNivZPk4xCiCe0k5OO1\nnXiU7qSLky4iiSzEd8o+0j/G8gMPZ9CF944kF60QIQKBgQDygfFrPjdYT5tpuPy+\nfpAZVnYWqLkvQHty0jmAqHucYRYVd1zpzY8zXW1JPXWSwGMSqB/Nz82v6oUw/Ovm\nRJ4+hvvUqZtUM1KJ10RUUWZDDLKoUgHp96IHarytdVy6kXZ0F2QNzW/VFTuzdKaK\n53c7Zc7iFK+4B/6XfyAumU0PSQKBgQDpFrdeQSoT4jXw/een7Hj3686cb9fkLEIf\na/pOOlqfGlJf7+NfqZpGBj5XxLGIJX80FFRtWTTAdgWrBmP0Nyvh48yd0KLALvyh\nmmqX/tBkkP41ASRMD+fWYh0AMhH6LmgrZtSUPKy0NvLIosH0qSbKGLIJEcXx3Pm4\nS1+eH0xKUQKBgA1hXhCsviEBQ3Hx4wAfu5OqUZmudYlF5YnQT5vpr+hQ8wb8LwQ3\nc09COGVyHqqaMt00qYyRiqfKKM8rJVjvMEwC5qI1OXzL2CIC3qJIW3wXl0PyQmjG\nYQpHuWFYuGUS4ZZGNB8O1rzLDyA3r3i6jLmaRG/09D0TM9joCr6HdtkBAoGBAIi6\n1p3nw/MeA1520uligiOMpAqIYTBr9e3QvWgeOwKRwjic09hN+T2SdAewTiP7Ov8l\n3dC3P4aWtQR6HzAnHQrJQkJhHNd3uKJjnpvC0iPsGfKl1ND5k5niu/hdZsZHarvq\n+lBqtzSP9yNStkv63dI3YliHoIIcijBdpp1u5qXBAoGBAOLrmvUKnx4NLEcauQ0e\naHndQ/6y4ie6knn1iJsJdYNJnYh9RKqDPTgpi8DbE2eb5JNkBQl0nSBMl74+MhVl\nMKBPVprkv7p3BdxoanpsncY14TUnzWIngkH21Rk0gqE3t/iJ7xnCTSv8qv3yYDj3\nL54zu6Y9GbjLgn6BtfhLHG4v\n-----END PRIVATE KEY-----\n",
185 "client_email": "dumba-504@appspot.gserviceaccount.com",
186 "client_id": "111",
187 "auth_uri": "https://accounts.google.com/o/oauth2/auth",
188 "token_uri": "https://accounts.google.com/o/oauth2/token",
189 "auth_provider_x509_cert_url": "https://www.googleapis.com/oauth2/v1/certs",
190 "client_x509_cert_url": "https://www.googleapis.com/robot/v1/metadata/x509/dumba-504%40appspot.gserviceaccount.com"
191 }`
192
193 func TestGetQuotaProject(t *testing.T) {
194 ctx := context.Background()
195 emptyCred, err := credentialsFromJSON(
196 ctx,
197 []byte(validServiceAccountJSON),
198 &DialSettings{
199 Endpoint: "foo.googleapis.com",
200 DefaultScopes: []string{"foo"},
201 })
202 if err != nil {
203 t.Fatalf("got %v, wanted no error", err)
204 }
205 quotaProjectJSON := []byte(`
206 {
207 "type": "authorized_user",
208 "quota_project_id": "foobar"
209 }`)
210
211 quotaCred, err := credentialsFromJSON(
212 ctx,
213 []byte(quotaProjectJSON),
214 &DialSettings{
215 Endpoint: "foo.googleapis.com",
216 DefaultScopes: []string{"foo"},
217 })
218 if err != nil {
219 t.Fatalf("got %v, wanted no error", err)
220 }
221
222 tests := []struct {
223 name string
224 cred *google.Credentials
225 clientOpt string
226 env string
227 want string
228 }{
229 {
230 name: "empty all",
231 cred: nil,
232 want: "",
233 },
234 {
235 name: "empty cred",
236 cred: emptyCred,
237 want: "",
238 },
239 {
240 name: "from cred",
241 cred: quotaCred,
242 want: "foobar",
243 },
244 {
245 name: "from opt",
246 cred: quotaCred,
247 clientOpt: "clientopt",
248 want: "clientopt",
249 },
250 {
251 name: "from env",
252 cred: quotaCred,
253 env: "envProject",
254 want: "envProject",
255 },
256 }
257 for _, tt := range tests {
258 t.Run(tt.name, func(t *testing.T) {
259 oldEnv := os.Getenv(quotaProjectEnvVar)
260 if tt.env != "" {
261 os.Setenv(quotaProjectEnvVar, tt.env)
262 }
263 if want, got := tt.want, GetQuotaProject(tt.cred, tt.clientOpt); want != got {
264 t.Errorf("GetQuotaProject(%v, %q): want %q, got %q", tt.cred, tt.clientOpt, want, got)
265 }
266 os.Setenv(quotaProjectEnvVar, oldEnv)
267 })
268 }
269 }
270
271 func TestCredsWithCredentials(t *testing.T) {
272 tests := []struct {
273 name string
274 ds *DialSettings
275 want string
276 }{
277 {
278 name: "only normal opt",
279 ds: &DialSettings{
280 Credentials: &google.Credentials{
281 TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
282 AccessToken: "normal",
283 }),
284 },
285 },
286 want: "normal",
287 },
288 {
289 name: "normal and internal creds opt",
290 ds: &DialSettings{
291 Credentials: &google.Credentials{
292 TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
293 AccessToken: "normal",
294 }),
295 },
296 InternalCredentials: &google.Credentials{
297 TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
298 AccessToken: "internal",
299 }),
300 },
301 },
302 want: "internal",
303 },
304 {
305 name: "only internal creds opt",
306 ds: &DialSettings{
307 InternalCredentials: &google.Credentials{
308 TokenSource: oauth2.StaticTokenSource(&oauth2.Token{
309 AccessToken: "internal",
310 }),
311 },
312 },
313 want: "internal",
314 },
315 }
316
317 for _, tc := range tests {
318 t.Run(tc.name, func(t *testing.T) {
319 creds, err := Creds(context.Background(), tc.ds)
320 if err != nil {
321 t.Fatalf("got %v, want nil error", err)
322 }
323 if tok, _ := creds.TokenSource.Token(); tok.AccessToken != tc.want {
324 t.Fatalf("tok.AccessToken = %q, want %q", tok.AccessToken, tc.want)
325 }
326 })
327 }
328 }
329
330 func TestIsSelfSignedJWTFlow(t *testing.T) {
331 tests := []struct {
332 name string
333 ds *DialSettings
334 want bool
335 }{
336 {
337 name: "EnableJwtWithScope true",
338 ds: &DialSettings{
339 CredentialsFile: "testdata/service-account.json",
340 Scopes: []string{"foo"},
341 EnableJwtWithScope: true,
342 },
343 want: true,
344 },
345 {
346 name: "EnableJwtWithScope false",
347 ds: &DialSettings{
348 CredentialsFile: "testdata/service-account.json",
349 Scopes: []string{"foo"},
350 EnableJwtWithScope: false,
351 },
352 want: false,
353 },
354 {
355 name: "UniverseDomain",
356 ds: &DialSettings{
357 CredentialsFile: "testdata/service-account.json",
358 Scopes: []string{"foo"},
359 EnableJwtWithScope: false,
360 UniverseDomain: "example.com",
361 },
362 want: true,
363 },
364 {
365 name: "UniverseDomainUserAccount",
366 ds: &DialSettings{
367 CredentialsFile: "testdata/user-account.json",
368 Scopes: []string{"foo"},
369 EnableJwtWithScope: false,
370 UniverseDomain: "example.com",
371 },
372 want: false,
373 },
374 }
375
376 for _, tc := range tests {
377
378 bytes, err := os.ReadFile(tc.ds.CredentialsFile)
379 if err != nil {
380 t.Fatal(err)
381 }
382 isSSJ, err := isSelfSignedJWTFlow(bytes, tc.ds)
383 if err != nil {
384 t.Errorf("[%s]: got %v, wanted no error", tc.name, err)
385 }
386 if isSSJ != tc.want {
387 t.Errorf("[%s]: got %t, wanted %t", tc.name, isSSJ, tc.want)
388 }
389 }
390 }
391
View as plain text