forked from remote/oauth2
Changes requested by @codyoss
This commit is contained in:
@@ -65,15 +65,15 @@ func executableError(err error) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func executablesDisallowedError() 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 {
|
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 {
|
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
|
// 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 {
|
if err == context.DeadlineExceeded {
|
||||||
return []byte{}, timeoutError()
|
return nil, timeoutError()
|
||||||
}
|
}
|
||||||
|
|
||||||
if exitError, ok := err.(*exec.ExitError); ok {
|
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 {
|
type executableCredentialSource struct {
|
||||||
@@ -131,14 +131,14 @@ func CreateExecutableCredential(ctx context.Context, ec *ExecutableConfig, confi
|
|||||||
}
|
}
|
||||||
|
|
||||||
type executableResponse struct {
|
type executableResponse struct {
|
||||||
Version *int `json:"version,omitempty"`
|
Version int `json:"version,omitempty"`
|
||||||
Success *bool `json:"success,omitempty"`
|
Success *bool `json:"success,omitempty"`
|
||||||
TokenType *string `json:"token_type,omitempty"`
|
TokenType string `json:"token_type,omitempty"`
|
||||||
ExpirationTime *int64 `json:"expiration_time,omitempty"`
|
ExpirationTime int64 `json:"expiration_time,omitempty"`
|
||||||
IdToken *string `json:"id_token,omitempty"`
|
IdToken string `json:"id_token,omitempty"`
|
||||||
SamlResponse *string `json:"saml_response,omitempty"`
|
SamlResponse string `json:"saml_response,omitempty"`
|
||||||
Code string `json:"code,omitempty"`
|
Code string `json:"code,omitempty"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func parseSubjectToken(response []byte) (string, error) {
|
func parseSubjectToken(response []byte) (string, error) {
|
||||||
@@ -147,7 +147,7 @@ func parseSubjectToken(response []byte) (string, error) {
|
|||||||
return "", jsonParsingError()
|
return "", jsonParsingError()
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.Version == nil {
|
if result.Version == 0 {
|
||||||
return "", missingFieldError("version")
|
return "", missingFieldError("version")
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -162,34 +162,34 @@ func parseSubjectToken(response []byte) (string, error) {
|
|||||||
return "", userDefinedError(result.Code, result.Message)
|
return "", userDefinedError(result.Code, result.Message)
|
||||||
}
|
}
|
||||||
|
|
||||||
if *result.Version > executableSupportedMaxVersion {
|
if result.Version > executableSupportedMaxVersion || result.Version < 0 {
|
||||||
return "", unsupportedVersionError(*result.Version)
|
return "", unsupportedVersionError(result.Version)
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.ExpirationTime == nil {
|
if result.ExpirationTime == 0 {
|
||||||
return "", missingFieldError("expiration_time")
|
return "", missingFieldError("expiration_time")
|
||||||
}
|
}
|
||||||
|
|
||||||
if result.TokenType == nil {
|
if result.TokenType == "" {
|
||||||
return "", missingFieldError("token_type")
|
return "", missingFieldError("token_type")
|
||||||
}
|
}
|
||||||
|
|
||||||
if *result.ExpirationTime < now().Unix() {
|
if result.ExpirationTime < now().Unix() {
|
||||||
return "", tokenExpiredError()
|
return "", tokenExpiredError()
|
||||||
}
|
}
|
||||||
|
|
||||||
if *result.TokenType == "urn:ietf:params:oauth:token-type:jwt" || *result.TokenType == "urn:ietf:params:oauth:token-type:id_token" {
|
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.IdToken == "" {
|
||||||
return "", missingFieldError("id_token")
|
return "", missingFieldError("id_token")
|
||||||
}
|
}
|
||||||
return *result.IdToken, nil
|
return result.IdToken, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
if *result.TokenType == "urn:ietf:params:oauth:token-type:saml2" {
|
if result.TokenType == "urn:ietf:params:oauth:token-type:saml2" {
|
||||||
if result.SamlResponse == nil {
|
if result.SamlResponse == "" {
|
||||||
return "", missingFieldError("saml_response")
|
return "", missingFieldError("saml_response")
|
||||||
}
|
}
|
||||||
return *result.SamlResponse, nil
|
return result.SamlResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return "", tokenTypeError()
|
return "", tokenTypeError()
|
||||||
@@ -218,8 +218,9 @@ func (cs executableCredentialSource) getEnvironment() []string {
|
|||||||
|
|
||||||
func (cs executableCredentialSource) getNewEnvironmentVariables() map[string]string {
|
func (cs executableCredentialSource) getNewEnvironmentVariables() map[string]string {
|
||||||
result := map[string]string{
|
result := map[string]string{
|
||||||
"GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE": cs.config.Audience,
|
"GOOGLE_EXTERNAL_ACCOUNT_AUDIENCE": cs.config.Audience,
|
||||||
"GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE": cs.config.SubjectTokenType,
|
"GOOGLE_EXTERNAL_ACCOUNT_TOKEN_TYPE": cs.config.SubjectTokenType,
|
||||||
|
"GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE": "0",
|
||||||
}
|
}
|
||||||
|
|
||||||
if cs.config.ServiceAccountImpersonationURL != "" {
|
if cs.config.ServiceAccountImpersonationURL != "" {
|
||||||
@@ -229,8 +230,6 @@ func (cs executableCredentialSource) getNewEnvironmentVariables() map[string]str
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
result["GOOGLE_EXTERNAL_ACCOUNT_INTERACTIVE"] = "0"
|
|
||||||
|
|
||||||
if cs.OutputFile != "" {
|
if cs.OutputFile != "" {
|
||||||
result["GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"] = cs.OutputFile
|
result["GOOGLE_EXTERNAL_ACCOUNT_OUTPUT_FILE"] = cs.OutputFile
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -396,7 +396,7 @@ func TestRetrieveExecutableSubjectTokenMissingSuccess(t *testing.T) {
|
|||||||
runCommand = func(ctx context.Context, command string, env []string) ([]byte, error) {
|
runCommand = func(ctx context.Context, command string, env []string) ([]byte, error) {
|
||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -443,7 +443,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithFields(t *testing
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(false),
|
Success: Bool(false),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
Code: "404",
|
Code: "404",
|
||||||
Message: "Token Not Found",
|
Message: "Token Not Found",
|
||||||
})
|
})
|
||||||
@@ -492,7 +492,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithCode(t *testing.T
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(false),
|
Success: Bool(false),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
Code: "404",
|
Code: "404",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -540,7 +540,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithMessage(t *testin
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(false),
|
Success: Bool(false),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
Message: "Token Not Found",
|
Message: "Token Not Found",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -588,7 +588,7 @@ func TestRetrieveExecutableSubjectTokenUnsuccessfulResponseWithoutFields(t *test
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(false),
|
Success: Bool(false),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -635,7 +635,7 @@ func TestRetrieveExecutableSubjectTokenNewerVersion(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(2),
|
Version: 2,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -682,8 +682,8 @@ func TestRetrieveExecutableSubjectTokenMissingExpiration(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:jwt"),
|
TokenType: "urn:ietf:params:oauth:token-type:jwt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -730,8 +730,8 @@ func TestRetrieveExecutableSubjectTokenTokenTypeMissing(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix()),
|
ExpirationTime: now().Unix(),
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -778,9 +778,9 @@ func TestRetrieveExecutableSubjectTokenInvalidTokenType(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix()),
|
ExpirationTime: now().Unix(),
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:invalid"),
|
TokenType: "urn:ietf:params:oauth:token-type:invalid",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -827,9 +827,9 @@ func TestRetrieveExecutableSubjectTokenExpired(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix() - 1),
|
ExpirationTime: now().Unix() - 1,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:jwt"),
|
TokenType: "urn:ietf:params:oauth:token-type:jwt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -876,10 +876,10 @@ func TestRetrieveExecutableSubjectTokenJwt(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix() + 3600),
|
ExpirationTime: now().Unix() + 3600,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:jwt"),
|
TokenType: "urn:ietf:params:oauth:token-type:jwt",
|
||||||
IdToken: String("tokentokentoken"),
|
IdToken: "tokentokentoken",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -927,9 +927,9 @@ func TestRetrieveExecutableSubjectTokenJwtMissingIdToken(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix() + 3600),
|
ExpirationTime: now().Unix() + 3600,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:jwt"),
|
TokenType: "urn:ietf:params:oauth:token-type:jwt",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -976,10 +976,10 @@ func TestRetrieveExecutableSubjectTokenIdToken(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix() + 3600),
|
ExpirationTime: now().Unix() + 3600,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:id_token"),
|
TokenType: "urn:ietf:params:oauth:token-type:id_token",
|
||||||
IdToken: String("tokentokentoken"),
|
IdToken: "tokentokentoken",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1027,10 +1027,10 @@ func TestRetrieveExecutableSubjectTokenSaml(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix() + 3600),
|
ExpirationTime: now().Unix() + 3600,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:saml2"),
|
TokenType: "urn:ietf:params:oauth:token-type:saml2",
|
||||||
SamlResponse: String("tokentokentoken"),
|
SamlResponse: "tokentokentoken",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1078,9 +1078,9 @@ func TestRetrieveExecutableSubjectTokenSamlMissingResponse(t *testing.T) {
|
|||||||
deadline, deadlineSet = ctx.Deadline()
|
deadline, deadlineSet = ctx.Deadline()
|
||||||
return json.Marshal(executableResponse{
|
return json.Marshal(executableResponse{
|
||||||
Success: Bool(true),
|
Success: Bool(true),
|
||||||
Version: Int(1),
|
Version: 1,
|
||||||
ExpirationTime: Int64(now().Unix() + 3600),
|
ExpirationTime: now().Unix() + 3600,
|
||||||
TokenType: String("urn:ietf:params:oauth:token-type:saml2"),
|
TokenType: "urn:ietf:params:oauth:token-type:saml2",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user