...

Source file src/google.golang.org/api/internal/creds_test.go

Documentation: google.golang.org/api/internal

     1  // Copyright 2017 Google LLC.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     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  	// Load a valid JSON file. No way to really test the contents; we just
    20  	// verify that there is no error.
    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  	// Load valid JSON. No way to really test the contents; we just
    30  	// verify that there is no error.
    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  	// Load a valid JSON file. No way to really test the contents; we just
    44  	// verify that there is no error.
    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  	// Load valid JSON. No way to really test the contents; we just
    51  	// verify that there is no error.
    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  	// Load a valid JSON file. No way to really test the contents; we just
    62  	// verify that there is no error.
    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  	// Load valid JSON. No way to really test the contents; we just
    73  	// verify that there is no error.
    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  	// Load a valid JSON file. No way to really test the contents; we just
    88  	// verify that there is no error.
    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  	// Load valid JSON. No way to really test the contents; we just
   100  	// verify that there is no error.
   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  	// Load a valid JSON file. No way to really test the contents; we just
   116  	// verify that there is no error.
   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  	// Load valid JSON. No way to really test the contents; we just
   127  	// verify that there is no error.
   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  	// Load a valid JSON file. No way to really test the contents; we just
   142  	// verify that there is no error.
   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  	// Load valid JSON. No way to really test the contents; we just
   152  	// verify that there is no error.
   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  	// Load a valid JSON file. No way to really test the contents; we just
   166  	// verify that there is no error.
   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  	// Load valid JSON. No way to really test the contents; we just
   173  	// verify that there is no error.
   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