forked from TrueCloudLab/frostfs-s3-gw
[#367] Add check of AccessBox attributes
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
parent
5315f7b733
commit
e22ff52165
22 changed files with 157 additions and 110 deletions
|
@ -186,7 +186,7 @@ func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
box, err := c.cli.GetBox(r.Context(), addr)
|
box, attrs, err := c.cli.GetBox(r.Context(), addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get box '%s': %w", addr, err)
|
return nil, fmt.Errorf("get box '%s': %w", addr, err)
|
||||||
}
|
}
|
||||||
|
@ -207,6 +207,7 @@ func (c *Center) Authenticate(r *http.Request) (*middleware.Box, error) {
|
||||||
Region: authHdr.Region,
|
Region: authHdr.Region,
|
||||||
SignatureV4: authHdr.SignatureV4,
|
SignatureV4: authHdr.SignatureV4,
|
||||||
},
|
},
|
||||||
|
Attributes: attrs,
|
||||||
}
|
}
|
||||||
if needClientTime {
|
if needClientTime {
|
||||||
result.ClientTime = signatureDateTime
|
result.ClientTime = signatureDateTime
|
||||||
|
@ -274,7 +275,7 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
box, err := c.cli.GetBox(r.Context(), addr)
|
box, attrs, err := c.cli.GetBox(r.Context(), addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get box '%s': %w", addr, err)
|
return nil, fmt.Errorf("get box '%s': %w", addr, err)
|
||||||
}
|
}
|
||||||
|
@ -289,7 +290,7 @@ func (c *Center) checkFormData(r *http.Request) (*middleware.Box, error) {
|
||||||
reqSignature, signature)
|
reqSignature, signature)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &middleware.Box{AccessBox: box}, nil
|
return &middleware.Box{AccessBox: box, Attributes: attrs}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func cloneRequest(r *http.Request, authHeader *AuthHeader) *http.Request {
|
func cloneRequest(r *http.Request, authHeader *AuthHeader) *http.Request {
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/tokens"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/aws/aws-sdk-go/aws/credentials"
|
"github.com/aws/aws-sdk-go/aws/credentials"
|
||||||
"github.com/stretchr/testify/require"
|
"github.com/stretchr/testify/require"
|
||||||
|
@ -31,13 +32,13 @@ func (m credentialsMock) addBox(addr oid.Address, box *accessbox.Box) {
|
||||||
m.boxes[addr.String()] = box
|
m.boxes[addr.String()] = box
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m credentialsMock) GetBox(_ context.Context, addr oid.Address) (*accessbox.Box, error) {
|
func (m credentialsMock) GetBox(_ context.Context, addr oid.Address) (*accessbox.Box, []object.Attribute, error) {
|
||||||
box, ok := m.boxes[addr.String()]
|
box, ok := m.boxes[addr.String()]
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, &apistatus.ObjectNotFound{}
|
return nil, nil, &apistatus.ObjectNotFound{}
|
||||||
}
|
}
|
||||||
|
|
||||||
return box, nil
|
return box, nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m credentialsMock) Put(context.Context, cid.ID, tokens.CredentialsParam) (oid.Address, error) {
|
func (m credentialsMock) Put(context.Context, cid.ID, tokens.CredentialsParam) (oid.Address, error) {
|
||||||
|
|
5
api/cache/accessbox.go
vendored
5
api/cache/accessbox.go
vendored
|
@ -6,6 +6,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/bluele/gcache"
|
"github.com/bluele/gcache"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
|
@ -27,6 +28,7 @@ type (
|
||||||
|
|
||||||
AccessBoxCacheValue struct {
|
AccessBoxCacheValue struct {
|
||||||
Box *accessbox.Box
|
Box *accessbox.Box
|
||||||
|
Attributes []object.Attribute
|
||||||
PutTime time.Time
|
PutTime time.Time
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
@ -72,9 +74,10 @@ func (o *AccessBoxCache) Get(address oid.Address) *AccessBoxCacheValue {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Put stores an accessbox to cache.
|
// Put stores an accessbox to cache.
|
||||||
func (o *AccessBoxCache) Put(address oid.Address, box *accessbox.Box) error {
|
func (o *AccessBoxCache) Put(address oid.Address, box *accessbox.Box, attrs []object.Attribute) error {
|
||||||
val := &AccessBoxCacheValue{
|
val := &AccessBoxCacheValue{
|
||||||
Box: box,
|
Box: box,
|
||||||
|
Attributes: attrs,
|
||||||
PutTime: time.Now(),
|
PutTime: time.Now(),
|
||||||
}
|
}
|
||||||
return o.cache.Set(address, val)
|
return o.cache.Set(address, val)
|
||||||
|
|
5
api/cache/cache_test.go
vendored
5
api/cache/cache_test.go
vendored
|
@ -7,6 +7,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/data"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
||||||
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
cidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id/test"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -21,11 +22,13 @@ func TestAccessBoxCacheType(t *testing.T) {
|
||||||
|
|
||||||
addr := oidtest.Address()
|
addr := oidtest.Address()
|
||||||
box := &accessbox.Box{}
|
box := &accessbox.Box{}
|
||||||
|
var attrs []object.Attribute
|
||||||
|
|
||||||
err := cache.Put(addr, box)
|
err := cache.Put(addr, box, attrs)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
val := cache.Get(addr)
|
val := cache.Get(addr)
|
||||||
require.Equal(t, box, val.Box)
|
require.Equal(t, box, val.Box)
|
||||||
|
require.Equal(t, attrs, val.Attributes)
|
||||||
require.Equal(t, 0, observedLog.Len())
|
require.Equal(t, 0, observedLog.Len())
|
||||||
|
|
||||||
err = cache.cache.Set(addr, "tmp")
|
err = cache.cache.Set(addr, "tmp")
|
||||||
|
|
|
@ -1728,7 +1728,7 @@ func createBucketAssertS3Error(hc *handlerContext, bktName string, box *accessbo
|
||||||
|
|
||||||
func createBucketBase(hc *handlerContext, bktName string, box *accessbox.Box) *httptest.ResponseRecorder {
|
func createBucketBase(hc *handlerContext, bktName string, box *accessbox.Box) *httptest.ResponseRecorder {
|
||||||
w, r := prepareTestRequest(hc, bktName, "", nil)
|
w, r := prepareTestRequest(hc, bktName, "", nil)
|
||||||
ctx := middleware.SetBoxData(r.Context(), box)
|
ctx := middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
hc.Handler().CreateBucketHandler(w, r)
|
hc.Handler().CreateBucketHandler(w, r)
|
||||||
return w
|
return w
|
||||||
|
@ -1749,7 +1749,7 @@ func putBucketACLBase(hc *handlerContext, bktName string, box *accessbox.Box, he
|
||||||
for key, val := range header {
|
for key, val := range header {
|
||||||
r.Header.Set(key, val)
|
r.Header.Set(key, val)
|
||||||
}
|
}
|
||||||
ctx := middleware.SetBoxData(r.Context(), box)
|
ctx := middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
hc.Handler().PutBucketACLHandler(w, r)
|
hc.Handler().PutBucketACLHandler(w, r)
|
||||||
return w
|
return w
|
||||||
|
@ -1779,7 +1779,7 @@ func putObjectACLBase(hc *handlerContext, bktName, objName string, box *accessbo
|
||||||
for key, val := range header {
|
for key, val := range header {
|
||||||
r.Header.Set(key, val)
|
r.Header.Set(key, val)
|
||||||
}
|
}
|
||||||
ctx := middleware.SetBoxData(r.Context(), box)
|
ctx := middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
hc.Handler().PutObjectACLHandler(w, r)
|
hc.Handler().PutObjectACLHandler(w, r)
|
||||||
return w
|
return w
|
||||||
|
@ -1818,7 +1818,7 @@ func putObjectWithHeadersBase(hc *handlerContext, bktName, objName string, heade
|
||||||
r.Header.Set(k, v)
|
r.Header.Set(k, v)
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx := middleware.SetBoxData(r.Context(), box)
|
ctx := middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
|
|
||||||
hc.Handler().PutObjectHandler(w, r)
|
hc.Handler().PutObjectHandler(w, r)
|
||||||
|
|
|
@ -23,14 +23,14 @@ func TestCORSOriginWildcard(t *testing.T) {
|
||||||
bktName := "bucket-for-cors"
|
bktName := "bucket-for-cors"
|
||||||
box, _ := createAccessBox(t)
|
box, _ := createAccessBox(t)
|
||||||
w, r := prepareTestRequest(hc, bktName, "", nil)
|
w, r := prepareTestRequest(hc, bktName, "", nil)
|
||||||
ctx := middleware.SetBoxData(r.Context(), box)
|
ctx := middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
r.Header.Add(api.AmzACL, "public-read")
|
r.Header.Add(api.AmzACL, "public-read")
|
||||||
hc.Handler().CreateBucketHandler(w, r)
|
hc.Handler().CreateBucketHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
||||||
w, r = prepareTestPayloadRequest(hc, bktName, "", strings.NewReader(body))
|
w, r = prepareTestPayloadRequest(hc, bktName, "", strings.NewReader(body))
|
||||||
ctx = middleware.SetBoxData(r.Context(), box)
|
ctx = middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
r = r.WithContext(ctx)
|
r = r.WithContext(ctx)
|
||||||
hc.Handler().PutBucketCorsHandler(w, r)
|
hc.Handler().PutBucketCorsHandler(w, r)
|
||||||
assertStatus(t, w, http.StatusOK)
|
assertStatus(t, w, http.StatusOK)
|
||||||
|
|
|
@ -192,7 +192,7 @@ func prepareHandlerContextBase(t *testing.T, cacheCfg *layer.CachesConfig) *hand
|
||||||
h: h,
|
h: h,
|
||||||
tp: tp,
|
tp: tp,
|
||||||
tree: treeMock,
|
tree: treeMock,
|
||||||
context: middleware.SetBoxData(context.Background(), newTestAccessBox(t, key)),
|
context: middleware.SetBox(context.Background(), &middleware.Box{AccessBox: newTestAccessBox(t, key)}),
|
||||||
config: cfg,
|
config: cfg,
|
||||||
|
|
||||||
layerFeatures: features,
|
layerFeatures: features,
|
||||||
|
|
|
@ -94,7 +94,7 @@ func TestInvalidAccessThroughCache(t *testing.T) {
|
||||||
headObject(t, hc, bktName, objName, nil, http.StatusOK)
|
headObject(t, hc, bktName, objName, nil, http.StatusOK)
|
||||||
|
|
||||||
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
w, r := prepareTestRequest(hc, bktName, objName, nil)
|
||||||
hc.Handler().HeadObjectHandler(w, r.WithContext(middleware.SetBoxData(r.Context(), newTestAccessBox(t, nil))))
|
hc.Handler().HeadObjectHandler(w, r.WithContext(middleware.SetBox(r.Context(), &middleware.Box{AccessBox: newTestAccessBox(t, nil)})))
|
||||||
assertStatus(t, w, http.StatusForbidden)
|
assertStatus(t, w, http.StatusForbidden)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -353,16 +353,18 @@ func getChunkedRequest(ctx context.Context, t *testing.T, bktName, objName strin
|
||||||
w := httptest.NewRecorder()
|
w := httptest.NewRecorder()
|
||||||
reqInfo := middleware.NewReqInfo(w, req, middleware.ObjectRequest{Bucket: bktName, Object: objName})
|
reqInfo := middleware.NewReqInfo(w, req, middleware.ObjectRequest{Bucket: bktName, Object: objName})
|
||||||
req = req.WithContext(middleware.SetReqInfo(ctx, reqInfo))
|
req = req.WithContext(middleware.SetReqInfo(ctx, reqInfo))
|
||||||
req = req.WithContext(middleware.SetClientTime(req.Context(), signTime))
|
req = req.WithContext(middleware.SetBox(req.Context(), &middleware.Box{
|
||||||
req = req.WithContext(middleware.SetAuthHeaders(req.Context(), &middleware.AuthHeader{
|
ClientTime: signTime,
|
||||||
|
AuthHeaders: &middleware.AuthHeader{
|
||||||
AccessKeyID: AWSAccessKeyID,
|
AccessKeyID: AWSAccessKeyID,
|
||||||
SignatureV4: "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9",
|
SignatureV4: "4f232c4386841ef735655705268965c44a0e4690baa4adea153f7db9fa80a0a9",
|
||||||
Region: "us-east-1",
|
Region: "us-east-1",
|
||||||
}))
|
},
|
||||||
req = req.WithContext(middleware.SetBoxData(req.Context(), &accessbox.Box{
|
AccessBox: &accessbox.Box{
|
||||||
Gate: &accessbox.GateData{
|
Gate: &accessbox.GateData{
|
||||||
SecretKey: AWSSecretAccessKey,
|
SecretKey: AWSSecretAccessKey,
|
||||||
},
|
},
|
||||||
|
},
|
||||||
}))
|
}))
|
||||||
|
|
||||||
return w, req, chunk
|
return w, req, chunk
|
||||||
|
@ -401,7 +403,7 @@ func TestCreateNamespacedBucket(t *testing.T) {
|
||||||
|
|
||||||
box, _ := createAccessBox(t)
|
box, _ := createAccessBox(t)
|
||||||
w, r := prepareTestRequest(hc, bktName, "", nil)
|
w, r := prepareTestRequest(hc, bktName, "", nil)
|
||||||
ctx := middleware.SetBoxData(r.Context(), box)
|
ctx := middleware.SetBox(r.Context(), &middleware.Box{AccessBox: box})
|
||||||
reqInfo := middleware.GetReqInfo(ctx)
|
reqInfo := middleware.GetReqInfo(ctx)
|
||||||
reqInfo.Namespace = namespace
|
reqInfo.Namespace = namespace
|
||||||
r = r.WithContext(middleware.SetReqInfo(ctx, reqInfo))
|
r = r.WithContext(middleware.SetReqInfo(ctx, reqInfo))
|
||||||
|
|
|
@ -334,7 +334,7 @@ func (n *layer) initNewVersionsByPrefixSession(ctx context.Context, p commonVers
|
||||||
session.Context, session.Cancel = context.WithCancel(context.Background())
|
session.Context, session.Cancel = context.WithCancel(context.Background())
|
||||||
|
|
||||||
if bd, err := middleware.GetBoxData(ctx); err == nil {
|
if bd, err := middleware.GetBoxData(ctx); err == nil {
|
||||||
session.Context = middleware.SetBoxData(session.Context, bd)
|
session.Context = middleware.SetBox(session.Context, &middleware.Box{AccessBox: bd})
|
||||||
}
|
}
|
||||||
|
|
||||||
session.Stream, err = n.treeService.InitVersionsByPrefixStream(session.Context, p.BktInfo, p.Prefix, latestOnly)
|
session.Stream, err = n.treeService.InitVersionsByPrefixStream(session.Context, p.BktInfo, p.Prefix, latestOnly)
|
||||||
|
|
|
@ -145,12 +145,12 @@ func prepareContext(t *testing.T, cachesConfig ...*CachesConfig) *testContext {
|
||||||
bearerToken := bearertest.Token()
|
bearerToken := bearertest.Token()
|
||||||
require.NoError(t, bearerToken.Sign(key.PrivateKey))
|
require.NoError(t, bearerToken.Sign(key.PrivateKey))
|
||||||
|
|
||||||
ctx := middleware.SetBoxData(context.Background(), &accessbox.Box{
|
ctx := middleware.SetBox(context.Background(), &middleware.Box{AccessBox: &accessbox.Box{
|
||||||
Gate: &accessbox.GateData{
|
Gate: &accessbox.GateData{
|
||||||
BearerToken: &bearerToken,
|
BearerToken: &bearerToken,
|
||||||
GateKey: key.PublicKey(),
|
GateKey: key.PublicKey(),
|
||||||
},
|
},
|
||||||
})
|
}})
|
||||||
tp := NewTestFrostFS(key)
|
tp := NewTestFrostFS(key)
|
||||||
|
|
||||||
bktName := "testbucket1"
|
bktName := "testbucket1"
|
||||||
|
|
|
@ -13,6 +13,7 @@ import (
|
||||||
frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
|
frostfsErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/errors"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/logs"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"go.uber.org/zap"
|
"go.uber.org/zap"
|
||||||
)
|
)
|
||||||
|
@ -23,6 +24,7 @@ type (
|
||||||
AccessBox *accessbox.Box
|
AccessBox *accessbox.Box
|
||||||
ClientTime time.Time
|
ClientTime time.Time
|
||||||
AuthHeaders *AuthHeader
|
AuthHeaders *AuthHeader
|
||||||
|
Attributes []object.Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
// Center is a user authentication interface.
|
// Center is a user authentication interface.
|
||||||
|
@ -65,11 +67,7 @@ func Auth(center Center, log *zap.Logger) Func {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
ctx = SetBoxData(ctx, box.AccessBox)
|
ctx = SetBox(ctx, box)
|
||||||
if !box.ClientTime.IsZero() {
|
|
||||||
ctx = SetClientTime(ctx, box.ClientTime)
|
|
||||||
}
|
|
||||||
ctx = SetAuthHeaders(ctx, box.AuthHeaders)
|
|
||||||
|
|
||||||
if box.AccessBox.Gate.BearerToken != nil {
|
if box.AccessBox.Gate.BearerToken != nil {
|
||||||
reqInfo.User = bearer.ResolveIssuer(*box.AccessBox.Gate.BearerToken).String()
|
reqInfo.User = bearer.ResolveIssuer(*box.AccessBox.Gate.BearerToken).String()
|
||||||
|
|
|
@ -444,6 +444,13 @@ func determineProperties(r *http.Request, decoder XMLDecoder, resolver BucketRes
|
||||||
res[k] = v
|
res[k] = v
|
||||||
}
|
}
|
||||||
|
|
||||||
|
attrs, err := GetAccessBoxAttrs(r.Context())
|
||||||
|
if err == nil {
|
||||||
|
for _, attr := range attrs {
|
||||||
|
res[fmt.Sprintf(s3.PropertyKeyFormatAccessBoxAttr, attr.Key())] = attr.Value()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return res, nil
|
return res, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,29 +6,27 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
)
|
)
|
||||||
|
|
||||||
// keyWrapper is wrapper for context keys.
|
// keyWrapper is wrapper for context keys.
|
||||||
type keyWrapper string
|
type keyWrapper string
|
||||||
|
|
||||||
// authHeaders is a wrapper for authentication headers of a request.
|
// boxKey is an ID used to store Box in a context.
|
||||||
var authHeadersKey = keyWrapper("__context_auth_headers_key")
|
var boxKey = keyWrapper("__context_box_key")
|
||||||
|
|
||||||
// boxData is an ID used to store accessbox.Box in a context.
|
|
||||||
var boxDataKey = keyWrapper("__context_box_key")
|
|
||||||
|
|
||||||
// clientTime is an ID used to store client time.Time in a context.
|
|
||||||
var clientTimeKey = keyWrapper("__context_client_time")
|
|
||||||
|
|
||||||
// GetBoxData extracts accessbox.Box from context.
|
// GetBoxData extracts accessbox.Box from context.
|
||||||
func GetBoxData(ctx context.Context) (*accessbox.Box, error) {
|
func GetBoxData(ctx context.Context) (*accessbox.Box, error) {
|
||||||
var box *accessbox.Box
|
data, ok := ctx.Value(boxKey).(*Box)
|
||||||
data, ok := ctx.Value(boxDataKey).(*accessbox.Box)
|
|
||||||
if !ok || data == nil {
|
if !ok || data == nil {
|
||||||
|
return nil, fmt.Errorf("couldn't get box from context")
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.AccessBox == nil {
|
||||||
return nil, fmt.Errorf("couldn't get box data from context")
|
return nil, fmt.Errorf("couldn't get box data from context")
|
||||||
}
|
}
|
||||||
|
|
||||||
box = data
|
box := data.AccessBox
|
||||||
if box.Gate == nil {
|
if box.Gate == nil {
|
||||||
box.Gate = &accessbox.GateData{}
|
box.Gate = &accessbox.GateData{}
|
||||||
}
|
}
|
||||||
|
@ -37,35 +35,39 @@ func GetBoxData(ctx context.Context) (*accessbox.Box, error) {
|
||||||
|
|
||||||
// GetAuthHeaders extracts auth.AuthHeader from context.
|
// GetAuthHeaders extracts auth.AuthHeader from context.
|
||||||
func GetAuthHeaders(ctx context.Context) (*AuthHeader, error) {
|
func GetAuthHeaders(ctx context.Context) (*AuthHeader, error) {
|
||||||
authHeaders, ok := ctx.Value(authHeadersKey).(*AuthHeader)
|
data, ok := ctx.Value(boxKey).(*Box)
|
||||||
if !ok {
|
if !ok || data == nil {
|
||||||
return nil, fmt.Errorf("couldn't get auth headers from context")
|
return nil, fmt.Errorf("couldn't get box from context")
|
||||||
}
|
}
|
||||||
|
|
||||||
return authHeaders, nil
|
return data.AuthHeaders, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClientTime extracts time.Time from context.
|
// GetClientTime extracts time.Time from context.
|
||||||
func GetClientTime(ctx context.Context) (time.Time, error) {
|
func GetClientTime(ctx context.Context) (time.Time, error) {
|
||||||
clientTime, ok := ctx.Value(clientTimeKey).(time.Time)
|
data, ok := ctx.Value(boxKey).(*Box)
|
||||||
if !ok {
|
if !ok || data == nil {
|
||||||
|
return time.Time{}, fmt.Errorf("couldn't get box from context")
|
||||||
|
}
|
||||||
|
|
||||||
|
if data.ClientTime.IsZero() {
|
||||||
return time.Time{}, fmt.Errorf("couldn't get client time from context")
|
return time.Time{}, fmt.Errorf("couldn't get client time from context")
|
||||||
}
|
}
|
||||||
|
|
||||||
return clientTime, nil
|
return data.ClientTime, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetBoxData sets accessbox.Box in the context.
|
// GetAccessBoxAttrs extracts []object.Attribute from context.
|
||||||
func SetBoxData(ctx context.Context, box *accessbox.Box) context.Context {
|
func GetAccessBoxAttrs(ctx context.Context) ([]object.Attribute, error) {
|
||||||
return context.WithValue(ctx, boxDataKey, box)
|
data, ok := ctx.Value(boxKey).(*Box)
|
||||||
|
if !ok || data == nil {
|
||||||
|
return nil, fmt.Errorf("couldn't get box from context")
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetAuthHeaders sets auth.AuthHeader in the context.
|
return data.Attributes, nil
|
||||||
func SetAuthHeaders(ctx context.Context, header *AuthHeader) context.Context {
|
|
||||||
return context.WithValue(ctx, authHeadersKey, header)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// SetClientTime sets time.Time in the context.
|
// SetBox sets Box in the context.
|
||||||
func SetClientTime(ctx context.Context, newTime time.Time) context.Context {
|
func SetBox(ctx context.Context, box *Box) context.Context {
|
||||||
return context.WithValue(ctx, clientTimeKey, newTime)
|
return context.WithValue(ctx, boxKey, box)
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
bearertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test"
|
bearertest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer/test"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||||
|
@ -33,6 +34,7 @@ func (p *poolStatisticMock) Statistic() pool.Statistic {
|
||||||
type centerMock struct {
|
type centerMock struct {
|
||||||
t *testing.T
|
t *testing.T
|
||||||
anon bool
|
anon bool
|
||||||
|
attrs []object.Attribute
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *centerMock) Authenticate(*http.Request) (*middleware.Box, error) {
|
func (c *centerMock) Authenticate(*http.Request) (*middleware.Box, error) {
|
||||||
|
@ -53,6 +55,7 @@ func (c *centerMock) Authenticate(*http.Request) (*middleware.Box, error) {
|
||||||
BearerToken: token,
|
BearerToken: token,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
Attributes: c.attrs,
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -17,6 +17,7 @@ import (
|
||||||
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
|
apiErrors "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
|
||||||
s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
|
s3middleware "git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/metrics"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
engineiam "git.frostfs.info/TrueCloudLab/policy-engine/iam"
|
engineiam "git.frostfs.info/TrueCloudLab/policy-engine/iam"
|
||||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/engine"
|
||||||
|
@ -576,6 +577,29 @@ func TestResourceTagsCheck(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestAccessBoxAttributesCheck(t *testing.T) {
|
||||||
|
router := prepareRouter(t)
|
||||||
|
|
||||||
|
ns, bktName, attrKey, attrValue := "", "bucket", "key", "true"
|
||||||
|
router.middlewareSettings.denyByDefault = true
|
||||||
|
|
||||||
|
allowOperations(router, ns, []string{"s3:CreateBucket"}, nil)
|
||||||
|
createBucket(router, ns, bktName)
|
||||||
|
|
||||||
|
// Add policy and check
|
||||||
|
allowOperations(router, ns, []string{"s3:ListBucket"}, engineiam.Conditions{
|
||||||
|
engineiam.CondBool: engineiam.Condition{fmt.Sprintf(s3.PropertyKeyFormatAccessBoxAttr, attrKey): []string{attrValue}},
|
||||||
|
})
|
||||||
|
|
||||||
|
listObjectsV1Err(router, ns, bktName, "", "", "", apiErrors.ErrAccessDenied)
|
||||||
|
|
||||||
|
var attr object.Attribute
|
||||||
|
attr.SetKey(attrKey)
|
||||||
|
attr.SetValue(attrValue)
|
||||||
|
router.cfg.Center.(*centerMock).attrs = []object.Attribute{attr}
|
||||||
|
listObjectsV1(router, ns, bktName, "", "", "")
|
||||||
|
}
|
||||||
|
|
||||||
func allowOperations(router *routerMock, ns string, operations []string, conditions engineiam.Conditions) {
|
func allowOperations(router *routerMock, ns string, operations []string, conditions engineiam.Conditions) {
|
||||||
addPolicy(router, ns, "allow", engineiam.AllowEffect, operations, conditions)
|
addPolicy(router, ns, "allow", engineiam.AllowEffect, operations, conditions)
|
||||||
}
|
}
|
||||||
|
|
|
@ -339,7 +339,7 @@ func (a *Agent) UpdateSecret(ctx context.Context, w io.Writer, options *UpdateSe
|
||||||
|
|
||||||
creds := tokens.New(cfg)
|
creds := tokens.New(cfg)
|
||||||
|
|
||||||
box, err := creds.GetBox(ctx, options.Address)
|
box, _, err := creds.GetBox(ctx, options.Address)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("get accessbox: %w", err)
|
return fmt.Errorf("get accessbox: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -426,7 +426,7 @@ func (a *Agent) ObtainSecret(ctx context.Context, w io.Writer, options *ObtainSe
|
||||||
return fmt.Errorf("failed to parse secret address: %w", err)
|
return fmt.Errorf("failed to parse secret address: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
box, err := bearerCreds.GetBox(ctx, addr)
|
box, _, err := bearerCreds.GetBox(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return fmt.Errorf("failed to get tokens: %w", err)
|
return fmt.Errorf("failed to get tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,7 +22,7 @@ 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, oid.Address) (*accessbox.Box, error)
|
GetBox(context.Context, oid.Address) (*accessbox.Box, []object.Attribute, error)
|
||||||
Put(context.Context, cid.ID, CredentialsParam) (oid.Address, error)
|
Put(context.Context, cid.ID, CredentialsParam) (oid.Address, error)
|
||||||
Update(context.Context, oid.Address, CredentialsParam) (oid.Address, error)
|
Update(context.Context, oid.Address, CredentialsParam) (oid.Address, error)
|
||||||
}
|
}
|
||||||
|
@ -86,13 +86,13 @@ type FrostFS interface {
|
||||||
// prevented the object from being created.
|
// prevented the object from being created.
|
||||||
CreateObject(context.Context, PrmObjectCreate) (oid.ID, error)
|
CreateObject(context.Context, PrmObjectCreate) (oid.ID, error)
|
||||||
|
|
||||||
// GetCredsPayload gets payload of the credential object from FrostFS network.
|
// GetCredsObject gets the credential object from FrostFS network.
|
||||||
// It uses search by system name and select using CRDT 2PSet. In case of absence CRDT header
|
// It uses search by system name and select using CRDT 2PSet. In case of absence CRDT header
|
||||||
// it heads object by address.
|
// it heads object by address.
|
||||||
//
|
//
|
||||||
// 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.
|
||||||
GetCredsPayload(context.Context, oid.Address) ([]byte, error)
|
GetCredsObject(context.Context, oid.Address) (*object.Object, error)
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -115,72 +115,72 @@ func New(cfg Config) Credentials {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, error) {
|
func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, []object.Attribute, error) {
|
||||||
cachedBoxValue := c.cache.Get(addr)
|
cachedBoxValue := c.cache.Get(addr)
|
||||||
if cachedBoxValue != nil {
|
if cachedBoxValue != nil {
|
||||||
return c.checkIfCredentialsAreRemoved(ctx, addr, cachedBoxValue)
|
return c.checkIfCredentialsAreRemoved(ctx, addr, cachedBoxValue)
|
||||||
}
|
}
|
||||||
|
|
||||||
box, err := c.getAccessBox(ctx, addr)
|
box, attrs, err := c.getAccessBox(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get access box: %w", err)
|
return nil, nil, fmt.Errorf("get access box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedBox, err := box.GetBox(c.key)
|
cachedBox, err := box.GetBox(c.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("get gate box: %w", err)
|
return nil, nil, fmt.Errorf("get gate box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
c.putBoxToCache(addr, cachedBox)
|
c.putBoxToCache(addr, cachedBox, attrs)
|
||||||
|
|
||||||
return cachedBox, nil
|
return cachedBox, attrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) checkIfCredentialsAreRemoved(ctx context.Context, addr oid.Address, cachedBoxValue *cache.AccessBoxCacheValue) (*accessbox.Box, error) {
|
func (c *cred) checkIfCredentialsAreRemoved(ctx context.Context, addr oid.Address, cachedBoxValue *cache.AccessBoxCacheValue) (*accessbox.Box, []object.Attribute, error) {
|
||||||
if time.Since(cachedBoxValue.PutTime) < c.removingCheckDuration {
|
if time.Since(cachedBoxValue.PutTime) < c.removingCheckDuration {
|
||||||
return cachedBoxValue.Box, nil
|
return cachedBoxValue.Box, cachedBoxValue.Attributes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
box, err := c.getAccessBox(ctx, addr)
|
box, attrs, err := c.getAccessBox(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if client.IsErrObjectAlreadyRemoved(err) {
|
if client.IsErrObjectAlreadyRemoved(err) {
|
||||||
c.cache.Delete(addr)
|
c.cache.Delete(addr)
|
||||||
return nil, fmt.Errorf("get access box: %w", err)
|
return nil, nil, fmt.Errorf("get access box: %w", err)
|
||||||
}
|
}
|
||||||
return cachedBoxValue.Box, nil
|
return cachedBoxValue.Box, cachedBoxValue.Attributes, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
cachedBox, err := box.GetBox(c.key)
|
cachedBox, err := box.GetBox(c.key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.cache.Delete(addr)
|
c.cache.Delete(addr)
|
||||||
return nil, fmt.Errorf("get gate box: %w", err)
|
return nil, nil, fmt.Errorf("get gate box: %w", err)
|
||||||
}
|
}
|
||||||
// we need this to reset PutTime
|
// we need this to reset PutTime
|
||||||
// to don't check for removing each time after removingCheckDuration interval
|
// to don't check for removing each time after removingCheckDuration interval
|
||||||
c.putBoxToCache(addr, cachedBox)
|
c.putBoxToCache(addr, cachedBox, attrs)
|
||||||
|
|
||||||
return cachedBoxValue.Box, nil
|
return cachedBoxValue.Box, attrs, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) putBoxToCache(addr oid.Address, box *accessbox.Box) {
|
func (c *cred) putBoxToCache(addr oid.Address, box *accessbox.Box, attrs []object.Attribute) {
|
||||||
if err := c.cache.Put(addr, box); err != nil {
|
if err := c.cache.Put(addr, box, attrs); err != nil {
|
||||||
c.log.Warn(logs.CouldntPutAccessBoxIntoCache, zap.String("address", addr.EncodeToString()))
|
c.log.Warn(logs.CouldntPutAccessBoxIntoCache, zap.String("address", addr.EncodeToString()))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, error) {
|
func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.AccessBox, []object.Attribute, error) {
|
||||||
data, err := c.frostFS.GetCredsPayload(ctx, addr)
|
obj, err := c.frostFS.GetCredsObject(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("read payload: %w", err)
|
return nil, nil, fmt.Errorf("read payload and attributes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// decode access box
|
// decode access box
|
||||||
var box accessbox.AccessBox
|
var box accessbox.AccessBox
|
||||||
if err = box.Unmarshal(data); err != nil {
|
if err = box.Unmarshal(obj.Payload()); err != nil {
|
||||||
return nil, fmt.Errorf("unmarhal access box: %w", err)
|
return nil, nil, fmt.Errorf("unmarhal access box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &box, nil
|
return &box, obj.Attributes(), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (c *cred) Put(ctx context.Context, idCnr cid.ID, prm CredentialsParam) (oid.Address, error) {
|
func (c *cred) Put(ctx context.Context, idCnr cid.ID, prm CredentialsParam) (oid.Address, error) {
|
||||||
|
|
|
@ -11,6 +11,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/creds/accessbox"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
oidtest "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id/test"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -27,7 +28,7 @@ func (f *frostfsMock) CreateObject(context.Context, PrmObjectCreate) (oid.ID, er
|
||||||
panic("implement me for test")
|
panic("implement me for test")
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *frostfsMock) GetCredsPayload(_ context.Context, address oid.Address) ([]byte, error) {
|
func (f *frostfsMock) GetCredsObject(_ context.Context, address oid.Address) (*object.Object, error) {
|
||||||
if err := f.errors[address]; err != nil {
|
if err := f.errors[address]; err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
@ -36,7 +37,10 @@ func (f *frostfsMock) GetCredsPayload(_ context.Context, address oid.Address) ([
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, errors.New("not found")
|
return nil, errors.New("not found")
|
||||||
}
|
}
|
||||||
return data, nil
|
|
||||||
|
var obj object.Object
|
||||||
|
obj.SetPayload(data)
|
||||||
|
return &obj, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestRemovingAccessBox(t *testing.T) {
|
func TestRemovingAccessBox(t *testing.T) {
|
||||||
|
@ -78,14 +82,14 @@ func TestRemovingAccessBox(t *testing.T) {
|
||||||
|
|
||||||
creds := New(cfg)
|
creds := New(cfg)
|
||||||
|
|
||||||
_, err = creds.GetBox(ctx, addr)
|
_, _, err = creds.GetBox(ctx, addr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
frostfs.errors[addr] = errors.New("network error")
|
frostfs.errors[addr] = errors.New("network error")
|
||||||
_, err = creds.GetBox(ctx, addr)
|
_, _, err = creds.GetBox(ctx, addr)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
frostfs.errors[addr] = &apistatus.ObjectAlreadyRemoved{}
|
frostfs.errors[addr] = &apistatus.ObjectAlreadyRemoved{}
|
||||||
_, err = creds.GetBox(ctx, addr)
|
_, _, err = creds.GetBox(ctx, addr)
|
||||||
require.Error(t, err)
|
require.Error(t, err)
|
||||||
}
|
}
|
||||||
|
|
2
go.mod
2
go.mod
|
@ -7,7 +7,7 @@ require (
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd
|
git.frostfs.info/TrueCloudLab/frostfs-contract v0.19.3-0.20240409115729-6eb492025bdd
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6
|
git.frostfs.info/TrueCloudLab/frostfs-observability v0.0.0-20230531082742-c97d21411eb6
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412102212-530248de754c
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240416071728-04a79f57ef1f
|
||||||
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
|
git.frostfs.info/TrueCloudLab/zapjournald v0.0.0-20240124114243-cb2e66427d02
|
||||||
github.com/aws/aws-sdk-go v1.44.6
|
github.com/aws/aws-sdk-go v1.44.6
|
||||||
github.com/bluele/gcache v0.0.2
|
github.com/bluele/gcache v0.0.2
|
||||||
|
|
4
go.sum
4
go.sum
|
@ -48,8 +48,8 @@ git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7
|
||||||
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7/go.mod h1:i0RKqiF4z3UOxLSNwhHw+cUz/JyYWuTRpnn9ere4Y3w=
|
git.frostfs.info/TrueCloudLab/frostfs-sdk-go v0.0.0-20240402141549-3790142b10c7/go.mod h1:i0RKqiF4z3UOxLSNwhHw+cUz/JyYWuTRpnn9ere4Y3w=
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc=
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1 h1:ccBRK21rFvY5R1WotI6LNoPlizk7qSvdfD8lNIRudVc=
|
||||||
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
git.frostfs.info/TrueCloudLab/hrw v1.2.1/go.mod h1:C1Ygde2n843yTZEQ0FP69jYiuaYV0kriLvP4zm8JuvM=
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412102212-530248de754c h1:Ei15WKKLDXoFqEIe292szb3RfsyLqRZfeJX2FjFvz6k=
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240416071728-04a79f57ef1f h1:hP1Q/MJvRsHSBIWXn48C+hVsRHfPWWLhdOg6IxjaWBs=
|
||||||
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240412102212-530248de754c/go.mod h1:H/AW85RtYxVTbcgwHW76DqXeKlsiCIOeNXHPqyDBrfQ=
|
git.frostfs.info/TrueCloudLab/policy-engine v0.0.0-20240416071728-04a79f57ef1f/go.mod h1:H/AW85RtYxVTbcgwHW76DqXeKlsiCIOeNXHPqyDBrfQ=
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0 h1:M2KR3iBj7WpY3hP10IevfIB9MURr4O9mwVfJ+SjT3HA=
|
||||||
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
git.frostfs.info/TrueCloudLab/rfc6979 v0.4.0/go.mod h1:okpbKfVYf/BpejtfFTfhZqFP+sZ8rsHrP8Rr/jYPNRc=
|
||||||
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
git.frostfs.info/TrueCloudLab/tzhash v1.8.0 h1:UFMnUIk0Zh17m8rjGHJMqku2hCgaXDqjqZzS4gsb4UA=
|
||||||
|
|
|
@ -4,7 +4,6 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"io"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -15,6 +14,7 @@ import (
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/crdt"
|
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/internal/frostfs/crdt"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/acl"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/pool"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||||
|
@ -69,8 +69,8 @@ func (x *AuthmateFrostFS) CreateContainer(ctx context.Context, prm authmate.PrmC
|
||||||
return res.ContainerID, nil
|
return res.ContainerID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCredsPayload implements authmate.FrostFS interface method.
|
// GetCredsObject implements authmate.FrostFS interface method.
|
||||||
func (x *AuthmateFrostFS) GetCredsPayload(ctx context.Context, addr oid.Address) ([]byte, error) {
|
func (x *AuthmateFrostFS) GetCredsObject(ctx context.Context, addr oid.Address) (*object.Object, error) {
|
||||||
versions, err := x.getCredVersions(ctx, addr)
|
versions, err := x.getCredVersions(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
@ -85,14 +85,13 @@ func (x *AuthmateFrostFS) GetCredsPayload(ctx context.Context, addr oid.Address)
|
||||||
Container: addr.Container(),
|
Container: addr.Container(),
|
||||||
Object: credObjID,
|
Object: credObjID,
|
||||||
WithPayload: true,
|
WithPayload: true,
|
||||||
|
WithHeader: true,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
defer res.Payload.Close()
|
return res.Head, err
|
||||||
|
|
||||||
return io.ReadAll(res.Payload)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// CreateObject implements authmate.FrostFS interface method.
|
// CreateObject implements authmate.FrostFS interface method.
|
||||||
|
|
Loading…
Reference in a new issue