diff --git a/google/internal/externalaccount/executablecredsource.go b/google/internal/externalaccount/executablecredsource.go index e43f950..6fbb70e 100644 --- a/google/internal/externalaccount/executablecredsource.go +++ b/google/internal/externalaccount/executablecredsource.go @@ -65,15 +65,15 @@ func executableError(err error) error { } func executablesDisallowedError() error { - return errors.New("oauth2/google: Executables need to be explicitly allowed (set GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES to '1') to run") + return errors.New("oauth2/google: executables need to be explicitly allowed (set GOOGLE_EXTERNAL_ACCOUNT_ALLOW_EXECUTABLES to '1') to run") } func timeoutRangeError() error { - return errors.New("oauth2/google: Invalid `timeout_millis` field. Executable timeout must be between 5 and 120 seconds.") + return errors.New("oauth2/google: invalid `timeout_millis` field. Executable timeout must be between 5 and 120 seconds") } func commandMissingError() error { - return errors.New("oauth2/google: Missing `command` field. Executable command must be provided.") + return errors.New("oauth2/google: missing `command` field. Executable command must be provided") } // baseEnv is an alias of os.Environ used for testing @@ -90,14 +90,14 @@ var runCommand = func(ctx context.Context, command string, env []string) ([]byte } if err == context.DeadlineExceeded { - return []byte{}, timeoutError() + return nil, timeoutError() } if exitError, ok := err.(*exec.ExitError); ok { - return []byte{}, exitCodeError(exitError.ExitCode()) + return nil, exitCodeError(exitError.ExitCode()) } - return []byte{}, executableError(err) + return nil, executableError(err) } type executableCredentialSource struct { @@ -131,14 +131,14 @@ func CreateExecutableCredential(ctx context.Context, ec *ExecutableConfig, confi } type executableResponse struct { - Version *int `json:"version,omitempty"` - Success *bool `json:"success,omitempty"` - TokenType *string `json:"token_type,omitempty"` - ExpirationTime *int64 `json:"expiration_time,omitempty"` - IdToken *string `json:"id_token,omitempty"` - SamlResponse *string `json:"saml_response,omitempty"` - Code string `json:"code,omitempty"` - Message string `json:"message,omitempty"` + Version int `json:"version,omitempty"` + Success *bool `json:"success,omitempty"` + TokenType string `json:"token_type,omitempty"` + ExpirationTime int64 `json:"expiration_time,omitempty"` + IdToken string `json:"id_token,omitempty"` + SamlResponse string `json:"saml_response,omitempty"` + Code string `json:"code,omitempty"` + Message string `json:"message,omitempty"` } func parseSubjectToken(response []byte) (string, error) { @@ -147,7 +147,7 @@ func parseSubjectToken(response []byte) (string, error) { return "", jsonParsingError() } - if result.Version == nil { + if result.Version == 0 { return "", missingFieldError("version") } @@ -162,34 +162,34 @@ func parseSubjectToken(response []byte) (string, error) { return "", userDefinedError(result.Code, result.Message) } - if *result.Version > executableSupportedMaxVersion { - return "", unsupportedVersionError(*result.Version) + if result.Version > executableSupportedMaxVersion || result.Version < 0 { + return "", unsupportedVersionError(result.Version) } - if result.ExpirationTime == nil { + if result.ExpirationTime == 0 { return "", missingFieldError("expiration_time") } - if result.TokenType == nil { + if result.TokenType == "" { return "", missingFieldError("token_type") } - if *result.ExpirationTime < now().Unix() { + if result.ExpirationTime < now().Unix() { return "", tokenExpiredError() } - if *result.TokenType == "urn:ietf:params:oauth:token-type:jwt" || *result.TokenType == "urn:ietf:params:oauth:token-type:id_token" { - if result.IdToken == nil { + if result.TokenType == "urn:ietf:params:oauth:token-type:jwt" || result.TokenType == "urn:ietf:params:oauth:token-type:id_token" { + if result.IdToken == "" { return "", missingFieldError("id_token") } - return *result.IdToken, nil + return result.IdToken, nil } - if *result.TokenType == "urn:ietf:params:oauth:token-type:saml2" { - if result.SamlResponse == nil { + if result.TokenType == "urn:ietf:params:oauth:token-type:saml2" { + if result.SamlResponse == "" { return "", missingFieldError("saml_response") } - return *result.SamlResponse, nil + return result.SamlResponse, nil } return "", tokenTypeError() @@ -218,8 +218,9 @@ func (cs executableCredentialSource) getEnvironment() []string { func (cs executableCredentialSource) getNewEnvironmentVariables() map[string]string { result := map[string]string{ - "GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE": cs.config.Audience, - "GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE": cs.config.SubjectTokenType, + "GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE": cs.config.Audience, + "GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE": cs.config.SubjectTokenType, + "GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE": "0", } if cs.config.ServiceAccountImpersonationURL != "" { @@ -229,8 +230,6 @@ func (cs executableCredentialSource) getNewEnvironmentVariables() map[string]str } } - result["GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"] = "0" - if cs.OutputFile != "" { result["GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"] = cs.OutputFile } diff --git a/google/internal/externalaccount/executablecredsource_test.go b/google/internal/externalaccount/executablecredsource_test.go index 3b29201..59f1e82 100644 --- a/google/internal/externalaccount/executablecredsource_test.go +++ b/google/internal/externalaccount/executablecredsource_test.go @@ -396,7 +396,7 @@ func TestRetrieveExecutableSubjectTokenMissingSuccess(t *testing.T) { runCommand = func(ctx context.Context, command string, env []string) ([]byte, error) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ - Version: Int(1), + Version: 1, }) } @@ -443,7 +443,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithFields(t *testing deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(false), - Version: Int(1), + Version: 1, Code: "404", Message: "Token Not Found", }) @@ -492,7 +492,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithCode(t *testing.T deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(false), - Version: Int(1), + Version: 1, Code: "404", }) } @@ -540,7 +540,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithMessage(t *testin deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(false), - Version: Int(1), + Version: 1, Message: "Token Not Found", }) } @@ -588,7 +588,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithoutFields(t *test deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(false), - Version: Int(1), + Version: 1, }) } @@ -635,7 +635,7 @@ func TestRetrieveExecutableSubjectTokenNewerVersion(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(2), + Version: 2, }) } @@ -682,8 +682,8 @@ func TestRetrieveExecutableSubjectTokenMissingExpiration(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - TokenType: String("urn:ietf:params:oauth:token-type:jwt"), + Version: 1, + TokenType: "urn:ietf:params:oauth:token-type:jwt", }) } @@ -730,8 +730,8 @@ func TestRetrieveExecutableSubjectTokenTokenTypeMissing(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix()), + Version: 1, + ExpirationTime: now().Unix(), }) } @@ -778,9 +778,9 @@ func TestRetrieveExecutableSubjectTokenInvalidTokenType(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix()), - TokenType: String("urn:ietf:params:oauth:token-type:invalid"), + Version: 1, + ExpirationTime: now().Unix(), + TokenType: "urn:ietf:params:oauth:token-type:invalid", }) } @@ -827,9 +827,9 @@ func TestRetrieveExecutableSubjectTokenExpired(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix() - 1), - TokenType: String("urn:ietf:params:oauth:token-type:jwt"), + Version: 1, + ExpirationTime: now().Unix() - 1, + TokenType: "urn:ietf:params:oauth:token-type:jwt", }) } @@ -876,10 +876,10 @@ func TestRetrieveExecutableSubjectTokenJwt(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix() + 3600), - TokenType: String("urn:ietf:params:oauth:token-type:jwt"), - IdToken: String("tokentokentoken"), + Version: 1, + ExpirationTime: now().Unix() + 3600, + TokenType: "urn:ietf:params:oauth:token-type:jwt", + IdToken: "tokentokentoken", }) } @@ -927,9 +927,9 @@ func TestRetrieveExecutableSubjectTokenJwtMissingIdToken(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix() + 3600), - TokenType: String("urn:ietf:params:oauth:token-type:jwt"), + Version: 1, + ExpirationTime: now().Unix() + 3600, + TokenType: "urn:ietf:params:oauth:token-type:jwt", }) } @@ -976,10 +976,10 @@ func TestRetrieveExecutableSubjectTokenIdToken(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix() + 3600), - TokenType: String("urn:ietf:params:oauth:token-type:id_token"), - IdToken: String("tokentokentoken"), + Version: 1, + ExpirationTime: now().Unix() + 3600, + TokenType: "urn:ietf:params:oauth:token-type:id_token", + IdToken: "tokentokentoken", }) } @@ -1027,10 +1027,10 @@ func TestRetrieveExecutableSubjectTokenSaml(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix() + 3600), - TokenType: String("urn:ietf:params:oauth:token-type:saml2"), - SamlResponse: String("tokentokentoken"), + Version: 1, + ExpirationTime: now().Unix() + 3600, + TokenType: "urn:ietf:params:oauth:token-type:saml2", + SamlResponse: "tokentokentoken", }) } @@ -1078,9 +1078,9 @@ func TestRetrieveExecutableSubjectTokenSamlMissingResponse(t *testing.T) { deadline, deadlineSet = ctx.Deadline() return json.Marshal(executableResponse{ Success: Bool(true), - Version: Int(1), - ExpirationTime: Int64(now().Unix() + 3600), - TokenType: String("urn:ietf:params:oauth:token-type:saml2"), + Version: 1, + ExpirationTime: now().Unix() + 3600, + TokenType: "urn:ietf:params:oauth:token-type:saml2", }) }