59 lines
1.7 KiB
Go
59 lines
1.7 KiB
Go
package common
|
|
|
|
import (
|
|
"fmt"
|
|
"log"
|
|
"regexp"
|
|
|
|
"github.com/aws/aws-sdk-go/aws/awserr"
|
|
|
|
"github.com/aws/aws-sdk-go/aws"
|
|
"github.com/aws/aws-sdk-go/aws/request"
|
|
"github.com/aws/aws-sdk-go/aws/session"
|
|
"github.com/aws/aws-sdk-go/service/sts"
|
|
)
|
|
|
|
var encodedFailureMessagePattern = regexp.MustCompile(`(?i)(.*) Encoded authorization failure message: ([\w-]+) ?( .*)?`)
|
|
|
|
type stsDecoder interface {
|
|
DecodeAuthorizationMessage(input *sts.DecodeAuthorizationMessageInput) (*sts.DecodeAuthorizationMessageOutput, error)
|
|
}
|
|
|
|
// decodeError replaces encoded authorization messages with the
|
|
// decoded results
|
|
func decodeAWSError(decoder stsDecoder, err error) error {
|
|
|
|
groups := encodedFailureMessagePattern.FindStringSubmatch(err.Error())
|
|
if len(groups) > 1 {
|
|
result, decodeErr := decoder.DecodeAuthorizationMessage(&sts.DecodeAuthorizationMessageInput{
|
|
EncodedMessage: aws.String(groups[2]),
|
|
})
|
|
if decodeErr == nil {
|
|
msg := aws.StringValue(result.DecodedMessage)
|
|
return fmt.Errorf("%s Authorization failure message: '%s'%s", groups[1], msg, groups[3])
|
|
}
|
|
log.Printf("[WARN] Attempted to decode authorization message, but received: %v", decodeErr)
|
|
}
|
|
return err
|
|
}
|
|
|
|
// DecodeAuthZMessages enables automatic decoding of any
|
|
// encoded authorization messages
|
|
func DecodeAuthZMessages(sess *session.Session) {
|
|
azd := &authZMessageDecoder{
|
|
Decoder: sts.New(sess),
|
|
}
|
|
sess.Handlers.UnmarshalError.AfterEachFn = azd.afterEachFn
|
|
}
|
|
|
|
type authZMessageDecoder struct {
|
|
Decoder stsDecoder
|
|
}
|
|
|
|
func (a *authZMessageDecoder) afterEachFn(item request.HandlerListRunItem) bool {
|
|
if err, ok := item.Request.Error.(awserr.Error); ok && err.Code() == "UnauthorizedOperation" {
|
|
item.Request.Error = decodeAWSError(a.Decoder, err)
|
|
}
|
|
return true
|
|
}
|