Skip to content

Commit

Permalink
test: integration Tests for Configurable Token Lifespan (#1657)
Browse files Browse the repository at this point in the history
  • Loading branch information
ScruffyProdigy committed Aug 25, 2022
1 parent 8757dbf commit 991f409
Showing 1 changed file with 95 additions and 25 deletions.
120 changes: 95 additions & 25 deletions integration-tests/byoid/integration_test.go
Expand Up @@ -142,13 +142,9 @@ func generateGoogleToken(keyFileName string) (string, error) {
return token.AccessToken, nil
}

// testBYOID makes sure that the default credentials works for
// whatever preconditions have been set beforehand
// by using those credentials to run our client libraries.
//
// In each test we will set up whatever preconditions we need,
// and then use this function.
func testBYOID(t *testing.T, c config) {
// writeConfig writes a temporary config file to memory, and cleans it up after
// testing code is run.
func writeConfig(t *testing.T, c config, f func(name string)) {
t.Helper()

// Set up config file.
Expand All @@ -164,40 +160,59 @@ func testBYOID(t *testing.T, c config) {
}
configFile.Close()

// Once the default credentials are obtained,
// we should be able to access Google Cloud resources.
dnsService, err := dns.NewService(context.Background(), option.WithCredentialsFile(configFile.Name()))
if err != nil {
t.Fatalf("Could not establish DNS Service: %v", err)
}
f(configFile.Name())
}

_, err = dnsService.Projects.Get(projectID).Do()
if err != nil {
t.Fatalf("DNS Service failed: %v", err)
}
// testBYOID makes sure that the default credentials works for
// whatever preconditions have been set beforehand
// by using those credentials to run our client libraries.
//
// In each test we will set up whatever preconditions we need,
// and then use this function.
func testBYOID(t *testing.T, c config) {
t.Helper()

writeConfig(t, c, func(name string) {
// Once the default credentials are obtained,
// we should be able to access Google Cloud resources.
dnsService, err := dns.NewService(context.Background(), option.WithCredentialsFile(name))
if err != nil {
t.Fatalf("Could not establish DNS Service: %v", err)
}

_, err = dnsService.Projects.Get(projectID).Do()
if err != nil {
t.Fatalf("DNS Service failed: %v", err)
}
})
}

// These structs makes writing our config as json to a file much easier.
type config struct {
Type string `json:"type"`
Audience string `json:"audience"`
SubjectTokenType string `json:"subject_token_type"`
TokenURL string `json:"token_url"`
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
CredentialSource credentialSource `json:"credential_source"`
Type string `json:"type"`
Audience string `json:"audience"`
SubjectTokenType string `json:"subject_token_type"`
TokenURL string `json:"token_url"`
ServiceAccountImpersonationURL string `json:"service_account_impersonation_url"`
ServiceAccountImpersonation serviceAccountImpersonationInfo `json:"service_account_impersonation,omitempty"`
CredentialSource credentialSource `json:"credential_source"`
}

type serviceAccountImpersonationInfo struct {
TokenLifetimeSeconds int `json:"token_lifetime_seconds,omitempty"`
}

type credentialSource struct {
File string `json:"file,omitempty"`
URL string `json:"url,omitempty"`
Executable executableConfig `json:"executable,omitempty"`
EnvironmentID string `json:"environment_id,omitempty"`
RegionURL string `json:"region_url"`
RegionURL string `json:"region_url,omitempty"`
RegionalCredVerificationURL string `json:"regional_cred_verification_url,omitempty"`
}

type executableConfig struct {
Command string `json:"command"`
Command string `json:"command,omitempty"`
TimeoutMillis int `json:"timeout_millis,omitempty"`
OutputFile string `json:"output_file,omitempty"`
}
Expand Down Expand Up @@ -380,3 +395,58 @@ echo "{\"success\":true,\"version\":1,\"expiration_time\":%v,\"token_type\":\"ur
},
})
}

func TestConfigurableTokenLifetime(t *testing.T) {
if testing.Short() {
t.Skip("skipping integration test")
}

// Set up Token as a file
tokenFile, err := ioutil.TempFile("", "token.txt")
if err != nil {
t.Fatalf("Error creating token file:")
}
defer os.Remove(tokenFile.Name())

tokenFile.WriteString(oidcToken)
tokenFile.Close()

const tokenLifetimeSeconds = 2800
const safetyBuffer = 5

writeConfig(t, config{
Type: "external_account",
Audience: oidcAudience,
SubjectTokenType: "urn:ietf:params:oauth:token-type:jwt",
TokenURL: "https://sts.googleapis.com/v1/token",
ServiceAccountImpersonationURL: fmt.Sprintf("https://iamcredentials.googleapis.com/v1/%s:generateAccessToken", clientID),
ServiceAccountImpersonation: serviceAccountImpersonationInfo{
TokenLifetimeSeconds: tokenLifetimeSeconds,
},
CredentialSource: credentialSource{
File: tokenFile.Name(),
},
}, func(filename string) {
b, err := ioutil.ReadFile(filename)
if err != nil {
t.Fatalf("Coudn't read temp config file")
}

creds, err := google.CredentialsFromJSON(context.Background(), b, "https://www.googleapis.com/auth/cloud-platform")
if err != nil {
t.Fatalf("Error retrieving credentials")
}

token, err := creds.TokenSource.Token()
if err != nil {
t.Fatalf("Error getting token")
}

now := time.Now()
expiryMax := now.Add(tokenLifetimeSeconds * time.Second)
expiryMin := expiryMax.Add(-safetyBuffer * time.Second)
if token.Expiry.Before(expiryMin) || token.Expiry.After(expiryMax) {
t.Fatalf("Expiry time not set correctly. Got %v, want %v", token.Expiry, expiryMax)
}
})
}

0 comments on commit 991f409

Please sign in to comment.