feat: implements integration tests for the new advanced router

This commit is contained in:
niksis02
2025-07-18 01:21:50 +04:00
parent 394675a5a8
commit dc16c0448f
15 changed files with 289 additions and 122 deletions

View File

@@ -22,6 +22,7 @@ import (
"hash"
"io"
"io/fs"
"math"
"net/url"
"os"
"regexp"
@@ -113,7 +114,10 @@ func ParseObjectRange(size int64, acceptRange string) (int64, int64, bool, error
return 0, size, false, nil
}
startOffset, err := strconv.ParseInt(bRange[0], 10, 64)
startOffset, err := strconv.ParseInt(bRange[0], 10, strconv.IntSize)
if startOffset > int64(math.MaxInt) || startOffset < int64(math.MinInt) {
return 0, size, false, errInvalidRange
}
if err != nil && bRange[0] != "" {
return 0, size, false, nil
}
@@ -128,7 +132,10 @@ func ParseObjectRange(size int64, acceptRange string) (int64, int64, bool, error
return startOffset, size - startOffset, true, nil
}
endOffset, err := strconv.ParseInt(bRange[1], 10, 64)
endOffset, err := strconv.ParseInt(bRange[1], 10, strconv.IntSize)
if endOffset > int64(math.MaxInt) {
return 0, size, false, errInvalidRange
}
if err != nil {
return 0, size, false, nil
}

3
go.mod
View File

@@ -22,6 +22,7 @@ require (
github.com/pkg/xattr v0.4.12
github.com/segmentio/kafka-go v0.4.48
github.com/smira/go-statsd v1.3.4
github.com/stretchr/testify v1.10.0
github.com/urfave/cli/v2 v2.27.7
github.com/valyala/fasthttp v1.64.0
github.com/versity/scoutfs-go v0.0.0-20240325223134-38eb2f5f7d44
@@ -39,6 +40,7 @@ require (
github.com/aws/aws-sdk-go-v2/service/sso v1.25.6 // indirect
github.com/aws/aws-sdk-go-v2/service/ssooidc v1.30.4 // indirect
github.com/aws/aws-sdk-go-v2/service/sts v1.34.1 // indirect
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/go-asn1-ber/asn1-ber v1.5.8-0.20250403174932-29230038a667 // indirect
github.com/golang-jwt/jwt/v5 v5.2.3 // indirect
github.com/hashicorp/go-cleanhttp v0.5.2 // indirect
@@ -57,6 +59,7 @@ require (
golang.org/x/net v0.42.0 // indirect
golang.org/x/text v0.27.0 // indirect
golang.org/x/time v0.12.0 // indirect
gopkg.in/yaml.v3 v3.0.1 // indirect
)
require (

View File

@@ -15,13 +15,10 @@
package controllers
import (
"encoding/json"
"encoding/xml"
"fmt"
"net/http"
"strings"
"github.com/aws/aws-sdk-go-v2/service/s3/types"
"github.com/gofiber/fiber/v2"
"github.com/versity/versitygw/auth"
"github.com/versity/versitygw/backend"
@@ -149,25 +146,7 @@ func (c AdminController) ChangeBucketOwner(ctx *fiber.Ctx) (*Response, error) {
}, s3err.GetAPIError(s3err.ErrAdminUserNotFound)
}
acl := auth.ACL{
Owner: owner,
Grantees: []auth.Grantee{
{
Permission: auth.PermissionFullControl,
Access: owner,
Type: types.TypeCanonicalUser,
},
},
}
aclParsed, err := json.Marshal(acl)
if err != nil {
return &Response{
MetaOpts: &MetaOptions{},
}, fmt.Errorf("failed to marshal the bucket acl: %w", err)
}
err = c.be.ChangeBucketOwner(ctx.Context(), bucket, aclParsed)
err = c.be.ChangeBucketOwner(ctx.Context(), bucket, owner)
return &Response{
MetaOpts: &MetaOptions{},
}, err

View File

@@ -490,7 +490,7 @@ func TestAdminController_ChangeBucketOwner(t *testing.T) {
},
}
be := &BackendMock{
ChangeBucketOwnerFunc: func(contextMoqParam context.Context, bucket string, acl []byte) error {
ChangeBucketOwnerFunc: func(contextMoqParam context.Context, bucket, owner string) error {
return tt.input.beErr
},
}

View File

@@ -69,8 +69,10 @@ func New(be backend.Backend, iam auth.IAMService, logger s3log.AuditLogger, evs
}
// Returns MethodNotAllowed for unmatched routes
func (c S3ApiController) HandleUnmatch(ctx *fiber.Ctx) (*Response, error) {
return &Response{}, s3err.GetAPIError(s3err.ErrMethodNotAllowed)
func (c S3ApiController) HandleErrorRoute(err error) Controller {
return func(ctx *fiber.Ctx) (*Response, error) {
return &Response{}, err
}
}
// MetaOptions holds the metadata for metrics, audit logs and s3 events

View File

@@ -201,27 +201,30 @@ func TestNew(t *testing.T) {
}
}
func TestS3ApiController_HandleUnmatch(t *testing.T) {
func TestS3ApiController_HandleErrorRoute(t *testing.T) {
tests := []struct {
name string
input testInput
output testOutput
}{
{
name: "return method not allowed",
name: "should return the passed error",
input: testInput{
extraMockErr: s3err.GetAPIError(s3err.ErrAnonymousCreateMp),
},
output: testOutput{
response: &Response{},
err: s3err.GetAPIError(s3err.ErrMethodNotAllowed),
err: s3err.GetAPIError(s3err.ErrAnonymousCreateMp),
},
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
ctrl := S3ApiController{}
s3Ctrl := S3ApiController{}
ctrl := s3Ctrl.HandleErrorRoute(tt.input.extraMockErr)
testController(
t,
ctrl.HandleUnmatch,
ctrl,
tt.output.response,
tt.output.err,
ctxInputs{})

View File

@@ -15,6 +15,7 @@
package controllers
import (
"bytes"
"encoding/xml"
"fmt"
"io"
@@ -266,7 +267,7 @@ func (c S3ApiController) UploadPart(ctx *fiber.Ctx) (*Response, error) {
if bodyi != nil {
body = bodyi.(io.Reader)
} else {
body = ctx.Request().BodyStream()
body = bytes.NewReader([]byte{})
}
res, err := c.be.UploadPart(ctx.Context(),
@@ -690,7 +691,7 @@ func (c S3ApiController) PutObject(ctx *fiber.Ctx) (*Response, error) {
if bodyi != nil {
body = bodyi.(io.Reader)
} else {
body = ctx.Request().BodyStream()
body = bytes.NewReader([]byte{})
}
res, err := c.be.PutObject(ctx.Context(),

View File

@@ -15,44 +15,28 @@
package middlewares
import (
"net/http"
"github.com/gofiber/fiber/v2"
"github.com/versity/versitygw/metrics"
"github.com/versity/versitygw/s3api/utils"
"github.com/versity/versitygw/s3err"
"github.com/versity/versitygw/s3log"
)
// BucketObjectNameValidator extracts and validates
// the bucket and object names from the request URI.
func BucketObjectNameValidator(l s3log.AuditLogger, mm *metrics.Manager) fiber.Handler {
func BucketObjectNameValidator() fiber.Handler {
return func(ctx *fiber.Ctx) error {
// skip the check for admin apis
if ctx.Method() == http.MethodPatch {
return ctx.Next()
}
path := ctx.Path()
// skip the check if the operation isn't bucket/object scoped
// e.g ListBuckets
if path == "/" {
return ctx.Next()
}
bucket, object := parsePath(path)
bucket, object := parsePath(ctx.Path())
// check if the provided bucket name is valid
if !utils.IsValidBucketName(bucket) {
return sendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidBucketName), l, mm)
return s3err.GetAPIError(s3err.ErrInvalidBucketName)
}
// check if the provided object name is valid
// skip for empty objects: e.g bucket operations: HeadBucket...
if object != "" && !utils.IsObjectNameValid(object) {
return sendResponse(ctx, s3err.GetAPIError(s3err.ErrBadRequest), l, mm)
return s3err.GetAPIError(s3err.ErrBadRequest)
}
return ctx.Next()
return nil
}
}

View File

@@ -76,26 +76,10 @@ func AuthorizePublicBucketAccess(be backend.Backend, s3action string, policyPerm
if err != nil {
return err
}
}
} else {
utils.ContextKeyBodyReader.Set(ctx, ctx.Request().BodyStream())
}
if utils.IsBigDataAction(ctx) {
payloadType := ctx.Get("X-Amz-Content-Sha256")
if utils.IsUnsignedStreamingPayload(payloadType) {
checksumType, err := utils.ExtractChecksumType(ctx)
if err != nil {
return err
}
wrapBodyReader(ctx, func(r io.Reader) io.Reader {
var cr io.Reader
cr, err = utils.NewUnsignedChunkReader(r, checksumType)
return cr
})
if err != nil {
return err
}
}
}
utils.ContextKeyPublicBucket.Set(ctx, true)

View File

@@ -21,6 +21,7 @@ import (
"github.com/versity/versitygw/metrics"
"github.com/versity/versitygw/s3api/controllers"
"github.com/versity/versitygw/s3api/middlewares"
"github.com/versity/versitygw/s3err"
"github.com/versity/versitygw/s3event"
"github.com/versity/versitygw/s3log"
)
@@ -109,6 +110,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutBucketTagging,
metrics.ActionPutBucketTagging,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketTagging, auth.PutBucketTaggingAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -121,6 +123,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutBucketOwnershipControls,
metrics.ActionPutBucketOwnershipControls,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketOwnershipControls, auth.PutBucketOwnershipControlsAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -133,6 +136,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutBucketVersioning,
metrics.ActionPutBucketVersioning,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketVersioning, auth.PutBucketVersioningAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -145,6 +149,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutObjectLockConfiguration,
metrics.ActionPutObjectLockConfiguration,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutObjectLockConfiguration, auth.PutBucketObjectLockConfigurationAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -157,6 +162,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutBucketCors,
metrics.ActionPutBucketCors,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketCors, auth.PutBucketCorsAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -169,6 +175,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutBucketPolicy,
metrics.ActionPutBucketPolicy,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketPolicy, auth.PutBucketPolicyAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -181,6 +188,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutBucketAcl,
metrics.ActionPutBucketAcl,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutBucketAcl, auth.PutBucketAclAction, auth.PermissionWriteAcp),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -192,6 +200,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.CreateBucket,
metrics.ActionCreateBucket,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionCreateBucket, auth.CreateBucketAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -204,6 +213,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.HeadBucket,
metrics.ActionHeadBucket,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionHeadBucket, auth.ListBucketAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -218,6 +228,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteBucketTagging,
metrics.ActionDeleteBucketTagging,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucketTagging, auth.PutBucketTaggingAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -230,6 +241,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteBucketOwnershipControls,
metrics.ActionDeleteBucketOwnershipControls,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucketOwnershipControls, auth.PutBucketOwnershipControlsAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -242,6 +254,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteBucketPolicy,
metrics.ActionDeleteBucketPolicy,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucketPolicy, auth.PutBucketPolicyAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -254,6 +267,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteBucketCors,
metrics.ActionDeleteBucketCors,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucketCors, auth.PutBucketCorsAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -265,6 +279,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteBucket,
metrics.ActionDeleteBucket,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteBucket, auth.DeleteBucketAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -279,6 +294,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetBucketTagging,
metrics.ActionGetBucketTagging,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketTagging, auth.GetBucketTaggingAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -291,6 +307,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetBucketOwnershipControls,
metrics.ActionGetBucketOwnershipControls,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketOwnershipControls, auth.GetBucketOwnershipControlsAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -303,6 +320,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetBucketVersioning,
metrics.ActionGetBucketVersioning,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketVersioning, auth.GetBucketVersioningAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -315,6 +333,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetBucketPolicy,
metrics.ActionGetBucketPolicy,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketPolicy, auth.GetBucketPolicyAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -327,6 +346,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetBucketCors,
metrics.ActionGetBucketCors,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketCors, auth.GetBucketCorsAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -339,6 +359,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObjectLockConfiguration,
metrics.ActionGetObjectLockConfiguration,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObjectLockConfiguration, auth.GetBucketObjectLockConfigurationAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -351,6 +372,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetBucketAcl,
metrics.ActionGetBucketAcl,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetBucketAcl, auth.GetBucketAclAction, auth.PermissionReadAcp),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -363,6 +385,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.ListMultipartUploads,
metrics.ActionListMultipartUploads,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListMultipartUploads, auth.ListBucketMultipartUploadsAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -375,6 +398,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.ListObjectVersions,
metrics.ActionListObjectVersions,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListObjectVersions, auth.ListBucketVersionsAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -387,6 +411,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.ListObjectsV2,
metrics.ActionListObjectsV2,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListObjectsV2, auth.ListBucketAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -398,6 +423,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.ListObjects,
metrics.ActionListObjects,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListObjects, auth.ListBucketAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -412,6 +438,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteObjects,
metrics.ActionDeleteObjects,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteObjects, auth.DeleteObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -425,6 +452,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.HeadObject,
metrics.ActionHeadObject,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionHeadObject, auth.GetObjectAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -439,6 +467,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObjectTagging,
metrics.ActionGetObjectTagging,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObjectTagging, auth.GetObjectTaggingAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -451,6 +480,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObjectRetention,
metrics.ActionGetObjectRetention,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObjectRetention, auth.GetObjectRetentionAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -463,6 +493,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObjectLegalHold,
metrics.ActionGetObjectLegalHold,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObjectLegalHold, auth.GetObjectLegalHoldAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -475,6 +506,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObjectAcl,
metrics.ActionGetObjectAcl,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObjectAcl, auth.GetObjectAclAction, auth.PermissionReadAcp),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -487,6 +519,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObjectAttributes,
metrics.ActionGetObjectAttributes,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObjectAttributes, auth.GetObjectAttributesAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -499,6 +532,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.ListParts,
metrics.ActionListParts,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionListParts, auth.ListMultipartUploadPartsAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -510,6 +544,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.GetObject,
metrics.ActionGetObject,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionGetObject, auth.GetObjectAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -524,6 +559,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteObjectTagging,
metrics.ActionDeleteObjectTagging,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteObjectTagging, auth.DeleteObjectTaggingAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -536,6 +572,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.AbortMultipartUpload,
metrics.ActionAbortMultipartUpload,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionAbortMultipartUpload, auth.AbortMultipartUploadAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -547,6 +584,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.DeleteObject,
metrics.ActionDeleteObject,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionDeleteObject, auth.DeleteObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -560,6 +598,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.RestoreObject,
metrics.ActionRestoreObject,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionRestoreObject, auth.RestoreObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -573,6 +612,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.SelectObjectContent,
metrics.ActionSelectObjectContent,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionSelectObjectContent, auth.GetObjectAction, auth.PermissionRead),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -585,6 +625,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.CompleteMultipartUpload,
metrics.ActionCompleteMultipartUpload,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionCompleteMultipartUpload, auth.PutObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -597,6 +638,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.CreateMultipartUpload,
metrics.ActionCreateMultipartUpload,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionCreateMultipartUpload, auth.PutObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -611,6 +653,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutObjectTagging,
metrics.ActionPutObjectTagging,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutObjectTagging, auth.PutObjectTaggingAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -623,6 +666,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutObjectRetention,
metrics.ActionPutObjectRetention,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutObjectRetention, auth.PutObjectRetentionAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -635,6 +679,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutObjectLegalHold,
metrics.ActionPutObjectLegalHold,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutObjectLegalHold, auth.PutObjectLegalHoldAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -647,6 +692,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutObjectAcl,
metrics.ActionPutObjectAcl,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutObjectAcl, auth.PutObjectAclAction, auth.PermissionWriteAcp),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -660,6 +706,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.UploadPartCopy,
metrics.ActionUploadPartCopy,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionUploadPartCopy, auth.PutObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -672,18 +719,32 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.UploadPart,
metrics.ActionUploadPart,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionUploadPart, auth.PutObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
middlewares.VerifyMD5Body(),
middlewares.ParseAcl(be),
))
// return error if partNumber is used without uploadId
objectRouter.Put("",
middlewares.MatchQueryArgs("partNumber"),
controllers.ProcessHandlers(ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrMissingUploadId)), metrics.ActionUndetected, services))
// return 'MethodNotAllowed' if uploadId is provided without partNumber
// before the router reaches to 'PutObject'
objectRouter.Put("",
middlewares.MatchQueryArgs("uploadId"),
controllers.ProcessHandlers(ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrMethodNotAllowed)), metrics.ActionUndetected, services))
objectRouter.Put("",
middlewares.MatchHeader("X-Amz-Copy-Source"),
controllers.ProcessHandlers(
ctrl.CopyObject,
metrics.ActionCopyObject,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionCopyObject, auth.PutObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -695,6 +756,7 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
ctrl.PutObject,
metrics.ActionPutObject,
services,
middlewares.BucketObjectNameValidator(),
middlewares.AuthorizePublicBucketAccess(be, metrics.ActionPutObject, auth.PutObjectAction, auth.PermissionWrite),
middlewares.VerifyPresignedV4Signature(root, iam, region, debug),
middlewares.VerifyV4Signature(root, iam, region, debug),
@@ -703,5 +765,5 @@ func (sa *S3ApiRouter) Init(app *fiber.App, be backend.Backend, iam auth.IAMServ
))
// Return MethodNotAllowed for all the unmatched routes
app.All("*", controllers.ProcessHandlers(ctrl.HandleUnmatch, metrics.ActionUndetected, services))
app.All("*", controllers.ProcessHandlers(ctrl.HandleErrorRoute(s3err.GetAPIError(s3err.ErrMethodNotAllowed)), metrics.ActionUndetected, services))
}

