mirror of
https://github.com/versity/versitygw.git
synced 2026-09-26 09:54:49 +00:00
fix: fixed merge conflicts
This commit is contained in:
@@ -18,7 +18,7 @@ import (
|
||||
"fmt"
|
||||
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/versity/versitygw/backend/auth"
|
||||
"github.com/versity/versitygw/auth"
|
||||
)
|
||||
|
||||
type AdminController struct {
|
||||
@@ -26,16 +26,16 @@ type AdminController struct {
|
||||
}
|
||||
|
||||
func (c AdminController) CreateUser(ctx *fiber.Ctx) error {
|
||||
access, secret, role, region := ctx.Query("access"), ctx.Query("secret"), ctx.Query("role"), ctx.Query("region")
|
||||
access, secret, role := ctx.Query("access"), ctx.Query("secret"), ctx.Query("role")
|
||||
requesterRole := ctx.Locals("role")
|
||||
|
||||
if requesterRole != "admin" {
|
||||
return fmt.Errorf("access denied: only admin users have access to this resource")
|
||||
}
|
||||
|
||||
user := auth.Account{Secret: secret, Role: role, Region: region}
|
||||
user := auth.Account{Secret: secret, Role: role}
|
||||
|
||||
err := c.IAMService.CreateAccount(access, &user)
|
||||
err := c.IAMService.CreateAccount(access, user)
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to create a user: %w", err)
|
||||
}
|
||||
|
||||
@@ -7,7 +7,6 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3/types"
|
||||
"github.com/versity/versitygw/backend"
|
||||
"github.com/versity/versitygw/backend/auth"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
"io"
|
||||
"sync"
|
||||
@@ -47,7 +46,7 @@ var _ backend.Backend = &BackendMock{}
|
||||
// DeleteObjectsFunc: func(bucket string, objects *s3.DeleteObjectsInput) error {
|
||||
// panic("mock out the DeleteObjects method")
|
||||
// },
|
||||
// GetBucketAclFunc: func(bucket string) (*auth.GetBucketAclOutput, error) {
|
||||
// GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
// panic("mock out the GetBucketAcl method")
|
||||
// },
|
||||
// GetObjectFunc: func(bucket string, object string, acceptRange string, writer io.Writer) (*s3.GetObjectOutput, error) {
|
||||
@@ -86,7 +85,7 @@ var _ backend.Backend = &BackendMock{}
|
||||
// PutBucketFunc: func(bucket string, owner string) error {
|
||||
// panic("mock out the PutBucket method")
|
||||
// },
|
||||
// PutBucketAclFunc: func(putBucketAclInput *s3.PutBucketAclInput) error {
|
||||
// PutBucketAclFunc: func(bucket string, data []byte) error {
|
||||
// panic("mock out the PutBucketAcl method")
|
||||
// },
|
||||
// PutObjectFunc: func(putObjectInput *s3.PutObjectInput) (string, error) {
|
||||
@@ -148,7 +147,7 @@ type BackendMock struct {
|
||||
DeleteObjectsFunc func(bucket string, objects *s3.DeleteObjectsInput) error
|
||||
|
||||
// GetBucketAclFunc mocks the GetBucketAcl method.
|
||||
GetBucketAclFunc func(bucket string) (*auth.GetBucketAclOutput, error)
|
||||
GetBucketAclFunc func(bucket string) ([]byte, error)
|
||||
|
||||
// GetObjectFunc mocks the GetObject method.
|
||||
GetObjectFunc func(bucket string, object string, acceptRange string, writer io.Writer) (*s3.GetObjectOutput, error)
|
||||
@@ -187,7 +186,7 @@ type BackendMock struct {
|
||||
PutBucketFunc func(bucket string, owner string) error
|
||||
|
||||
// PutBucketAclFunc mocks the PutBucketAcl method.
|
||||
PutBucketAclFunc func(putBucketAclInput *s3.PutBucketAclInput) error
|
||||
PutBucketAclFunc func(bucket string, data []byte) error
|
||||
|
||||
// PutObjectFunc mocks the PutObject method.
|
||||
PutObjectFunc func(putObjectInput *s3.PutObjectInput) (string, error)
|
||||
@@ -391,8 +390,10 @@ type BackendMock struct {
|
||||
}
|
||||
// PutBucketAcl holds details about calls to the PutBucketAcl method.
|
||||
PutBucketAcl []struct {
|
||||
// PutBucketAclInput is the putBucketAclInput argument value.
|
||||
PutBucketAclInput *s3.PutBucketAclInput
|
||||
// Bucket is the bucket argument value.
|
||||
Bucket string
|
||||
// Data is the data argument value.
|
||||
Data []byte
|
||||
}
|
||||
// PutObject holds details about calls to the PutObject method.
|
||||
PutObject []struct {
|
||||
@@ -798,7 +799,7 @@ func (mock *BackendMock) DeleteObjectsCalls() []struct {
|
||||
}
|
||||
|
||||
// GetBucketAcl calls GetBucketAclFunc.
|
||||
func (mock *BackendMock) GetBucketAcl(bucket string) (*auth.GetBucketAclOutput, error) {
|
||||
func (mock *BackendMock) GetBucketAcl(bucket string) ([]byte, error) {
|
||||
if mock.GetBucketAclFunc == nil {
|
||||
panic("BackendMock.GetBucketAclFunc: method is nil but Backend.GetBucketAcl was just called")
|
||||
}
|
||||
@@ -1293,19 +1294,21 @@ func (mock *BackendMock) PutBucketCalls() []struct {
|
||||
}
|
||||
|
||||
// PutBucketAcl calls PutBucketAclFunc.
|
||||
func (mock *BackendMock) PutBucketAcl(putBucketAclInput *s3.PutBucketAclInput) error {
|
||||
func (mock *BackendMock) PutBucketAcl(bucket string, data []byte) error {
|
||||
if mock.PutBucketAclFunc == nil {
|
||||
panic("BackendMock.PutBucketAclFunc: method is nil but Backend.PutBucketAcl was just called")
|
||||
}
|
||||
callInfo := struct {
|
||||
PutBucketAclInput *s3.PutBucketAclInput
|
||||
Bucket string
|
||||
Data []byte
|
||||
}{
|
||||
PutBucketAclInput: putBucketAclInput,
|
||||
Bucket: bucket,
|
||||
Data: data,
|
||||
}
|
||||
mock.lockPutBucketAcl.Lock()
|
||||
mock.calls.PutBucketAcl = append(mock.calls.PutBucketAcl, callInfo)
|
||||
mock.lockPutBucketAcl.Unlock()
|
||||
return mock.PutBucketAclFunc(putBucketAclInput)
|
||||
return mock.PutBucketAclFunc(bucket, data)
|
||||
}
|
||||
|
||||
// PutBucketAclCalls gets all the calls that were made to PutBucketAcl.
|
||||
@@ -1313,10 +1316,12 @@ func (mock *BackendMock) PutBucketAcl(putBucketAclInput *s3.PutBucketAclInput) e
|
||||
//
|
||||
// len(mockedBackend.PutBucketAclCalls())
|
||||
func (mock *BackendMock) PutBucketAclCalls() []struct {
|
||||
PutBucketAclInput *s3.PutBucketAclInput
|
||||
Bucket string
|
||||
Data []byte
|
||||
} {
|
||||
var calls []struct {
|
||||
PutBucketAclInput *s3.PutBucketAclInput
|
||||
Bucket string
|
||||
Data []byte
|
||||
}
|
||||
mock.lockPutBucketAcl.RLock()
|
||||
calls = mock.calls.PutBucketAcl
|
||||
|
||||
+138
-33
@@ -29,24 +29,24 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"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"
|
||||
"github.com/versity/versitygw/backend/auth"
|
||||
"github.com/versity/versitygw/s3api/utils"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
)
|
||||
|
||||
type S3ApiController struct {
|
||||
be backend.Backend
|
||||
acl auth.ACLService
|
||||
iam auth.IAMService
|
||||
}
|
||||
|
||||
func New(be backend.Backend) S3ApiController {
|
||||
return S3ApiController{be: be, acl: auth.ACLServiceUnsupported{}}
|
||||
return S3ApiController{be: be}
|
||||
}
|
||||
|
||||
func (c S3ApiController) ListBuckets(ctx *fiber.Ctx) error {
|
||||
access, isRoot := ctx.Locals("access").(string), ctx.Locals("isRoot").(bool)
|
||||
if err := c.acl.IsAdmin(access, isRoot); err != nil {
|
||||
if err := auth.IsAdmin(access, isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
res, err := c.be.ListBuckets()
|
||||
@@ -67,6 +67,16 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
|
||||
key = strings.Join([]string{key, keyEnd}, "/")
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if uploadId != "" {
|
||||
if maxParts < 0 || (maxParts == 0 && ctx.Query("max-parts") != "") {
|
||||
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidMaxParts))
|
||||
@@ -75,7 +85,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
|
||||
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidPartNumberMarker))
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
|
||||
@@ -84,7 +94,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if ctx.Request().URI().QueryArgs().Has("acl") {
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ_ACP", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ_ACP", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
res, err := c.be.GetObjectAcl(bucket, key)
|
||||
@@ -92,14 +102,14 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if attrs := ctx.Get("X-Amz-Object-Attributes"); attrs != "" {
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
res, err := c.be.GetObjectAttributes(bucket, key, strings.Split(attrs, ","))
|
||||
return SendXMLResponse(ctx, res, err)
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ_ACP", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ_ACP", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -157,16 +167,27 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error {
|
||||
access := ctx.Locals("access").(string)
|
||||
isRoot := ctx.Locals("isRoot").(bool)
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if ctx.Request().URI().QueryArgs().Has("acl") {
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ_ACP", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ_ACP", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
res, err := c.be.GetBucketAcl(ctx.Params("bucket"))
|
||||
|
||||
res, err := auth.ParseACLOutput(data)
|
||||
return SendXMLResponse(ctx, res, err)
|
||||
}
|
||||
|
||||
if ctx.Request().URI().QueryArgs().Has("uploads") {
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
res, err := c.be.ListMultipartUploads(&s3.ListMultipartUploadsInput{Bucket: aws.String(ctx.Params("bucket"))})
|
||||
@@ -174,14 +195,14 @@ func (c S3ApiController) ListActions(ctx *fiber.Ctx) error {
|
||||
}
|
||||
|
||||
if ctx.QueryInt("list-type") == 2 {
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
res, err := c.be.ListObjectsV2(bucket, prefix, marker, delimiter, maxkeys)
|
||||
return SendXMLResponse(ctx, res, err)
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
|
||||
@@ -212,11 +233,21 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error {
|
||||
return errors.New("wrong api call")
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE_ACP", isRoot); err != nil {
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
err := c.be.PutBucketAcl(&s3.PutBucketAclInput{
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE_ACP", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
input := &s3.PutBucketAclInput{
|
||||
Bucket: &bucket,
|
||||
ACL: types.BucketCannedACL(acl),
|
||||
GrantFullControl: &grantFullControl,
|
||||
@@ -225,8 +256,9 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error {
|
||||
GrantWrite: &granWrite,
|
||||
GrantWriteACP: &grantWriteACP,
|
||||
AccessControlPolicy: &types.AccessControlPolicy{Owner: &types.Owner{ID: &access}},
|
||||
})
|
||||
}
|
||||
|
||||
err = auth.UpdateACL(input, parsedAcl, c.iam)
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -280,13 +312,23 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
|
||||
}
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if uploadId != "" && partNumberStr != "" {
|
||||
partNumber := ctx.QueryInt("partNumber", -1)
|
||||
if partNumber < 1 {
|
||||
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidPart))
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -302,7 +344,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
|
||||
return errors.New("wrong api call")
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE_ACP", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE_ACP", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -325,7 +367,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
|
||||
copySourceSplit := strings.Split(copySource, "/")
|
||||
srcBucket, srcObject := copySourceSplit[0], copySourceSplit[1:]
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
|
||||
@@ -335,7 +377,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
|
||||
|
||||
metadata := utils.GetUserMetaData(&ctx.Request().Header)
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -352,10 +394,22 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
|
||||
|
||||
func (c S3ApiController) DeleteBucket(ctx *fiber.Ctx) error {
|
||||
bucket, access, isRoot := ctx.Params("bucket"), ctx.Locals("access").(string), ctx.Locals("isRoot").(bool)
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
err := c.be.DeleteBucket(bucket)
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
err = c.be.DeleteBucket(bucket)
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -367,11 +421,21 @@ func (c S3ApiController) DeleteObjects(ctx *fiber.Ctx) error {
|
||||
return errors.New("wrong api call")
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
err := c.be.DeleteObjects(bucket, &s3.DeleteObjectsInput{Delete: &dObj})
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
err = c.be.DeleteObjects(bucket, &s3.DeleteObjectsInput{Delete: &dObj})
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -387,10 +451,20 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error {
|
||||
key = strings.Join([]string{key, keyEnd}, "/")
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if uploadId != "" {
|
||||
expectedBucketOwner, requestPayer := ctx.Get("X-Amz-Expected-Bucket-Owner"), ctx.Get("X-Amz-Request-Payer")
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -404,21 +478,32 @@ func (c S3ApiController) DeleteActions(ctx *fiber.Ctx) error {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
err := c.be.DeleteObject(bucket, key)
|
||||
err = c.be.DeleteObject(bucket, key)
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
func (c S3ApiController) HeadBucket(ctx *fiber.Ctx) error {
|
||||
bucket, access, isRoot := ctx.Params("bucket"), ctx.Locals("access").(string), ctx.Locals("isRoot").(bool)
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
_, err := c.be.HeadBucket(bucket)
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
_, err = c.be.HeadBucket(bucket)
|
||||
// TODO: set bucket response headers
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
@@ -435,7 +520,17 @@ func (c S3ApiController) HeadObject(ctx *fiber.Ctx) error {
|
||||
key = strings.Join([]string{key, keyEnd}, "/")
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "READ", isRoot); err != nil {
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "READ", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -490,6 +585,16 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error {
|
||||
key = strings.Join([]string{key, keyEnd}, "/")
|
||||
}
|
||||
|
||||
data, err := c.be.GetBucketAcl(bucket)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
parsedAcl, err := auth.ParseACL(data)
|
||||
if err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
var restoreRequest s3.RestoreObjectInput
|
||||
if ctx.Request().URI().QueryArgs().Has("restore") {
|
||||
xmlErr := xml.Unmarshal(ctx.Body(), &restoreRequest)
|
||||
@@ -497,7 +602,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error {
|
||||
return errors.New("wrong api call")
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendResponse(ctx, err)
|
||||
}
|
||||
|
||||
@@ -514,7 +619,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error {
|
||||
return errors.New("wrong api call")
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
|
||||
@@ -522,7 +627,7 @@ func (c S3ApiController) CreateActions(ctx *fiber.Ctx) error {
|
||||
return SendXMLResponse(ctx, res, err)
|
||||
}
|
||||
|
||||
if err := c.acl.VerifyACL(bucket, access, "WRITE", isRoot); err != nil {
|
||||
if err := auth.VerifyACL(parsedAcl, bucket, access, "WRITE", isRoot); err != nil {
|
||||
return SendXMLResponse(ctx, nil, err)
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@
|
||||
package controllers
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"io"
|
||||
"net/http"
|
||||
"net/http/httptest"
|
||||
@@ -26,19 +27,31 @@ import (
|
||||
"github.com/aws/aws-sdk-go-v2/service/s3"
|
||||
"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"
|
||||
"github.com/versity/versitygw/backend/auth"
|
||||
"github.com/versity/versitygw/s3err"
|
||||
"github.com/versity/versitygw/s3response"
|
||||
)
|
||||
|
||||
var (
|
||||
acl auth.ACL
|
||||
acldata []byte
|
||||
)
|
||||
|
||||
func init() {
|
||||
var err error
|
||||
acldata, err = json.Marshal(acl)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestNew(t *testing.T) {
|
||||
type args struct {
|
||||
be backend.Backend
|
||||
}
|
||||
|
||||
be := backend.BackendUnsupported{}
|
||||
acl := auth.ACLServiceUnsupported{}
|
||||
|
||||
tests := []struct {
|
||||
name string
|
||||
@@ -51,8 +64,7 @@ func TestNew(t *testing.T) {
|
||||
be: be,
|
||||
},
|
||||
want: S3ApiController{
|
||||
be: be,
|
||||
acl: acl,
|
||||
be: be,
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -73,11 +85,13 @@ func TestS3ApiController_ListBuckets(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
ListBucketsFunc: func() (s3response.ListAllMyBucketsResult, error) {
|
||||
return s3response.ListAllMyBucketsResult{}, nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -91,11 +105,13 @@ func TestS3ApiController_ListBuckets(t *testing.T) {
|
||||
appErr := fiber.New()
|
||||
s3ApiControllerErr := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
ListBucketsFunc: func() (s3response.ListAllMyBucketsResult, error) {
|
||||
return s3response.ListAllMyBucketsResult{}, s3err.GetAPIError(s3err.ErrMethodNotAllowed)
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
appErr.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -154,6 +170,9 @@ func TestS3ApiController_GetActions(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
ListObjectPartsFunc: func(bucket, object, uploadID string, partNumberMarker int, maxParts int) (s3response.ListPartsResponse, error) {
|
||||
return s3response.ListPartsResponse{}, nil
|
||||
},
|
||||
@@ -167,7 +186,6 @@ func TestS3ApiController_GetActions(t *testing.T) {
|
||||
return &s3.GetObjectOutput{Metadata: nil}, nil
|
||||
},
|
||||
},
|
||||
acl: &auth.ACLServiceUnsupported{},
|
||||
}
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
ctx.Locals("access", "valid access")
|
||||
@@ -264,8 +282,8 @@ func TestS3ApiController_ListActions(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) (*auth.GetBucketAclOutput, error) {
|
||||
return nil, nil
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
ListMultipartUploadsFunc: func(output *s3.ListMultipartUploadsInput) (s3response.ListMultipartUploadsResponse, error) {
|
||||
return s3response.ListMultipartUploadsResponse{}, nil
|
||||
@@ -277,7 +295,6 @@ func TestS3ApiController_ListActions(t *testing.T) {
|
||||
return &s3.ListObjectsOutput{}, nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -291,11 +308,13 @@ func TestS3ApiController_ListActions(t *testing.T) {
|
||||
//Error case
|
||||
s3ApiControllerError := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
ListObjectsFunc: func(bucket, prefix, marker, delim string, maxkeys int) (*s3.ListObjectsOutput, error) {
|
||||
return nil, s3err.GetAPIError(s3err.ErrNotImplemented)
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
appError := fiber.New()
|
||||
appError.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -381,14 +400,16 @@ func TestS3ApiController_PutBucketActions(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
PutBucketAclFunc: func(*s3.PutBucketAclInput) error {
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
PutBucketAclFunc: func(string, []byte) error {
|
||||
return nil
|
||||
},
|
||||
PutBucketFunc: func(bucket, owner string) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
// Mock ctx.Locals
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -463,6 +484,9 @@ func TestS3ApiController_PutActions(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
UploadPartCopyFunc: func(*s3.UploadPartCopyInput) (*s3.UploadPartCopyOutput, error) {
|
||||
return &s3.UploadPartCopyOutput{}, nil
|
||||
},
|
||||
@@ -476,7 +500,6 @@ func TestS3ApiController_PutActions(t *testing.T) {
|
||||
return "Hey", nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
ctx.Locals("access", "valid access")
|
||||
@@ -601,11 +624,13 @@ func TestS3ApiController_DeleteBucket(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
DeleteBucketFunc: func(bucket string) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -621,11 +646,13 @@ func TestS3ApiController_DeleteBucket(t *testing.T) {
|
||||
|
||||
s3ApiControllerErr := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
DeleteBucketFunc: func(bucket string) error {
|
||||
return s3err.GetAPIError(48)
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
appErr.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -682,11 +709,13 @@ func TestS3ApiController_DeleteObjects(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
DeleteObjectsFunc: func(bucket string, objects *s3.DeleteObjectsInput) error {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -749,6 +778,9 @@ func TestS3ApiController_DeleteActions(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
DeleteObjectFunc: func(bucket, object string) error {
|
||||
return nil
|
||||
},
|
||||
@@ -756,7 +788,6 @@ func TestS3ApiController_DeleteActions(t *testing.T) {
|
||||
return nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -770,6 +801,9 @@ func TestS3ApiController_DeleteActions(t *testing.T) {
|
||||
appErr := fiber.New()
|
||||
|
||||
s3ApiControllerErr := S3ApiController{be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
DeleteObjectFunc: func(bucket, object string) error {
|
||||
return s3err.GetAPIError(7)
|
||||
},
|
||||
@@ -838,11 +872,13 @@ func TestS3ApiController_HeadBucket(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
HeadBucketFunc: func(bucket string) (*s3.HeadBucketOutput, error) {
|
||||
return &s3.HeadBucketOutput{}, nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -857,11 +893,13 @@ func TestS3ApiController_HeadBucket(t *testing.T) {
|
||||
appErr := fiber.New()
|
||||
|
||||
s3ApiControllerErr := S3ApiController{be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
HeadBucketFunc: func(bucket string) (*s3.HeadBucketOutput, error) {
|
||||
return nil, s3err.GetAPIError(3)
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
appErr.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -926,6 +964,9 @@ func TestS3ApiController_HeadObject(t *testing.T) {
|
||||
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
HeadObjectFunc: func(bucket, object string) (*s3.HeadObjectOutput, error) {
|
||||
return &s3.HeadObjectOutput{
|
||||
ContentEncoding: &contentEncoding,
|
||||
@@ -936,7 +977,6 @@ func TestS3ApiController_HeadObject(t *testing.T) {
|
||||
}, nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -951,11 +991,13 @@ func TestS3ApiController_HeadObject(t *testing.T) {
|
||||
|
||||
s3ApiControllerErr := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
HeadObjectFunc: func(bucket, object string) (*s3.HeadObjectOutput, error) {
|
||||
return nil, s3err.GetAPIError(42)
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
appErr.Use(func(ctx *fiber.Ctx) error {
|
||||
@@ -1011,6 +1053,9 @@ func TestS3ApiController_CreateActions(t *testing.T) {
|
||||
app := fiber.New()
|
||||
s3ApiController := S3ApiController{
|
||||
be: &BackendMock{
|
||||
GetBucketAclFunc: func(bucket string) ([]byte, error) {
|
||||
return acldata, nil
|
||||
},
|
||||
RestoreObjectFunc: func(bucket, object string, restoreRequest *s3.RestoreObjectInput) error {
|
||||
return nil
|
||||
},
|
||||
@@ -1021,7 +1066,6 @@ func TestS3ApiController_CreateActions(t *testing.T) {
|
||||
return &s3.CreateMultipartUploadOutput{}, nil
|
||||
},
|
||||
},
|
||||
acl: auth.ACLServiceUnsupported{},
|
||||
}
|
||||
|
||||
app.Use(func(ctx *fiber.Ctx) error {
|
||||
|
||||
Reference in New Issue
Block a user