[#339] Drop unused and add link to source files
Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
09ffe7287a
commit
d7a1cfe6a3
38 changed files with 74 additions and 725 deletions
|
@ -1,3 +1,7 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/credentials.go
|
||||||
|
// with changes:
|
||||||
|
// * use `time.Now()` instead of `sdk.NowTime()`
|
||||||
|
|
||||||
package v4a
|
package v4a
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/credentials_test.go
|
||||||
|
|
||||||
package v4a
|
package v4a
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import "fmt"
|
|
||||||
|
|
||||||
// SigningError indicates an error condition occurred while performing SigV4a signing
|
|
||||||
type SigningError struct {
|
|
||||||
Err error
|
|
||||||
}
|
|
||||||
|
|
||||||
func (e *SigningError) Error() string {
|
|
||||||
return fmt.Sprintf("failed to sign request: %v", e.Err)
|
|
||||||
}
|
|
||||||
|
|
||||||
// Unwrap returns the underlying error cause
|
|
||||||
func (e *SigningError) Unwrap() error {
|
|
||||||
return e.Err
|
|
||||||
}
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/crypto/compare.go
|
||||||
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import "fmt"
|
import "fmt"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/crypto/compare_test.go
|
||||||
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/crypto/ecc.go
|
||||||
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/crypto/ecc_test.go
|
||||||
|
|
||||||
package crypto
|
package crypto
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/const.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/header_rules.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/header.go
|
||||||
|
// with changes:
|
||||||
|
// * drop User-Agent header from ignored
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
// IgnoredPresignedHeaders is a list of headers that are ignored during signing
|
// IgnoredPresignedHeaders is a list of headers that are ignored during signing
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/hmac.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/host.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/time.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/util.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/internal/v4/tuil_test.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,118 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
|
||||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
|
||||||
"github.com/aws/smithy-go/middleware"
|
|
||||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HTTPSigner is SigV4a HTTP signer implementation
|
|
||||||
type HTTPSigner interface {
|
|
||||||
SignHTTP(ctx context.Context, credentials Credentials, r *http.Request, payloadHash string, service string, regionSet []string, signingTime time.Time, optfns ...func(*SignerOptions)) error
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignHTTPRequestMiddlewareOptions is the middleware options for constructing a SignHTTPRequestMiddleware.
|
|
||||||
type SignHTTPRequestMiddlewareOptions struct {
|
|
||||||
Credentials CredentialsProvider
|
|
||||||
Signer HTTPSigner
|
|
||||||
LogSigning bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignHTTPRequestMiddleware is a middleware for signing an HTTP request using SigV4a.
|
|
||||||
type SignHTTPRequestMiddleware struct {
|
|
||||||
credentials CredentialsProvider
|
|
||||||
signer HTTPSigner
|
|
||||||
logSigning bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewSignHTTPRequestMiddleware constructs a SignHTTPRequestMiddleware using the given SignHTTPRequestMiddlewareOptions.
|
|
||||||
func NewSignHTTPRequestMiddleware(options SignHTTPRequestMiddlewareOptions) *SignHTTPRequestMiddleware {
|
|
||||||
return &SignHTTPRequestMiddleware{
|
|
||||||
credentials: options.Credentials,
|
|
||||||
signer: options.Signer,
|
|
||||||
logSigning: options.LogSigning,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID the middleware identifier.
|
|
||||||
func (s *SignHTTPRequestMiddleware) ID() string {
|
|
||||||
return "Signing"
|
|
||||||
}
|
|
||||||
|
|
||||||
// HandleFinalize signs an HTTP request using SigV4a.
|
|
||||||
func (s *SignHTTPRequestMiddleware) HandleFinalize(
|
|
||||||
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
|
|
||||||
) (
|
|
||||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
|
||||||
) {
|
|
||||||
if !hasCredentialProvider(s.credentials) {
|
|
||||||
return next.HandleFinalize(ctx, in)
|
|
||||||
}
|
|
||||||
|
|
||||||
req, ok := in.Request.(*smithyhttp.Request)
|
|
||||||
if !ok {
|
|
||||||
return out, metadata, fmt.Errorf("unexpected request middleware type %T", in.Request)
|
|
||||||
}
|
|
||||||
|
|
||||||
signingName, signingRegion := awsmiddleware.GetSigningName(ctx), awsmiddleware.GetSigningRegion(ctx)
|
|
||||||
payloadHash := v4.GetPayloadHash(ctx)
|
|
||||||
if len(payloadHash) == 0 {
|
|
||||||
return out, metadata, &SigningError{Err: fmt.Errorf("computed payload hash missing from context")}
|
|
||||||
}
|
|
||||||
|
|
||||||
credentials, err := s.credentials.RetrievePrivateKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return out, metadata, &SigningError{Err: fmt.Errorf("failed to retrieve credentials: %w", err)}
|
|
||||||
}
|
|
||||||
|
|
||||||
signerOptions := []func(o *SignerOptions){
|
|
||||||
func(o *SignerOptions) {
|
|
||||||
o.Logger = middleware.GetLogger(ctx)
|
|
||||||
o.LogSigning = s.logSigning
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
// existing DisableURIPathEscaping is equivalent in purpose
|
|
||||||
// to authentication scheme property DisableDoubleEncoding
|
|
||||||
//disableDoubleEncoding, overridden := internalauth.GetDisableDoubleEncoding(ctx) // internalauth "github.com/aws/aws-sdk-go-v2/internal/auth"
|
|
||||||
//if overridden {
|
|
||||||
// signerOptions = append(signerOptions, func(o *SignerOptions) {
|
|
||||||
// o.DisableURIPathEscaping = disableDoubleEncoding
|
|
||||||
// })
|
|
||||||
//}
|
|
||||||
|
|
||||||
err = s.signer.SignHTTP(ctx, credentials, req.Request, payloadHash, signingName, []string{signingRegion}, time.Now().UTC(), signerOptions...)
|
|
||||||
if err != nil {
|
|
||||||
return out, metadata, &SigningError{Err: fmt.Errorf("failed to sign http request, %w", err)}
|
|
||||||
}
|
|
||||||
|
|
||||||
return next.HandleFinalize(ctx, in)
|
|
||||||
}
|
|
||||||
|
|
||||||
func hasCredentialProvider(p CredentialsProvider) bool {
|
|
||||||
if p == nil {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
// RegisterSigningMiddleware registers the SigV4a signing middleware to the stack. If a signing middleware is already
|
|
||||||
// present, this provided middleware will be swapped. Otherwise the middleware will be added at the tail of the
|
|
||||||
// finalize step.
|
|
||||||
func RegisterSigningMiddleware(stack *middleware.Stack, signingMiddleware *SignHTTPRequestMiddleware) (err error) {
|
|
||||||
const signedID = "Signing"
|
|
||||||
_, present := stack.Finalize.Get(signedID)
|
|
||||||
if present {
|
|
||||||
_, err = stack.Finalize.Swap(signedID, signingMiddleware)
|
|
||||||
} else {
|
|
||||||
err = stack.Finalize.Add(signingMiddleware, middleware.After)
|
|
||||||
}
|
|
||||||
return err
|
|
||||||
}
|
|
|
@ -1,149 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"errors"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
|
||||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
|
||||||
"github.com/aws/smithy-go/logging"
|
|
||||||
"github.com/aws/smithy-go/middleware"
|
|
||||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type stubCredentialsProviderFunc func(context.Context) (Credentials, error)
|
|
||||||
|
|
||||||
func (f stubCredentialsProviderFunc) RetrievePrivateKey(ctx context.Context) (Credentials, error) {
|
|
||||||
return f(ctx)
|
|
||||||
}
|
|
||||||
|
|
||||||
type httpSignerFunc func(ctx context.Context, credentials Credentials, r *http.Request, payloadHash string, service string, regionSet []string, signingTime time.Time, optFns ...func(*SignerOptions)) error
|
|
||||||
|
|
||||||
func (f httpSignerFunc) SignHTTP(ctx context.Context, credentials Credentials, r *http.Request, payloadHash string, service string, regionSet []string, signingTime time.Time, optFns ...func(*SignerOptions)) error {
|
|
||||||
return f(ctx, credentials, r, payloadHash, service, regionSet, signingTime, optFns...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSignHTTPRequestMiddleware(t *testing.T) {
|
|
||||||
cases := map[string]struct {
|
|
||||||
creds CredentialsProvider
|
|
||||||
hash string
|
|
||||||
logSigning bool
|
|
||||||
expectedErr interface{}
|
|
||||||
}{
|
|
||||||
"success": {
|
|
||||||
creds: stubCredentials,
|
|
||||||
hash: "0123456789abcdef",
|
|
||||||
},
|
|
||||||
"error": {
|
|
||||||
creds: stubCredentialsProviderFunc(func(ctx context.Context) (Credentials, error) {
|
|
||||||
return Credentials{}, fmt.Errorf("credential error")
|
|
||||||
}),
|
|
||||||
hash: "",
|
|
||||||
expectedErr: &SigningError{},
|
|
||||||
},
|
|
||||||
"nil creds": {
|
|
||||||
creds: nil,
|
|
||||||
},
|
|
||||||
"with log signing": {
|
|
||||||
creds: stubCredentials,
|
|
||||||
hash: "0123456789abcdef",
|
|
||||||
logSigning: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
signingName = "serviceId"
|
|
||||||
signingRegion = "regionName"
|
|
||||||
)
|
|
||||||
|
|
||||||
for name, tt := range cases {
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
c := &SignHTTPRequestMiddleware{
|
|
||||||
credentials: tt.creds,
|
|
||||||
signer: httpSignerFunc(
|
|
||||||
func(ctx context.Context,
|
|
||||||
credentials Credentials, r *http.Request, payloadHash string,
|
|
||||||
service string, regionSet []string, signingTime time.Time,
|
|
||||||
optFns ...func(*SignerOptions),
|
|
||||||
) error {
|
|
||||||
var options SignerOptions
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(&options)
|
|
||||||
}
|
|
||||||
if options.Logger == nil {
|
|
||||||
t.Errorf("expect logger, got none")
|
|
||||||
}
|
|
||||||
if options.LogSigning {
|
|
||||||
options.Logger.Logf(logging.Debug, t.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
expectCreds, _ := tt.creds.RetrievePrivateKey(ctx)
|
|
||||||
if diff := cmpDiff(expectCreds, credentials); len(diff) > 0 {
|
|
||||||
t.Error(diff)
|
|
||||||
}
|
|
||||||
if e, a := tt.hash, payloadHash; e != a {
|
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
|
||||||
}
|
|
||||||
if e, a := signingName, service; e != a {
|
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
|
||||||
}
|
|
||||||
if diff := cmpDiff([]string{signingRegion}, regionSet); len(diff) > 0 {
|
|
||||||
t.Error(diff)
|
|
||||||
}
|
|
||||||
return nil
|
|
||||||
}),
|
|
||||||
logSigning: tt.logSigning,
|
|
||||||
}
|
|
||||||
|
|
||||||
next := middleware.FinalizeHandlerFunc(func(ctx context.Context, in middleware.FinalizeInput) (out middleware.FinalizeOutput, metadata middleware.Metadata, err error) {
|
|
||||||
return out, metadata, err
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx := awsmiddleware.SetSigningRegion(
|
|
||||||
awsmiddleware.SetSigningName(context.Background(), signingName),
|
|
||||||
signingRegion)
|
|
||||||
|
|
||||||
var loggerBuf bytes.Buffer
|
|
||||||
logger := logging.NewStandardLogger(&loggerBuf)
|
|
||||||
ctx = middleware.SetLogger(ctx, logger)
|
|
||||||
|
|
||||||
if len(tt.hash) != 0 {
|
|
||||||
ctx = v4.SetPayloadHash(ctx, tt.hash)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, _, err := c.HandleFinalize(ctx, middleware.FinalizeInput{
|
|
||||||
Request: &smithyhttp.Request{Request: &http.Request{}},
|
|
||||||
}, next)
|
|
||||||
if err != nil && tt.expectedErr == nil {
|
|
||||||
t.Errorf("expected no error, got %v", err)
|
|
||||||
} else if err != nil && tt.expectedErr != nil {
|
|
||||||
e, a := tt.expectedErr, err
|
|
||||||
if !errors.As(a, &e) {
|
|
||||||
t.Errorf("expected error type %T, got %T", e, a)
|
|
||||||
}
|
|
||||||
} else if err == nil && tt.expectedErr != nil {
|
|
||||||
t.Errorf("expected error, got nil")
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.logSigning {
|
|
||||||
if e, a := t.Name(), loggerBuf.String(); !strings.Contains(a, e) {
|
|
||||||
t.Errorf("expect %v logged in %v", e, a)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if loggerBuf.Len() != 0 {
|
|
||||||
t.Errorf("expect no log, got %v", loggerBuf.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ middleware.FinalizeMiddleware = &SignHTTPRequestMiddleware{}
|
|
||||||
)
|
|
|
@ -1,116 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"net/http"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
|
||||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
|
||||||
"github.com/aws/smithy-go/middleware"
|
|
||||||
smithyHTTP "github.com/aws/smithy-go/transport/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// HTTPPresigner is an interface to a SigV4a signer that can sign create a
|
|
||||||
// presigned URL for a HTTP requests.
|
|
||||||
type HTTPPresigner interface {
|
|
||||||
PresignHTTP(
|
|
||||||
ctx context.Context, credentials Credentials, r *http.Request,
|
|
||||||
payloadHash string, service string, regionSet []string, signingTime time.Time,
|
|
||||||
optFns ...func(*SignerOptions),
|
|
||||||
) (url string, signedHeader http.Header, err error)
|
|
||||||
}
|
|
||||||
|
|
||||||
// PresignHTTPRequestMiddlewareOptions is the options for the PresignHTTPRequestMiddleware middleware.
|
|
||||||
type PresignHTTPRequestMiddlewareOptions struct {
|
|
||||||
CredentialsProvider CredentialsProvider
|
|
||||||
Presigner HTTPPresigner
|
|
||||||
LogSigning bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// PresignHTTPRequestMiddleware provides the Finalize middleware for creating a
|
|
||||||
// presigned URL for an HTTP request.
|
|
||||||
//
|
|
||||||
// Will short circuit the middleware stack and not forward onto the next
|
|
||||||
// Finalize handler.
|
|
||||||
type PresignHTTPRequestMiddleware struct {
|
|
||||||
credentialsProvider CredentialsProvider
|
|
||||||
presigner HTTPPresigner
|
|
||||||
logSigning bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewPresignHTTPRequestMiddleware returns a new PresignHTTPRequestMiddleware
|
|
||||||
// initialized with the presigner.
|
|
||||||
func NewPresignHTTPRequestMiddleware(options PresignHTTPRequestMiddlewareOptions) *PresignHTTPRequestMiddleware {
|
|
||||||
return &PresignHTTPRequestMiddleware{
|
|
||||||
credentialsProvider: options.CredentialsProvider,
|
|
||||||
presigner: options.Presigner,
|
|
||||||
logSigning: options.LogSigning,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ID provides the middleware ID.
|
|
||||||
func (*PresignHTTPRequestMiddleware) ID() string { return "PresignHTTPRequest" }
|
|
||||||
|
|
||||||
// HandleFinalize will take the provided input and create a presigned url for
|
|
||||||
// the http request using the SigV4 presign authentication scheme.
|
|
||||||
func (s *PresignHTTPRequestMiddleware) HandleFinalize(
|
|
||||||
ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler,
|
|
||||||
) (
|
|
||||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
|
||||||
) {
|
|
||||||
req, ok := in.Request.(*smithyHTTP.Request)
|
|
||||||
if !ok {
|
|
||||||
return out, metadata, &SigningError{
|
|
||||||
Err: fmt.Errorf("unexpected request middleware type %T", in.Request),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
httpReq := req.Build(ctx)
|
|
||||||
if !hasCredentialProvider(s.credentialsProvider) {
|
|
||||||
out.Result = &v4.PresignedHTTPRequest{
|
|
||||||
URL: httpReq.URL.String(),
|
|
||||||
Method: httpReq.Method,
|
|
||||||
SignedHeader: http.Header{},
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, metadata, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
signingName := awsmiddleware.GetSigningName(ctx)
|
|
||||||
signingRegion := awsmiddleware.GetSigningRegion(ctx)
|
|
||||||
payloadHash := v4.GetPayloadHash(ctx)
|
|
||||||
if len(payloadHash) == 0 {
|
|
||||||
return out, metadata, &SigningError{
|
|
||||||
Err: fmt.Errorf("computed payload hash missing from context"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
credentials, err := s.credentialsProvider.RetrievePrivateKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return out, metadata, &SigningError{
|
|
||||||
Err: fmt.Errorf("failed to retrieve credentials: %w", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
u, h, err := s.presigner.PresignHTTP(ctx, credentials,
|
|
||||||
httpReq, payloadHash, signingName, []string{signingRegion}, time.Now(),
|
|
||||||
func(o *SignerOptions) {
|
|
||||||
o.Logger = middleware.GetLogger(ctx)
|
|
||||||
o.LogSigning = s.logSigning
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return out, metadata, &SigningError{
|
|
||||||
Err: fmt.Errorf("failed to sign http request, %w", err),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
out.Result = &v4.PresignedHTTPRequest{
|
|
||||||
URL: u,
|
|
||||||
Method: httpReq.Method,
|
|
||||||
SignedHeader: h,
|
|
||||||
}
|
|
||||||
|
|
||||||
return out, metadata, nil
|
|
||||||
}
|
|
|
@ -1,222 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"net/http"
|
|
||||||
"net/url"
|
|
||||||
"strings"
|
|
||||||
"testing"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware"
|
|
||||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
|
||||||
"github.com/aws/smithy-go/logging"
|
|
||||||
"github.com/aws/smithy-go/middleware"
|
|
||||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
type httpPresignerFunc func(
|
|
||||||
ctx context.Context, credentials Credentials, r *http.Request,
|
|
||||||
payloadHash string, service string, regionSet []string, signingTime time.Time,
|
|
||||||
optFns ...func(*SignerOptions),
|
|
||||||
) (url string, signedHeader http.Header, err error)
|
|
||||||
|
|
||||||
func (f httpPresignerFunc) PresignHTTP(
|
|
||||||
ctx context.Context, credentials Credentials, r *http.Request,
|
|
||||||
payloadHash string, service string, regionSet []string, signingTime time.Time,
|
|
||||||
optFns ...func(*SignerOptions),
|
|
||||||
) (
|
|
||||||
url string, signedHeader http.Header, err error,
|
|
||||||
) {
|
|
||||||
return f(ctx, credentials, r, payloadHash, service, regionSet, signingTime, optFns...)
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPresignHTTPRequestMiddleware(t *testing.T) {
|
|
||||||
cases := map[string]struct {
|
|
||||||
Request *http.Request
|
|
||||||
Creds CredentialsProvider
|
|
||||||
PayloadHash string
|
|
||||||
LogSigning bool
|
|
||||||
ExpectResult *v4.PresignedHTTPRequest
|
|
||||||
ExpectErr string
|
|
||||||
}{
|
|
||||||
"success": {
|
|
||||||
Request: &http.Request{
|
|
||||||
URL: func() *url.URL {
|
|
||||||
u, _ := url.Parse("https://example.aws/path?query=foo")
|
|
||||||
return u
|
|
||||||
}(),
|
|
||||||
Header: http.Header{},
|
|
||||||
},
|
|
||||||
Creds: stubCredentials,
|
|
||||||
PayloadHash: "0123456789abcdef",
|
|
||||||
ExpectResult: &v4.PresignedHTTPRequest{
|
|
||||||
URL: "https://example.aws/path?query=foo",
|
|
||||||
SignedHeader: http.Header{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"error": {
|
|
||||||
Request: func() *http.Request {
|
|
||||||
return &http.Request{}
|
|
||||||
}(),
|
|
||||||
Creds: stubCredentials,
|
|
||||||
PayloadHash: "",
|
|
||||||
ExpectErr: "failed to sign request",
|
|
||||||
},
|
|
||||||
"anonymous creds": {
|
|
||||||
Request: &http.Request{
|
|
||||||
URL: func() *url.URL {
|
|
||||||
u, _ := url.Parse("https://example.aws/path?query=foo")
|
|
||||||
return u
|
|
||||||
}(),
|
|
||||||
Header: http.Header{},
|
|
||||||
},
|
|
||||||
Creds: stubCredentials,
|
|
||||||
PayloadHash: "",
|
|
||||||
ExpectErr: "failed to sign request",
|
|
||||||
ExpectResult: &v4.PresignedHTTPRequest{
|
|
||||||
URL: "https://example.aws/path?query=foo",
|
|
||||||
SignedHeader: http.Header{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"nil creds": {
|
|
||||||
Request: &http.Request{
|
|
||||||
URL: func() *url.URL {
|
|
||||||
u, _ := url.Parse("https://example.aws/path?query=foo")
|
|
||||||
return u
|
|
||||||
}(),
|
|
||||||
Header: http.Header{},
|
|
||||||
},
|
|
||||||
Creds: nil,
|
|
||||||
ExpectResult: &v4.PresignedHTTPRequest{
|
|
||||||
URL: "https://example.aws/path?query=foo",
|
|
||||||
SignedHeader: http.Header{},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
"with log signing": {
|
|
||||||
Request: &http.Request{
|
|
||||||
URL: func() *url.URL {
|
|
||||||
u, _ := url.Parse("https://example.aws/path?query=foo")
|
|
||||||
return u
|
|
||||||
}(),
|
|
||||||
Header: http.Header{},
|
|
||||||
},
|
|
||||||
Creds: stubCredentials,
|
|
||||||
PayloadHash: "0123456789abcdef",
|
|
||||||
ExpectResult: &v4.PresignedHTTPRequest{
|
|
||||||
URL: "https://example.aws/path?query=foo",
|
|
||||||
SignedHeader: http.Header{},
|
|
||||||
},
|
|
||||||
|
|
||||||
LogSigning: true,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
const (
|
|
||||||
signingName = "serviceId"
|
|
||||||
signingRegion = "regionName"
|
|
||||||
)
|
|
||||||
|
|
||||||
for name, tt := range cases {
|
|
||||||
t.Run(name, func(t *testing.T) {
|
|
||||||
m := &PresignHTTPRequestMiddleware{
|
|
||||||
credentialsProvider: tt.Creds,
|
|
||||||
|
|
||||||
presigner: httpPresignerFunc(func(
|
|
||||||
ctx context.Context, credentials Credentials, r *http.Request,
|
|
||||||
payloadHash string, service string, regionSet []string, signingTime time.Time,
|
|
||||||
optFns ...func(*SignerOptions),
|
|
||||||
) (url string, signedHeader http.Header, err error) {
|
|
||||||
var options SignerOptions
|
|
||||||
for _, fn := range optFns {
|
|
||||||
fn(&options)
|
|
||||||
}
|
|
||||||
if options.Logger == nil {
|
|
||||||
t.Errorf("expect logger, got none")
|
|
||||||
}
|
|
||||||
if options.LogSigning {
|
|
||||||
options.Logger.Logf(logging.Debug, t.Name())
|
|
||||||
}
|
|
||||||
|
|
||||||
if !hasCredentialProvider(tt.Creds) {
|
|
||||||
t.Errorf("expect presigner not to be called for not credentials provider")
|
|
||||||
}
|
|
||||||
|
|
||||||
expectCreds, _ := tt.Creds.RetrievePrivateKey(context.Background())
|
|
||||||
if diff := cmpDiff(expectCreds, credentials); len(diff) > 0 {
|
|
||||||
t.Error(diff)
|
|
||||||
}
|
|
||||||
if e, a := tt.PayloadHash, payloadHash; e != a {
|
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
|
||||||
}
|
|
||||||
if e, a := signingName, service; e != a {
|
|
||||||
t.Errorf("expected %v, got %v", e, a)
|
|
||||||
}
|
|
||||||
if diff := cmpDiff([]string{signingRegion}, regionSet); len(diff) > 0 {
|
|
||||||
t.Error(diff)
|
|
||||||
}
|
|
||||||
|
|
||||||
return tt.ExpectResult.URL, tt.ExpectResult.SignedHeader, nil
|
|
||||||
}),
|
|
||||||
logSigning: tt.LogSigning,
|
|
||||||
}
|
|
||||||
|
|
||||||
next := middleware.FinalizeHandlerFunc(
|
|
||||||
func(ctx context.Context, in middleware.FinalizeInput) (
|
|
||||||
out middleware.FinalizeOutput, metadata middleware.Metadata, err error,
|
|
||||||
) {
|
|
||||||
t.Errorf("expect next handler not to be called")
|
|
||||||
return out, metadata, err
|
|
||||||
})
|
|
||||||
|
|
||||||
ctx := awsmiddleware.SetSigningRegion(
|
|
||||||
awsmiddleware.SetSigningName(context.Background(), signingName),
|
|
||||||
signingRegion)
|
|
||||||
|
|
||||||
var loggerBuf bytes.Buffer
|
|
||||||
logger := logging.NewStandardLogger(&loggerBuf)
|
|
||||||
ctx = middleware.SetLogger(ctx, logger)
|
|
||||||
|
|
||||||
if len(tt.PayloadHash) != 0 {
|
|
||||||
ctx = v4.SetPayloadHash(ctx, tt.PayloadHash)
|
|
||||||
}
|
|
||||||
|
|
||||||
result, _, err := m.HandleFinalize(ctx, middleware.FinalizeInput{
|
|
||||||
Request: &smithyhttp.Request{
|
|
||||||
Request: tt.Request,
|
|
||||||
},
|
|
||||||
}, next)
|
|
||||||
if len(tt.ExpectErr) != 0 {
|
|
||||||
if err == nil {
|
|
||||||
t.Fatalf("expect error, got none")
|
|
||||||
}
|
|
||||||
if e, a := tt.ExpectErr, err.Error(); !strings.Contains(a, e) {
|
|
||||||
t.Fatalf("expect error to contain %v, got %v", e, a)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("expect no error, got %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if diff := cmpDiff(tt.ExpectResult, result.Result); len(diff) != 0 {
|
|
||||||
t.Errorf("expect result match\n%v", diff)
|
|
||||||
}
|
|
||||||
|
|
||||||
if tt.LogSigning {
|
|
||||||
if e, a := t.Name(), loggerBuf.String(); !strings.Contains(a, e) {
|
|
||||||
t.Errorf("expect %v logged in %v", e, a)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if loggerBuf.Len() != 0 {
|
|
||||||
t.Errorf("expect no log, got %v", loggerBuf.String())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
_ middleware.FinalizeMiddleware = &PresignHTTPRequestMiddleware{}
|
|
||||||
)
|
|
|
@ -1,18 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytes"
|
|
||||||
"context"
|
|
||||||
"crypto/ecdsa"
|
|
||||||
)
|
|
||||||
|
|
||||||
var stubCredentials = stubCredentialsProviderFunc(func(ctx context.Context) (Credentials, error) {
|
|
||||||
stubKey, err := ecdsa.GenerateKey(p256, bytes.NewReader(bytes.Repeat([]byte{1}, 40)))
|
|
||||||
if err != nil {
|
|
||||||
return Credentials{}, err
|
|
||||||
}
|
|
||||||
return Credentials{
|
|
||||||
Context: "STUB",
|
|
||||||
PrivateKey: stubKey,
|
|
||||||
}, nil
|
|
||||||
})
|
|
|
@ -1,85 +0,0 @@
|
||||||
package v4a
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"fmt"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
v4 "github.com/aws/aws-sdk-go-v2/aws/signer/v4"
|
|
||||||
"github.com/aws/smithy-go"
|
|
||||||
"github.com/aws/smithy-go/auth"
|
|
||||||
"github.com/aws/smithy-go/logging"
|
|
||||||
smithyhttp "github.com/aws/smithy-go/transport/http"
|
|
||||||
)
|
|
||||||
|
|
||||||
// CredentialsAdapter adapts v4a.Credentials to smithy auth.Identity.
|
|
||||||
type CredentialsAdapter struct {
|
|
||||||
Credentials Credentials
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ auth.Identity = (*CredentialsAdapter)(nil)
|
|
||||||
|
|
||||||
// Expiration returns the time of expiration for the credentials.
|
|
||||||
func (v *CredentialsAdapter) Expiration() time.Time {
|
|
||||||
return v.Credentials.Expires
|
|
||||||
}
|
|
||||||
|
|
||||||
// CredentialsProviderAdapter adapts v4a.CredentialsProvider to
|
|
||||||
// auth.IdentityResolver.
|
|
||||||
type CredentialsProviderAdapter struct {
|
|
||||||
Provider CredentialsProvider
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ (auth.IdentityResolver) = (*CredentialsProviderAdapter)(nil)
|
|
||||||
|
|
||||||
// GetIdentity retrieves v4a credentials using the underlying provider.
|
|
||||||
func (v *CredentialsProviderAdapter) GetIdentity(ctx context.Context, _ smithy.Properties) (
|
|
||||||
auth.Identity, error,
|
|
||||||
) {
|
|
||||||
creds, err := v.Provider.RetrievePrivateKey(ctx)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("get credentials: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return &CredentialsAdapter{Credentials: creds}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// SignerAdapter adapts v4a.HTTPSigner to smithy http.Signer.
|
|
||||||
type SignerAdapter struct {
|
|
||||||
Signer HTTPSigner
|
|
||||||
Logger logging.Logger
|
|
||||||
LogSigning bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var _ (smithyhttp.Signer) = (*SignerAdapter)(nil)
|
|
||||||
|
|
||||||
// SignRequest signs the request with the provided identity.
|
|
||||||
func (v *SignerAdapter) SignRequest(ctx context.Context, r *smithyhttp.Request, identity auth.Identity, props smithy.Properties) error {
|
|
||||||
ca, ok := identity.(*CredentialsAdapter)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("unexpected identity type: %T", identity)
|
|
||||||
}
|
|
||||||
|
|
||||||
name, ok := smithyhttp.GetSigV4SigningName(&props)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("sigv4a signing name is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
regions, ok := smithyhttp.GetSigV4ASigningRegions(&props)
|
|
||||||
if !ok {
|
|
||||||
return fmt.Errorf("sigv4a signing region is required")
|
|
||||||
}
|
|
||||||
|
|
||||||
hash := v4.GetPayloadHash(ctx)
|
|
||||||
err := v.Signer.SignHTTP(ctx, ca.Credentials, r.Request, hash, name, regions, time.Now(), func(o *SignerOptions) {
|
|
||||||
o.DisableURIPathEscaping, _ = smithyhttp.GetDisableDoubleEncoding(&props)
|
|
||||||
|
|
||||||
o.Logger = v.Logger
|
|
||||||
o.LogSigning = v.LogSigning
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return fmt.Errorf("sign http: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is adopting https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/v4/stream.go for sigv4a.
|
||||||
|
|
||||||
package v4a
|
package v4a
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,9 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/v4a.go
|
||||||
|
// with changes:
|
||||||
|
// * adding exported VerifySignature methods
|
||||||
|
// * using different ignore headers for sing/presign requests
|
||||||
|
// * don't duplicate content-length as signed header
|
||||||
|
|
||||||
package v4a
|
package v4a
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This file is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/internal/v4a/v4a_test.go
|
||||||
|
|
||||||
package v4a
|
package v4a
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/cache.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/const.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
// Signature Version 4 (SigV4) Constants
|
// Signature Version 4 (SigV4) Constants
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/header_rules.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/header.go
|
||||||
|
// with changes:
|
||||||
|
// * drop User-Agent header from ignored
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
// IgnoredPresignedHeaders is a list of headers that are ignored during signing
|
// IgnoredPresignedHeaders is a list of headers that are ignored during signing
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/header_test.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import "testing"
|
import "testing"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/hmac.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/host.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/scope.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import "strings"
|
import "strings"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/time.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import "time"
|
import "time"
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/util.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/internal/v4/util_test.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/v4/stream.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/v4/v4.go
|
||||||
|
// with changes:
|
||||||
|
// * using different headers for sign/presign
|
||||||
|
|
||||||
// Package v4 implements the AWS signature version 4 algorithm (commonly known
|
// Package v4 implements the AWS signature version 4 algorithm (commonly known
|
||||||
// as SigV4).
|
// as SigV4).
|
||||||
//
|
//
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
|
// This is https://github.com/aws/aws-sdk-go-v2/blob/a2b751d1ba71f59175a41f9cae5f159f1044360f/aws/signer/v4/v4_test.go
|
||||||
|
|
||||||
package v4
|
package v4
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
|
Loading…
Reference in a new issue