View File

@@ -95,19 +95,7 @@ func New(
app.Use(middlewares.DebugLogger())
}
// initialize the bucket/object name validator
app.Use(middlewares.BucketObjectNameValidator(l, mm))
// Public buckets access checker
app.Use(middlewares.AuthorizePublicBucketAccess(be, l, mm))
// Authentication middlewares
app.Use(middlewares.VerifyPresignedV4Signature(root, iam, l, mm, region, server.debug))
app.Use(middlewares.VerifyV4Signature(root, iam, l, mm, region, server.debug))
app.Use(middlewares.VerifyMD5Body(l))
app.Use(middlewares.AclParser(be, l, server.readonly))
server.router.Init(app, be, iam, l, adminLogger, evs, mm, server.debug, server.readonly)
server.router.Init(app, be, iam, l, adminLogger, evs, mm, server.debug, server.readonly, region, root)
return server, nil
}

View File

@@ -168,6 +168,7 @@ const (
ErrInvalidChecksumHeader
ErrTrailerHeaderNotSupported
ErrBadRequest
ErrMissingUploadId
// Non-AWS errors
ErrExistingObjectIsDirectory
@@ -732,6 +733,11 @@ var errorCodeResponse = map[ErrorCode]APIError{
Description: "Bad Request",
HTTPStatusCode: http.StatusBadRequest,
},
ErrMissingUploadId: {
Code: "InvalidArgument",
Description: "This operation does not accept partNumber without uploadId",
HTTPStatusCode: http.StatusBadRequest,
},
// non aws errors
ErrExistingObjectIsDirectory: {

View File

@@ -637,6 +637,7 @@ func TestFullFlow(s *S3Conf) {
TestGetObjectLegalHold(s)
TestWORMProtection(s)
TestAccessControl(s)
TestRouter(s)
// FIXME: The tests should pass for azure as well
// but this issue should be fixed with https://github.com/versity/versitygw/issues/1336
if !s.azureTests {
@@ -652,6 +653,7 @@ func TestPosix(s *S3Conf) {
PutObject_overwrite_file_obj(s)
PutObject_overwrite_file_obj_with_nested_obj(s)
PutObject_dir_obj_with_data(s)
PutObject_with_slashes(s)
CreateMultipartUpload_dir_obj(s)
PutObject_name_too_long(s)
HeadObject_name_too_long(s)
@@ -749,6 +751,7 @@ func TestScoutfs(s *S3Conf) {
PutObject_overwrite_file_obj(s)
PutObject_overwrite_file_obj_with_nested_obj(s)
PutObject_dir_obj_with_data(s)
PutObject_with_slashes(s)
CreateMultipartUpload_dir_obj(s)
PutObject_name_too_long(s)
HeadObject_name_too_long(s)
@@ -872,6 +875,12 @@ func TestVersioningDisabled(s *S3Conf) {
VersioningDisabled_PutBucketVersioning_not_configured(s)
}
func TestRouter(s *S3Conf) {
RouterPutPartNumberWithoutUploadId(s)
RouterPostRoot(s)
RouterPostObjectWithoutQuery(s)
}
type IntTests map[string]func(s *S3Conf) error
func GetIntTests() IntTests {
@@ -1274,6 +1283,7 @@ func GetIntTests() IntTests {
"PutObject_overwrite_file_obj": PutObject_overwrite_file_obj,
"PutObject_overwrite_file_obj_with_nested_obj": PutObject_overwrite_file_obj_with_nested_obj,
"PutObject_dir_obj_with_data": PutObject_dir_obj_with_data,
"PutObject_with_slashes": PutObject_with_slashes,
"CreateMultipartUpload_dir_obj": CreateMultipartUpload_dir_obj,
"IAM_user_access_denied": IAM_user_access_denied,
"IAM_userplus_access_denied": IAM_userplus_access_denied,
@@ -1355,5 +1365,9 @@ func GetIntTests() IntTests {
"Versioning_WORM_obj_version_locked_with_governance_retention": Versioning_WORM_obj_version_locked_with_governance_retention,
"Versioning_WORM_obj_version_locked_with_compliance_retention": Versioning_WORM_obj_version_locked_with_compliance_retention,
"Versioning_concurrent_upload_object": Versioning_concurrent_upload_object,
"RouterPutPartNumberWithoutUploadId": RouterPutPartNumberWithoutUploadId,
"RouterPostRoot": RouterPostRoot,
"RouterPostObjectWithoutQuery": RouterPostObjectWithoutQuery,
"RouterPUTObjectOnlyUploadId": RouterPUTObjectOnlyUploadId,
}
}

View File

@@ -63,7 +63,7 @@ func Authentication_invalid_auth_header(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMissingFields)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMissingFields)); err != nil {
return err
}
@@ -89,7 +89,7 @@ func Authentication_unsupported_signature_version(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureVersionNotSupported)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureVersionNotSupported)); err != nil {
return err
}
@@ -116,7 +116,7 @@ func Authentication_malformed_credentials(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil {
return err
}
@@ -143,7 +143,7 @@ func Authentication_malformed_credentials_invalid_parts(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil {
return err
}
@@ -170,7 +170,7 @@ func Authentication_credentials_terminated_string(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureTerminationStr)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureTerminationStr)); err != nil {
return err
}
@@ -193,7 +193,7 @@ func Authentication_credentials_incorrect_service(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureIncorrService)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureIncorrService)); err != nil {
return err
}
@@ -227,7 +227,7 @@ func Authentication_credentials_incorrect_region(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, apiErr); err != nil {
if err := checkHTTPResponseApiErr(resp, apiErr); err != nil {
return err
}
@@ -254,7 +254,7 @@ func Authentication_credentials_invalid_date(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
return err
}
@@ -355,7 +355,7 @@ func Authentication_credentials_non_existing_access_key(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidAccessKeyID)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidAccessKeyID)); err != nil {
return err
}
@@ -382,7 +382,7 @@ func Authentication_invalid_signed_headers(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
return err
}
@@ -406,7 +406,7 @@ func Authentication_missing_date_header(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMissingDateHeader)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMissingDateHeader)); err != nil {
return err
}
@@ -430,7 +430,7 @@ func Authentication_invalid_date_header(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMalformedDate)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMalformedDate)); err != nil {
return err
}
@@ -454,7 +454,7 @@ func Authentication_date_mismatch(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
return err
}
@@ -478,7 +478,7 @@ func Authentication_incorrect_payload_hash(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrContentSHA256Mismatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrContentSHA256Mismatch)); err != nil {
return err
}
@@ -503,7 +503,7 @@ func Authentication_incorrect_md5(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidDigest)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidDigest)); err != nil {
return err
}
@@ -528,7 +528,7 @@ func Authentication_signature_error_incorrect_secret_key(s *S3Conf) error {
return err
}
defer resp.Body.Close()
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDoesNotMatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureDoesNotMatch)); err != nil {
return err
}
@@ -558,7 +558,7 @@ func PresignedAuth_unsupported_algorithm(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidQuerySignatureAlgo)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidQuerySignatureAlgo)); err != nil {
return err
}
@@ -595,7 +595,7 @@ func PresignedAuth_missing_credentials_query_param(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
return err
}
@@ -632,7 +632,7 @@ func PresignedAuth_malformed_creds_invalid_parts(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrCredMalformed)); err != nil {
return err
}
@@ -665,7 +665,7 @@ func PresignedAuth_creds_invalid_terminator(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureTerminationStr)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureTerminationStr)); err != nil {
return err
}
@@ -698,7 +698,7 @@ func PresignedAuth_creds_incorrect_service(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureIncorrService)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureIncorrService)); err != nil {
return err
}
@@ -736,7 +736,7 @@ func PresignedAuth_creds_incorrect_region(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.APIError{
if err := checkHTTPResponseApiErr(resp, s3err.APIError{
Code: "SignatureDoesNotMatch",
Description: fmt.Sprintf("Credential should be scoped to a valid Region, not %v", cfg.awsRegion),
HTTPStatusCode: http.StatusForbidden,
@@ -773,7 +773,7 @@ func PresignedAuth_creds_invalid_date(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
return err
}
@@ -806,7 +806,7 @@ func PresignedAuth_non_existing_access_key_id(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidAccessKeyID)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidAccessKeyID)); err != nil {
return err
}
@@ -843,7 +843,7 @@ func PresignedAuth_missing_date_query(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
return err
}
@@ -876,7 +876,7 @@ func PresignedAuth_dates_mismatch(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureDateDoesNotMatch)); err != nil {
return err
}
@@ -913,7 +913,7 @@ func PresignedAuth_missing_signed_headers_query_param(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
return err
}
@@ -950,7 +950,7 @@ func PresignedAuth_missing_expiration_query_param(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrInvalidQueryParams)); err != nil {
return err
}
@@ -987,7 +987,7 @@ func PresignedAuth_invalid_expiration_query_param(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMalformedExpires)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMalformedExpires)); err != nil {
return err
}
@@ -1024,7 +1024,7 @@ func PresignedAuth_negative_expiration_query_param(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrNegativeExpires)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrNegativeExpires)); err != nil {
return err
}
@@ -1061,7 +1061,7 @@ func PresignedAuth_exceeding_expiration_query_param(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrMaximumExpires)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMaximumExpires)); err != nil {
return err
}
@@ -1105,7 +1105,7 @@ func PresignedAuth_expired_request(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrExpiredPresignRequest)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrExpiredPresignRequest)); err != nil {
return err
}
@@ -1137,7 +1137,7 @@ func PresignedAuth_incorrect_secret_key(s *S3Conf) error {
return err
}
if err := checkAuthErr(resp, s3err.GetAPIError(s3err.ErrSignatureDoesNotMatch)); err != nil {
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrSignatureDoesNotMatch)); err != nil {
return err
}
@@ -17944,6 +17944,47 @@ func PutObject_dir_obj_with_data(s *S3Conf) error {
})
}
func PutObject_with_slashes(s *S3Conf) error {
testName := "PutObject_with_slashes"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
objs, err := putObjects(s3client, []string{
"/obj", "foo//bar", "/foo/baz/bar", "////////bar", "foo//////quxx",
}, bucket)
if err != nil {
return err
}
ctx, cancel := context.WithTimeout(context.Background(), shortTimeout)
res, err := s3client.ListObjectsV2(ctx, &s3.ListObjectsV2Input{
Bucket: &bucket,
})
cancel()
if err != nil {
return err
}
// it's en expected bahvior in posix to normalize the object pahts,
// by removing multiple slashes
normalizedObjs := []string{
"bar",
"foo/bar",
"foo/baz/bar",
"foo/quxx",
"obj",
}
for i := range objs {
objs[i].Key = &normalizedObjs[i]
}
if !compareObjects(objs, res.Contents) {
return fmt.Errorf("expected the objects to be %vß, instead got %v",
objStrings(objs), objStrings(res.Contents))
}
return nil
})
}
func CreateMultipartUpload_dir_obj(s *S3Conf) error {
testName := "CreateMultipartUpload_dir_obj"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
@@ -20827,3 +20868,96 @@ func Versioning_concurrent_upload_object(s *S3Conf) error {
return nil
}, withVersioning(types.BucketVersioningStatusEnabled))
}
// router tests
func RouterPutPartNumberWithoutUploadId(s *S3Conf) error {
testName := "RouterPutPartNumberWithoutUploadId"
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
req, err := http.NewRequest(http.MethodPut, s.endpoint+"/bucket/object", nil)
if err != nil {
return err
}
query := req.URL.Query()
query.Add("partNumber", "1")
req.URL.RawQuery = query.Encode()
resp, err := s.httpClient.Do(req)
if err != nil {
return err
}
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMissingUploadId)); err != nil {
return err
}
return nil
})
}
func RouterPostRoot(s *S3Conf) error {
testName := "RouterPostRoot"
return actionHandlerNoSetup(s, testName, func(s3client *s3.Client, bucket string) error {
req, err := http.NewRequest(http.MethodPost, s.endpoint+"/", nil)
if err != nil {
return err
}
resp, err := s.httpClient.Do(req)
if err != nil {
return err
}
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMethodNotAllowed)); err != nil {
return err
}
return nil
})
}
func RouterPostObjectWithoutQuery(s *S3Conf) error {
testName := "RouterPostObjectWithoutQuery"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
req, err := http.NewRequest(http.MethodPost, s.endpoint+"/bucket/object", nil)
if err != nil {
return err
}
resp, err := s.httpClient.Do(req)
if err != nil {
return err
}
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMethodNotAllowed)); err != nil {
return err
}
return nil
})
}
func RouterPUTObjectOnlyUploadId(s *S3Conf) error {
testName := "RouterPUTObjectOnlyUploadId"
return actionHandler(s, testName, func(s3client *s3.Client, bucket string) error {
req, err := http.NewRequest(http.MethodPut, s.endpoint+"/bucket/object", nil)
if err != nil {
return err
}
query := req.URL.Query()
query.Add("uploadId", "my-upload-id")
req.URL.RawQuery = query.Encode()
resp, err := s.httpClient.Do(req)
if err != nil {
return err
}
if err := checkHTTPResponseApiErr(resp, s3err.GetAPIError(s3err.ErrMethodNotAllowed)); err != nil {
return err
}
return nil
})
}

View File

@@ -334,7 +334,7 @@ func createSignedReq(method, endpoint, path, access, secret, service, region str
return req, nil
}
func checkAuthErr(resp *http.Response, apiErr s3err.APIError) error {
func checkHTTPResponseApiErr(resp *http.Response, apiErr s3err.APIError) error {
body, err := io.ReadAll(resp.Body)
if err != nil {
return err