feat: Changed object lock actions interface to put/get []byte

This commit is contained in:
jonaustin09
2024-04-22 15:01:09 -04:00
committed by Ben McClelland
parent 00476ef70c
commit 89755ea5aa
6 changed files with 281 additions and 266 deletions

View File

@@ -7,7 +7,6 @@ import (
"bufio"
"context"
"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/s3response"
"io"
@@ -81,13 +80,13 @@ var _ backend.Backend = &BackendMock{}
// GetObjectAttributesFunc: func(contextMoqParam context.Context, getObjectAttributesInput *s3.GetObjectAttributesInput) (*s3.GetObjectAttributesOutput, error) {
// panic("mock out the GetObjectAttributes method")
// },
// GetObjectLegalHoldFunc: func(contextMoqParam context.Context, bucket string, object string, versionId string) (*types.ObjectLockLegalHold, error) {
// GetObjectLegalHoldFunc: func(contextMoqParam context.Context, bucket string, object string, versionId string) (*bool, error) {
// panic("mock out the GetObjectLegalHold method")
// },
// GetObjectLockConfigurationFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) {
// panic("mock out the GetObjectLockConfiguration method")
// },
// GetObjectRetentionFunc: func(contextMoqParam context.Context, bucket string, object string, versionId string) (*types.ObjectLockRetention, error) {
// GetObjectRetentionFunc: func(contextMoqParam context.Context, bucket string, object string, versionId string) ([]byte, error) {
// panic("mock out the GetObjectRetention method")
// },
// GetObjectTaggingFunc: func(contextMoqParam context.Context, bucket string, object string) (map[string]string, error) {
@@ -138,13 +137,13 @@ var _ backend.Backend = &BackendMock{}
// PutObjectAclFunc: func(contextMoqParam context.Context, putObjectAclInput *s3.PutObjectAclInput) error {
// panic("mock out the PutObjectAcl method")
// },
// PutObjectLegalHoldFunc: func(contextMoqParam context.Context, putObjectLegalHoldInput *s3.PutObjectLegalHoldInput) error {
// PutObjectLegalHoldFunc: func(contextMoqParam context.Context, bucket string, object string, versionId string, status bool) error {
// panic("mock out the PutObjectLegalHold method")
// },
// PutObjectLockConfigurationFunc: func(contextMoqParam context.Context, putObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput) error {
// PutObjectLockConfigurationFunc: func(contextMoqParam context.Context, bucket string, config []byte) error {
// panic("mock out the PutObjectLockConfiguration method")
// },
// PutObjectRetentionFunc: func(contextMoqParam context.Context, putObjectRetentionInput *s3.PutObjectRetentionInput) error {
// PutObjectRetentionFunc: func(contextMoqParam context.Context, bucket string, object string, versionId string, retention []byte) error {
// panic("mock out the PutObjectRetention method")
// },
// PutObjectTaggingFunc: func(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error {
@@ -233,13 +232,13 @@ type BackendMock struct {
GetObjectAttributesFunc func(contextMoqParam context.Context, getObjectAttributesInput *s3.GetObjectAttributesInput) (*s3.GetObjectAttributesOutput, error)
// GetObjectLegalHoldFunc mocks the GetObjectLegalHold method.
GetObjectLegalHoldFunc func(contextMoqParam context.Context, bucket string, object string, versionId string) (*types.ObjectLockLegalHold, error)
GetObjectLegalHoldFunc func(contextMoqParam context.Context, bucket string, object string, versionId string) (*bool, error)
// GetObjectLockConfigurationFunc mocks the GetObjectLockConfiguration method.
GetObjectLockConfigurationFunc func(contextMoqParam context.Context, bucket string) ([]byte, error)
// GetObjectRetentionFunc mocks the GetObjectRetention method.
GetObjectRetentionFunc func(contextMoqParam context.Context, bucket string, object string, versionId string) (*types.ObjectLockRetention, error)
GetObjectRetentionFunc func(contextMoqParam context.Context, bucket string, object string, versionId string) ([]byte, error)
// GetObjectTaggingFunc mocks the GetObjectTagging method.
GetObjectTaggingFunc func(contextMoqParam context.Context, bucket string, object string) (map[string]string, error)
@@ -290,13 +289,13 @@ type BackendMock struct {
PutObjectAclFunc func(contextMoqParam context.Context, putObjectAclInput *s3.PutObjectAclInput) error
// PutObjectLegalHoldFunc mocks the PutObjectLegalHold method.
PutObjectLegalHoldFunc func(contextMoqParam context.Context, putObjectLegalHoldInput *s3.PutObjectLegalHoldInput) error
PutObjectLegalHoldFunc func(contextMoqParam context.Context, bucket string, object string, versionId string, status bool) error
// PutObjectLockConfigurationFunc mocks the PutObjectLockConfiguration method.
PutObjectLockConfigurationFunc func(contextMoqParam context.Context, putObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput) error
PutObjectLockConfigurationFunc func(contextMoqParam context.Context, bucket string, config []byte) error
// PutObjectRetentionFunc mocks the PutObjectRetention method.
PutObjectRetentionFunc func(contextMoqParam context.Context, putObjectRetentionInput *s3.PutObjectRetentionInput) error
PutObjectRetentionFunc func(contextMoqParam context.Context, bucket string, object string, versionId string, retention []byte) error
// PutObjectTaggingFunc mocks the PutObjectTagging method.
PutObjectTaggingFunc func(contextMoqParam context.Context, bucket string, object string, tags map[string]string) error
@@ -615,22 +614,36 @@ type BackendMock struct {
PutObjectLegalHold []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// PutObjectLegalHoldInput is the putObjectLegalHoldInput argument value.
PutObjectLegalHoldInput *s3.PutObjectLegalHoldInput
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
// VersionId is the versionId argument value.
VersionId string
// Status is the status argument value.
Status bool
}
// PutObjectLockConfiguration holds details about calls to the PutObjectLockConfiguration method.
PutObjectLockConfiguration []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// PutObjectLockConfigurationInput is the putObjectLockConfigurationInput argument value.
PutObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput
// Bucket is the bucket argument value.
Bucket string
// Config is the config argument value.
Config []byte
}
// PutObjectRetention holds details about calls to the PutObjectRetention method.
PutObjectRetention []struct {
// ContextMoqParam is the contextMoqParam argument value.
ContextMoqParam context.Context
// PutObjectRetentionInput is the putObjectRetentionInput argument value.
PutObjectRetentionInput *s3.PutObjectRetentionInput
// Bucket is the bucket argument value.
Bucket string
// Object is the object argument value.
Object string
// VersionId is the versionId argument value.
VersionId string
// Retention is the retention argument value.
Retention []byte
}
// PutObjectTagging holds details about calls to the PutObjectTagging method.
PutObjectTagging []struct {
@@ -1429,7 +1442,7 @@ func (mock *BackendMock) GetObjectAttributesCalls() []struct {
}
// GetObjectLegalHold calls GetObjectLegalHoldFunc.
func (mock *BackendMock) GetObjectLegalHold(contextMoqParam context.Context, bucket string, object string, versionId string) (*types.ObjectLockLegalHold, error) {
func (mock *BackendMock) GetObjectLegalHold(contextMoqParam context.Context, bucket string, object string, versionId string) (*bool, error) {
if mock.GetObjectLegalHoldFunc == nil {
panic("BackendMock.GetObjectLegalHoldFunc: method is nil but Backend.GetObjectLegalHold was just called")
}
@@ -1509,7 +1522,7 @@ func (mock *BackendMock) GetObjectLockConfigurationCalls() []struct {
}
// GetObjectRetention calls GetObjectRetentionFunc.
func (mock *BackendMock) GetObjectRetention(contextMoqParam context.Context, bucket string, object string, versionId string) (*types.ObjectLockRetention, error) {
func (mock *BackendMock) GetObjectRetention(contextMoqParam context.Context, bucket string, object string, versionId string) ([]byte, error) {
if mock.GetObjectRetentionFunc == nil {
panic("BackendMock.GetObjectRetentionFunc: method is nil but Backend.GetObjectRetention was just called")
}
@@ -2145,21 +2158,27 @@ func (mock *BackendMock) PutObjectAclCalls() []struct {
}
// PutObjectLegalHold calls PutObjectLegalHoldFunc.
func (mock *BackendMock) PutObjectLegalHold(contextMoqParam context.Context, putObjectLegalHoldInput *s3.PutObjectLegalHoldInput) error {
func (mock *BackendMock) PutObjectLegalHold(contextMoqParam context.Context, bucket string, object string, versionId string, status bool) error {
if mock.PutObjectLegalHoldFunc == nil {
panic("BackendMock.PutObjectLegalHoldFunc: method is nil but Backend.PutObjectLegalHold was just called")
}
callInfo := struct {
ContextMoqParam context.Context
PutObjectLegalHoldInput *s3.PutObjectLegalHoldInput
ContextMoqParam context.Context
Bucket string
Object string
VersionId string
Status bool
}{
ContextMoqParam: contextMoqParam,
PutObjectLegalHoldInput: putObjectLegalHoldInput,
ContextMoqParam: contextMoqParam,
Bucket: bucket,
Object: object,
VersionId: versionId,
Status: status,
}
mock.lockPutObjectLegalHold.Lock()
mock.calls.PutObjectLegalHold = append(mock.calls.PutObjectLegalHold, callInfo)
mock.lockPutObjectLegalHold.Unlock()
return mock.PutObjectLegalHoldFunc(contextMoqParam, putObjectLegalHoldInput)
return mock.PutObjectLegalHoldFunc(contextMoqParam, bucket, object, versionId, status)
}
// PutObjectLegalHoldCalls gets all the calls that were made to PutObjectLegalHold.
@@ -2167,12 +2186,18 @@ func (mock *BackendMock) PutObjectLegalHold(contextMoqParam context.Context, put
//
// len(mockedBackend.PutObjectLegalHoldCalls())
func (mock *BackendMock) PutObjectLegalHoldCalls() []struct {
ContextMoqParam context.Context
PutObjectLegalHoldInput *s3.PutObjectLegalHoldInput
ContextMoqParam context.Context
Bucket string
Object string
VersionId string
Status bool
} {
var calls []struct {
ContextMoqParam context.Context
PutObjectLegalHoldInput *s3.PutObjectLegalHoldInput
ContextMoqParam context.Context
Bucket string
Object string
VersionId string
Status bool
}
mock.lockPutObjectLegalHold.RLock()
calls = mock.calls.PutObjectLegalHold
@@ -2181,21 +2206,23 @@ func (mock *BackendMock) PutObjectLegalHoldCalls() []struct {
}
// PutObjectLockConfiguration calls PutObjectLockConfigurationFunc.
func (mock *BackendMock) PutObjectLockConfiguration(contextMoqParam context.Context, putObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput) error {
func (mock *BackendMock) PutObjectLockConfiguration(contextMoqParam context.Context, bucket string, config []byte) error {
if mock.PutObjectLockConfigurationFunc == nil {
panic("BackendMock.PutObjectLockConfigurationFunc: method is nil but Backend.PutObjectLockConfiguration was just called")
}
callInfo := struct {
ContextMoqParam context.Context
PutObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput
ContextMoqParam context.Context
Bucket string
Config []byte
}{
ContextMoqParam: contextMoqParam,
PutObjectLockConfigurationInput: putObjectLockConfigurationInput,
ContextMoqParam: contextMoqParam,
Bucket: bucket,
Config: config,
}
mock.lockPutObjectLockConfiguration.Lock()
mock.calls.PutObjectLockConfiguration = append(mock.calls.PutObjectLockConfiguration, callInfo)
mock.lockPutObjectLockConfiguration.Unlock()
return mock.PutObjectLockConfigurationFunc(contextMoqParam, putObjectLockConfigurationInput)
return mock.PutObjectLockConfigurationFunc(contextMoqParam, bucket, config)
}
// PutObjectLockConfigurationCalls gets all the calls that were made to PutObjectLockConfiguration.
@@ -2203,12 +2230,14 @@ func (mock *BackendMock) PutObjectLockConfiguration(contextMoqParam context.Cont
//
// len(mockedBackend.PutObjectLockConfigurationCalls())
func (mock *BackendMock) PutObjectLockConfigurationCalls() []struct {
ContextMoqParam context.Context
PutObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput
ContextMoqParam context.Context
Bucket string
Config []byte
} {
var calls []struct {
ContextMoqParam context.Context
PutObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput
ContextMoqParam context.Context
Bucket string
Config []byte
}
mock.lockPutObjectLockConfiguration.RLock()
calls = mock.calls.PutObjectLockConfiguration
@@ -2217,21 +2246,27 @@ func (mock *BackendMock) PutObjectLockConfigurationCalls() []struct {
}
// PutObjectRetention calls PutObjectRetentionFunc.
func (mock *BackendMock) PutObjectRetention(contextMoqParam context.Context, putObjectRetentionInput *s3.PutObjectRetentionInput) error {
func (mock *BackendMock) PutObjectRetention(contextMoqParam context.Context, bucket string, object string, versionId string, retention []byte) error {
if mock.PutObjectRetentionFunc == nil {
panic("BackendMock.PutObjectRetentionFunc: method is nil but Backend.PutObjectRetention was just called")
}
callInfo := struct {
ContextMoqParam context.Context
PutObjectRetentionInput *s3.PutObjectRetentionInput
ContextMoqParam context.Context
Bucket string
Object string
VersionId string
Retention []byte
}{
ContextMoqParam: contextMoqParam,
PutObjectRetentionInput: putObjectRetentionInput,
ContextMoqParam: contextMoqParam,
Bucket: bucket,
Object: object,
VersionId: versionId,
Retention: retention,
}
mock.lockPutObjectRetention.Lock()
mock.calls.PutObjectRetention = append(mock.calls.PutObjectRetention, callInfo)
mock.lockPutObjectRetention.Unlock()
return mock.PutObjectRetentionFunc(contextMoqParam, putObjectRetentionInput)
return mock.PutObjectRetentionFunc(contextMoqParam, bucket, object, versionId, retention)
}
// PutObjectRetentionCalls gets all the calls that were made to PutObjectRetention.
@@ -2239,12 +2274,18 @@ func (mock *BackendMock) PutObjectRetention(contextMoqParam context.Context, put
//
// len(mockedBackend.PutObjectRetentionCalls())
func (mock *BackendMock) PutObjectRetentionCalls() []struct {
ContextMoqParam context.Context
PutObjectRetentionInput *s3.PutObjectRetentionInput
ContextMoqParam context.Context
Bucket string
Object string
VersionId string
Retention []byte
} {
var calls []struct {
ContextMoqParam context.Context
PutObjectRetentionInput *s3.PutObjectRetentionInput
ContextMoqParam context.Context
Bucket string
Object string
VersionId string
Retention []byte
}
mock.lockPutObjectRetention.RLock()
calls = mock.calls.PutObjectRetention

View File

@@ -151,7 +151,17 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
}
data, err := c.be.GetObjectRetention(ctx.Context(), bucket, key, versionId)
return SendXMLResponse(ctx, data, err,
if err != nil {
return SendXMLResponse(ctx, data, err,
&MetaOpts{
Logger: c.logger,
Action: "GetObjectRetention",
BucketOwner: parsedAcl.Owner,
})
}
retention, err := auth.ParseObjectLockRetentionOutput(data)
return SendXMLResponse(ctx, retention, err,
&MetaOpts{
Logger: c.logger,
Action: "GetObjectRetention",
@@ -179,7 +189,7 @@ func (c S3ApiController) GetActions(ctx *fiber.Ctx) error {
}
data, err := c.be.GetObjectLegalHold(ctx.Context(), bucket, key, versionId)
return SendXMLResponse(ctx, data, err,
return SendXMLResponse(ctx, auth.ParseObjectLegalHoldOutput(data), err,
&MetaOpts{
Logger: c.logger,
Action: "GetObjectLegalHold",
@@ -941,16 +951,6 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error {
if ctx.Request().URI().QueryArgs().Has("object-lock") {
parsedAcl := ctx.Locals("parsedAcl").(auth.ACL)
var input types.ObjectLockConfiguration
if err := xml.Unmarshal(ctx.Body(), &input); err != nil {
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest),
&MetaOpts{
Logger: c.logger,
Action: "PutObjectLockConfiguration",
BucketOwner: parsedAcl.Owner,
})
}
if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
Acl: parsedAcl,
AclPermission: types.PermissionWrite,
@@ -967,10 +967,17 @@ func (c S3ApiController) PutBucketActions(ctx *fiber.Ctx) error {
})
}
err := c.be.PutObjectLockConfiguration(ctx.Context(), &s3.PutObjectLockConfigurationInput{
Bucket: &bucket,
ObjectLockConfiguration: &input,
})
config, err := auth.ParseBucketLockConfigurationInput(ctx.Body())
if err != nil {
return SendResponse(ctx, err,
&MetaOpts{
Logger: c.logger,
Action: "PutObjectLockConfiguration",
BucketOwner: parsedAcl.Owner,
})
}
err = c.be.PutObjectLockConfiguration(ctx.Context(), bucket, config)
return SendResponse(ctx, err,
&MetaOpts{
Logger: c.logger,
@@ -1211,7 +1218,6 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
keyEnd := ctx.Params("*1")
uploadId := ctx.Query("uploadId")
versionId := ctx.Query("versionId")
bypassGovernanceRetention := ctx.Get("X-Amz-Bypass-Governance-Retention")
acct := ctx.Locals("account").(auth.Account)
isRoot := ctx.Locals("isRoot").(bool)
parsedAcl := ctx.Locals("parsedAcl").(auth.ACL)
@@ -1313,24 +1319,6 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
}
if ctx.Request().URI().QueryArgs().Has("retention") {
var retention types.ObjectLockRetention
if err := xml.Unmarshal(ctx.Body(), &retention); err != nil {
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrInvalidRequest), &MetaOpts{
Logger: c.logger,
Action: "PutObjectRetention",
BucketOwner: parsedAcl.Owner,
})
}
if retention.RetainUntilDate == nil || retention.RetainUntilDate.Before(time.Now()) {
return SendResponse(ctx, s3err.GetAPIError(s3err.ErrPastObjectLockRetainDate),
&MetaOpts{
Logger: c.logger,
Action: "PutObjectRetention",
BucketOwner: parsedAcl.Owner,
})
}
if err := auth.VerifyAccess(ctx.Context(), c.be, auth.AccessOptions{
Acl: parsedAcl,
AclPermission: types.PermissionWrite,
@@ -1348,15 +1336,16 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
})
}
pass := bypassGovernanceRetention == "True"
retention, err := auth.ParseObjectLockRetentionInput(ctx.Body())
if err != nil {
return SendResponse(ctx, err, &MetaOpts{
Logger: c.logger,
Action: "PutObjectRetention",
BucketOwner: parsedAcl.Owner,
})
}
err := c.be.PutObjectRetention(ctx.Context(), &s3.PutObjectRetentionInput{
Bucket: &bucket,
Key: &keyStart,
VersionId: &versionId,
Retention: &retention,
BypassGovernanceRetention: &pass,
})
err = c.be.PutObjectRetention(ctx.Context(), bucket, keyStart, versionId, retention)
return SendResponse(ctx, err, &MetaOpts{
Logger: c.logger,
Action: "PutObjectRetention",
@@ -1391,12 +1380,7 @@ func (c S3ApiController) PutActions(ctx *fiber.Ctx) error {
})
}
err := c.be.PutObjectLegalHold(ctx.Context(), &s3.PutObjectLegalHoldInput{
Bucket: &bucket,
Key: &keyStart,
VersionId: &versionId,
LegalHold: &legalHold,
})
err := c.be.PutObjectLegalHold(ctx.Context(), bucket, keyStart, versionId, legalHold.Status == types.ObjectLockLegalHoldStatusOn)
return SendResponse(ctx, err, &MetaOpts{
Logger: c.logger,
Action: "PutObjectLegalHold",

View File

@@ -205,11 +205,18 @@ func TestS3ApiController_GetActions(t *testing.T) {
GetObjectTaggingFunc: func(_ context.Context, bucket, object string) (map[string]string, error) {
return map[string]string{"hello": "world"}, nil
},
GetObjectRetentionFunc: func(contextMoqParam context.Context, bucket, object, versionId string) (*types.ObjectLockRetention, error) {
return &types.ObjectLockRetention{}, nil
GetObjectRetentionFunc: func(contextMoqParam context.Context, bucket, object, versionId string) ([]byte, error) {
result, err := json.Marshal(types.ObjectLockRetention{
Mode: types.ObjectLockRetentionModeCompliance,
})
if err != nil {
return nil, err
}
return result, nil
},
GetObjectLegalHoldFunc: func(contextMoqParam context.Context, bucket, object, versionId string) (*types.ObjectLockLegalHold, error) {
return &types.ObjectLockLegalHold{}, nil
GetObjectLegalHoldFunc: func(contextMoqParam context.Context, bucket, object, versionId string) (*bool, error) {
result := true
return &result, nil
},
},
}
@@ -657,7 +664,7 @@ func TestS3ApiController_PutBucketActions(t *testing.T) {
PutBucketPolicyFunc: func(contextMoqParam context.Context, bucket string, policy []byte) error {
return nil
},
PutObjectLockConfigurationFunc: func(contextMoqParam context.Context, putObjectLockConfigurationInput *s3.PutObjectLockConfigurationInput) error {
PutObjectLockConfigurationFunc: func(contextMoqParam context.Context, bucket string, config []byte) error {
return nil
},
},
@@ -919,10 +926,10 @@ func TestS3ApiController_PutActions(t *testing.T) {
UploadPartCopyFunc: func(context.Context, *s3.UploadPartCopyInput) (s3response.CopyObjectResult, error) {
return s3response.CopyObjectResult{}, nil
},
PutObjectLegalHoldFunc: func(contextMoqParam context.Context, putObjectLegalHoldInput *s3.PutObjectLegalHoldInput) error {
PutObjectLegalHoldFunc: func(contextMoqParam context.Context, bucket, object, versionId string, status bool) error {
return nil
},
PutObjectRetentionFunc: func(contextMoqParam context.Context, putObjectRetentionInput *s3.PutObjectRetentionInput) error {
PutObjectRetentionFunc: func(contextMoqParam context.Context, bucket, object, versionId string, retention []byte) error {
return nil
},
GetObjectLockConfigurationFunc: func(contextMoqParam context.Context, bucket string) ([]byte, error) {