Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(auth): make package externalaccount public #9633

Merged
merged 12 commits into from
Mar 25, 2024
2 changes: 1 addition & 1 deletion auth/credentials/externalaccount/externalaccount.go
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,7 @@ type ExecutableConfig struct {
// This can include arguments. Must be an absolute path for the program. Required.
Command string
// TimeoutMillis is the timeout duration, in milliseconds. Defaults to 30000 milliseconds when not provided. Optional.
TimeoutMillis *int
TimeoutMillis int
quartzmo marked this conversation as resolved.
Show resolved Hide resolved
// OutputFile is the absolute path to the output file where the executable will cache the response.
// If specified the auth libraries will first check this location before running the executable. Optional.
OutputFile string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func TestCreateExecutableCredential(t *testing.T) {
name: "Basic Creation",
executableConfig: credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(50000),
TimeoutMillis: 50000,
},
wantTimeout: 50000 * time.Millisecond,
},
Expand All @@ -64,31 +64,31 @@ func TestCreateExecutableCredential(t *testing.T) {
name: "Timeout Too Low",
executableConfig: credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(4999),
TimeoutMillis: 4999,
},
skipErrorEquals: true,
},
{
name: "Timeout Lower Bound",
executableConfig: credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
},
wantTimeout: 5000 * time.Millisecond,
},
{
name: "Timeout Upper Bound",
executableConfig: credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(120000),
TimeoutMillis: 120000,
},
wantTimeout: 120000 * time.Millisecond,
},
{
name: "Timeout Too High",
executableConfig: credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(120001),
TimeoutMillis: 120001,
},
skipErrorEquals: true,
},
Expand Down Expand Up @@ -244,7 +244,7 @@ func TestRetrieveExecutableSubjectTokenExecutableErrors(t *testing.T) {
cs := credsfile.CredentialSource{
Executable: &credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
},
}

Expand Down Expand Up @@ -476,7 +476,7 @@ func TestRetrieveExecutableSubjectTokenSuccesses(t *testing.T) {
cs := credsfile.CredentialSource{
Executable: &credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
},
}

Expand Down Expand Up @@ -585,7 +585,7 @@ func TestRetrieveOutputFileSubjectTokenNotJSON(t *testing.T) {
cs := credsfile.CredentialSource{
Executable: &credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
OutputFile: outputFile.Name(),
},
}
Expand Down Expand Up @@ -733,7 +733,7 @@ func TestRetrieveOutputFileSubjectTokenFailureTests(t *testing.T) {
cs := credsfile.CredentialSource{
Executable: &credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
OutputFile: outputFile.Name(),
},
}
Expand Down Expand Up @@ -835,7 +835,7 @@ func TestRetrieveOutputFileSubjectTokenInvalidCache(t *testing.T) {
cs := credsfile.CredentialSource{
Executable: &credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
OutputFile: outputFile.Name(),
},
}
Expand Down Expand Up @@ -940,7 +940,7 @@ func TestRetrieveOutputFileSubjectTokenJwt(t *testing.T) {
cs := credsfile.CredentialSource{
Executable: &credsfile.ExecutableConfig{
Command: "blarg",
TimeoutMillis: Int(5000),
TimeoutMillis: 5000,
OutputFile: outputFile.Name(),
},
}
Expand Down Expand Up @@ -1022,10 +1022,6 @@ func Bool(b bool) *bool {
return &b
}

func Int(i int) *int {
return &i
}

func TestServiceAccountImpersonationRE(t *testing.T) {
tests := []struct {
name string
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -228,10 +228,10 @@ func newSubjectTokenProvider(o *Options) (subjectTokenProvider, error) {

execProvider := &executableSubjectProvider{}
execProvider.Command = ec.Command
if ec.TimeoutMillis == nil {
if ec.TimeoutMillis == 0 {
execProvider.Timeout = executableDefaultTimeout
} else {
execProvider.Timeout = time.Duration(*ec.TimeoutMillis) * time.Millisecond
execProvider.Timeout = time.Duration(ec.TimeoutMillis) * time.Millisecond
if execProvider.Timeout < timeoutMinimum || execProvider.Timeout > timeoutMaximum {
return nil, fmt.Errorf("credentials: invalid `timeout_millis` field — executable timeout must be between %v and %v seconds", timeoutMinimum.Seconds(), timeoutMaximum.Seconds())
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,10 @@ func (sp *fileSubjectProvider) subjectToken(context.Context) (string, error) {
return "", fmt.Errorf("credentials: failed to read credential file: %w", err)
}
tokenBytes = bytes.TrimSpace(tokenBytes)

if sp.Format == nil {
return string(tokenBytes), nil
}
switch sp.Format.Type {
case fileTypeJSON:
jsonData := make(map[string]interface{})
Expand All @@ -62,7 +66,7 @@ func (sp *fileSubjectProvider) subjectToken(context.Context) (string, error) {
return "", errors.New("credentials: improperly formatted subject token")
}
return token, nil
case fileTypeText, "":
case fileTypeText:
return string(tokenBytes), nil
default:
return "", errors.New("credentials: invalid credential_source file format type: " + sp.Format.Type)
Expand Down
5 changes: 4 additions & 1 deletion auth/credentials/internal/externalaccount/url_provider.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,9 @@ func (sp *urlSubjectProvider) subjectToken(ctx context.Context) (string, error)
return "", fmt.Errorf("credentials: status code %d: %s", c, respBody)
}

if sp.Format == nil {
return string(respBody), nil
}
switch sp.Format.Type {
case "json":
jsonData := make(map[string]interface{})
Expand All @@ -77,7 +80,7 @@ func (sp *urlSubjectProvider) subjectToken(ctx context.Context) (string, error)
return "", errors.New("credentials: improperly formatted subject token")
}
return token, nil
case fileTypeText, "":
case fileTypeText:
return string(respBody), nil
default:
return "", errors.New("credentials: invalid credential_source file format type: " + sp.Format.Type)
Expand Down
2 changes: 1 addition & 1 deletion auth/internal/credsfile/filetype.go
Original file line number Diff line number Diff line change
Expand Up @@ -115,7 +115,7 @@ type Format struct {
// [CredentialSource].
type ExecutableConfig struct {
Command string `json:"command"`
TimeoutMillis *int `json:"timeout_millis"`
TimeoutMillis int `json:"timeout_millis"`
OutputFile string `json:"output_file"`
}

Expand Down
3 changes: 1 addition & 2 deletions auth/internal/credsfile/parse_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -273,8 +273,7 @@ func TestParseExternalAccount_Cmd(t *testing.T) {
},
},
}
timeout := 5000
want.CredentialSource.Executable.TimeoutMillis = &timeout
want.CredentialSource.Executable.TimeoutMillis = 5000
if diff := cmp.Diff(want, got); diff != "" {
t.Errorf("(-want +got):\n%s", diff)
}
Expand Down