forked from TrueCloudLab/frostfs-s3-gw
[#713] Update tests
Add bearer token to test context Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
1a21e6e6e8
commit
cb55d36063
13 changed files with 244 additions and 199 deletions
|
@ -1349,7 +1349,7 @@ func createAccessBox(t *testing.T) *accessbox.Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBucket(t *testing.T, tc *handlerContext, bktName string, box *accessbox.Box) *data.BucketInfo {
|
func createBucket(t *testing.T, tc *handlerContext, bktName string, box *accessbox.Box) *data.BucketInfo {
|
||||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||||
ctx := context.WithValue(r.Context(), api.BoxData, box)
|
ctx := context.WithValue(r.Context(), api.BoxData, box)
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
tc.Handler().CreateBucketHandler(w, r)
|
tc.Handler().CreateBucketHandler(w, r)
|
||||||
|
@ -1361,7 +1361,7 @@ func createBucket(t *testing.T, tc *handlerContext, bktName string, box *accessb
|
||||||
}
|
}
|
||||||
|
|
||||||
func putBucketACL(t *testing.T, tc *handlerContext, bktName string, box *accessbox.Box, header map[string]string) {
|
func putBucketACL(t *testing.T, tc *handlerContext, bktName string, box *accessbox.Box, header map[string]string) {
|
||||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||||
for key, val := range header {
|
for key, val := range header {
|
||||||
r.Header.Set(key, val)
|
r.Header.Set(key, val)
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -13,33 +12,32 @@ import (
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestGetObjectPartsAttributes(t *testing.T) {
|
func TestGetObjectPartsAttributes(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-get-attributes"
|
bktName := "bucket-get-attributes"
|
||||||
objName, objMultipartName := "object", "object-multipart"
|
objName, objMultipartName := "object", "object-multipart"
|
||||||
|
|
||||||
createTestBucket(ctx, t, hc, bktName)
|
createTestBucket(hc, bktName)
|
||||||
|
|
||||||
body := bytes.NewReader([]byte("content"))
|
body := bytes.NewReader([]byte("content"))
|
||||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||||
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
||||||
hc.Handler().GetObjectAttributesHandler(w, r)
|
hc.Handler().GetObjectAttributesHandler(w, r)
|
||||||
result := &GetObjectAttributesResponse{}
|
result := &GetObjectAttributesResponse{}
|
||||||
parseTestResponse(t, w, result)
|
parseTestResponse(t, w, result)
|
||||||
require.Nil(t, result.ObjectParts)
|
require.Nil(t, result.ObjectParts)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objMultipartName, nil)
|
w, r = prepareTestRequest(hc, bktName, objMultipartName, nil)
|
||||||
hc.Handler().CreateMultipartUploadHandler(w, r)
|
hc.Handler().CreateMultipartUploadHandler(w, r)
|
||||||
multipartUpload := &InitiateMultipartUploadResponse{}
|
multipartUpload := &InitiateMultipartUploadResponse{}
|
||||||
parseTestResponse(t, w, multipartUpload)
|
parseTestResponse(t, w, multipartUpload)
|
||||||
|
|
||||||
body2 := bytes.NewReader([]byte("content2"))
|
body2 := bytes.NewReader([]byte("content2"))
|
||||||
w, r = prepareTestPayloadRequest(bktName, objMultipartName, body2)
|
w, r = prepareTestPayloadRequest(hc, bktName, objMultipartName, body2)
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
||||||
query.Add(partNumberHeaderName, "1")
|
query.Add(partNumberHeaderName, "1")
|
||||||
|
@ -54,14 +52,14 @@ func TestGetObjectPartsAttributes(t *testing.T) {
|
||||||
PartNumber: 1,
|
PartNumber: 1,
|
||||||
}},
|
}},
|
||||||
}
|
}
|
||||||
w, r = prepareTestRequest(t, bktName, objMultipartName, completeUpload)
|
w, r = prepareTestRequest(hc, bktName, objMultipartName, completeUpload)
|
||||||
query = make(url.Values)
|
query = make(url.Values)
|
||||||
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
query.Add(uploadIDHeaderName, multipartUpload.UploadID)
|
||||||
r.URL.RawQuery = query.Encode()
|
r.URL.RawQuery = query.Encode()
|
||||||
hc.Handler().CompleteMultipartUploadHandler(w, r)
|
hc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objMultipartName, nil)
|
w, r = prepareTestRequest(hc, bktName, objMultipartName, nil)
|
||||||
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
r.Header.Set(api.AmzObjectAttributes, objectParts)
|
||||||
hc.Handler().GetObjectAttributesHandler(w, r)
|
hc.Handler().GetObjectAttributesHandler(w, r)
|
||||||
result = &GetObjectAttributesResponse{}
|
result = &GetObjectAttributesResponse{}
|
||||||
|
|
|
@ -22,7 +22,7 @@ func TestCopyWithTaggingDirective(t *testing.T) {
|
||||||
|
|
||||||
bktName, objName := "bucket-for-copy", "object-from-copy"
|
bktName, objName := "bucket-for-copy", "object-from-copy"
|
||||||
objToCopy, objToCopy2 := "object-to-copy", "object-to-copy-2"
|
objToCopy, objToCopy2 := "object-to-copy", "object-to-copy-2"
|
||||||
createBucketAndObject(t, tc, bktName, objName)
|
createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
putObjectTagging(t, tc, bktName, objName, map[string]string{"key": "val"})
|
putObjectTagging(t, tc, bktName, objName, map[string]string{"key": "val"})
|
||||||
|
|
||||||
|
@ -47,7 +47,7 @@ func TestCopyToItself(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-copy", "object-for-copy"
|
bktName, objName := "bucket-for-copy", "object-for-copy"
|
||||||
createBucketAndObject(t, tc, bktName, objName)
|
createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
copyMeta := CopyMeta{MetadataDirective: replaceDirective}
|
copyMeta := CopyMeta{MetadataDirective: replaceDirective}
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ func TestCopyToItself(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func copyObject(t *testing.T, tc *handlerContext, bktName, fromObject, toObject string, copyMeta CopyMeta, statusCode int) {
|
func copyObject(t *testing.T, tc *handlerContext, bktName, fromObject, toObject string, copyMeta CopyMeta, statusCode int) {
|
||||||
w, r := prepareTestRequest(t, bktName, toObject, nil)
|
w, r := prepareTestRequest(tc, bktName, toObject, nil)
|
||||||
r.Header.Set(api.AmzCopySource, bktName+"/"+fromObject)
|
r.Header.Set(api.AmzCopySource, bktName+"/"+fromObject)
|
||||||
|
|
||||||
r.Header.Set(api.AmzMetadataDirective, copyMeta.MetadataDirective)
|
r.Header.Set(api.AmzMetadataDirective, copyMeta.MetadataDirective)
|
||||||
|
@ -95,7 +95,7 @@ func putObjectTagging(t *testing.T, tc *handlerContext, bktName, objName string,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objName, body)
|
w, r := prepareTestRequest(tc, bktName, objName, body)
|
||||||
tc.Handler().PutObjectTaggingHandler(w, r)
|
tc.Handler().PutObjectTaggingHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
@ -104,7 +104,7 @@ func getObjectTagging(t *testing.T, tc *handlerContext, bktName, objName, versio
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Add(api.QueryVersionID, version)
|
query.Add(api.QueryVersionID, version)
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||||
tc.Handler().GetObjectTaggingHandler(w, r)
|
tc.Handler().GetObjectTaggingHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
|
|
|
@ -35,7 +35,7 @@ func TestDeleteObject(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
checkFound(t, tc, bktName, objName, emptyVersion)
|
checkFound(t, tc, bktName, objName, emptyVersion)
|
||||||
deleteObject(t, tc, bktName, objName, emptyVersion)
|
deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||||
|
@ -61,7 +61,7 @@ func TestDeleteDeletedObject(t *testing.T) {
|
||||||
|
|
||||||
t.Run("unversioned bucket", func(t *testing.T) {
|
t.Run("unversioned bucket", func(t *testing.T) {
|
||||||
bktName, objName := "bucket-unversioned-removal", "object-to-delete"
|
bktName, objName := "bucket-unversioned-removal", "object-to-delete"
|
||||||
createBucketAndObject(t, tc, bktName, objName)
|
createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
versionID, isDeleteMarker := deleteObject(t, tc, bktName, objName, emptyVersion)
|
versionID, isDeleteMarker := deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||||
require.Empty(t, versionID)
|
require.Empty(t, versionID)
|
||||||
|
@ -116,7 +116,7 @@ func TestDeleteObjectUnversioned(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-removal-unversioned", "object-to-delete-unversioned"
|
bktName, objName := "bucket-for-removal-unversioned", "object-to-delete-unversioned"
|
||||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
checkFound(t, tc, bktName, objName, emptyVersion)
|
checkFound(t, tc, bktName, objName, emptyVersion)
|
||||||
deleteObject(t, tc, bktName, objName, emptyVersion)
|
deleteObject(t, tc, bktName, objName, emptyVersion)
|
||||||
|
@ -151,7 +151,7 @@ func TestDeleteObjectCombined(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
putBucketVersioning(t, tc, bktName, true)
|
putBucketVersioning(t, tc, bktName, true)
|
||||||
|
|
||||||
|
@ -168,7 +168,7 @@ func TestDeleteObjectSuspended(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||||
bktInfo, objInfo := createBucketAndObject(t, tc, bktName, objName)
|
bktInfo, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
putBucketVersioning(t, tc, bktName, true)
|
putBucketVersioning(t, tc, bktName, true)
|
||||||
|
|
||||||
|
@ -188,7 +188,7 @@ func TestDeleteMarkers(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-removal", "object-to-delete"
|
bktName, objName := "bucket-for-removal", "object-to-delete"
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
putBucketVersioning(t, tc, bktName, true)
|
putBucketVersioning(t, tc, bktName, true)
|
||||||
|
|
||||||
checkNotFound(t, tc, bktName, objName, emptyVersion)
|
checkNotFound(t, tc, bktName, objName, emptyVersion)
|
||||||
|
@ -243,21 +243,21 @@ func TestDeleteObjectCheckMarkerReturn(t *testing.T) {
|
||||||
require.Equal(t, deleteMarkerVersion, deleteMarkerVersion2)
|
require.Equal(t, deleteMarkerVersion, deleteMarkerVersion2)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createBucketAndObject(t *testing.T, tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
func createBucketAndObject(tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
||||||
bktInfo := createTestBucket(tc.Context(), t, tc, bktName)
|
bktInfo := createTestBucket(tc, bktName)
|
||||||
|
|
||||||
objInfo := createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
objInfo := createTestObject(tc, bktInfo, objName)
|
||||||
|
|
||||||
return bktInfo, objInfo
|
return bktInfo, objInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func createVersionedBucketAndObject(t *testing.T, tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
func createVersionedBucketAndObject(t *testing.T, tc *handlerContext, bktName, objName string) (*data.BucketInfo, *data.ObjectInfo) {
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
putBucketVersioning(t, tc, bktName, true)
|
putBucketVersioning(t, tc, bktName, true)
|
||||||
|
|
||||||
objInfo := createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
objInfo := createTestObject(tc, bktInfo, objName)
|
||||||
|
|
||||||
return bktInfo, objInfo
|
return bktInfo, objInfo
|
||||||
}
|
}
|
||||||
|
@ -267,7 +267,7 @@ func putBucketVersioning(t *testing.T, tc *handlerContext, bktName string, enabl
|
||||||
if enabled {
|
if enabled {
|
||||||
cfg.Status = "Enabled"
|
cfg.Status = "Enabled"
|
||||||
}
|
}
|
||||||
w, r := prepareTestRequest(t, bktName, "", cfg)
|
w, r := prepareTestRequest(tc, bktName, "", cfg)
|
||||||
tc.Handler().PutBucketVersioningHandler(w, r)
|
tc.Handler().PutBucketVersioningHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
@ -276,7 +276,7 @@ func deleteObject(t *testing.T, tc *handlerContext, bktName, objName, version st
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Add(api.QueryVersionID, version)
|
query.Add(api.QueryVersionID, version)
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||||
tc.Handler().DeleteObjectHandler(w, r)
|
tc.Handler().DeleteObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusNoContent)
|
assertStatus(t, w, http.StatusNoContent)
|
||||||
|
|
||||||
|
@ -284,7 +284,7 @@ func deleteObject(t *testing.T, tc *handlerContext, bktName, objName, version st
|
||||||
}
|
}
|
||||||
|
|
||||||
func deleteBucket(t *testing.T, tc *handlerContext, bktName string, code int) {
|
func deleteBucket(t *testing.T, tc *handlerContext, bktName string, code int) {
|
||||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||||
tc.Handler().DeleteBucketHandler(w, r)
|
tc.Handler().DeleteBucketHandler(w, r)
|
||||||
assertStatus(t, w, code)
|
assertStatus(t, w, code)
|
||||||
}
|
}
|
||||||
|
@ -293,7 +293,7 @@ func checkNotFound(t *testing.T, tc *handlerContext, bktName, objName, version s
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Add(api.QueryVersionID, version)
|
query.Add(api.QueryVersionID, version)
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
tc.Handler().HeadObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusNotFound)
|
assertStatus(t, w, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
@ -302,13 +302,13 @@ func checkFound(t *testing.T, tc *handlerContext, bktName, objName, version stri
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Add(api.QueryVersionID, version)
|
query.Add(api.QueryVersionID, version)
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, objName, query, nil)
|
w, r := prepareTestFullRequest(tc, bktName, objName, query, nil)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
tc.Handler().HeadObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func listVersions(t *testing.T, tc *handlerContext, bktName string) *ListObjectsVersionsResponse {
|
func listVersions(t *testing.T, tc *handlerContext, bktName string) *ListObjectsVersionsResponse {
|
||||||
w, r := prepareTestRequest(t, bktName, "", nil)
|
w, r := prepareTestRequest(tc, bktName, "", nil)
|
||||||
tc.Handler().ListBucketObjectVersionsHandler(w, r)
|
tc.Handler().ListBucketObjectVersionsHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
res := &ListObjectsVersionsResponse{}
|
res := &ListObjectsVersionsResponse{}
|
||||||
|
@ -318,13 +318,13 @@ func listVersions(t *testing.T, tc *handlerContext, bktName string) *ListObjects
|
||||||
|
|
||||||
func putObject(t *testing.T, tc *handlerContext, bktName, objName string) {
|
func putObject(t *testing.T, tc *handlerContext, bktName, objName string) {
|
||||||
body := bytes.NewReader([]byte("content"))
|
body := bytes.NewReader([]byte("content"))
|
||||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
||||||
tc.Handler().PutObjectHandler(w, r)
|
tc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func createSuspendedBucket(t *testing.T, tc *handlerContext, bktName string) *data.BucketInfo {
|
func createSuspendedBucket(t *testing.T, tc *handlerContext, bktName string) *data.BucketInfo {
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
bktInfo, err := tc.Layer().GetBucketInfo(tc.Context(), bktName)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
putBucketVersioning(t, tc, bktName, false)
|
putBucketVersioning(t, tc, bktName, false)
|
||||||
|
|
|
@ -27,7 +27,7 @@ func TestSimpleGetEncrypted(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-sse-c", "object-to-encrypt"
|
bktName, objName := "bucket-for-sse-c", "object-to-encrypt"
|
||||||
bktInfo := createTestBucket(tc.Context(), t, tc, bktName)
|
bktInfo := createTestBucket(tc, bktName)
|
||||||
|
|
||||||
content := "content"
|
content := "content"
|
||||||
putEncryptedObject(t, tc, bktName, objName, content)
|
putEncryptedObject(t, tc, bktName, objName, content)
|
||||||
|
@ -48,7 +48,7 @@ func TestGetEncryptedRange(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-sse-c", "object-to-encrypt"
|
bktName, objName := "bucket-for-sse-c", "object-to-encrypt"
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
|
|
||||||
var sb strings.Builder
|
var sb strings.Builder
|
||||||
for i := 0; i < 1<<16+11; i++ {
|
for i := 0; i < 1<<16+11; i++ {
|
||||||
|
@ -89,7 +89,7 @@ func TestGetEncryptedRange(t *testing.T) {
|
||||||
func TestS3EncryptionSSECMultipartUpload(t *testing.T) {
|
func TestS3EncryptionSSECMultipartUpload(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
bktName, objName := "bucket-for-sse-c-multipart-s3-tests", "multipart_enc"
|
bktName, objName := "bucket-for-sse-c-multipart-s3-tests", "multipart_enc"
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
|
|
||||||
objLen := 30 * 1024 * 1024
|
objLen := 30 * 1024 * 1024
|
||||||
partSize := objLen / 6
|
partSize := objLen / 6
|
||||||
|
@ -168,7 +168,7 @@ func multipartUploadEncrypted(t *testing.T, tc *handlerContext, bktName, objName
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string) *InitiateMultipartUploadResponse {
|
func createMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string) *InitiateMultipartUploadResponse {
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
setHeaders(r, headers)
|
setHeaders(r, headers)
|
||||||
tc.Handler().CreateMultipartUploadHandler(w, r)
|
tc.Handler().CreateMultipartUploadHandler(w, r)
|
||||||
|
@ -190,7 +190,7 @@ func completeMultipartUpload(t *testing.T, tc *handlerContext, bktName, objName,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, objName, query, complete)
|
w, r := prepareTestFullRequest(tc, bktName, objName, query, complete)
|
||||||
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
@ -204,7 +204,7 @@ func uploadPart(t *testing.T, tc *handlerContext, bktName, objName, uploadID str
|
||||||
query.Set(uploadIDQuery, uploadID)
|
query.Set(uploadIDQuery, uploadID)
|
||||||
query.Set(partNumberQuery, strconv.Itoa(num))
|
query.Set(partNumberQuery, strconv.Itoa(num))
|
||||||
|
|
||||||
w, r := prepareTestRequestWithQuery(bktName, objName, query, partBody)
|
w, r := prepareTestRequestWithQuery(tc, bktName, objName, query, partBody)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
tc.Handler().UploadPartHandler(w, r)
|
tc.Handler().UploadPartHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
@ -218,9 +218,9 @@ func TestMultipartEncrypted(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-sse-c-multipart", "object-to-encrypt-multipart"
|
bktName, objName := "bucket-for-sse-c-multipart", "object-to-encrypt-multipart"
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
tc.Handler().CreateMultipartUploadHandler(w, r)
|
tc.Handler().CreateMultipartUploadHandler(w, r)
|
||||||
multipartInitInfo := &InitiateMultipartUploadResponse{}
|
multipartInitInfo := &InitiateMultipartUploadResponse{}
|
||||||
|
@ -233,7 +233,7 @@ func TestMultipartEncrypted(t *testing.T) {
|
||||||
query := make(url.Values)
|
query := make(url.Values)
|
||||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
||||||
query.Set(partNumberQuery, "1")
|
query.Set(partNumberQuery, "1")
|
||||||
w, r = prepareTestRequestWithQuery(bktName, objName, query, part1)
|
w, r = prepareTestRequestWithQuery(tc, bktName, objName, query, part1)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
tc.Handler().UploadPartHandler(w, r)
|
tc.Handler().UploadPartHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
@ -243,7 +243,7 @@ func TestMultipartEncrypted(t *testing.T) {
|
||||||
query = make(url.Values)
|
query = make(url.Values)
|
||||||
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
query.Set(uploadIDQuery, multipartInitInfo.UploadID)
|
||||||
query.Set(partNumberQuery, "2")
|
query.Set(partNumberQuery, "2")
|
||||||
w, r = prepareTestRequestWithQuery(bktName, objName, query, part2)
|
w, r = prepareTestRequestWithQuery(tc, bktName, objName, query, part2)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
tc.Handler().UploadPartHandler(w, r)
|
tc.Handler().UploadPartHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
@ -257,7 +257,7 @@ func TestMultipartEncrypted(t *testing.T) {
|
||||||
{ETag: part2ETag, PartNumber: 2},
|
{ETag: part2ETag, PartNumber: 2},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
w, r = prepareTestFullRequest(t, bktName, objName, query, complete)
|
w, r = prepareTestFullRequest(tc, bktName, objName, query, complete)
|
||||||
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
tc.Handler().CompleteMultipartUploadHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
|
@ -271,14 +271,14 @@ func TestMultipartEncrypted(t *testing.T) {
|
||||||
|
|
||||||
func putEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
func putEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
||||||
body := bytes.NewReader([]byte(content))
|
body := bytes.NewReader([]byte(content))
|
||||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
tc.Handler().PutObjectHandler(w, r)
|
tc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName string) ([]byte, http.Header) {
|
func getEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName string) ([]byte, http.Header) {
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
tc.Handler().GetObjectHandler(w, r)
|
tc.Handler().GetObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
@ -288,7 +288,7 @@ func getEncryptedObject(t *testing.T, tc *handlerContext, bktName, objName strin
|
||||||
}
|
}
|
||||||
|
|
||||||
func getEncryptedObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
func getEncryptedObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
setEncryptHeaders(r)
|
setEncryptHeaders(r)
|
||||||
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
|
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
|
||||||
tc.Handler().GetObjectHandler(w, r)
|
tc.Handler().GetObjectHandler(w, r)
|
||||||
|
|
|
@ -152,7 +152,7 @@ func TestGetRange(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-range", "object-to-range"
|
bktName, objName := "bucket-for-range", "object-to-range"
|
||||||
createTestBucket(tc.Context(), t, tc, bktName)
|
createTestBucket(tc, bktName)
|
||||||
|
|
||||||
content := "123456789abcdef"
|
content := "123456789abcdef"
|
||||||
putObjectContent(t, tc, bktName, objName, content)
|
putObjectContent(t, tc, bktName, objName, content)
|
||||||
|
@ -172,13 +172,13 @@ func TestGetRange(t *testing.T) {
|
||||||
|
|
||||||
func putObjectContent(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
func putObjectContent(t *testing.T, tc *handlerContext, bktName, objName, content string) {
|
||||||
body := bytes.NewReader([]byte(content))
|
body := bytes.NewReader([]byte(content))
|
||||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
w, r := prepareTestPayloadRequest(tc, bktName, objName, body)
|
||||||
tc.Handler().PutObjectHandler(w, r)
|
tc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func getObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
func getObjectRange(t *testing.T, tc *handlerContext, bktName, objName string, start, end int) []byte {
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
|
r.Header.Set("Range", fmt.Sprintf("bytes=%d-%d", start, end))
|
||||||
tc.Handler().GetObjectHandler(w, r)
|
tc.Handler().GetObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusPartialContent)
|
assertStatus(t, w, http.StatusPartialContent)
|
||||||
|
|
|
@ -22,12 +22,13 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
type handlerContext struct {
|
type handlerContext struct {
|
||||||
|
owner user.ID
|
||||||
|
t *testing.T
|
||||||
h *handler
|
h *handler
|
||||||
tp *layer.TestNeoFS
|
tp *layer.TestNeoFS
|
||||||
context context.Context
|
context context.Context
|
||||||
|
@ -61,6 +62,9 @@ func prepareHandlerContext(t *testing.T) *handlerContext {
|
||||||
return tp.ContainerID(name)
|
return tp.ContainerID(name)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
var owner user.ID
|
||||||
|
user.IDFromKey(&owner, key.PrivateKey.PublicKey)
|
||||||
|
|
||||||
layerCfg := &layer.Config{
|
layerCfg := &layer.Config{
|
||||||
Caches: layer.DefaultCachesConfigs(zap.NewExample()),
|
Caches: layer.DefaultCachesConfigs(zap.NewExample()),
|
||||||
AnonKey: layer.AnonymousKey{Key: key},
|
AnonKey: layer.AnonymousKey{Key: key},
|
||||||
|
@ -77,31 +81,33 @@ func prepareHandlerContext(t *testing.T) *handlerContext {
|
||||||
}
|
}
|
||||||
|
|
||||||
return &handlerContext{
|
return &handlerContext{
|
||||||
|
owner: owner,
|
||||||
|
t: t,
|
||||||
h: h,
|
h: h,
|
||||||
tp: tp,
|
tp: tp,
|
||||||
context: context.Background(),
|
context: context.WithValue(context.Background(), api.BoxData, newTestAccessBox(t, key)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestBucket(ctx context.Context, t *testing.T, h *handlerContext, bktName string) *data.BucketInfo {
|
func createTestBucket(hc *handlerContext, bktName string) *data.BucketInfo {
|
||||||
_, err := h.MockedPool().CreateContainer(ctx, layer.PrmContainerCreate{
|
_, err := hc.MockedPool().CreateContainer(hc.Context(), layer.PrmContainerCreate{
|
||||||
Creator: *usertest.ID(),
|
Creator: hc.owner,
|
||||||
Name: bktName,
|
Name: bktName,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
bktInfo, err := h.Layer().GetBucketInfo(ctx, bktName)
|
bktInfo, err := hc.Layer().GetBucketInfo(hc.Context(), bktName)
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
return bktInfo
|
return bktInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerContext, bktName string, conf *data.ObjectLockConfiguration) *data.BucketInfo {
|
func createTestBucketWithLock(hc *handlerContext, bktName string, conf *data.ObjectLockConfiguration) *data.BucketInfo {
|
||||||
cnrID, err := h.MockedPool().CreateContainer(ctx, layer.PrmContainerCreate{
|
cnrID, err := hc.MockedPool().CreateContainer(hc.Context(), layer.PrmContainerCreate{
|
||||||
Creator: *usertest.ID(),
|
Creator: hc.owner,
|
||||||
Name: bktName,
|
Name: bktName,
|
||||||
AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}},
|
AdditionalAttributes: [][2]string{{layer.AttributeLockEnabled, "true"}},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
var ownerID user.ID
|
var ownerID user.ID
|
||||||
|
|
||||||
|
@ -120,61 +126,61 @@ func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerConte
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
err = h.Layer().PutBucketSettings(ctx, sp)
|
err = hc.Layer().PutBucketSettings(hc.Context(), sp)
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
return bktInfo
|
return bktInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func createTestObject(ctx context.Context, t *testing.T, h *handlerContext, bktInfo *data.BucketInfo, objName string) *data.ObjectInfo {
|
func createTestObject(hc *handlerContext, bktInfo *data.BucketInfo, objName string) *data.ObjectInfo {
|
||||||
content := make([]byte, 1024)
|
content := make([]byte, 1024)
|
||||||
_, err := rand.Read(content)
|
_, err := rand.Read(content)
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
header := map[string]string{
|
header := map[string]string{
|
||||||
object.AttributeTimestamp: strconv.FormatInt(time.Now().UTC().Unix(), 10),
|
object.AttributeTimestamp: strconv.FormatInt(time.Now().UTC().Unix(), 10),
|
||||||
}
|
}
|
||||||
|
|
||||||
objInfo, err := h.Layer().PutObject(ctx, &layer.PutObjectParams{
|
objInfo, err := hc.Layer().PutObject(hc.Context(), &layer.PutObjectParams{
|
||||||
BktInfo: bktInfo,
|
BktInfo: bktInfo,
|
||||||
Object: objName,
|
Object: objName,
|
||||||
Size: int64(len(content)),
|
Size: int64(len(content)),
|
||||||
Reader: bytes.NewReader(content),
|
Reader: bytes.NewReader(content),
|
||||||
Header: header,
|
Header: header,
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
return objInfo
|
return objInfo
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareTestRequest(t *testing.T, bktName, objName string, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
func prepareTestRequest(hc *handlerContext, bktName, objName string, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
||||||
return prepareTestFullRequest(t, bktName, objName, make(url.Values), body)
|
return prepareTestFullRequest(hc, bktName, objName, make(url.Values), body)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareTestFullRequest(t *testing.T, bktName, objName string, query url.Values, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
func prepareTestFullRequest(hc *handlerContext, bktName, objName string, query url.Values, body interface{}) (*httptest.ResponseRecorder, *http.Request) {
|
||||||
rawBody, err := xml.Marshal(body)
|
rawBody, err := xml.Marshal(body)
|
||||||
require.NoError(t, err)
|
require.NoError(hc.t, err)
|
||||||
|
|
||||||
return prepareTestRequestWithQuery(bktName, objName, query, rawBody)
|
return prepareTestRequestWithQuery(hc, bktName, objName, query, rawBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareTestRequestWithQuery(bktName, objName string, query url.Values, body []byte) (*httptest.ResponseRecorder, *http.Request) {
|
func prepareTestRequestWithQuery(hc *handlerContext, bktName, objName string, query url.Values, body []byte) (*httptest.ResponseRecorder, *http.Request) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
r := httptest.NewRequest(http.MethodPut, defaultURL, bytes.NewReader(body))
|
r := httptest.NewRequest(http.MethodPut, defaultURL, bytes.NewReader(body))
|
||||||
r.URL.RawQuery = query.Encode()
|
r.URL.RawQuery = query.Encode()
|
||||||
|
|
||||||
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
||||||
r = r.WithContext(api.SetReqInfo(r.Context(), reqInfo))
|
r = r.WithContext(api.SetReqInfo(hc.Context(), reqInfo))
|
||||||
|
|
||||||
return w, r
|
return w, r
|
||||||
}
|
}
|
||||||
|
|
||||||
func prepareTestPayloadRequest(bktName, objName string, payload io.Reader) (*httptest.ResponseRecorder, *http.Request) {
|
func prepareTestPayloadRequest(hc *handlerContext, bktName, objName string, payload io.Reader) (*httptest.ResponseRecorder, *http.Request) {
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
r := httptest.NewRequest(http.MethodPut, defaultURL, payload)
|
r := httptest.NewRequest(http.MethodPut, defaultURL, payload)
|
||||||
|
|
||||||
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
reqInfo := api.NewReqInfo(w, r, api.ObjectRequest{Bucket: bktName, Object: objName})
|
||||||
r = r.WithContext(api.SetReqInfo(r.Context(), reqInfo))
|
r = r.WithContext(api.SetReqInfo(hc.Context(), reqInfo))
|
||||||
|
|
||||||
return w, r
|
return w, r
|
||||||
}
|
}
|
||||||
|
|
|
@ -6,81 +6,101 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||||
|
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestConditionalHead(t *testing.T) {
|
func TestConditionalHead(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-for-conditional"
|
bktName, objName := "bucket-for-conditional", "object"
|
||||||
createTestBucket(ctx, t, tc, bktName)
|
_, objInfo := createBucketAndObject(tc, bktName, objName)
|
||||||
bktInfo, err := tc.Layer().GetBucketInfo(ctx, bktName)
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
objName := "object"
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
objInfo := createTestObject(ctx, t, tc, bktInfo, objName)
|
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
tc.Handler().HeadObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
etag := w.Result().Header.Get(api.ETag)
|
etag := w.Result().Header.Get(api.ETag)
|
||||||
lastModified := w.Result().Header.Get(api.LastModified)
|
|
||||||
_ = lastModified
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headers := map[string]string{api.IfMatch: etag}
|
||||||
r.Header.Set(api.IfMatch, etag)
|
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headers = map[string]string{api.IfMatch: "etag"}
|
||||||
r.Header.Set(api.IfMatch, "etag")
|
headObject(t, tc, bktName, objName, headers, http.StatusPreconditionFailed)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusPreconditionFailed)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headers = map[string]string{api.IfUnmodifiedSince: objInfo.Created.Add(time.Minute).Format(http.TimeFormat)}
|
||||||
unmodifiedSince := objInfo.Created.Add(time.Minute)
|
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||||
r.Header.Set(api.IfUnmodifiedSince, unmodifiedSince.Format(http.TimeFormat))
|
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
|
||||||
var zeroTime time.Time
|
var zeroTime time.Time
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headers = map[string]string{api.IfUnmodifiedSince: zeroTime.UTC().Format(http.TimeFormat)}
|
||||||
r.Header.Set(api.IfUnmodifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
headObject(t, tc, bktName, objName, headers, http.StatusPreconditionFailed)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusPreconditionFailed)
|
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headers = map[string]string{
|
||||||
r.Header.Set(api.IfMatch, etag)
|
api.IfMatch: etag,
|
||||||
r.Header.Set(api.IfUnmodifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
api.IfUnmodifiedSince: zeroTime.UTC().Format(http.TimeFormat),
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
}
|
||||||
assertStatus(t, w, http.StatusOK)
|
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headers = map[string]string{api.IfNoneMatch: etag}
|
||||||
r.Header.Set(api.IfNoneMatch, etag)
|
headObject(t, tc, bktName, objName, headers, http.StatusNotModified)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
|
||||||
assertStatus(t, w, http.StatusNotModified)
|
headers = map[string]string{api.IfNoneMatch: "etag"}
|
||||||
|
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
|
||||||
r.Header.Set(api.IfNoneMatch, "etag")
|
headers = map[string]string{api.IfModifiedSince: zeroTime.UTC().Format(http.TimeFormat)}
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
headObject(t, tc, bktName, objName, headers, http.StatusOK)
|
||||||
assertStatus(t, w, http.StatusOK)
|
|
||||||
|
headers = map[string]string{api.IfModifiedSince: time.Now().Add(time.Minute).UTC().Format(http.TimeFormat)}
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
headObject(t, tc, bktName, objName, headers, http.StatusNotModified)
|
||||||
r.Header.Set(api.IfModifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
headers = map[string]string{
|
||||||
assertStatus(t, w, http.StatusOK)
|
api.IfNoneMatch: etag,
|
||||||
|
api.IfModifiedSince: zeroTime.UTC().Format(http.TimeFormat),
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
}
|
||||||
r.Header.Set(api.IfModifiedSince, time.Now().Add(time.Minute).UTC().Format(http.TimeFormat))
|
headObject(t, tc, bktName, objName, headers, http.StatusNotModified)
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
}
|
||||||
assertStatus(t, w, http.StatusNotModified)
|
|
||||||
|
func headObject(t *testing.T, tc *handlerContext, bktName, objName string, headers map[string]string, status int) {
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
r.Header.Set(api.IfNoneMatch, etag)
|
|
||||||
r.Header.Set(api.IfModifiedSince, zeroTime.UTC().Format(http.TimeFormat))
|
for key, val := range headers {
|
||||||
tc.Handler().HeadObjectHandler(w, r)
|
r.Header.Set(key, val)
|
||||||
assertStatus(t, w, http.StatusNotModified)
|
}
|
||||||
|
|
||||||
|
tc.Handler().HeadObjectHandler(w, r)
|
||||||
|
assertStatus(t, w, status)
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvalidAccessThroughCache(t *testing.T) {
|
||||||
|
tc := prepareHandlerContext(t)
|
||||||
|
bktName, objName := "bucket-for-cache", "obj-for-cache"
|
||||||
|
createBucketAndObject(tc, bktName, objName)
|
||||||
|
|
||||||
|
headObject(t, tc, bktName, objName, nil, http.StatusOK)
|
||||||
|
|
||||||
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
|
tc.Handler().HeadObjectHandler(w, r.WithContext(context.WithValue(r.Context(), api.BoxData, newTestAccessBox(t, nil))))
|
||||||
|
assertStatus(t, w, http.StatusForbidden)
|
||||||
|
}
|
||||||
|
|
||||||
|
func newTestAccessBox(t *testing.T, key *keys.PrivateKey) *accessbox.Box {
|
||||||
|
var err error
|
||||||
|
if key == nil {
|
||||||
|
key, err = keys.NewPrivateKey()
|
||||||
|
require.NoError(t, err)
|
||||||
|
}
|
||||||
|
|
||||||
|
var btoken bearer.Token
|
||||||
|
btoken.SetEACLTable(*eacl.NewTable())
|
||||||
|
err = btoken.Sign(key.PrivateKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
return &accessbox.Box{
|
||||||
|
Gate: &accessbox.GateData{
|
||||||
|
BearerToken: &btoken,
|
||||||
|
},
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -245,13 +245,13 @@ func TestPutBucketLockConfigurationHandler(t *testing.T) {
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktLockDisabled := "bucket-lock-disabled"
|
bktLockDisabled := "bucket-lock-disabled"
|
||||||
createTestBucket(ctx, t, hc, bktLockDisabled)
|
createTestBucket(hc, bktLockDisabled)
|
||||||
|
|
||||||
bktLockEnabled := "bucket-lock-enabled"
|
bktLockEnabled := "bucket-lock-enabled"
|
||||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabled, nil)
|
createTestBucketWithLock(hc, bktLockEnabled, nil)
|
||||||
|
|
||||||
bktLockEnabledWithOldConfig := "bucket-lock-enabled-old-conf"
|
bktLockEnabledWithOldConfig := "bucket-lock-enabled-old-conf"
|
||||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabledWithOldConfig,
|
createTestBucketWithLock(hc, bktLockEnabledWithOldConfig,
|
||||||
&data.ObjectLockConfiguration{
|
&data.ObjectLockConfiguration{
|
||||||
Rule: &data.ObjectLockRule{
|
Rule: &data.ObjectLockRule{
|
||||||
DefaultRetention: &data.DefaultRetention{
|
DefaultRetention: &data.DefaultRetention{
|
||||||
|
@ -331,14 +331,13 @@ func TestPutBucketLockConfigurationHandler(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGetBucketLockConfigurationHandler(t *testing.T) {
|
func TestGetBucketLockConfigurationHandler(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktLockDisabled := "bucket-lock-disabled"
|
bktLockDisabled := "bucket-lock-disabled"
|
||||||
createTestBucket(ctx, t, hc, bktLockDisabled)
|
createTestBucket(hc, bktLockDisabled)
|
||||||
|
|
||||||
bktLockEnabled := "bucket-lock-enabled"
|
bktLockEnabled := "bucket-lock-enabled"
|
||||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabled, nil)
|
createTestBucketWithLock(hc, bktLockEnabled, nil)
|
||||||
|
|
||||||
oldConfig := &data.ObjectLockConfiguration{
|
oldConfig := &data.ObjectLockConfiguration{
|
||||||
Rule: &data.ObjectLockRule{
|
Rule: &data.ObjectLockRule{
|
||||||
|
@ -349,7 +348,7 @@ func TestGetBucketLockConfigurationHandler(t *testing.T) {
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
bktLockEnabledWithOldConfig := "bucket-lock-enabled-old-conf"
|
bktLockEnabledWithOldConfig := "bucket-lock-enabled-old-conf"
|
||||||
createTestBucketWithLock(ctx, t, hc, bktLockEnabledWithOldConfig, oldConfig)
|
createTestBucketWithLock(hc, bktLockEnabledWithOldConfig, oldConfig)
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
|
@ -416,44 +415,43 @@ func assertS3Error(t *testing.T, w *httptest.ResponseRecorder, expectedError api
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectLegalHold(t *testing.T) {
|
func TestObjectLegalHold(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-lock-enabled"
|
bktName := "bucket-lock-enabled"
|
||||||
bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
bktInfo := createTestBucketWithLock(hc, bktName, nil)
|
||||||
|
|
||||||
objName := "obj-for-legal-hold"
|
objName := "obj-for-legal-hold"
|
||||||
createTestObject(ctx, t, hc, bktInfo, objName)
|
createTestObject(hc, bktInfo, objName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||||
assertLegalHold(t, w, legalHoldOff)
|
assertLegalHold(t, w, legalHoldOff)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||||
require.Equal(t, http.StatusOK, w.Code)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||||
assertLegalHold(t, w, legalHoldOn)
|
assertLegalHold(t, w, legalHoldOn)
|
||||||
|
|
||||||
// to make sure put hold is an idempotent operation
|
// to make sure put hold is an idempotent operation
|
||||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOn})
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||||
require.Equal(t, http.StatusOK, w.Code)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||||
require.Equal(t, http.StatusOK, w.Code)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||||
assertLegalHold(t, w, legalHoldOff)
|
assertLegalHold(t, w, legalHoldOff)
|
||||||
|
|
||||||
// to make sure put hold is an idempotent operation
|
// to make sure put hold is an idempotent operation
|
||||||
w, r = prepareTestRequest(t, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
w, r = prepareTestRequest(hc, bktName, objName, &data.LegalHold{Status: legalHoldOff})
|
||||||
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
hc.Handler().PutObjectLegalHoldHandler(w, r)
|
||||||
require.Equal(t, http.StatusOK, w.Code)
|
assertStatus(t, w, http.StatusOK)
|
||||||
}
|
}
|
||||||
|
|
||||||
func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string) {
|
func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string) {
|
||||||
|
@ -465,44 +463,43 @@ func assertLegalHold(t *testing.T, w *httptest.ResponseRecorder, status string)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestObjectRetention(t *testing.T) {
|
func TestObjectRetention(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-lock-enabled"
|
bktName := "bucket-lock-enabled"
|
||||||
bktInfo := createTestBucketWithLock(ctx, t, hc, bktName, nil)
|
bktInfo := createTestBucketWithLock(hc, bktName, nil)
|
||||||
|
|
||||||
objName := "obj-for-retention"
|
objName := "obj-for-retention"
|
||||||
createTestObject(ctx, t, hc, bktInfo, objName)
|
createTestObject(hc, bktInfo, objName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrNoSuchKey))
|
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrNoSuchKey))
|
||||||
|
|
||||||
retention := &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
retention := &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
||||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
assertRetention(t, w, retention)
|
assertRetention(t, w, retention)
|
||||||
|
|
||||||
retention = &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().UTC().Add(time.Minute).Format(time.RFC3339)}
|
retention = &data.Retention{Mode: governanceMode, RetainUntilDate: time.Now().UTC().Add(time.Minute).Format(time.RFC3339)}
|
||||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
||||||
|
|
||||||
retention = &data.Retention{Mode: complianceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
retention = &data.Retention{Mode: complianceMode, RetainUntilDate: time.Now().Add(time.Minute).UTC().Format(time.RFC3339)}
|
||||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||||
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
assertRetention(t, w, retention)
|
assertRetention(t, w, retention)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, retention)
|
w, r = prepareTestRequest(hc, bktName, objName, retention)
|
||||||
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
r.Header.Set(api.AmzBypassGovernanceRetention, strconv.FormatBool(true))
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||||
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
assertS3Error(t, w, apiErrors.GetAPIError(apiErrors.ErrInternalError))
|
||||||
|
@ -518,7 +515,6 @@ func assertRetention(t *testing.T, w *httptest.ResponseRecorder, retention *data
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPutObjectWithLock(t *testing.T) {
|
func TestPutObjectWithLock(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-lock-enabled"
|
bktName := "bucket-lock-enabled"
|
||||||
|
@ -531,15 +527,15 @@ func TestPutObjectWithLock(t *testing.T) {
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
createTestBucketWithLock(ctx, t, hc, bktName, lockConfig)
|
createTestBucketWithLock(hc, bktName, lockConfig)
|
||||||
|
|
||||||
objDefault := "obj-default-retention"
|
objDefault := "obj-default-retention"
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objDefault, nil)
|
w, r := prepareTestRequest(hc, bktName, objDefault, nil)
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objDefault, nil)
|
w, r = prepareTestRequest(hc, bktName, objDefault, nil)
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
expectedRetention := &data.Retention{
|
expectedRetention := &data.Retention{
|
||||||
Mode: governanceMode,
|
Mode: governanceMode,
|
||||||
|
@ -547,12 +543,12 @@ func TestPutObjectWithLock(t *testing.T) {
|
||||||
}
|
}
|
||||||
assertRetentionApproximate(t, w, expectedRetention, 1)
|
assertRetentionApproximate(t, w, expectedRetention, 1)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objDefault, nil)
|
w, r = prepareTestRequest(hc, bktName, objDefault, nil)
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||||
assertLegalHold(t, w, legalHoldOff)
|
assertLegalHold(t, w, legalHoldOff)
|
||||||
|
|
||||||
objOverride := "obj-override-retention"
|
objOverride := "obj-override-retention"
|
||||||
w, r = prepareTestRequest(t, bktName, objOverride, nil)
|
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
||||||
r.Header.Set(api.AmzObjectLockMode, complianceMode)
|
r.Header.Set(api.AmzObjectLockMode, complianceMode)
|
||||||
r.Header.Set(api.AmzObjectLockLegalHold, legalHoldOn)
|
r.Header.Set(api.AmzObjectLockLegalHold, legalHoldOn)
|
||||||
r.Header.Set(api.AmzBypassGovernanceRetention, "true")
|
r.Header.Set(api.AmzBypassGovernanceRetention, "true")
|
||||||
|
@ -560,7 +556,7 @@ func TestPutObjectWithLock(t *testing.T) {
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objOverride, nil)
|
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
||||||
hc.Handler().GetObjectRetentionHandler(w, r)
|
hc.Handler().GetObjectRetentionHandler(w, r)
|
||||||
expectedRetention = &data.Retention{
|
expectedRetention = &data.Retention{
|
||||||
Mode: complianceMode,
|
Mode: complianceMode,
|
||||||
|
@ -568,7 +564,7 @@ func TestPutObjectWithLock(t *testing.T) {
|
||||||
}
|
}
|
||||||
assertRetentionApproximate(t, w, expectedRetention, 1)
|
assertRetentionApproximate(t, w, expectedRetention, 1)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objOverride, nil)
|
w, r = prepareTestRequest(hc, bktName, objOverride, nil)
|
||||||
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
hc.Handler().GetObjectLegalHoldHandler(w, r)
|
||||||
assertLegalHold(t, w, legalHoldOn)
|
assertLegalHold(t, w, legalHoldOn)
|
||||||
}
|
}
|
||||||
|
@ -577,7 +573,7 @@ func TestPutLockErrors(t *testing.T) {
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-lock-enabled", "object"
|
bktName, objName := "bucket-lock-enabled", "object"
|
||||||
createTestBucketWithLock(hc.Context(), t, hc, bktName, nil)
|
createTestBucketWithLock(hc, bktName, nil)
|
||||||
|
|
||||||
headers := map[string]string{api.AmzObjectLockMode: complianceMode}
|
headers := map[string]string{api.AmzObjectLockMode: complianceMode}
|
||||||
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrObjectLockInvalidHeaders)
|
putObjectWithLockFailed(t, hc, bktName, objName, headers, apiErrors.ErrObjectLockInvalidHeaders)
|
||||||
|
@ -611,7 +607,7 @@ func TestPutLockErrors(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName string, headers map[string]string, errCode apiErrors.ErrorCode) {
|
func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName string, headers map[string]string, errCode apiErrors.ErrorCode) {
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
|
|
||||||
for key, val := range headers {
|
for key, val := range headers {
|
||||||
r.Header.Set(key, val)
|
r.Header.Set(key, val)
|
||||||
|
@ -622,7 +618,7 @@ func putObjectWithLockFailed(t *testing.T, hc *handlerContext, bktName, objName
|
||||||
}
|
}
|
||||||
|
|
||||||
func putObjectRetentionFailed(t *testing.T, hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apiErrors.ErrorCode) {
|
func putObjectRetentionFailed(t *testing.T, hc *handlerContext, bktName, objName string, retention *data.Retention, errCode apiErrors.ErrorCode) {
|
||||||
w, r := prepareTestRequest(t, bktName, objName, retention)
|
w, r := prepareTestRequest(hc, bktName, objName, retention)
|
||||||
hc.Handler().PutObjectRetentionHandler(w, r)
|
hc.Handler().PutObjectRetentionHandler(w, r)
|
||||||
assertS3Error(t, w, apiErrors.GetAPIError(errCode))
|
assertS3Error(t, w, apiErrors.GetAPIError(errCode))
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,6 @@ package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/url"
|
"net/url"
|
||||||
"strconv"
|
"strconv"
|
||||||
|
@ -43,30 +42,29 @@ func TestParseContinuationToken(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestListObjectNullVersions(t *testing.T) {
|
func TestListObjectNullVersions(t *testing.T) {
|
||||||
ctx := context.Background()
|
|
||||||
hc := prepareHandlerContext(t)
|
hc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName := "bucket-versioning-enabled"
|
bktName := "bucket-versioning-enabled"
|
||||||
createTestBucket(ctx, t, hc, bktName)
|
createTestBucket(hc, bktName)
|
||||||
|
|
||||||
objName := "object"
|
objName := "object"
|
||||||
|
|
||||||
body := bytes.NewReader([]byte("content"))
|
body := bytes.NewReader([]byte("content"))
|
||||||
w, r := prepareTestPayloadRequest(bktName, objName, body)
|
w, r := prepareTestPayloadRequest(hc, bktName, objName, body)
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
versioning := &VersioningConfiguration{Status: "Enabled"}
|
versioning := &VersioningConfiguration{Status: "Enabled"}
|
||||||
w, r = prepareTestRequest(t, bktName, objName, versioning)
|
w, r = prepareTestRequest(hc, bktName, objName, versioning)
|
||||||
hc.Handler().PutBucketVersioningHandler(w, r)
|
hc.Handler().PutBucketVersioningHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
body2 := bytes.NewReader([]byte("content2"))
|
body2 := bytes.NewReader([]byte("content2"))
|
||||||
w, r = prepareTestPayloadRequest(bktName, objName, body2)
|
w, r = prepareTestPayloadRequest(hc, bktName, objName, body2)
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestRequest(t, bktName, objName, nil)
|
w, r = prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().ListBucketObjectVersionsHandler(w, r)
|
hc.Handler().ListBucketObjectVersionsHandler(w, r)
|
||||||
|
|
||||||
result := &ListObjectsVersionsResponse{}
|
result := &ListObjectsVersionsResponse{}
|
||||||
|
@ -81,10 +79,10 @@ func TestS3CompatibilityBucketListV2BothContinuationTokenStartAfter(t *testing.T
|
||||||
|
|
||||||
bktName := "bucket-for-listing"
|
bktName := "bucket-for-listing"
|
||||||
objects := []string{"bar", "baz", "foo", "quxx"}
|
objects := []string{"bar", "baz", "foo", "quxx"}
|
||||||
bktInfo, _ := createBucketAndObject(t, tc, bktName, objects[0])
|
bktInfo, _ := createBucketAndObject(tc, bktName, objects[0])
|
||||||
|
|
||||||
for _, objName := range objects[1:] {
|
for _, objName := range objects[1:] {
|
||||||
createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
createTestObject(tc, bktInfo, objName)
|
||||||
}
|
}
|
||||||
|
|
||||||
listV2Response1 := listObjectsV2(t, tc, bktName, "", "", "bar", "", 1)
|
listV2Response1 := listObjectsV2(t, tc, bktName, "", "", "bar", "", 1)
|
||||||
|
@ -106,10 +104,10 @@ func TestS3BucketListDelimiterBasic(t *testing.T) {
|
||||||
|
|
||||||
bktName := "bucket-for-listing"
|
bktName := "bucket-for-listing"
|
||||||
objects := []string{"foo/bar", "foo/bar/xyzzy", "quux/thud", "asdf"}
|
objects := []string{"foo/bar", "foo/bar/xyzzy", "quux/thud", "asdf"}
|
||||||
bktInfo, _ := createBucketAndObject(t, tc, bktName, objects[0])
|
bktInfo, _ := createBucketAndObject(tc, bktName, objects[0])
|
||||||
|
|
||||||
for _, objName := range objects[1:] {
|
for _, objName := range objects[1:] {
|
||||||
createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
createTestObject(tc, bktInfo, objName)
|
||||||
}
|
}
|
||||||
|
|
||||||
listV1Response := listObjectsV1(t, tc, bktName, "", "/", "", -1)
|
listV1Response := listObjectsV1(t, tc, bktName, "", "/", "", -1)
|
||||||
|
@ -125,10 +123,10 @@ func TestS3BucketListV2DelimiterPrefix(t *testing.T) {
|
||||||
|
|
||||||
bktName := "bucket-for-listingv2"
|
bktName := "bucket-for-listingv2"
|
||||||
objects := []string{"asdf", "boo/bar", "boo/baz/xyzzy", "cquux/thud", "cquux/bla"}
|
objects := []string{"asdf", "boo/bar", "boo/baz/xyzzy", "cquux/thud", "cquux/bla"}
|
||||||
bktInfo, _ := createBucketAndObject(t, tc, bktName, objects[0])
|
bktInfo, _ := createBucketAndObject(tc, bktName, objects[0])
|
||||||
|
|
||||||
for _, objName := range objects[1:] {
|
for _, objName := range objects[1:] {
|
||||||
createTestObject(tc.Context(), t, tc, bktInfo, objName)
|
createTestObject(tc, bktInfo, objName)
|
||||||
}
|
}
|
||||||
|
|
||||||
var empty []string
|
var empty []string
|
||||||
|
@ -158,7 +156,7 @@ func listObjectsV2(t *testing.T, tc *handlerContext, bktName, prefix, delimiter,
|
||||||
query.Add("continuation-token", continuationToken)
|
query.Add("continuation-token", continuationToken)
|
||||||
}
|
}
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, "", query, nil)
|
w, r := prepareTestFullRequest(tc, bktName, "", query, nil)
|
||||||
tc.Handler().ListObjectsV2Handler(w, r)
|
tc.Handler().ListObjectsV2Handler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
res := &ListObjectsV2Response{}
|
res := &ListObjectsV2Response{}
|
||||||
|
@ -208,7 +206,7 @@ func listObjectsV1(t *testing.T, tc *handlerContext, bktName, prefix, delimiter,
|
||||||
query.Add("marker", marker)
|
query.Add("marker", marker)
|
||||||
}
|
}
|
||||||
|
|
||||||
w, r := prepareTestFullRequest(t, bktName, "", query, nil)
|
w, r := prepareTestFullRequest(tc, bktName, "", query, nil)
|
||||||
tc.Handler().ListObjectsV1Handler(w, r)
|
tc.Handler().ListObjectsV1Handler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
res := &ListObjectsV1Response{}
|
res := &ListObjectsV1Response{}
|
||||||
|
|
|
@ -111,9 +111,9 @@ func TestPutObjectOverrideCopiesNumber(t *testing.T) {
|
||||||
tc := prepareHandlerContext(t)
|
tc := prepareHandlerContext(t)
|
||||||
|
|
||||||
bktName, objName := "bucket-for-copies-number", "object-for-copies-number"
|
bktName, objName := "bucket-for-copies-number", "object-for-copies-number"
|
||||||
bktInfo := createTestBucket(tc.Context(), t, tc, bktName)
|
bktInfo := createTestBucket(tc, bktName)
|
||||||
|
|
||||||
w, r := prepareTestRequest(t, bktName, objName, nil)
|
w, r := prepareTestRequest(tc, bktName, objName, nil)
|
||||||
r.Header.Set(api.MetadataPrefix+strings.ToUpper(layer.AttributeNeofsCopiesNumber), "1")
|
r.Header.Set(api.MetadataPrefix+strings.ToUpper(layer.AttributeNeofsCopiesNumber), "1")
|
||||||
tc.Handler().PutObjectHandler(w, r)
|
tc.Handler().PutObjectHandler(w, r)
|
||||||
|
|
||||||
|
|
|
@ -11,6 +11,9 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
objectv2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
objectv2 "github.com/nspcc-dev/neofs-api-go/v2/object"
|
||||||
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||||
|
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||||
|
"github.com/nspcc-dev/neofs-sdk-go/bearer"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
"github.com/nspcc-dev/neofs-sdk-go/checksum"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/container"
|
"github.com/nspcc-dev/neofs-sdk-go/container"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
|
@ -127,7 +130,7 @@ func (t *TestNeoFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, erro
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) ReadObject(_ context.Context, prm PrmObjectRead) (*ObjectPart, error) {
|
func (t *TestNeoFS) ReadObject(ctx context.Context, prm PrmObjectRead) (*ObjectPart, error) {
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetContainer(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObject(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
@ -135,6 +138,11 @@ func (t *TestNeoFS) ReadObject(_ context.Context, prm PrmObjectRead) (*ObjectPar
|
||||||
sAddr := addr.EncodeToString()
|
sAddr := addr.EncodeToString()
|
||||||
|
|
||||||
if obj, ok := t.objects[sAddr]; ok {
|
if obj, ok := t.objects[sAddr]; ok {
|
||||||
|
owner := getOwner(ctx)
|
||||||
|
if !obj.OwnerID().Equals(owner) {
|
||||||
|
return nil, ErrAccessDenied
|
||||||
|
}
|
||||||
|
|
||||||
payload := obj.Payload()
|
payload := obj.Payload()
|
||||||
|
|
||||||
if prm.PayloadRange[0]+prm.PayloadRange[1] > 0 {
|
if prm.PayloadRange[0]+prm.PayloadRange[1] > 0 {
|
||||||
|
@ -151,7 +159,7 @@ func (t *TestNeoFS) ReadObject(_ context.Context, prm PrmObjectRead) (*ObjectPar
|
||||||
return nil, fmt.Errorf("object not found %s", addr)
|
return nil, fmt.Errorf("object not found %s", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID, error) {
|
func (t *TestNeoFS) CreateObject(ctx context.Context, prm PrmObjectCreate) (oid.ID, error) {
|
||||||
b := make([]byte, 32)
|
b := make([]byte, 32)
|
||||||
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
if _, err := io.ReadFull(rand.Reader, b); err != nil {
|
||||||
return oid.ID{}, err
|
return oid.ID{}, err
|
||||||
|
@ -181,6 +189,7 @@ func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID
|
||||||
obj.SetPayloadSize(prm.PayloadSize)
|
obj.SetPayloadSize(prm.PayloadSize)
|
||||||
obj.SetAttributes(attrs...)
|
obj.SetAttributes(attrs...)
|
||||||
obj.SetCreationEpoch(t.currentEpoch)
|
obj.SetCreationEpoch(t.currentEpoch)
|
||||||
|
obj.SetOwnerID(&prm.Creator)
|
||||||
t.currentEpoch++
|
t.currentEpoch++
|
||||||
|
|
||||||
if len(prm.Locks) > 0 {
|
if len(prm.Locks) > 0 {
|
||||||
|
@ -209,12 +218,19 @@ func (t *TestNeoFS) CreateObject(_ context.Context, prm PrmObjectCreate) (oid.ID
|
||||||
return objID, nil
|
return objID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) DeleteObject(_ context.Context, prm PrmObjectDelete) error {
|
func (t *TestNeoFS) DeleteObject(ctx context.Context, prm PrmObjectDelete) error {
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
addr.SetContainer(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObject(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
|
||||||
|
if obj, ok := t.objects[addr.EncodeToString()]; ok {
|
||||||
|
owner := getOwner(ctx)
|
||||||
|
if !obj.OwnerID().Equals(owner) {
|
||||||
|
return ErrAccessDenied
|
||||||
|
}
|
||||||
|
|
||||||
delete(t.objects, addr.EncodeToString())
|
delete(t.objects, addr.EncodeToString())
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -260,3 +276,11 @@ func (t *TestNeoFS) ContainerEACL(_ context.Context, cnrID cid.ID) (*eacl.Table,
|
||||||
|
|
||||||
return table, nil
|
return table, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getOwner(ctx context.Context) user.ID {
|
||||||
|
if bd, ok := ctx.Value(api.BoxData).(*accessbox.Box); ok && bd != nil && bd.Gate != nil && bd.Gate.BearerToken != nil {
|
||||||
|
return bearer.ResolveIssuer(*bd.Gate.BearerToken)
|
||||||
|
}
|
||||||
|
|
||||||
|
return user.ID{}
|
||||||
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@ import (
|
||||||
bearertest "github.com/nspcc-dev/neofs-sdk-go/bearer/test"
|
bearertest "github.com/nspcc-dev/neofs-sdk-go/bearer/test"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -159,6 +159,9 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
config = cachesConfig[0]
|
config = cachesConfig[0]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var owner user.ID
|
||||||
|
user.IDFromKey(&owner, key.PrivateKey.PublicKey)
|
||||||
|
|
||||||
layerCfg := &Config{
|
layerCfg := &Config{
|
||||||
Caches: config,
|
Caches: config,
|
||||||
AnonKey: AnonymousKey{Key: key},
|
AnonKey: AnonymousKey{Key: key},
|
||||||
|
@ -170,7 +173,7 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
layer: NewLayer(logger, tp, layerCfg),
|
layer: NewLayer(logger, tp, layerCfg),
|
||||||
bktInfo: &data.BucketInfo{
|
bktInfo: &data.BucketInfo{
|
||||||
Name: bktName,
|
Name: bktName,
|
||||||
Owner: *usertest.ID(),
|
Owner: owner,
|
||||||
CID: bktID,
|
CID: bktID,
|
||||||
},
|
},
|
||||||
obj: "obj1",
|
obj: "obj1",
|
||||||
|
|
Loading…
Reference in a new issue