forked from TrueCloudLab/frostfs-s3-gw
[#458] *: Refactor working with NeoFS identities
Pull latest changes from NeoFS SDK Go library. Decrease redundant and unsafe usage of ID pointers. Use `EncodeToString` method in order to calculate protocol strings. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
3f0dbcc995
commit
087d500c5f
34 changed files with 259 additions and 280 deletions
|
@ -21,7 +21,7 @@ import (
|
||||||
apiErrors "github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
apiErrors "github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/creds/tokens"
|
"github.com/nspcc-dev/neofs-s3-gw/creds/tokens"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// authorizationFieldRegexp -- is regexp for credentials with Base58 encoded cid and oid and '0' (zero) as delimiter.
|
// authorizationFieldRegexp -- is regexp for credentials with Base58 encoded cid and oid and '0' (zero) as delimiter.
|
||||||
|
@ -105,12 +105,12 @@ func (c *center) parseAuthHeader(header string) (*authHeader, error) {
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (a *authHeader) getAddress() (*address.Address, error) {
|
func (a *authHeader) getAddress() (*oid.Address, error) {
|
||||||
addr := address.NewAddress()
|
var addr oid.Address
|
||||||
if err := addr.Parse(strings.ReplaceAll(a.AccessKeyID, "0", "/")); err != nil {
|
if err := addr.DecodeString(strings.ReplaceAll(a.AccessKeyID, "0", "/")); err != nil {
|
||||||
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidAccessKeyID)
|
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidAccessKeyID)
|
||||||
}
|
}
|
||||||
return addr, nil
|
return &addr, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) {
|
func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) {
|
||||||
|
@ -142,7 +142,7 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
box, err := c.cli.GetBox(r.Context(), addr)
|
box, err := c.cli.GetBox(r.Context(), *addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -179,8 +179,8 @@ func (c *center) checkFormData(r *http.Request) (*accessbox.Box, error) {
|
||||||
return nil, fmt.Errorf("failed to parse x-amz-date field: %w", err)
|
return nil, fmt.Errorf("failed to parse x-amz-date field: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := address.NewAddress()
|
var addr oid.Address
|
||||||
if err = addr.Parse(strings.ReplaceAll(submatches["access_key_id"], "0", "/")); err != nil {
|
if err = addr.DecodeString(strings.ReplaceAll(submatches["access_key_id"], "0", "/")); err != nil {
|
||||||
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidAccessKeyID)
|
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidAccessKeyID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
10
api/cache/accessbox.go
vendored
10
api/cache/accessbox.go
vendored
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/bluele/gcache"
|
"github.com/bluele/gcache"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
type (
|
type (
|
||||||
|
@ -41,8 +41,8 @@ func NewAccessBoxCache(config *Config) *AccessBoxCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a cached object.
|
// Get returns a cached object.
|
||||||
func (o *AccessBoxCache) Get(address *address.Address) *accessbox.Box {
|
func (o *AccessBoxCache) Get(address oid.Address) *accessbox.Box {
|
||||||
entry, err := o.cache.Get(address.String())
|
entry, err := o.cache.Get(address.EncodeToString())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -56,6 +56,6 @@ func (o *AccessBoxCache) Get(address *address.Address) *accessbox.Box {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put stores an object to cache.
|
// Put stores an object to cache.
|
||||||
func (o *AccessBoxCache) Put(address *address.Address, box *accessbox.Box) error {
|
func (o *AccessBoxCache) Put(address oid.Address, box *accessbox.Box) error {
|
||||||
return o.cache.Set(address.String(), box)
|
return o.cache.Set(address.EncodeToString(), box)
|
||||||
}
|
}
|
||||||
|
|
12
api/cache/names.go
vendored
12
api/cache/names.go
vendored
|
@ -4,7 +4,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/bluele/gcache"
|
"github.com/bluele/gcache"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectsNameCache provides lru cache for objects.
|
// ObjectsNameCache provides lru cache for objects.
|
||||||
|
@ -32,23 +32,23 @@ func NewObjectsNameCache(config *Config) *ObjectsNameCache {
|
||||||
return &ObjectsNameCache{cache: gc}
|
return &ObjectsNameCache{cache: gc}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a cached object.
|
// Get returns a cached object. Returns nil if value is missing.
|
||||||
func (o *ObjectsNameCache) Get(key string) *address.Address {
|
func (o *ObjectsNameCache) Get(key string) *oid.Address {
|
||||||
entry, err := o.cache.Get(key)
|
entry, err := o.cache.Get(key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
result, ok := entry.(*address.Address)
|
result, ok := entry.(oid.Address)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return result
|
return &result
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put puts an object to cache.
|
// Put puts an object to cache.
|
||||||
func (o *ObjectsNameCache) Put(key string, address *address.Address) error {
|
func (o *ObjectsNameCache) Put(key string, address oid.Address) error {
|
||||||
return o.cache.Set(key, address)
|
return o.cache.Set(key, address)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
17
api/cache/objects.go
vendored
17
api/cache/objects.go
vendored
|
@ -5,7 +5,7 @@ import (
|
||||||
|
|
||||||
"github.com/bluele/gcache"
|
"github.com/bluele/gcache"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
)
|
)
|
||||||
|
|
||||||
// ObjectsCache provides lru cache for objects.
|
// ObjectsCache provides lru cache for objects.
|
||||||
|
@ -32,8 +32,8 @@ func New(config *Config) *ObjectsCache {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get returns a cached object.
|
// Get returns a cached object.
|
||||||
func (o *ObjectsCache) Get(address *address.Address) *object.Object {
|
func (o *ObjectsCache) Get(address oid.Address) *object.Object {
|
||||||
entry, err := o.cache.Get(address.String())
|
entry, err := o.cache.Get(address.EncodeToString())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -50,10 +50,15 @@ func (o *ObjectsCache) Get(address *address.Address) *object.Object {
|
||||||
func (o *ObjectsCache) Put(obj object.Object) error {
|
func (o *ObjectsCache) Put(obj object.Object) error {
|
||||||
cnrID, _ := obj.ContainerID()
|
cnrID, _ := obj.ContainerID()
|
||||||
objID, _ := obj.ID()
|
objID, _ := obj.ID()
|
||||||
return o.cache.Set(cnrID.String()+"/"+objID.String(), obj)
|
|
||||||
|
var addr oid.Address
|
||||||
|
addr.SetContainer(cnrID)
|
||||||
|
addr.SetObject(objID)
|
||||||
|
|
||||||
|
return o.cache.Set(addr.EncodeToString(), obj)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Delete deletes an object from cache.
|
// Delete deletes an object from cache.
|
||||||
func (o *ObjectsCache) Delete(address *address.Address) bool {
|
func (o *ObjectsCache) Delete(address oid.Address) bool {
|
||||||
return o.cache.Remove(address.String())
|
return o.cache.Remove(address.EncodeToString())
|
||||||
}
|
}
|
||||||
|
|
9
api/cache/objects_test.go
vendored
9
api/cache/objects_test.go
vendored
|
@ -4,7 +4,7 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
|
objecttest "github.com/nspcc-dev/neofs-sdk-go/object/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
@ -20,9 +20,10 @@ func TestCache(t *testing.T) {
|
||||||
obj := objecttest.Object()
|
obj := objecttest.Object()
|
||||||
objID, _ := obj.ID()
|
objID, _ := obj.ID()
|
||||||
cnrID, _ := obj.ContainerID()
|
cnrID, _ := obj.ContainerID()
|
||||||
addr := address.NewAddress()
|
|
||||||
addr.SetContainerID(cnrID)
|
var addr oid.Address
|
||||||
addr.SetObjectID(objID)
|
addr.SetContainer(cnrID)
|
||||||
|
addr.SetObject(objID)
|
||||||
|
|
||||||
t.Run("check get", func(t *testing.T) {
|
t.Run("check get", func(t *testing.T) {
|
||||||
cache := New(getTestConfig())
|
cache := New(getTestConfig())
|
||||||
|
|
8
api/cache/objectslist.go
vendored
8
api/cache/objectslist.go
vendored
|
@ -79,8 +79,8 @@ func (l *ObjectsListCache) Put(key ObjectsListKey, oids []oid.ID) error {
|
||||||
}
|
}
|
||||||
|
|
||||||
// CleanCacheEntriesContainingObject deletes entries containing specified object.
|
// CleanCacheEntriesContainingObject deletes entries containing specified object.
|
||||||
func (l *ObjectsListCache) CleanCacheEntriesContainingObject(objectName string, cid *cid.ID) {
|
func (l *ObjectsListCache) CleanCacheEntriesContainingObject(objectName string, cnr cid.ID) {
|
||||||
cidStr := cid.String()
|
cidStr := cnr.EncodeToString()
|
||||||
keys := l.cache.Keys(true)
|
keys := l.cache.Keys(true)
|
||||||
for _, key := range keys {
|
for _, key := range keys {
|
||||||
k, ok := key.(ObjectsListKey)
|
k, ok := key.(ObjectsListKey)
|
||||||
|
@ -94,9 +94,9 @@ func (l *ObjectsListCache) CleanCacheEntriesContainingObject(objectName string,
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateObjectsListCacheKey returns ObjectsListKey with the given CID and prefix.
|
// CreateObjectsListCacheKey returns ObjectsListKey with the given CID and prefix.
|
||||||
func CreateObjectsListCacheKey(cid *cid.ID, prefix string) ObjectsListKey {
|
func CreateObjectsListCacheKey(cnr cid.ID, prefix string) ObjectsListKey {
|
||||||
p := ObjectsListKey{
|
p := ObjectsListKey{
|
||||||
cid: cid.String(),
|
cid: cnr.EncodeToString(),
|
||||||
prefix: prefix,
|
prefix: prefix,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
29
api/cache/objectslist_test.go
vendored
29
api/cache/objectslist_test.go
vendored
|
@ -1,13 +1,12 @@
|
||||||
package cache
|
package cache
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
|
||||||
"crypto/sha256"
|
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -21,20 +20,6 @@ func getTestObjectsListConfig() *Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func randID(t *testing.T) *oid.ID {
|
|
||||||
var id oid.ID
|
|
||||||
id.SetSHA256(randSHA256Checksum(t))
|
|
||||||
|
|
||||||
return &id
|
|
||||||
}
|
|
||||||
|
|
||||||
func randSHA256Checksum(t *testing.T) (cs [sha256.Size]byte) {
|
|
||||||
_, err := rand.Read(cs[:])
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestObjectsListCache(t *testing.T) {
|
func TestObjectsListCache(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
listSize = 10
|
listSize = 10
|
||||||
|
@ -43,7 +28,7 @@ func TestObjectsListCache(t *testing.T) {
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < listSize; i++ {
|
for i := 0; i < listSize; i++ {
|
||||||
ids = append(ids, *randID(t))
|
ids = append(ids, oidtest.ID())
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("lifetime", func(t *testing.T) {
|
t.Run("lifetime", func(t *testing.T) {
|
||||||
|
@ -141,12 +126,12 @@ func TestObjectsListCache(t *testing.T) {
|
||||||
func TestCleanCacheEntriesChangedWithPutObject(t *testing.T) {
|
func TestCleanCacheEntriesChangedWithPutObject(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
id cid.ID
|
id cid.ID
|
||||||
oids = []oid.ID{*randID(t)}
|
oids = []oid.ID{oidtest.ID()}
|
||||||
keys []ObjectsListKey
|
keys []ObjectsListKey
|
||||||
)
|
)
|
||||||
|
|
||||||
for _, p := range []string{"", "dir/", "dir/lol/"} {
|
for _, p := range []string{"", "dir/", "dir/lol/"} {
|
||||||
keys = append(keys, ObjectsListKey{cid: id.String(), prefix: p})
|
keys = append(keys, ObjectsListKey{cid: id.EncodeToString(), prefix: p})
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("put object to the root of the bucket", func(t *testing.T) {
|
t.Run("put object to the root of the bucket", func(t *testing.T) {
|
||||||
|
@ -157,7 +142,7 @@ func TestCleanCacheEntriesChangedWithPutObject(t *testing.T) {
|
||||||
err := cache.Put(k, oids)
|
err := cache.Put(k, oids)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
cache.CleanCacheEntriesContainingObject("obj1", &id)
|
cache.CleanCacheEntriesContainingObject("obj1", id)
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
list := cache.Get(k)
|
list := cache.Get(k)
|
||||||
if k.prefix == "" {
|
if k.prefix == "" {
|
||||||
|
@ -176,7 +161,7 @@ func TestCleanCacheEntriesChangedWithPutObject(t *testing.T) {
|
||||||
err := cache.Put(k, oids)
|
err := cache.Put(k, oids)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
cache.CleanCacheEntriesContainingObject("dir/obj", &id)
|
cache.CleanCacheEntriesContainingObject("dir/obj", id)
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
list := cache.Get(k)
|
list := cache.Get(k)
|
||||||
if k.prefix == "" || k.prefix == "dir/" {
|
if k.prefix == "" || k.prefix == "dir/" {
|
||||||
|
@ -195,7 +180,7 @@ func TestCleanCacheEntriesChangedWithPutObject(t *testing.T) {
|
||||||
err := cache.Put(k, oids)
|
err := cache.Put(k, oids)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
}
|
}
|
||||||
cache.CleanCacheEntriesContainingObject("dir/lol/obj", &id)
|
cache.CleanCacheEntriesContainingObject("dir/lol/obj", id)
|
||||||
for _, k := range keys {
|
for _, k := range keys {
|
||||||
list := cache.Get(k)
|
list := cache.Get(k)
|
||||||
require.Nil(t, list)
|
require.Nil(t, list)
|
||||||
|
|
|
@ -5,7 +5,6 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
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"
|
||||||
)
|
)
|
||||||
|
@ -20,8 +19,8 @@ type (
|
||||||
// BucketInfo stores basic bucket data.
|
// BucketInfo stores basic bucket data.
|
||||||
BucketInfo struct {
|
BucketInfo struct {
|
||||||
Name string
|
Name string
|
||||||
CID *cid.ID
|
CID cid.ID
|
||||||
Owner *user.ID
|
Owner user.ID
|
||||||
Created time.Time
|
Created time.Time
|
||||||
BasicACL uint32
|
BasicACL uint32
|
||||||
LocationConstraint string
|
LocationConstraint string
|
||||||
|
@ -30,8 +29,8 @@ type (
|
||||||
|
|
||||||
// ObjectInfo holds S3 object data.
|
// ObjectInfo holds S3 object data.
|
||||||
ObjectInfo struct {
|
ObjectInfo struct {
|
||||||
ID *oid.ID
|
ID oid.ID
|
||||||
CID *cid.ID
|
CID cid.ID
|
||||||
IsDir bool
|
IsDir bool
|
||||||
|
|
||||||
Bucket string
|
Bucket string
|
||||||
|
@ -41,7 +40,7 @@ type (
|
||||||
Created time.Time
|
Created time.Time
|
||||||
CreationEpoch uint64
|
CreationEpoch uint64
|
||||||
HashSum string
|
HashSum string
|
||||||
Owner *user.ID
|
Owner user.ID
|
||||||
Headers map[string]string
|
Headers map[string]string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -79,7 +78,7 @@ func (b *BucketInfo) NotificationConfigurationObjectName() string {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Version returns object version from ObjectInfo.
|
// Version returns object version from ObjectInfo.
|
||||||
func (o *ObjectInfo) Version() string { return o.ID.String() }
|
func (o *ObjectInfo) Version() string { return o.ID.EncodeToString() }
|
||||||
|
|
||||||
// NullableVersion returns object version from ObjectInfo.
|
// NullableVersion returns object version from ObjectInfo.
|
||||||
// Return "null" if "S3-Versions-unversioned" header is present.
|
// Return "null" if "S3-Versions-unversioned" header is present.
|
||||||
|
@ -94,10 +93,10 @@ func (o *ObjectInfo) NullableVersion() string {
|
||||||
func (o *ObjectInfo) NiceName() string { return o.Bucket + "/" + o.Name }
|
func (o *ObjectInfo) NiceName() string { return o.Bucket + "/" + o.Name }
|
||||||
|
|
||||||
// Address returns object address.
|
// Address returns object address.
|
||||||
func (o *ObjectInfo) Address() *address.Address {
|
func (o *ObjectInfo) Address() oid.Address {
|
||||||
addr := address.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(*o.CID)
|
addr.SetContainer(o.CID)
|
||||||
addr.SetObjectID(*o.ID)
|
addr.SetObject(o.ID)
|
||||||
|
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
|
@ -217,8 +217,10 @@ func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bktInfo *data.
|
||||||
}
|
}
|
||||||
|
|
||||||
parentAst := tableToAst(bucketACL.EACL, bktInfo.Name)
|
parentAst := tableToAst(bucketACL.EACL, bktInfo.Name)
|
||||||
|
strCID := bucketACL.Info.CID.EncodeToString()
|
||||||
|
|
||||||
for _, resource := range parentAst.Resources {
|
for _, resource := range parentAst.Resources {
|
||||||
if resource.Bucket == bucketACL.Info.CID.String() {
|
if resource.Bucket == strCID {
|
||||||
resource.Bucket = bktInfo.Name
|
resource.Bucket = bktInfo.Name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -57,7 +57,7 @@ func TestTableToAst(t *testing.T) {
|
||||||
resourceInfo: resourceInfo{
|
resourceInfo: resourceInfo{
|
||||||
Bucket: "bucketName",
|
Bucket: "bucketName",
|
||||||
Object: "objectName",
|
Object: "objectName",
|
||||||
Version: id.String(),
|
Version: id.EncodeToString(),
|
||||||
},
|
},
|
||||||
Operations: []*astOperation{{
|
Operations: []*astOperation{{
|
||||||
Users: []string{
|
Users: []string{
|
||||||
|
@ -775,7 +775,7 @@ func TestObjectAclToAst(t *testing.T) {
|
||||||
resInfo := &resourceInfo{
|
resInfo := &resourceInfo{
|
||||||
Bucket: "bucketName",
|
Bucket: "bucketName",
|
||||||
Object: "object",
|
Object: "object",
|
||||||
Version: objID.String(),
|
Version: objID.EncodeToString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
var operations []*astOperation
|
var operations []*astOperation
|
||||||
|
|
|
@ -121,7 +121,7 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
Event: EventObjectRemovedDelete,
|
Event: EventObjectRemovedDelete,
|
||||||
ObjInfo: &data.ObjectInfo{
|
ObjInfo: &data.ObjectInfo{
|
||||||
Name: reqInfo.ObjectName,
|
Name: reqInfo.ObjectName,
|
||||||
ID: &objID,
|
ID: objID,
|
||||||
},
|
},
|
||||||
BktInfo: bktInfo,
|
BktInfo: bktInfo,
|
||||||
ReqInfo: reqInfo,
|
ReqInfo: reqInfo,
|
||||||
|
|
|
@ -82,7 +82,7 @@ func writeHeaders(h http.Header, info *data.ObjectInfo, tagSetLength int) {
|
||||||
h.Set(api.LastModified, info.Created.UTC().Format(http.TimeFormat))
|
h.Set(api.LastModified, info.Created.UTC().Format(http.TimeFormat))
|
||||||
h.Set(api.ContentLength, strconv.FormatInt(info.Size, 10))
|
h.Set(api.ContentLength, strconv.FormatInt(info.Size, 10))
|
||||||
h.Set(api.ETag, info.HashSum)
|
h.Set(api.ETag, info.HashSum)
|
||||||
h.Set(api.AmzVersionID, info.ID.String())
|
h.Set(api.AmzVersionID, info.ID.EncodeToString())
|
||||||
h.Set(api.AmzTaggingCount, strconv.Itoa(tagSetLength))
|
h.Set(api.AmzTaggingCount, strconv.Itoa(tagSetLength))
|
||||||
|
|
||||||
if cacheControl := info.Headers[api.CacheControl]; cacheControl != "" {
|
if cacheControl := info.Headers[api.CacheControl]; cacheControl != "" {
|
||||||
|
|
|
@ -86,10 +86,10 @@ func createTestBucketWithLock(ctx context.Context, t *testing.T, h *handlerConte
|
||||||
var ownerID user.ID
|
var ownerID user.ID
|
||||||
|
|
||||||
bktInfo := &data.BucketInfo{
|
bktInfo := &data.BucketInfo{
|
||||||
CID: cnrID,
|
CID: *cnrID,
|
||||||
Name: bktName,
|
Name: bktName,
|
||||||
ObjectLockEnabled: true,
|
ObjectLockEnabled: true,
|
||||||
Owner: &ownerID,
|
Owner: ownerID,
|
||||||
}
|
}
|
||||||
|
|
||||||
sp := &layer.PutSettingsParams{
|
sp := &layer.PutSettingsParams{
|
||||||
|
|
|
@ -89,7 +89,7 @@ func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
w.Header().Set(api.ContainerID, bktInfo.CID.String())
|
w.Header().Set(api.ContainerID, bktInfo.CID.EncodeToString())
|
||||||
api.WriteResponse(w, http.StatusOK, nil, api.MimeNone)
|
api.WriteResponse(w, http.StatusOK, nil, api.MimeNone)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ func (h *handler) ListBucketsHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(list) > 0 {
|
if len(list) > 0 {
|
||||||
own = *list[0].Owner
|
own = list[0].Owner
|
||||||
}
|
}
|
||||||
|
|
||||||
res = &ListBucketsResponse{
|
res = &ListBucketsResponse{
|
||||||
|
|
|
@ -162,7 +162,7 @@ func (h *handler) PutObjectLegalHoldHandler(w http.ResponseWriter, r *http.Reque
|
||||||
ps := &layer.PutSystemObjectParams{
|
ps := &layer.PutSystemObjectParams{
|
||||||
BktInfo: bktInfo,
|
BktInfo: bktInfo,
|
||||||
ObjName: objInfo.LegalHoldObject(),
|
ObjName: objInfo.LegalHoldObject(),
|
||||||
Lock: &data.ObjectLock{LegalHold: true, Objects: []oid.ID{*objInfo.ID}},
|
Lock: &data.ObjectLock{LegalHold: true, Objects: []oid.ID{objInfo.ID}},
|
||||||
Metadata: make(map[string]string),
|
Metadata: make(map[string]string),
|
||||||
}
|
}
|
||||||
if _, err = h.obj.PutSystemObject(r.Context(), ps); err != nil {
|
if _, err = h.obj.PutSystemObject(r.Context(), ps); err != nil {
|
||||||
|
@ -252,7 +252,7 @@ func (h *handler) PutObjectRetentionHandler(w http.ResponseWriter, r *http.Reque
|
||||||
h.logAndSendError(w, "could not get object info", reqInfo, err)
|
h.logAndSendError(w, "could not get object info", reqInfo, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
lock.Objects = append(lock.Objects, *objInfo.ID)
|
lock.Objects = append(lock.Objects, objInfo.ID)
|
||||||
|
|
||||||
lockInfo, err := h.obj.HeadSystemObject(r.Context(), bktInfo, objInfo.RetentionObject())
|
lockInfo, err := h.obj.HeadSystemObject(r.Context(), bktInfo, objInfo.RetentionObject())
|
||||||
if err != nil && !apiErrors.IsS3Error(err, apiErrors.ErrNoSuchKey) {
|
if err != nil && !apiErrors.IsS3Error(err, apiErrors.ErrNoSuchKey) {
|
||||||
|
|
|
@ -519,8 +519,10 @@ func (h *handler) getNewEAclTable(r *http.Request, bktInfo *data.BucketInfo, obj
|
||||||
}
|
}
|
||||||
|
|
||||||
parentAst := tableToAst(bacl.EACL, objInfo.Bucket)
|
parentAst := tableToAst(bacl.EACL, objInfo.Bucket)
|
||||||
|
strCID := bacl.Info.CID.EncodeToString()
|
||||||
|
|
||||||
for _, resource := range parentAst.Resources {
|
for _, resource := range parentAst.Resources {
|
||||||
if resource.Bucket == bacl.Info.CID.String() {
|
if resource.Bucket == strCID {
|
||||||
resource.Bucket = objInfo.Bucket
|
resource.Bucket = objInfo.Bucket
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -31,7 +31,7 @@ const (
|
||||||
AttributeLockEnabled = "LockEnabled"
|
AttributeLockEnabled = "LockEnabled"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *layer) containerInfo(ctx context.Context, idCnr *cid.ID) (*data.BucketInfo, error) {
|
func (n *layer) containerInfo(ctx context.Context, idCnr cid.ID) (*data.BucketInfo, error) {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
res *container.Container
|
res *container.Container
|
||||||
|
@ -40,10 +40,10 @@ func (n *layer) containerInfo(ctx context.Context, idCnr *cid.ID) (*data.BucketI
|
||||||
|
|
||||||
info = &data.BucketInfo{
|
info = &data.BucketInfo{
|
||||||
CID: idCnr,
|
CID: idCnr,
|
||||||
Name: idCnr.String(),
|
Name: idCnr.EncodeToString(),
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
res, err = n.neoFS.Container(ctx, *idCnr)
|
res, err = n.neoFS.Container(ctx, idCnr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("could not fetch container", zap.Error(err))
|
log.Error("could not fetch container", zap.Error(err))
|
||||||
|
|
||||||
|
@ -53,7 +53,7 @@ func (n *layer) containerInfo(ctx context.Context, idCnr *cid.ID) (*data.BucketI
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Owner = res.OwnerID()
|
info.Owner = *res.OwnerID()
|
||||||
info.BasicACL = res.BasicACL()
|
info.BasicACL = res.BasicACL()
|
||||||
|
|
||||||
for _, attr := range res.Attributes() {
|
for _, attr := range res.Attributes() {
|
||||||
|
@ -106,7 +106,7 @@ func (n *layer) containerList(ctx context.Context) ([]*data.BucketInfo, error) {
|
||||||
|
|
||||||
list := make([]*data.BucketInfo, 0, len(res))
|
list := make([]*data.BucketInfo, 0, len(res))
|
||||||
for i := range res {
|
for i := range res {
|
||||||
info, err := n.containerInfo(ctx, &res[i])
|
info, err := n.containerInfo(ctx, res[i])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.log.Error("could not fetch container info",
|
n.log.Error("could not fetch container info",
|
||||||
zap.String("request_id", rid),
|
zap.String("request_id", rid),
|
||||||
|
@ -125,7 +125,7 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*da
|
||||||
ownerID := n.Owner(ctx)
|
ownerID := n.Owner(ctx)
|
||||||
bktInfo := &data.BucketInfo{
|
bktInfo := &data.BucketInfo{
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
Owner: &ownerID,
|
Owner: ownerID,
|
||||||
Created: time.Now(), // this can be a little incorrect since the real time is set later
|
Created: time.Now(), // this can be a little incorrect since the real time is set later
|
||||||
BasicACL: p.ACL,
|
BasicACL: p.ACL,
|
||||||
LocationConstraint: p.LocationConstraint,
|
LocationConstraint: p.LocationConstraint,
|
||||||
|
@ -146,17 +146,20 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*da
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
if bktInfo.CID, err = n.neoFS.CreateContainer(ctx, neofs.PrmContainerCreate{
|
idCnr, err := n.neoFS.CreateContainer(ctx, neofs.PrmContainerCreate{
|
||||||
Creator: *bktInfo.Owner,
|
Creator: bktInfo.Owner,
|
||||||
Policy: *p.Policy,
|
Policy: *p.Policy,
|
||||||
Name: p.Name,
|
Name: p.Name,
|
||||||
SessionToken: p.SessionToken,
|
SessionToken: p.SessionToken,
|
||||||
BasicACL: acl.BasicACL(p.ACL),
|
BasicACL: acl.BasicACL(p.ACL),
|
||||||
AdditionalAttributes: attributes,
|
AdditionalAttributes: attributes,
|
||||||
}); err != nil {
|
})
|
||||||
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bktInfo.CID = *idCnr
|
||||||
|
|
||||||
if err = n.setContainerEACLTable(ctx, bktInfo.CID, p.EACL); err != nil {
|
if err = n.setContainerEACLTable(ctx, bktInfo.CID, p.EACL); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -171,8 +174,8 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*da
|
||||||
return bktInfo, nil
|
return bktInfo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) setContainerEACLTable(ctx context.Context, idCnr *cid.ID, table *eacl.Table) error {
|
func (n *layer) setContainerEACLTable(ctx context.Context, idCnr cid.ID, table *eacl.Table) error {
|
||||||
table.SetCID(*idCnr)
|
table.SetCID(idCnr)
|
||||||
|
|
||||||
boxData, err := GetBoxData(ctx)
|
boxData, err := GetBoxData(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
|
@ -182,16 +185,16 @@ func (n *layer) setContainerEACLTable(ctx context.Context, idCnr *cid.ID, table
|
||||||
return n.neoFS.SetContainerEACL(ctx, *table)
|
return n.neoFS.SetContainerEACL(ctx, *table)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) GetContainerEACL(ctx context.Context, idCnr *cid.ID) (*eacl.Table, error) {
|
func (n *layer) GetContainerEACL(ctx context.Context, idCnr cid.ID) (*eacl.Table, error) {
|
||||||
return n.neoFS.ContainerEACL(ctx, *idCnr)
|
return n.neoFS.ContainerEACL(ctx, idCnr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) deleteContainer(ctx context.Context, idCnr *cid.ID) error {
|
func (n *layer) deleteContainer(ctx context.Context, idCnr cid.ID) error {
|
||||||
var sessionToken *session.Container
|
var sessionToken *session.Container
|
||||||
boxData, err := GetBoxData(ctx)
|
boxData, err := GetBoxData(ctx)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
sessionToken = boxData.Gate.SessionTokenForDelete()
|
sessionToken = boxData.Gate.SessionTokenForDelete()
|
||||||
}
|
}
|
||||||
|
|
||||||
return n.neoFS.DeleteContainer(ctx, *idCnr, sessionToken)
|
return n.neoFS.DeleteContainer(ctx, idCnr, sessionToken)
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ func (n *layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInf
|
||||||
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
||||||
}
|
}
|
||||||
|
|
||||||
return n.containerInfo(ctx, containerID)
|
return n.containerInfo(ctx, *containerID)
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetBucketACL returns bucket acl info by name.
|
// GetBucketACL returns bucket acl info by name.
|
||||||
|
@ -536,7 +536,7 @@ func (n *layer) CopyObject(ctx context.Context, p *CopyObjectParams) (*data.Obje
|
||||||
func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, settings *data.BucketSettings, obj *VersionedObject) *VersionedObject {
|
func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, settings *data.BucketSettings, obj *VersionedObject) *VersionedObject {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
ids []*oid.ID
|
ids []oid.ID
|
||||||
)
|
)
|
||||||
|
|
||||||
p := &PutObjectParams{
|
p := &PutObjectParams{
|
||||||
|
@ -571,7 +571,7 @@ func (n *layer) deleteObject(ctx context.Context, bkt *data.BucketInfo, settings
|
||||||
obj.Error = err
|
obj.Error = err
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
ids = []*oid.ID{version.ID}
|
ids = []oid.ID{version.ID}
|
||||||
if version.Headers[VersionsDeleteMarkAttr] == DelMarkFullObject {
|
if version.Headers[VersionsDeleteMarkAttr] == DelMarkFullObject {
|
||||||
obj.DeleteMarkVersion = version.Version()
|
obj.DeleteMarkVersion = version.Version()
|
||||||
}
|
}
|
||||||
|
@ -627,7 +627,7 @@ func (n *layer) CreateBucket(ctx context.Context, p *CreateBucketParams) (*data.
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.SessionToken != nil && p.SessionToken.IssuedBy(*bktInfo.Owner) {
|
if p.SessionToken != nil && session.IssuedBy(*p.SessionToken, bktInfo.Owner) {
|
||||||
return nil, errors.GetAPIError(errors.ErrBucketAlreadyOwnedByYou)
|
return nil, errors.GetAPIError(errors.ErrBucketAlreadyOwnedByYou)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ func TestObjectLockAttributes(t *testing.T) {
|
||||||
Metadata: make(map[string]string),
|
Metadata: make(map[string]string),
|
||||||
Lock: &data.ObjectLock{
|
Lock: &data.ObjectLock{
|
||||||
Until: time.Now(),
|
Until: time.Now(),
|
||||||
Objects: []oid.ID{*obj.ID},
|
Objects: []oid.ID{obj.ID},
|
||||||
},
|
},
|
||||||
})
|
})
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -90,7 +90,7 @@ type (
|
||||||
|
|
||||||
ListPartsInfo struct {
|
ListPartsInfo struct {
|
||||||
Parts []*Part
|
Parts []*Part
|
||||||
Owner *user.ID
|
Owner user.ID
|
||||||
NextPartNumberMarker int
|
NextPartNumberMarker int
|
||||||
IsTruncated bool
|
IsTruncated bool
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,7 @@ type (
|
||||||
IsDir bool
|
IsDir bool
|
||||||
Key string
|
Key string
|
||||||
UploadID string
|
UploadID string
|
||||||
Owner *user.ID
|
Owner user.ID
|
||||||
Created time.Time
|
Created time.Time
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -599,7 +599,7 @@ func uploadInfoFromMeta(meta *object.Object, prefix, delimiter string) *UploadIn
|
||||||
IsDir: isDir,
|
IsDir: isDir,
|
||||||
Key: key,
|
Key: key,
|
||||||
UploadID: userHeaders[UploadIDAttributeName],
|
UploadID: userHeaders[UploadIDAttributeName],
|
||||||
Owner: meta.OwnerID(),
|
Owner: *meta.OwnerID(),
|
||||||
Created: creation,
|
Created: creation,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,7 +19,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/client"
|
"github.com/nspcc-dev/neofs-sdk-go/client"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -27,7 +26,7 @@ import (
|
||||||
type (
|
type (
|
||||||
findParams struct {
|
findParams struct {
|
||||||
attr [2]string
|
attr [2]string
|
||||||
cid *cid.ID
|
cid cid.ID
|
||||||
prefix string
|
prefix string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,8 +34,8 @@ type (
|
||||||
// payload range
|
// payload range
|
||||||
off, ln uint64
|
off, ln uint64
|
||||||
|
|
||||||
cid *cid.ID
|
cid cid.ID
|
||||||
oid *oid.ID
|
oid oid.ID
|
||||||
}
|
}
|
||||||
|
|
||||||
// ListObjectsParamsCommon contains common parameters for ListObjectsV1 and ListObjectsV2.
|
// ListObjectsParamsCommon contains common parameters for ListObjectsV1 and ListObjectsV2.
|
||||||
|
@ -69,10 +68,10 @@ type (
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
func (n *layer) objectSearchByName(ctx context.Context, cid *cid.ID, filename string) ([]oid.ID, error) {
|
func (n *layer) objectSearchByName(ctx context.Context, cnr cid.ID, filename string) ([]oid.ID, error) {
|
||||||
f := &findParams{
|
f := &findParams{
|
||||||
attr: [2]string{object.AttributeFileName, filename},
|
attr: [2]string{object.AttributeFileName, filename},
|
||||||
cid: cid,
|
cid: cnr,
|
||||||
}
|
}
|
||||||
return n.objectSearch(ctx, f)
|
return n.objectSearch(ctx, f)
|
||||||
}
|
}
|
||||||
|
@ -80,7 +79,7 @@ func (n *layer) objectSearchByName(ctx context.Context, cid *cid.ID, filename st
|
||||||
// objectSearch returns all available objects by search params.
|
// objectSearch returns all available objects by search params.
|
||||||
func (n *layer) objectSearch(ctx context.Context, p *findParams) ([]oid.ID, error) {
|
func (n *layer) objectSearch(ctx context.Context, p *findParams) ([]oid.ID, error) {
|
||||||
prm := neofs.PrmObjectSelect{
|
prm := neofs.PrmObjectSelect{
|
||||||
Container: *p.cid,
|
Container: p.cid,
|
||||||
ExactAttribute: p.attr,
|
ExactAttribute: p.attr,
|
||||||
FilePrefix: p.prefix,
|
FilePrefix: p.prefix,
|
||||||
}
|
}
|
||||||
|
@ -92,17 +91,17 @@ func (n *layer) objectSearch(ctx context.Context, p *findParams) ([]oid.ID, erro
|
||||||
return res, n.transformNeofsError(ctx, err)
|
return res, n.transformNeofsError(ctx, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAddress(cid cid.ID, oid oid.ID) *address.Address {
|
func newAddress(cnr cid.ID, obj oid.ID) oid.Address {
|
||||||
addr := address.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(cid)
|
addr.SetContainer(cnr)
|
||||||
addr.SetObjectID(oid)
|
addr.SetObject(obj)
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectHead returns all object's headers.
|
// objectHead returns all object's headers.
|
||||||
func (n *layer) objectHead(ctx context.Context, idCnr *cid.ID, idObj oid.ID) (*object.Object, error) {
|
func (n *layer) objectHead(ctx context.Context, idCnr cid.ID, idObj oid.ID) (*object.Object, error) {
|
||||||
prm := neofs.PrmObjectRead{
|
prm := neofs.PrmObjectRead{
|
||||||
Container: *idCnr,
|
Container: idCnr,
|
||||||
Object: idObj,
|
Object: idObj,
|
||||||
WithHeader: true,
|
WithHeader: true,
|
||||||
}
|
}
|
||||||
|
@ -121,8 +120,8 @@ func (n *layer) objectHead(ctx context.Context, idCnr *cid.ID, idObj oid.ID) (*o
|
||||||
// Zero range corresponds to full payload (panics if only offset is set).
|
// Zero range corresponds to full payload (panics if only offset is set).
|
||||||
func (n *layer) initObjectPayloadReader(ctx context.Context, p getParams) (io.Reader, error) {
|
func (n *layer) initObjectPayloadReader(ctx context.Context, p getParams) (io.Reader, error) {
|
||||||
prm := neofs.PrmObjectRead{
|
prm := neofs.PrmObjectRead{
|
||||||
Container: *p.cid,
|
Container: p.cid,
|
||||||
Object: *p.oid,
|
Object: p.oid,
|
||||||
WithPayload: true,
|
WithPayload: true,
|
||||||
PayloadRange: [2]uint64{p.off, p.ln},
|
PayloadRange: [2]uint64{p.off, p.ln},
|
||||||
}
|
}
|
||||||
|
@ -138,12 +137,10 @@ func (n *layer) initObjectPayloadReader(ctx context.Context, p getParams) (io.Re
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectGet returns an object with payload in the object.
|
// objectGet returns an object with payload in the object.
|
||||||
func (n *layer) objectGet(ctx context.Context, addr *address.Address) (*object.Object, error) {
|
func (n *layer) objectGet(ctx context.Context, addr oid.Address) (*object.Object, error) {
|
||||||
cnrID, _ := addr.ContainerID()
|
|
||||||
objID, _ := addr.ObjectID()
|
|
||||||
prm := neofs.PrmObjectRead{
|
prm := neofs.PrmObjectRead{
|
||||||
Container: cnrID,
|
Container: addr.Container(),
|
||||||
Object: objID,
|
Object: addr.Object(),
|
||||||
WithHeader: true,
|
WithHeader: true,
|
||||||
WithPayload: true,
|
WithPayload: true,
|
||||||
}
|
}
|
||||||
|
@ -181,7 +178,7 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
prm := neofs.PrmObjectCreate{
|
prm := neofs.PrmObjectCreate{
|
||||||
Container: *p.BktInfo.CID,
|
Container: p.BktInfo.CID,
|
||||||
Creator: own,
|
Creator: own,
|
||||||
PayloadSize: uint64(p.Size),
|
PayloadSize: uint64(p.Size),
|
||||||
Filename: p.Object,
|
Filename: p.Object,
|
||||||
|
@ -206,7 +203,7 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
if p.Lock != nil {
|
if p.Lock != nil {
|
||||||
objInfo := &data.ObjectInfo{ID: id, Name: p.Object}
|
objInfo := &data.ObjectInfo{ID: *id, Name: p.Object}
|
||||||
p.Lock.Objects = append(p.Lock.Objects, *id)
|
p.Lock.Objects = append(p.Lock.Objects, *id)
|
||||||
if p.Lock.LegalHold {
|
if p.Lock.LegalHold {
|
||||||
if err = n.putLockObject(ctx, p.BktInfo, objInfo.LegalHoldObject(), p.Lock); err != nil {
|
if err = n.putLockObject(ctx, p.BktInfo, objInfo.LegalHoldObject(), p.Lock); err != nil {
|
||||||
|
@ -240,10 +237,10 @@ func (n *layer) PutObject(ctx context.Context, p *PutObjectParams) (*data.Object
|
||||||
}
|
}
|
||||||
|
|
||||||
return &data.ObjectInfo{
|
return &data.ObjectInfo{
|
||||||
ID: id,
|
ID: *id,
|
||||||
CID: p.BktInfo.CID,
|
CID: p.BktInfo.CID,
|
||||||
|
|
||||||
Owner: &own,
|
Owner: own,
|
||||||
Bucket: p.BktInfo.Name,
|
Bucket: p.BktInfo.Name,
|
||||||
Name: p.Object,
|
Name: p.Object,
|
||||||
Size: p.Size,
|
Size: p.Size,
|
||||||
|
@ -269,12 +266,12 @@ func (n *layer) putLockObject(ctx context.Context, bktInfo *data.BucketInfo, obj
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func updateCRDT2PSetHeaders(header map[string]string, versions *objectVersions, versioningEnabled bool) []*oid.ID {
|
func updateCRDT2PSetHeaders(header map[string]string, versions *objectVersions, versioningEnabled bool) []oid.ID {
|
||||||
if !versioningEnabled {
|
if !versioningEnabled {
|
||||||
header[versionsUnversionedAttr] = "true"
|
header[versionsUnversionedAttr] = "true"
|
||||||
}
|
}
|
||||||
|
|
||||||
var idsToDeleteArr []*oid.ID
|
var idsToDeleteArr []oid.ID
|
||||||
if versions.isEmpty() {
|
if versions.isEmpty() {
|
||||||
return idsToDeleteArr
|
return idsToDeleteArr
|
||||||
}
|
}
|
||||||
|
@ -324,7 +321,7 @@ func updateCRDT2PSetHeaders(header map[string]string, versions *objectVersions,
|
||||||
|
|
||||||
func (n *layer) headLastVersionIfNotDeleted(ctx context.Context, bkt *data.BucketInfo, objectName string) (*data.ObjectInfo, error) {
|
func (n *layer) headLastVersionIfNotDeleted(ctx context.Context, bkt *data.BucketInfo, objectName string) (*data.ObjectInfo, error) {
|
||||||
if addr := n.namesCache.Get(bkt.Name + "/" + objectName); addr != nil {
|
if addr := n.namesCache.Get(bkt.Name + "/" + objectName); addr != nil {
|
||||||
if headInfo := n.objCache.Get(addr); headInfo != nil {
|
if headInfo := n.objCache.Get(*addr); headInfo != nil {
|
||||||
return objInfoFromMeta(bkt, headInfo), nil
|
return objInfoFromMeta(bkt, headInfo), nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -405,7 +402,7 @@ func (n *layer) headVersion(ctx context.Context, bkt *data.BucketInfo, p *HeadOb
|
||||||
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidVersion)
|
return nil, apiErrors.GetAPIError(apiErrors.ErrInvalidVersion)
|
||||||
}
|
}
|
||||||
|
|
||||||
if headInfo := n.objCache.Get(newAddress(*bkt.CID, id)); headInfo != nil {
|
if headInfo := n.objCache.Get(newAddress(bkt.CID, id)); headInfo != nil {
|
||||||
return objInfoFromMeta(bkt, headInfo), nil
|
return objInfoFromMeta(bkt, headInfo), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -431,15 +428,15 @@ func (n *layer) headVersion(ctx context.Context, bkt *data.BucketInfo, p *HeadOb
|
||||||
}
|
}
|
||||||
|
|
||||||
// objectDelete puts tombstone object into neofs.
|
// objectDelete puts tombstone object into neofs.
|
||||||
func (n *layer) objectDelete(ctx context.Context, idCnr *cid.ID, idObj *oid.ID) error {
|
func (n *layer) objectDelete(ctx context.Context, idCnr cid.ID, idObj oid.ID) error {
|
||||||
prm := neofs.PrmObjectDelete{
|
prm := neofs.PrmObjectDelete{
|
||||||
Container: *idCnr,
|
Container: idCnr,
|
||||||
Object: *idObj,
|
Object: idObj,
|
||||||
}
|
}
|
||||||
|
|
||||||
n.prepareAuthParameters(ctx, &prm.PrmAuth)
|
n.prepareAuthParameters(ctx, &prm.PrmAuth)
|
||||||
|
|
||||||
n.objCache.Delete(newAddress(*idCnr, *idObj))
|
n.objCache.Delete(newAddress(idCnr, idObj))
|
||||||
|
|
||||||
return n.transformNeofsError(ctx, n.neoFS.DeleteObject(ctx, prm))
|
return n.transformNeofsError(ctx, n.neoFS.DeleteObject(ctx, prm))
|
||||||
}
|
}
|
||||||
|
@ -530,7 +527,7 @@ func (n *layer) ListObjectsV2(ctx context.Context, p *ListObjectsParamsV2) (*Lis
|
||||||
if len(allObjects) > p.MaxKeys {
|
if len(allObjects) > p.MaxKeys {
|
||||||
result.IsTruncated = true
|
result.IsTruncated = true
|
||||||
allObjects = allObjects[:p.MaxKeys]
|
allObjects = allObjects[:p.MaxKeys]
|
||||||
result.NextContinuationToken = allObjects[len(allObjects)-1].ID.String()
|
result.NextContinuationToken = allObjects[len(allObjects)-1].ID.EncodeToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
result.Prefixes, result.Objects = triageObjects(allObjects)
|
result.Prefixes, result.Objects = triageObjects(allObjects)
|
||||||
|
@ -578,7 +575,7 @@ func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *data.BucketInfo,
|
||||||
versions := make(map[string]*objectVersions, len(ids)/2)
|
versions := make(map[string]*objectVersions, len(ids)/2)
|
||||||
|
|
||||||
for i := 0; i < len(ids); i++ {
|
for i := 0; i < len(ids); i++ {
|
||||||
obj := n.objectFromObjectsCacheOrNeoFS(ctx, bkt.CID, &ids[i])
|
obj := n.objectFromObjectsCacheOrNeoFS(ctx, bkt.CID, ids[i])
|
||||||
if obj == nil {
|
if obj == nil {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -630,11 +627,11 @@ func trimAfterObjectName(startAfter string, objects []*data.ObjectInfo) []*data.
|
||||||
}
|
}
|
||||||
|
|
||||||
func trimAfterObjectID(id string, objects []*data.ObjectInfo) []*data.ObjectInfo {
|
func trimAfterObjectID(id string, objects []*data.ObjectInfo) []*data.ObjectInfo {
|
||||||
if len(objects) != 0 && objects[len(objects)-1].ID.String() == id {
|
if len(objects) != 0 && objects[len(objects)-1].ID.EncodeToString() == id {
|
||||||
return []*data.ObjectInfo{}
|
return []*data.ObjectInfo{}
|
||||||
}
|
}
|
||||||
for i, obj := range objects {
|
for i, obj := range objects {
|
||||||
if obj.ID.String() == id {
|
if obj.ID.EncodeToString() == id {
|
||||||
return objects[i+1:]
|
return objects[i+1:]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -682,13 +679,13 @@ func (n *layer) isVersioningEnabled(ctx context.Context, bktInfo *data.BucketInf
|
||||||
return settings.VersioningEnabled
|
return settings.VersioningEnabled
|
||||||
}
|
}
|
||||||
|
|
||||||
func (n *layer) objectFromObjectsCacheOrNeoFS(ctx context.Context, cid *cid.ID, oid *oid.ID) *object.Object {
|
func (n *layer) objectFromObjectsCacheOrNeoFS(ctx context.Context, cnr cid.ID, obj oid.ID) *object.Object {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
meta = n.objCache.Get(newAddress(*cid, *oid))
|
meta = n.objCache.Get(newAddress(cnr, obj))
|
||||||
)
|
)
|
||||||
if meta == nil {
|
if meta == nil {
|
||||||
meta, err = n.objectHead(ctx, cid, *oid)
|
meta, err = n.objectHead(ctx, cnr, obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
n.log.Warn("could not fetch object meta", zap.Error(err))
|
n.log.Warn("could not fetch object meta", zap.Error(err))
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -9,23 +9,10 @@ import (
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
||||||
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
|
oidtest "github.com/nspcc-dev/neofs-sdk-go/object/id/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
)
|
)
|
||||||
|
|
||||||
func randID(t *testing.T) *oid.ID {
|
|
||||||
var id oid.ID
|
|
||||||
id.SetSHA256(randSHA256Checksum(t))
|
|
||||||
|
|
||||||
return &id
|
|
||||||
}
|
|
||||||
|
|
||||||
func randSHA256Checksum(t *testing.T) (cs [sha256.Size]byte) {
|
|
||||||
_, err := rand.Read(cs[:])
|
|
||||||
require.NoError(t, err)
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestTrimAfterObjectName(t *testing.T) {
|
func TestTrimAfterObjectName(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
objects []*data.ObjectInfo
|
objects []*data.ObjectInfo
|
||||||
|
@ -79,23 +66,23 @@ func TestTrimAfterObjectName(t *testing.T) {
|
||||||
func TestTrimAfterObjectID(t *testing.T) {
|
func TestTrimAfterObjectID(t *testing.T) {
|
||||||
var (
|
var (
|
||||||
objects []*data.ObjectInfo
|
objects []*data.ObjectInfo
|
||||||
ids []*oid.ID
|
ids []oid.ID
|
||||||
numberOfIDS = 3
|
numberOfIDS = 3
|
||||||
)
|
)
|
||||||
|
|
||||||
for i := 0; i < numberOfIDS; i++ {
|
for i := 0; i < numberOfIDS; i++ {
|
||||||
id := randID(t)
|
id := oidtest.ID()
|
||||||
objects = append(objects, &data.ObjectInfo{ID: id})
|
objects = append(objects, &data.ObjectInfo{ID: id})
|
||||||
ids = append(ids, id)
|
ids = append(ids, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
t.Run("existing id", func(t *testing.T) {
|
t.Run("existing id", func(t *testing.T) {
|
||||||
actual := trimAfterObjectID(ids[0].String(), objects)
|
actual := trimAfterObjectID(ids[0].EncodeToString(), objects)
|
||||||
require.Equal(t, objects[1:], actual)
|
require.Equal(t, objects[1:], actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("second to last id", func(t *testing.T) {
|
t.Run("second to last id", func(t *testing.T) {
|
||||||
actual := trimAfterObjectID(ids[len(ids)-2].String(), objects)
|
actual := trimAfterObjectID(ids[len(ids)-2].EncodeToString(), objects)
|
||||||
require.Equal(t, objects[len(objects)-1:], actual)
|
require.Equal(t, objects[len(objects)-1:], actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -105,7 +92,7 @@ func TestTrimAfterObjectID(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("last id", func(t *testing.T) {
|
t.Run("last id", func(t *testing.T) {
|
||||||
actual := trimAfterObjectID(ids[len(ids)-1].String(), objects)
|
actual := trimAfterObjectID(ids[len(ids)-1].EncodeToString(), objects)
|
||||||
require.Empty(t, actual)
|
require.Empty(t, actual)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -13,7 +13,7 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api/layer/neofs"
|
"github.com/nspcc-dev/neofs-s3-gw/api/layer/neofs"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -67,7 +67,7 @@ func (n *layer) DeleteSystemObject(ctx context.Context, bktInfo *data.BucketInfo
|
||||||
|
|
||||||
n.systemCache.Delete(systemObjectKey(bktInfo, name))
|
n.systemCache.Delete(systemObjectKey(bktInfo, name))
|
||||||
for i := range ids {
|
for i := range ids {
|
||||||
if err = n.objectDelete(ctx, bktInfo.CID, &ids[i]); err != nil {
|
if err = n.objectDelete(ctx, bktInfo.CID, ids[i]); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,8 @@ func (n *layer) putSystemObjectIntoNeoFS(ctx context.Context, p *PutSystemObject
|
||||||
// note that updateCRDT2PSetHeaders modifies p.Metadata and must be called further processing
|
// note that updateCRDT2PSetHeaders modifies p.Metadata and must be called further processing
|
||||||
|
|
||||||
prm := neofs.PrmObjectCreate{
|
prm := neofs.PrmObjectCreate{
|
||||||
Container: *p.BktInfo.CID,
|
Container: p.BktInfo.CID,
|
||||||
Creator: *p.BktInfo.Owner,
|
Creator: p.BktInfo.Owner,
|
||||||
Attributes: make([][2]string, 2, 2+len(p.Metadata)),
|
Attributes: make([][2]string, 2, 2+len(p.Metadata)),
|
||||||
Payload: p.Reader,
|
Payload: p.Reader,
|
||||||
}
|
}
|
||||||
|
@ -147,12 +147,12 @@ func (n *layer) getSystemObjectFromNeoFS(ctx context.Context, bkt *data.BucketIn
|
||||||
|
|
||||||
objInfo := versions.getLast()
|
objInfo := versions.getLast()
|
||||||
|
|
||||||
var addr address.Address
|
var addr oid.Address
|
||||||
|
|
||||||
addr.SetContainerID(*bkt.CID)
|
addr.SetContainer(bkt.CID)
|
||||||
addr.SetObjectID(*objInfo.ID)
|
addr.SetObject(objInfo.ID)
|
||||||
|
|
||||||
obj, err := n.objectGet(ctx, &addr)
|
obj, err := n.objectGet(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
|
@ -115,7 +115,7 @@ func objectInfoFromMeta(bkt *data.BucketInfo, meta *object.Object, prefix, delim
|
||||||
objID, _ := meta.ID()
|
objID, _ := meta.ID()
|
||||||
payloadChecksum, _ := meta.PayloadChecksum()
|
payloadChecksum, _ := meta.PayloadChecksum()
|
||||||
return &data.ObjectInfo{
|
return &data.ObjectInfo{
|
||||||
ID: &objID,
|
ID: objID,
|
||||||
CID: bkt.CID,
|
CID: bkt.CID,
|
||||||
IsDir: isDir,
|
IsDir: isDir,
|
||||||
|
|
||||||
|
@ -125,7 +125,7 @@ func objectInfoFromMeta(bkt *data.BucketInfo, meta *object.Object, prefix, delim
|
||||||
CreationEpoch: meta.CreationEpoch(),
|
CreationEpoch: meta.CreationEpoch(),
|
||||||
ContentType: mimeType,
|
ContentType: mimeType,
|
||||||
Headers: userHeaders,
|
Headers: userHeaders,
|
||||||
Owner: meta.OwnerID(),
|
Owner: *meta.OwnerID(),
|
||||||
Size: size,
|
Size: size,
|
||||||
HashSum: hex.EncodeToString(payloadChecksum.Value()),
|
HashSum: hex.EncodeToString(payloadChecksum.Value()),
|
||||||
}
|
}
|
||||||
|
@ -138,7 +138,7 @@ func filenameFromObject(o *object.Object) string {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
objID, _ := o.ID()
|
objID, _ := o.ID()
|
||||||
return objID.String()
|
return objID.EncodeToString()
|
||||||
}
|
}
|
||||||
|
|
||||||
// NameFromString splits name into a base file name and a directory path.
|
// NameFromString splits name into a base file name and a directory path.
|
||||||
|
|
|
@ -23,7 +23,7 @@ var (
|
||||||
defaultTestContentType = http.DetectContentType(defaultTestPayload)
|
defaultTestContentType = http.DetectContentType(defaultTestPayload)
|
||||||
)
|
)
|
||||||
|
|
||||||
func newTestObject(id *oid.ID, bkt *data.BucketInfo, name string) *object.Object {
|
func newTestObject(id oid.ID, bkt *data.BucketInfo, name string) *object.Object {
|
||||||
filename := object.NewAttribute()
|
filename := object.NewAttribute()
|
||||||
filename.SetKey(object.AttributeFileName)
|
filename.SetKey(object.AttributeFileName)
|
||||||
filename.SetValue(name)
|
filename.SetValue(name)
|
||||||
|
@ -37,9 +37,9 @@ func newTestObject(id *oid.ID, bkt *data.BucketInfo, name string) *object.Object
|
||||||
contentType.SetValue(defaultTestContentType)
|
contentType.SetValue(defaultTestContentType)
|
||||||
|
|
||||||
obj := object.New()
|
obj := object.New()
|
||||||
obj.SetID(*id)
|
obj.SetID(id)
|
||||||
obj.SetOwnerID(bkt.Owner)
|
obj.SetOwnerID(&bkt.Owner)
|
||||||
obj.SetContainerID(*bkt.CID)
|
obj.SetContainerID(bkt.CID)
|
||||||
obj.SetPayload(defaultTestPayload)
|
obj.SetPayload(defaultTestPayload)
|
||||||
obj.SetAttributes(*filename, *created, *contentType)
|
obj.SetAttributes(*filename, *created, *contentType)
|
||||||
obj.SetPayloadSize(uint64(defaultTestPayloadLength))
|
obj.SetPayloadSize(uint64(defaultTestPayloadLength))
|
||||||
|
@ -47,10 +47,10 @@ func newTestObject(id *oid.ID, bkt *data.BucketInfo, name string) *object.Object
|
||||||
return obj
|
return obj
|
||||||
}
|
}
|
||||||
|
|
||||||
func newTestInfo(oid *oid.ID, bkt *data.BucketInfo, name string, isDir bool) *data.ObjectInfo {
|
func newTestInfo(obj oid.ID, bkt *data.BucketInfo, name string, isDir bool) *data.ObjectInfo {
|
||||||
var hashSum checksum.Checksum
|
var hashSum checksum.Checksum
|
||||||
info := &data.ObjectInfo{
|
info := &data.ObjectInfo{
|
||||||
ID: oid,
|
ID: obj,
|
||||||
Name: name,
|
Name: name,
|
||||||
Bucket: bkt.Name,
|
Bucket: bkt.Name,
|
||||||
CID: bkt.CID,
|
CID: bkt.CID,
|
||||||
|
@ -79,8 +79,8 @@ func Test_objectInfoFromMeta(t *testing.T) {
|
||||||
|
|
||||||
bkt := &data.BucketInfo{
|
bkt := &data.BucketInfo{
|
||||||
Name: "test-container",
|
Name: "test-container",
|
||||||
CID: &containerID,
|
CID: containerID,
|
||||||
Owner: &uid,
|
Owner: uid,
|
||||||
Created: time.Now(),
|
Created: time.Now(),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,66 +93,66 @@ func Test_objectInfoFromMeta(t *testing.T) {
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "small.jpg",
|
name: "small.jpg",
|
||||||
result: newTestInfo(&id, bkt, "small.jpg", false),
|
result: newTestInfo(id, bkt, "small.jpg", false),
|
||||||
object: newTestObject(&id, bkt, "small.jpg"),
|
object: newTestObject(id, bkt, "small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "small.jpg not matched prefix",
|
name: "small.jpg not matched prefix",
|
||||||
prefix: "big",
|
prefix: "big",
|
||||||
result: nil,
|
result: nil,
|
||||||
object: newTestObject(&id, bkt, "small.jpg"),
|
object: newTestObject(id, bkt, "small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "small.jpg delimiter",
|
name: "small.jpg delimiter",
|
||||||
delimiter: "/",
|
delimiter: "/",
|
||||||
result: newTestInfo(&id, bkt, "small.jpg", false),
|
result: newTestInfo(id, bkt, "small.jpg", false),
|
||||||
object: newTestObject(&id, bkt, "small.jpg"),
|
object: newTestObject(id, bkt, "small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test/small.jpg",
|
name: "test/small.jpg",
|
||||||
result: newTestInfo(&id, bkt, "test/small.jpg", false),
|
result: newTestInfo(id, bkt, "test/small.jpg", false),
|
||||||
object: newTestObject(&id, bkt, "test/small.jpg"),
|
object: newTestObject(id, bkt, "test/small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "test/small.jpg with prefix and delimiter",
|
name: "test/small.jpg with prefix and delimiter",
|
||||||
prefix: "test/",
|
prefix: "test/",
|
||||||
delimiter: "/",
|
delimiter: "/",
|
||||||
result: newTestInfo(&id, bkt, "test/small.jpg", false),
|
result: newTestInfo(id, bkt, "test/small.jpg", false),
|
||||||
object: newTestObject(&id, bkt, "test/small.jpg"),
|
object: newTestObject(id, bkt, "test/small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "a/b/small.jpg",
|
name: "a/b/small.jpg",
|
||||||
prefix: "a",
|
prefix: "a",
|
||||||
result: newTestInfo(&id, bkt, "a/b/small.jpg", false),
|
result: newTestInfo(id, bkt, "a/b/small.jpg", false),
|
||||||
object: newTestObject(&id, bkt, "a/b/small.jpg"),
|
object: newTestObject(id, bkt, "a/b/small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "a/b/small.jpg",
|
name: "a/b/small.jpg",
|
||||||
prefix: "a/",
|
prefix: "a/",
|
||||||
delimiter: "/",
|
delimiter: "/",
|
||||||
result: newTestInfo(&id, bkt, "a/b/", true),
|
result: newTestInfo(id, bkt, "a/b/", true),
|
||||||
object: newTestObject(&id, bkt, "a/b/small.jpg"),
|
object: newTestObject(id, bkt, "a/b/small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "a/b/c/small.jpg",
|
name: "a/b/c/small.jpg",
|
||||||
prefix: "a/",
|
prefix: "a/",
|
||||||
delimiter: "/",
|
delimiter: "/",
|
||||||
result: newTestInfo(&id, bkt, "a/b/", true),
|
result: newTestInfo(id, bkt, "a/b/", true),
|
||||||
object: newTestObject(&id, bkt, "a/b/c/small.jpg"),
|
object: newTestObject(id, bkt, "a/b/c/small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "a/b/c/small.jpg",
|
name: "a/b/c/small.jpg",
|
||||||
prefix: "a/b/c/s",
|
prefix: "a/b/c/s",
|
||||||
delimiter: "/",
|
delimiter: "/",
|
||||||
result: newTestInfo(&id, bkt, "a/b/c/small.jpg", false),
|
result: newTestInfo(id, bkt, "a/b/c/small.jpg", false),
|
||||||
object: newTestObject(&id, bkt, "a/b/c/small.jpg"),
|
object: newTestObject(id, bkt, "a/b/c/small.jpg"),
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "a/b/c/big.jpg",
|
name: "a/b/c/big.jpg",
|
||||||
prefix: "a/b/",
|
prefix: "a/b/",
|
||||||
delimiter: "/",
|
delimiter: "/",
|
||||||
result: newTestInfo(&id, bkt, "a/b/c/", true),
|
result: newTestInfo(id, bkt, "a/b/c/", true),
|
||||||
object: newTestObject(&id, bkt, "a/b/c/big.jpg"),
|
object: newTestObject(id, bkt, "a/b/c/big.jpg"),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -271,10 +271,11 @@ func (v *objectVersions) getDelHeader() string {
|
||||||
return strings.Join(v.delList, ",")
|
return strings.Join(v.delList, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (v *objectVersions) getVersion(oid *oid.ID) *data.ObjectInfo {
|
func (v *objectVersions) getVersion(obj oid.ID) *data.ObjectInfo {
|
||||||
|
strObj := obj.EncodeToString()
|
||||||
for _, version := range v.objects {
|
for _, version := range v.objects {
|
||||||
if version.Version() == oid.String() {
|
if version.Version() == strObj {
|
||||||
if contains(v.delList, oid.String()) {
|
if contains(v.delList, strObj) {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
return version
|
return version
|
||||||
|
@ -397,7 +398,7 @@ func (n *layer) checkVersionsExist(ctx context.Context, bkt *data.BucketInfo, ob
|
||||||
if err = id.DecodeString(obj.VersionID); err != nil {
|
if err = id.DecodeString(obj.VersionID); err != nil {
|
||||||
return nil, errors.GetAPIError(errors.ErrInvalidVersion)
|
return nil, errors.GetAPIError(errors.ErrInvalidVersion)
|
||||||
}
|
}
|
||||||
version = versions.getVersion(&id)
|
version = versions.getVersion(id)
|
||||||
}
|
}
|
||||||
|
|
||||||
if version == nil {
|
if version == nil {
|
||||||
|
|
|
@ -15,7 +15,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/internal/neofstest"
|
"github.com/nspcc-dev/neofs-s3-gw/internal/neofstest"
|
||||||
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"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
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"
|
usertest "github.com/nspcc-dev/neofs-sdk-go/user/test"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -104,7 +103,7 @@ func (tc *testContext) listVersions() *ListObjectVersionsInfo {
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
func (tc *testContext) checkListObjects(ids ...*oid.ID) {
|
func (tc *testContext) checkListObjects(ids ...oid.ID) {
|
||||||
objs := tc.listObjectsV1()
|
objs := tc.listObjectsV1()
|
||||||
require.Equal(tc.t, len(ids), len(objs))
|
require.Equal(tc.t, len(ids), len(objs))
|
||||||
for _, id := range ids {
|
for _, id := range ids {
|
||||||
|
@ -174,8 +173,8 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
layer: NewLayer(zap.NewNop(), tp, layerCfg),
|
layer: NewLayer(zap.NewNop(), tp, layerCfg),
|
||||||
bktInfo: &data.BucketInfo{
|
bktInfo: &data.BucketInfo{
|
||||||
Name: bktName,
|
Name: bktName,
|
||||||
Owner: usertest.ID(),
|
Owner: *usertest.ID(),
|
||||||
CID: bktID,
|
CID: *bktID,
|
||||||
},
|
},
|
||||||
obj: "obj1",
|
obj: "obj1",
|
||||||
t: t,
|
t: t,
|
||||||
|
@ -199,9 +198,9 @@ func TestSimpleVersioning(t *testing.T) {
|
||||||
|
|
||||||
objv2, buffer2 := tc.getObject(tc.obj, "", false)
|
objv2, buffer2 := tc.getObject(tc.obj, "", false)
|
||||||
require.Equal(t, obj1Content2, buffer2)
|
require.Equal(t, obj1Content2, buffer2)
|
||||||
require.Contains(t, objv2.Headers[versionsAddAttr], obj1v1.ID.String())
|
require.Contains(t, objv2.Headers[versionsAddAttr], obj1v1.ID.EncodeToString())
|
||||||
|
|
||||||
_, buffer1 := tc.getObject(tc.obj, obj1v1.ID.String(), false)
|
_, buffer1 := tc.getObject(tc.obj, obj1v1.ID.EncodeToString(), false)
|
||||||
require.Equal(t, obj1Content1, buffer1)
|
require.Equal(t, obj1Content1, buffer1)
|
||||||
|
|
||||||
tc.checkListObjects(obj1v2.ID)
|
tc.checkListObjects(obj1v2.ID)
|
||||||
|
@ -218,9 +217,9 @@ func TestSimpleNoVersioning(t *testing.T) {
|
||||||
|
|
||||||
objv2, buffer2 := tc.getObject(tc.obj, "", false)
|
objv2, buffer2 := tc.getObject(tc.obj, "", false)
|
||||||
require.Equal(t, obj1Content2, buffer2)
|
require.Equal(t, obj1Content2, buffer2)
|
||||||
require.Contains(t, objv2.Headers[versionsDelAttr], obj1v1.ID.String())
|
require.Contains(t, objv2.Headers[versionsDelAttr], obj1v1.ID.EncodeToString())
|
||||||
|
|
||||||
tc.getObject(tc.obj, obj1v1.ID.String(), true)
|
tc.getObject(tc.obj, obj1v1.ID.EncodeToString(), true)
|
||||||
tc.checkListObjects(obj1v2.ID)
|
tc.checkListObjects(obj1v2.ID)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -479,13 +478,13 @@ func joinVers(objs ...*data.ObjectInfo) string {
|
||||||
return strings.Join(versions, ",")
|
return strings.Join(versions, ",")
|
||||||
}
|
}
|
||||||
|
|
||||||
func getOID(id byte) *oid.ID {
|
func getOID(id byte) oid.ID {
|
||||||
b := [32]byte{}
|
b := [32]byte{}
|
||||||
b[31] = id
|
b[31] = id
|
||||||
|
|
||||||
var idObj oid.ID
|
var idObj oid.ID
|
||||||
idObj.SetSHA256(b)
|
idObj.SetSHA256(b)
|
||||||
return &idObj
|
return idObj
|
||||||
}
|
}
|
||||||
|
|
||||||
func getTestObjectInfo(id byte, addAttr, delAttr, delMarkAttr string) *data.ObjectInfo {
|
func getTestObjectInfo(id byte, addAttr, delAttr, delMarkAttr string) *data.ObjectInfo {
|
||||||
|
@ -531,7 +530,7 @@ func TestUpdateCRDT2PSetHeaders(t *testing.T) {
|
||||||
versions *objectVersions
|
versions *objectVersions
|
||||||
versioningEnabled bool
|
versioningEnabled bool
|
||||||
expectedHeader map[string]string
|
expectedHeader map[string]string
|
||||||
expectedIdsToDelete []*oid.ID
|
expectedIdsToDelete []oid.ID
|
||||||
}{
|
}{
|
||||||
{
|
{
|
||||||
name: "unversioned save headers",
|
name: "unversioned save headers",
|
||||||
|
@ -549,7 +548,7 @@ func TestUpdateCRDT2PSetHeaders(t *testing.T) {
|
||||||
versionsDelAttr: obj1.Version(),
|
versionsDelAttr: obj1.Version(),
|
||||||
versionsUnversionedAttr: "true",
|
versionsUnversionedAttr: "true",
|
||||||
},
|
},
|
||||||
expectedIdsToDelete: []*oid.ID{obj1.ID},
|
expectedIdsToDelete: []oid.ID{obj1.ID},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "unversioned del header",
|
name: "unversioned del header",
|
||||||
|
@ -563,7 +562,7 @@ func TestUpdateCRDT2PSetHeaders(t *testing.T) {
|
||||||
versionsDelAttr: joinVers(obj1, obj2),
|
versionsDelAttr: joinVers(obj1, obj2),
|
||||||
versionsUnversionedAttr: "true",
|
versionsUnversionedAttr: "true",
|
||||||
},
|
},
|
||||||
expectedIdsToDelete: []*oid.ID{obj2.ID},
|
expectedIdsToDelete: []oid.ID{obj2.ID},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "versioned put",
|
name: "versioned put",
|
||||||
|
@ -598,7 +597,7 @@ func TestUpdateCRDT2PSetHeaders(t *testing.T) {
|
||||||
versionsDelAttr: obj1.Version(),
|
versionsDelAttr: obj1.Version(),
|
||||||
versionsUnversionedAttr: "true",
|
versionsUnversionedAttr: "true",
|
||||||
},
|
},
|
||||||
expectedIdsToDelete: []*oid.ID{obj1.ID},
|
expectedIdsToDelete: []oid.ID{obj1.ID},
|
||||||
},
|
},
|
||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
@ -631,12 +630,13 @@ func TestSystemObjectsVersioning(t *testing.T) {
|
||||||
|
|
||||||
cnrID, _ := objMeta.ContainerID()
|
cnrID, _ := objMeta.ContainerID()
|
||||||
objID, _ := objMeta.ID()
|
objID, _ := objMeta.ID()
|
||||||
addr := address.NewAddress()
|
|
||||||
addr.SetContainerID(cnrID)
|
var addr oid.Address
|
||||||
addr.SetObjectID(objID)
|
addr.SetContainer(cnrID)
|
||||||
|
addr.SetObject(objID)
|
||||||
|
|
||||||
// simulate failed deletion
|
// simulate failed deletion
|
||||||
tc.testNeoFS.AddObject(addr.String(), objMeta)
|
tc.testNeoFS.AddObject(addr.EncodeToString(), objMeta)
|
||||||
|
|
||||||
versioning, err := tc.layer.GetBucketSettings(tc.ctx, tc.bktInfo)
|
versioning, err := tc.layer.GetBucketSettings(tc.ctx, tc.bktInfo)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
@ -656,7 +656,7 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
|
||||||
err := tc.layer.PutBucketTagging(tc.ctx, tc.bktInfo, tagSet)
|
err := tc.layer.PutBucketTagging(tc.ctx, tc.bktInfo, tagSet)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktInfo.CID.String()))
|
objMeta := tc.getSystemObject(formBucketTagObjectName(tc.bktInfo.CID.EncodeToString()))
|
||||||
|
|
||||||
tagSet["tag2"] = "val2"
|
tagSet["tag2"] = "val2"
|
||||||
err = tc.layer.PutBucketTagging(tc.ctx, tc.bktInfo, tagSet)
|
err = tc.layer.PutBucketTagging(tc.ctx, tc.bktInfo, tagSet)
|
||||||
|
@ -665,7 +665,7 @@ func TestDeleteSystemObjectsVersioning(t *testing.T) {
|
||||||
// simulate failed deletion
|
// simulate failed deletion
|
||||||
cnrID, _ := objMeta.ContainerID()
|
cnrID, _ := objMeta.ContainerID()
|
||||||
objID, _ := objMeta.ID()
|
objID, _ := objMeta.ID()
|
||||||
tc.testNeoFS.AddObject(newAddress(cnrID, objID).String(), objMeta)
|
tc.testNeoFS.AddObject(newAddress(cnrID, objID).EncodeToString(), objMeta)
|
||||||
|
|
||||||
tagging, err := tc.layer.GetBucketTagging(tc.ctx, tc.bktInfo)
|
tagging, err := tc.layer.GetBucketTagging(tc.ctx, tc.bktInfo)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
|
@ -21,7 +21,7 @@ import (
|
||||||
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
neofsecdsa "github.com/nspcc-dev/neofs-sdk-go/crypto/ecdsa"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/policy"
|
"github.com/nspcc-dev/neofs-sdk-go/policy"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/user"
|
"github.com/nspcc-dev/neofs-sdk-go/user"
|
||||||
|
@ -207,7 +207,6 @@ func preparePolicy(policy ContainerPolicies) ([]*accessbox.AccessBox_ContainerPo
|
||||||
func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecretOptions) error {
|
func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecretOptions) error {
|
||||||
var (
|
var (
|
||||||
err error
|
err error
|
||||||
id *cid.ID
|
|
||||||
box *accessbox.AccessBox
|
box *accessbox.AccessBox
|
||||||
lifetime lifetimeOptions
|
lifetime lifetimeOptions
|
||||||
)
|
)
|
||||||
|
@ -240,7 +239,8 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
|
a.log.Info("check container or create", zap.Stringer("cid", options.Container.ID),
|
||||||
zap.String("friendly_name", options.Container.FriendlyName),
|
zap.String("friendly_name", options.Container.FriendlyName),
|
||||||
zap.String("placement_policy", options.Container.PlacementPolicy))
|
zap.String("placement_policy", options.Container.PlacementPolicy))
|
||||||
if id, err = a.checkContainer(ctx, options.Container, idOwner); err != nil {
|
id, err := a.checkContainer(ctx, options.Container, idOwner)
|
||||||
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -249,20 +249,21 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
|
|
||||||
addr, err := tokens.
|
addr, err := tokens.
|
||||||
New(a.neoFS, secrets.EphemeralKey, cache.DefaultAccessBoxConfig()).
|
New(a.neoFS, secrets.EphemeralKey, cache.DefaultAccessBoxConfig()).
|
||||||
Put(ctx, id, idOwner, box, lifetime.Exp, options.GatesPublicKeys...)
|
Put(ctx, *id, idOwner, box, lifetime.Exp, options.GatesPublicKeys...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to put bearer token: %w", err)
|
return fmt.Errorf("failed to put bearer token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cnrID, _ := addr.ContainerID()
|
objID := addr.Object()
|
||||||
objID, _ := addr.ObjectID()
|
strIDObj := objID.EncodeToString()
|
||||||
accessKeyID := cnrID.EncodeToString() + "0" + objID.EncodeToString()
|
|
||||||
|
accessKeyID := addr.Container().EncodeToString() + "0" + strIDObj
|
||||||
|
|
||||||
ir := &issuingResult{
|
ir := &issuingResult{
|
||||||
AccessKeyID: accessKeyID,
|
AccessKeyID: accessKeyID,
|
||||||
SecretAccessKey: secrets.AccessKey,
|
SecretAccessKey: secrets.AccessKey,
|
||||||
OwnerPrivateKey: hex.EncodeToString(secrets.EphemeralKey.Bytes()),
|
OwnerPrivateKey: hex.EncodeToString(secrets.EphemeralKey.Bytes()),
|
||||||
ContainerID: id.String(),
|
ContainerID: id.EncodeToString(),
|
||||||
}
|
}
|
||||||
|
|
||||||
enc := json.NewEncoder(w)
|
enc := json.NewEncoder(w)
|
||||||
|
@ -272,7 +273,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
}
|
}
|
||||||
|
|
||||||
if options.AwsCliCredentialsFile != "" {
|
if options.AwsCliCredentialsFile != "" {
|
||||||
profileName := "authmate_cred_" + objID.EncodeToString()
|
profileName := "authmate_cred_" + strIDObj
|
||||||
if _, err = os.Stat(options.AwsCliCredentialsFile); os.IsNotExist(err) {
|
if _, err = os.Stat(options.AwsCliCredentialsFile); os.IsNotExist(err) {
|
||||||
profileName = "default"
|
profileName = "default"
|
||||||
}
|
}
|
||||||
|
@ -293,8 +294,9 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
// writes to io.Writer the secret access key.
|
// writes to io.Writer the secret access key.
|
||||||
func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error {
|
func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSecretOptions) error {
|
||||||
bearerCreds := tokens.New(a.neoFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig())
|
bearerCreds := tokens.New(a.neoFS, options.GatePrivateKey, cache.DefaultAccessBoxConfig())
|
||||||
addr := address.NewAddress()
|
|
||||||
if err := addr.Parse(options.SecretAddress); err != nil {
|
var addr oid.Address
|
||||||
|
if err := addr.DecodeString(options.SecretAddress); err != nil {
|
||||||
return fmt.Errorf("failed to parse secret address: %w", err)
|
return fmt.Errorf("failed to parse secret address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
"github.com/nspcc-dev/neofs-s3-gw/api/cache"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
|
||||||
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
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"
|
||||||
)
|
)
|
||||||
|
@ -19,8 +18,8 @@ import (
|
||||||
type (
|
type (
|
||||||
// Credentials is a bearer token get/put interface.
|
// Credentials is a bearer token get/put interface.
|
||||||
Credentials interface {
|
Credentials interface {
|
||||||
GetBox(context.Context, *address.Address) (*accessbox.Box, error)
|
GetBox(context.Context, oid.Address) (*accessbox.Box, error)
|
||||||
Put(context.Context, *cid.ID, user.ID, *accessbox.AccessBox, uint64, ...*keys.PublicKey) (*address.Address, error)
|
Put(context.Context, cid.ID, user.ID, *accessbox.AccessBox, uint64, ...*keys.PublicKey) (*oid.Address, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
cred struct {
|
cred struct {
|
||||||
|
@ -63,7 +62,7 @@ type NeoFS interface {
|
||||||
//
|
//
|
||||||
// It returns exactly one non-nil value. It returns any error encountered which
|
// It returns exactly one non-nil value. It returns any error encountered which
|
||||||
// prevented the object payload from being read.
|
// prevented the object payload from being read.
|
||||||
ReadObjectPayload(context.Context, address.Address) ([]byte, error)
|
ReadObjectPayload(context.Context, oid.Address) ([]byte, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -80,7 +79,7 @@ func New(neoFS NeoFS, key *keys.PrivateKey, config *cache.Config) Credentials {
|
||||||
return &cred{neoFS: neoFS, key: key, cache: cache.NewAccessBoxCache(config)}
|
return &cred{neoFS: neoFS, key: key, cache: cache.NewAccessBoxCache(config)}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) GetBox(ctx context.Context, addr *address.Address) (*accessbox.Box, error) {
|
func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, error) {
|
||||||
cachedBox := c.cache.Get(addr)
|
cachedBox := c.cache.Get(addr)
|
||||||
if cachedBox != nil {
|
if cachedBox != nil {
|
||||||
return cachedBox, nil
|
return cachedBox, nil
|
||||||
|
@ -103,8 +102,8 @@ func (c *cred) GetBox(ctx context.Context, addr *address.Address) (*accessbox.Bo
|
||||||
return cachedBox, nil
|
return cachedBox, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) getAccessBox(ctx context.Context, addr *address.Address) (*accessbox.AccessBox, error) {
|
func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, error) {
|
||||||
data, err := c.neoFS.ReadObjectPayload(ctx, *addr)
|
data, err := c.neoFS.ReadObjectPayload(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("read payload: %w", err)
|
return nil, fmt.Errorf("read payload: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -118,7 +117,7 @@ func (c *cred) getAccessBox(ctx context.Context, addr *address.Address) (*access
|
||||||
return &box, nil
|
return &box, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) Put(ctx context.Context, idCnr *cid.ID, issuer user.ID, box *accessbox.AccessBox, expiration uint64, keys ...*keys.PublicKey) (*address.Address, error) {
|
func (c *cred) Put(ctx context.Context, idCnr cid.ID, issuer user.ID, box *accessbox.AccessBox, expiration uint64, keys ...*keys.PublicKey) (*oid.Address, error) {
|
||||||
if len(keys) == 0 {
|
if len(keys) == 0 {
|
||||||
return nil, ErrEmptyPublicKeys
|
return nil, ErrEmptyPublicKeys
|
||||||
} else if box == nil {
|
} else if box == nil {
|
||||||
|
@ -131,7 +130,7 @@ func (c *cred) Put(ctx context.Context, idCnr *cid.ID, issuer user.ID, box *acce
|
||||||
|
|
||||||
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
||||||
Creator: issuer,
|
Creator: issuer,
|
||||||
Container: *idCnr,
|
Container: idCnr,
|
||||||
Filename: strconv.FormatInt(time.Now().Unix(), 10) + "_access.box",
|
Filename: strconv.FormatInt(time.Now().Unix(), 10) + "_access.box",
|
||||||
ExpirationEpoch: expiration,
|
ExpirationEpoch: expiration,
|
||||||
Payload: data,
|
Payload: data,
|
||||||
|
@ -140,8 +139,9 @@ func (c *cred) Put(ctx context.Context, idCnr *cid.ID, issuer user.ID, box *acce
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
addr := address.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetObjectID(*idObj)
|
addr.SetObject(*idObj)
|
||||||
addr.SetContainerID(*idCnr)
|
addr.SetContainer(idCnr)
|
||||||
return addr, nil
|
|
||||||
|
return &addr, nil
|
||||||
}
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -10,7 +10,7 @@ require (
|
||||||
github.com/nats-io/nats.go v1.13.1-0.20220121202836-972a071d373d
|
github.com/nats-io/nats.go v1.13.1-0.20220121202836-972a071d373d
|
||||||
github.com/nspcc-dev/neo-go v0.98.2
|
github.com/nspcc-dev/neo-go v0.98.2
|
||||||
github.com/nspcc-dev/neofs-api-go/v2 v2.12.1
|
github.com/nspcc-dev/neofs-api-go/v2 v2.12.1
|
||||||
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220504192402-12ea1e8d740f
|
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220527094135-3bbf7ee15d76
|
||||||
github.com/prometheus/client_golang v1.11.0
|
github.com/prometheus/client_golang v1.11.0
|
||||||
github.com/spf13/pflag v1.0.5
|
github.com/spf13/pflag v1.0.5
|
||||||
github.com/spf13/viper v1.7.1
|
github.com/spf13/viper v1.7.1
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -306,8 +306,8 @@ github.com/nspcc-dev/neofs-crypto v0.3.0 h1:zlr3pgoxuzrmGCxc5W8dGVfA9Rro8diFvVnB
|
||||||
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
github.com/nspcc-dev/neofs-crypto v0.3.0/go.mod h1:8w16GEJbH6791ktVqHN9YRNH3s9BEEKYxGhlFnp0cDw=
|
||||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211201182451-a5b61c4f6477/go.mod h1:dfMtQWmBHYpl9Dez23TGtIUKiFvCIxUZq/CkSIhEpz4=
|
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20211201182451-a5b61c4f6477/go.mod h1:dfMtQWmBHYpl9Dez23TGtIUKiFvCIxUZq/CkSIhEpz4=
|
||||||
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20220113123743-7f3162110659/go.mod h1:/jay1lr3w7NQd/VDBkEhkJmDmyPNsu4W+QV2obsUV40=
|
github.com/nspcc-dev/neofs-sdk-go v0.0.0-20220113123743-7f3162110659/go.mod h1:/jay1lr3w7NQd/VDBkEhkJmDmyPNsu4W+QV2obsUV40=
|
||||||
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220504192402-12ea1e8d740f h1:cMxSTUkugwaBFL7dEYirmjOEQ2p12phcpKO1Z3UhP64=
|
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220527094135-3bbf7ee15d76 h1:wa2DGnV258ek5sKE1DAOHsve1sG0KZA4OEw9e/TRQNM=
|
||||||
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220504192402-12ea1e8d740f/go.mod h1:u567oWTnAyGXbPWMrbcN0NB5zCPF+PqkaKg+vcijcho=
|
github.com/nspcc-dev/neofs-sdk-go v1.0.0-rc.3.0.20220527094135-3bbf7ee15d76/go.mod h1:u567oWTnAyGXbPWMrbcN0NB5zCPF+PqkaKg+vcijcho=
|
||||||
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.1.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
github.com/nspcc-dev/rfc6979 v0.2.0 h1:3e1WNxrN60/6N0DW7+UYisLeZJyfqZTNOjeV/toYvOE=
|
||||||
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
github.com/nspcc-dev/rfc6979 v0.2.0/go.mod h1:exhIh1PdpDC5vQmyEsGvc4YDM/lyQp/452QxGq/UEso=
|
||||||
|
|
|
@ -22,7 +22,6 @@ import (
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
"github.com/nspcc-dev/neofs-sdk-go/eacl"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
"github.com/nspcc-dev/neofs-sdk-go/netmap"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
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/pool"
|
"github.com/nspcc-dev/neofs-sdk-go/pool"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/session"
|
"github.com/nspcc-dev/neofs-sdk-go/session"
|
||||||
|
@ -348,9 +347,9 @@ func (x payloadReader) Read(p []byte) (int, error) {
|
||||||
|
|
||||||
// ReadObject implements neofs.NeoFS interface method.
|
// ReadObject implements neofs.NeoFS interface method.
|
||||||
func (x *NeoFS) ReadObject(ctx context.Context, prm neofs.PrmObjectRead) (*neofs.ObjectPart, error) {
|
func (x *NeoFS) ReadObject(ctx context.Context, prm neofs.PrmObjectRead) (*neofs.ObjectPart, error) {
|
||||||
var addr address.Address
|
var addr oid.Address
|
||||||
addr.SetContainerID(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObjectID(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
|
||||||
var prmGet pool.PrmObjectGet
|
var prmGet pool.PrmObjectGet
|
||||||
prmGet.SetAddress(addr)
|
prmGet.SetAddress(addr)
|
||||||
|
@ -449,9 +448,9 @@ func (x *NeoFS) ReadObject(ctx context.Context, prm neofs.PrmObjectRead) (*neofs
|
||||||
|
|
||||||
// DeleteObject implements neofs.NeoFS interface method.
|
// DeleteObject implements neofs.NeoFS interface method.
|
||||||
func (x *NeoFS) DeleteObject(ctx context.Context, prm neofs.PrmObjectDelete) error {
|
func (x *NeoFS) DeleteObject(ctx context.Context, prm neofs.PrmObjectDelete) error {
|
||||||
var addr address.Address
|
var addr oid.Address
|
||||||
addr.SetContainerID(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObjectID(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
|
||||||
var prmDelete pool.PrmObjectDelete
|
var prmDelete pool.PrmObjectDelete
|
||||||
prmDelete.SetAddress(addr)
|
prmDelete.SetAddress(addr)
|
||||||
|
@ -557,13 +556,10 @@ func (x *AuthmateNeoFS) CreateContainer(ctx context.Context, prm authmate.PrmCon
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReadObjectPayload implements authmate.NeoFS interface method.
|
// ReadObjectPayload implements authmate.NeoFS interface method.
|
||||||
func (x *AuthmateNeoFS) ReadObjectPayload(ctx context.Context, addr address.Address) ([]byte, error) {
|
func (x *AuthmateNeoFS) ReadObjectPayload(ctx context.Context, addr oid.Address) ([]byte, error) {
|
||||||
cnrID, _ := addr.ContainerID()
|
|
||||||
objID, _ := addr.ObjectID()
|
|
||||||
|
|
||||||
res, err := x.neoFS.ReadObject(ctx, neofs.PrmObjectRead{
|
res, err := x.neoFS.ReadObject(ctx, neofs.PrmObjectRead{
|
||||||
Container: cnrID,
|
Container: addr.Container(),
|
||||||
Object: objID,
|
Object: addr.Object(),
|
||||||
WithPayload: true,
|
WithPayload: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -16,7 +16,6 @@ import (
|
||||||
"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"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object"
|
"github.com/nspcc-dev/neofs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neofs-sdk-go/object/address"
|
|
||||||
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"
|
||||||
)
|
)
|
||||||
|
@ -98,19 +97,19 @@ func (t *TestNeoFS) CreateContainer(_ context.Context, prm neofs.PrmContainerCre
|
||||||
|
|
||||||
var id cid.ID
|
var id cid.ID
|
||||||
id.SetSHA256(sha256.Sum256(b))
|
id.SetSHA256(sha256.Sum256(b))
|
||||||
t.containers[id.String()] = cnr
|
t.containers[id.EncodeToString()] = cnr
|
||||||
|
|
||||||
return &id, nil
|
return &id, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) Container(_ context.Context, id cid.ID) (*container.Container, error) {
|
func (t *TestNeoFS) Container(_ context.Context, id cid.ID) (*container.Container, error) {
|
||||||
for k, v := range t.containers {
|
for k, v := range t.containers {
|
||||||
if k == id.String() {
|
if k == id.EncodeToString() {
|
||||||
return v, nil
|
return v, nil
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("container not found " + id.String())
|
return nil, fmt.Errorf("container not found %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, error) {
|
func (t *TestNeoFS) UserContainers(_ context.Context, _ user.ID) ([]cid.ID, error) {
|
||||||
|
@ -138,7 +137,7 @@ func (t *TestNeoFS) SelectObjects(_ context.Context, prm neofs.PrmObjectSelect)
|
||||||
filters.AddFilter(prm.ExactAttribute[0], prm.ExactAttribute[1], object.MatchStringEqual)
|
filters.AddFilter(prm.ExactAttribute[0], prm.ExactAttribute[1], object.MatchStringEqual)
|
||||||
}
|
}
|
||||||
|
|
||||||
cidStr := prm.Container.String()
|
cidStr := prm.Container.EncodeToString()
|
||||||
|
|
||||||
var res []oid.ID
|
var res []oid.ID
|
||||||
|
|
||||||
|
@ -169,11 +168,11 @@ func (t *TestNeoFS) SelectObjects(_ context.Context, prm neofs.PrmObjectSelect)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) ReadObject(_ context.Context, prm neofs.PrmObjectRead) (*neofs.ObjectPart, error) {
|
func (t *TestNeoFS) ReadObject(_ context.Context, prm neofs.PrmObjectRead) (*neofs.ObjectPart, error) {
|
||||||
var addr address.Address
|
var addr oid.Address
|
||||||
addr.SetContainerID(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObjectID(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
|
||||||
sAddr := addr.String()
|
sAddr := addr.EncodeToString()
|
||||||
|
|
||||||
if obj, ok := t.objects[sAddr]; ok {
|
if obj, ok := t.objects[sAddr]; ok {
|
||||||
return &neofs.ObjectPart{
|
return &neofs.ObjectPart{
|
||||||
|
@ -182,7 +181,7 @@ func (t *TestNeoFS) ReadObject(_ context.Context, prm neofs.PrmObjectRead) (*neo
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, fmt.Errorf("object not found " + addr.String())
|
return nil, fmt.Errorf("object not found %s", addr)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) CreateObject(_ context.Context, prm neofs.PrmObjectCreate) (*oid.ID, error) {
|
func (t *TestNeoFS) CreateObject(_ context.Context, prm neofs.PrmObjectCreate) (*oid.ID, error) {
|
||||||
|
@ -236,16 +235,16 @@ func (t *TestNeoFS) CreateObject(_ context.Context, prm neofs.PrmObjectCreate) (
|
||||||
objID, _ := obj.ID()
|
objID, _ := obj.ID()
|
||||||
|
|
||||||
addr := newAddress(cnrID, objID)
|
addr := newAddress(cnrID, objID)
|
||||||
t.objects[addr.String()] = obj
|
t.objects[addr.EncodeToString()] = obj
|
||||||
return &objID, nil
|
return &objID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestNeoFS) DeleteObject(_ context.Context, prm neofs.PrmObjectDelete) error {
|
func (t *TestNeoFS) DeleteObject(_ context.Context, prm neofs.PrmObjectDelete) error {
|
||||||
var addr address.Address
|
var addr oid.Address
|
||||||
addr.SetContainerID(prm.Container)
|
addr.SetContainer(prm.Container)
|
||||||
addr.SetObjectID(prm.Object)
|
addr.SetObject(prm.Object)
|
||||||
|
|
||||||
delete(t.objects, addr.String())
|
delete(t.objects, addr.EncodeToString())
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -264,9 +263,9 @@ func isMatched(attributes []object.Attribute, filter object.SearchFilter) bool {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
func newAddress(cid cid.ID, oid oid.ID) *address.Address {
|
func newAddress(cnr cid.ID, obj oid.ID) oid.Address {
|
||||||
addr := address.NewAddress()
|
var addr oid.Address
|
||||||
addr.SetContainerID(cid)
|
addr.SetContainer(cnr)
|
||||||
addr.SetObjectID(oid)
|
addr.SetObject(obj)
|
||||||
return addr
|
return addr
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue