forked from TrueCloudLab/frostfs-s3-gw
[#539] Add context to errors
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
e1f1e6d960
commit
7ca519cb32
26 changed files with 111 additions and 102 deletions
|
@ -178,7 +178,7 @@ func (c *center) Authenticate(r *http.Request) (*accessbox.Box, error) {
|
||||||
|
|
||||||
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, fmt.Errorf("get box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
clonedRequest := cloneRequest(r, authHdr)
|
clonedRequest := cloneRequest(r, authHdr)
|
||||||
|
@ -220,7 +220,7 @@ func (c *center) checkFormData(r *http.Request) (*accessbox.Box, error) {
|
||||||
|
|
||||||
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, fmt.Errorf("get box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
secret := box.Gate.AccessKey
|
secret := box.Gate.AccessKey
|
||||||
|
@ -340,12 +340,12 @@ func prepareForm(form *multipart.Form) error {
|
||||||
if len(v) > 0 {
|
if len(v) > 0 {
|
||||||
field, err := v[0].Open()
|
field, err := v[0].Open()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("file header open: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
data, err := io.ReadAll(field)
|
data, err := io.ReadAll(field)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("read field: %w", err)
|
||||||
}
|
}
|
||||||
form.Value[lowerKey] = []string{string(data)}
|
form.Value[lowerKey] = []string{string(data)}
|
||||||
}
|
}
|
||||||
|
|
|
@ -159,7 +159,7 @@ func (h *handler) bearerTokenIssuerKey(ctx context.Context) (*keys.PublicKey, er
|
||||||
|
|
||||||
key, err := keys.NewPublicKeyFromBytes(btoken.GetSignature().GetKey(), elliptic.P256())
|
key, err := keys.NewPublicKeyFromBytes(btoken.GetSignature().GetKey(), elliptic.P256())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("public key from bytes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return key, nil
|
return key, nil
|
||||||
|
@ -186,7 +186,7 @@ func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
h.logAndSendError(w, "could not parse bucket acl", reqInfo, err)
|
h.logAndSendError(w, "could not parse bucket acl", reqInfo, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if err := xml.NewDecoder(r.Body).Decode(list); err != nil {
|
} else if err = xml.NewDecoder(r.Body).Decode(list); err != nil {
|
||||||
h.logAndSendError(w, "could not parse bucket acl", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
|
h.logAndSendError(w, "could not parse bucket acl", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -291,7 +291,7 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
|
||||||
h.logAndSendError(w, "could not parse bucket acl", reqInfo, err)
|
h.logAndSendError(w, "could not parse bucket acl", reqInfo, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
} else if err := xml.NewDecoder(r.Body).Decode(list); err != nil {
|
} else if err = xml.NewDecoder(r.Body).Decode(list); err != nil {
|
||||||
h.logAndSendError(w, "could not parse bucket acl", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
|
h.logAndSendError(w, "could not parse bucket acl", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -399,7 +399,7 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
|
||||||
}
|
}
|
||||||
|
|
||||||
bktPolicy := &bucketPolicy{Bucket: reqInfo.BucketName}
|
bktPolicy := &bucketPolicy{Bucket: reqInfo.BucketName}
|
||||||
if err := json.NewDecoder(r.Body).Decode(bktPolicy); err != nil {
|
if err = json.NewDecoder(r.Body).Decode(bktPolicy); err != nil {
|
||||||
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err)
|
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -437,13 +437,13 @@ func parseACLHeaders(header http.Header, key *keys.PublicKey) (*AccessControlPol
|
||||||
}
|
}
|
||||||
|
|
||||||
if acp.AccessControlList, err = addGrantees(acp.AccessControlList, header, api.AmzGrantFullControl); err != nil {
|
if acp.AccessControlList, err = addGrantees(acp.AccessControlList, header, api.AmzGrantFullControl); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("add grantees full control: %w", err)
|
||||||
}
|
}
|
||||||
if acp.AccessControlList, err = addGrantees(acp.AccessControlList, header, api.AmzGrantRead); err != nil {
|
if acp.AccessControlList, err = addGrantees(acp.AccessControlList, header, api.AmzGrantRead); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("add grantees read: %w", err)
|
||||||
}
|
}
|
||||||
if acp.AccessControlList, err = addGrantees(acp.AccessControlList, header, api.AmzGrantWrite); err != nil {
|
if acp.AccessControlList, err = addGrantees(acp.AccessControlList, header, api.AmzGrantWrite); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("add grantees write: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return acp, nil
|
return acp, nil
|
||||||
|
@ -457,12 +457,12 @@ func addGrantees(list []*Grant, headers http.Header, hdr string) ([]*Grant, erro
|
||||||
|
|
||||||
permission, err := grantHdrToPermission(hdr)
|
permission, err := grantHdrToPermission(hdr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("parse header: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
grantees, err := parseGrantee(grant)
|
grantees, err := parseGrantee(grant)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("parse grantee: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, grantee := range grantees {
|
for _, grantee := range grantees {
|
||||||
|
@ -502,7 +502,7 @@ func parseGrantee(grantees string) ([]*Grantee, error) {
|
||||||
|
|
||||||
grantee, err := formGrantee(split2[0], split2[1])
|
grantee, err := formGrantee(split2[0], split2[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("form grantee: %w", err)
|
||||||
}
|
}
|
||||||
result = append(result, grantee)
|
result = append(result, grantee)
|
||||||
}
|
}
|
||||||
|
@ -779,7 +779,7 @@ func astToTable(ast *ast) (*eacl.Table, error) {
|
||||||
for _, resource := range ast.Resources {
|
for _, resource := range ast.Resources {
|
||||||
records, err := formRecords(resource.Operations, resource)
|
records, err := formRecords(resource.Operations, resource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("form records: %w", err)
|
||||||
}
|
}
|
||||||
for _, rec := range records {
|
for _, rec := range records {
|
||||||
table.AddRecord(rec)
|
table.AddRecord(rec)
|
||||||
|
@ -802,7 +802,7 @@ func formRecords(operations []*astOperation, resource *astResource) ([]*eacl.Rec
|
||||||
for _, user := range astOp.Users {
|
for _, user := range astOp.Users {
|
||||||
pk, err := keys.NewPublicKeyFromString(user)
|
pk, err := keys.NewPublicKeyFromString(user)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("public key from string: %w", err)
|
||||||
}
|
}
|
||||||
eacl.AddFormedTarget(record, eacl.RoleUser, (ecdsa.PublicKey)(*pk))
|
eacl.AddFormedTarget(record, eacl.RoleUser, (ecdsa.PublicKey)(*pk))
|
||||||
}
|
}
|
||||||
|
@ -811,7 +811,7 @@ func formRecords(operations []*astOperation, resource *astResource) ([]*eacl.Rec
|
||||||
if len(resource.Version) != 0 {
|
if len(resource.Version) != 0 {
|
||||||
var id oid.ID
|
var id oid.ID
|
||||||
if err := id.DecodeString(resource.Version); err != nil {
|
if err := id.DecodeString(resource.Version); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("parse object version (oid): %w", err)
|
||||||
}
|
}
|
||||||
record.AddObjectIDFilter(eacl.MatchStringEqual, id)
|
record.AddObjectIDFilter(eacl.MatchStringEqual, id)
|
||||||
}
|
}
|
||||||
|
@ -1256,7 +1256,7 @@ func bucketACLToTable(acp *AccessControlPolicy, resInfo *resourceInfo) (*eacl.Ta
|
||||||
|
|
||||||
ownerKey, err := keys.NewPublicKeyFromString(acp.Owner.ID)
|
ownerKey, err := keys.NewPublicKeyFromString(acp.Owner.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("public key from string: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, grant := range acp.AccessControlList {
|
for _, grant := range acp.AccessControlList {
|
||||||
|
@ -1269,7 +1269,7 @@ func bucketACLToTable(acp *AccessControlPolicy, resInfo *resourceInfo) (*eacl.Ta
|
||||||
|
|
||||||
getRecord, err := getRecordFunction(grant.Grantee)
|
getRecord, err := getRecordFunction(grant.Grantee)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("record func from grantee: %w", err)
|
||||||
}
|
}
|
||||||
for _, op := range permissionToOperations(grant.Permission) {
|
for _, op := range permissionToOperations(grant.Permission) {
|
||||||
table.AddRecord(getRecord(op))
|
table.AddRecord(getRecord(op))
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
@ -176,7 +177,7 @@ func encodeToObjectAttributesResponse(info *data.ObjectInfo, p *GetObjectAttribu
|
||||||
case objectParts:
|
case objectParts:
|
||||||
parts, err := formUploadAttributes(info, p.MaxParts, p.PartNumberMarker)
|
parts, err := formUploadAttributes(info, p.MaxParts, p.PartNumberMarker)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("form upload attributes: %w", err)
|
||||||
}
|
}
|
||||||
if parts != nil {
|
if parts != nil {
|
||||||
resp.ObjectParts = parts
|
resp.ObjectParts = parts
|
||||||
|
@ -210,7 +211,7 @@ func formUploadAttributes(info *data.ObjectInfo, maxParts, marker int) (*ObjectP
|
||||||
}
|
}
|
||||||
size, err := strconv.Atoi(nums[1])
|
size, err := strconv.Atoi(nums[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("parse part size: %w", err)
|
||||||
}
|
}
|
||||||
parts = append(parts, Part{PartNumber: num, Size: size})
|
parts = append(parts, Part{PartNumber: num, Size: size})
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,8 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
"go.uber.org/zap"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||||
"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"
|
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
|
||||||
|
@ -89,11 +91,13 @@ func (h *handler) AppendCORSHeaders(w http.ResponseWriter, r *http.Request) {
|
||||||
}
|
}
|
||||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
h.log.Warn("get bucket info", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
cors, err := h.obj.GetBucketCORS(r.Context(), bktInfo)
|
cors, err := h.obj.GetBucketCORS(r.Context(), bktInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
h.log.Warn("get bucket cors", zap.Error(err))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -258,7 +258,7 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
||||||
h.log.Error("couldn't delete objects", fields...)
|
h.log.Error("couldn't delete objects", fields...)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := api.EncodeToResponse(w, response); err != nil {
|
if err = api.EncodeToResponse(w, response); err != nil {
|
||||||
h.logAndSendError(w, "could not write response", reqInfo, err, zap.Array("objects", marshaler))
|
h.logAndSendError(w, "could not write response", reqInfo, err, zap.Array("objects", marshaler))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -182,7 +182,7 @@ func (h *handler) CreateMultipartUploadHandler(w http.ResponseWriter, r *http.Re
|
||||||
UploadID: info.Headers[layer.UploadIDAttributeName],
|
UploadID: info.Headers[layer.UploadIDAttributeName],
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := api.EncodeToResponse(w, resp); err != nil {
|
if err = api.EncodeToResponse(w, resp); err != nil {
|
||||||
h.logAndSendError(w, "could not encode InitiateMultipartUploadResponse to response", reqInfo, err, additional...)
|
h.logAndSendError(w, "could not encode InitiateMultipartUploadResponse to response", reqInfo, err, additional...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -360,7 +360,7 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
|
||||||
)
|
)
|
||||||
|
|
||||||
reqBody := new(CompleteMultipartUpload)
|
reqBody := new(CompleteMultipartUpload)
|
||||||
if err := xml.NewDecoder(r.Body).Decode(reqBody); err != nil {
|
if err = xml.NewDecoder(r.Body).Decode(reqBody); err != nil {
|
||||||
h.logAndSendError(w, "could not read complete multipart upload xml", reqInfo,
|
h.logAndSendError(w, "could not read complete multipart upload xml", reqInfo,
|
||||||
errors.GetAPIError(errors.ErrMalformedXML), additional...)
|
errors.GetAPIError(errors.ErrMalformedXML), additional...)
|
||||||
return
|
return
|
||||||
|
@ -599,7 +599,7 @@ func (h *handler) AbortMultipartUploadHandler(w http.ResponseWriter, r *http.Req
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := h.obj.AbortMultipartUpload(r.Context(), p); err != nil {
|
if err = h.obj.AbortMultipartUpload(r.Context(), p); err != nil {
|
||||||
h.logAndSendError(w, "could not abort multipart upload", reqInfo, err, additional...)
|
h.logAndSendError(w, "could not abort multipart upload", reqInfo, err, additional...)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@ package handler
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"net/http"
|
"net/http"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
|
@ -153,7 +154,7 @@ func (h *handler) sendNotifications(ctx context.Context, p *SendNotificationPara
|
||||||
|
|
||||||
conf, err := h.obj.GetBucketNotificationConfiguration(ctx, p.BktInfo)
|
conf, err := h.obj.GetBucketNotificationConfiguration(ctx, p.BktInfo)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to get notification configuration: %w", err)
|
||||||
}
|
}
|
||||||
if conf.IsEmpty() {
|
if conf.IsEmpty() {
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -113,7 +113,7 @@ func (p *policyCondition) UnmarshalJSON(data []byte) error {
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := json.Unmarshal(data, &v); err != nil {
|
if err := json.Unmarshal(data, &v); err != nil {
|
||||||
return err
|
return fmt.Errorf("unmarshal policy condition: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch v := v.(type) {
|
switch v := v.(type) {
|
||||||
|
@ -487,7 +487,7 @@ func (h *handler) getNewEAclTable(r *http.Request, bktInfo *data.BucketInfo, obj
|
||||||
var newEaclTable *eacl.Table
|
var newEaclTable *eacl.Table
|
||||||
key, err := h.bearerTokenIssuerKey(r.Context())
|
key, err := h.bearerTokenIssuerKey(r.Context())
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get bearer token issuer: %w", err)
|
||||||
}
|
}
|
||||||
objectACL, err := parseACLHeaders(r.Header, key)
|
objectACL, err := parseACLHeaders(r.Header, key)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package handler
|
package handler
|
||||||
|
|
||||||
import "encoding/xml"
|
import (
|
||||||
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
)
|
||||||
|
|
||||||
// ListBucketsResponse -- format for list buckets response.
|
// ListBucketsResponse -- format for list buckets response.
|
||||||
type ListBucketsResponse struct {
|
type ListBucketsResponse struct {
|
||||||
|
@ -207,7 +210,7 @@ func (s StringMap) MarshalXML(e *xml.Encoder, start xml.StartElement) error {
|
||||||
|
|
||||||
for _, t := range tokens {
|
for _, t := range tokens {
|
||||||
if err := e.EncodeToken(t); err != nil {
|
if err := e.EncodeToken(t); err != nil {
|
||||||
return err
|
return fmt.Errorf("encode token: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ package layer
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"fmt"
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
@ -48,7 +49,7 @@ func (n *layer) containerInfo(ctx context.Context, idCnr cid.ID) (*data.BucketIn
|
||||||
if client.IsErrContainerNotFound(err) {
|
if client.IsErrContainerNotFound(err) {
|
||||||
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
return nil, errors.GetAPIError(errors.ErrNoSuchBucket)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, fmt.Errorf("get neofs container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
info.Owner = *res.OwnerID()
|
info.Owner = *res.OwnerID()
|
||||||
|
@ -151,13 +152,13 @@ func (n *layer) createContainer(ctx context.Context, p *CreateBucketParams) (*da
|
||||||
AdditionalAttributes: attributes,
|
AdditionalAttributes: attributes,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
bktInfo.CID = *idCnr
|
bktInfo.CID = *idCnr
|
||||||
|
|
||||||
if err = n.setContainerEACLTable(ctx, bktInfo.CID, p.EACL, p.SessionEACL); err != nil {
|
if err = n.setContainerEACLTable(ctx, bktInfo.CID, p.EACL, p.SessionEACL); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("set container eacl: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = n.bucketCache.Put(bktInfo); err != nil {
|
if err = n.bucketCache.Put(bktInfo); err != nil {
|
||||||
|
|
|
@ -24,7 +24,7 @@ func (n *layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
|
||||||
)
|
)
|
||||||
|
|
||||||
if err := xml.NewDecoder(tee).Decode(cors); err != nil {
|
if err := xml.NewDecoder(tee).Decode(cors); err != nil {
|
||||||
return err
|
return fmt.Errorf("xml decode cors: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if cors.CORSRules == nil {
|
if cors.CORSRules == nil {
|
||||||
|
@ -44,12 +44,11 @@ func (n *layer) PutBucketCORS(ctx context.Context, p *PutCORSParams) error {
|
||||||
Size: int64(buf.Len()),
|
Size: int64(buf.Len()),
|
||||||
}
|
}
|
||||||
|
|
||||||
_, err := n.putSystemObjectIntoNeoFS(ctx, s)
|
if _, err := n.putSystemObjectIntoNeoFS(ctx, s); err != nil {
|
||||||
if err != nil {
|
return fmt.Errorf("put system object: %w", err)
|
||||||
return err
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = n.systemCache.PutCORS(systemObjectKey(p.BktInfo, s.ObjName), cors); err != nil {
|
if err := n.systemCache.PutCORS(systemObjectKey(p.BktInfo, s.ObjName), cors); err != nil {
|
||||||
n.log.Error("couldn't cache system object", zap.Error(err))
|
n.log.Error("couldn't cache system object", zap.Error(err))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -340,7 +340,7 @@ func (n *layer) prepareAuthParameters(ctx context.Context, prm *PrmAuth, bktOwne
|
||||||
func (n *layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInfo, error) {
|
func (n *layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInfo, error) {
|
||||||
name, err := url.QueryUnescape(name)
|
name, err := url.QueryUnescape(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unescape bucket name: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if bktInfo := n.bucketCache.Get(name); bktInfo != nil {
|
if bktInfo := n.bucketCache.Get(name); bktInfo != nil {
|
||||||
|
@ -360,7 +360,7 @@ func (n *layer) GetBucketInfo(ctx context.Context, name string) (*data.BucketInf
|
||||||
func (n *layer) GetBucketACL(ctx context.Context, bktInfo *data.BucketInfo) (*BucketACL, error) {
|
func (n *layer) GetBucketACL(ctx context.Context, bktInfo *data.BucketInfo) (*BucketACL, error) {
|
||||||
eACL, err := n.GetContainerEACL(ctx, bktInfo.CID)
|
eACL, err := n.GetContainerEACL(ctx, bktInfo.CID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get container eacl: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &BucketACL{
|
return &BucketACL{
|
||||||
|
|
|
@ -422,8 +422,7 @@ func (n *layer) AbortMultipartUpload(ctx context.Context, p *UploadInfoParams) e
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, info := range objects {
|
for _, info := range objects {
|
||||||
err := n.objectDelete(ctx, p.Bkt, info.ID)
|
if err = n.objectDelete(ctx, p.Bkt, info.ID); err != nil {
|
||||||
if err != nil {
|
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
|
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api"
|
"github.com/nspcc-dev/neofs-s3-gw/api"
|
||||||
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
"github.com/nspcc-dev/neofs-s3-gw/api/data"
|
||||||
|
@ -20,7 +21,7 @@ type PutBucketNotificationConfigurationParams struct {
|
||||||
func (n *layer) PutBucketNotificationConfiguration(ctx context.Context, p *PutBucketNotificationConfigurationParams) error {
|
func (n *layer) PutBucketNotificationConfiguration(ctx context.Context, p *PutBucketNotificationConfigurationParams) error {
|
||||||
confXML, err := xml.Marshal(p.Configuration)
|
confXML, err := xml.Marshal(p.Configuration)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("marshal notify configuration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
s := &PutSystemObjectParams{
|
s := &PutSystemObjectParams{
|
||||||
|
@ -68,7 +69,7 @@ func (n *layer) getNotificationConf(ctx context.Context, bkt *data.BucketInfo, s
|
||||||
conf := &data.NotificationConfiguration{}
|
conf := &data.NotificationConfiguration{}
|
||||||
|
|
||||||
if err = xml.Unmarshal(obj.Payload(), &conf); err != nil {
|
if err = xml.Unmarshal(obj.Payload(), &conf); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal notify configuration: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = n.systemCache.PutNotificationConfiguration(systemObjectKey(bkt, sysName), conf); err != nil {
|
if err = n.systemCache.PutNotificationConfiguration(systemObjectKey(bkt, sysName), conf); err != nil {
|
||||||
|
|
|
@ -568,7 +568,7 @@ func (n *layer) getAllObjectsVersions(ctx context.Context, bkt *data.BucketInfo,
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
if err := n.listsCache.Put(cacheKey, ids); err != nil {
|
if err = n.listsCache.Put(cacheKey, ids); err != nil {
|
||||||
n.log.Error("couldn't cache list of objects", zap.Error(err))
|
n.log.Error("couldn't cache list of objects", zap.Error(err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ func (n *layer) putSystemObjectIntoNeoFS(ctx context.Context, p *PutSystemObject
|
||||||
|
|
||||||
attrs, err := n.attributesFromLock(ctx, p.Lock)
|
attrs, err := n.attributesFromLock(ctx, p.Lock)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get lock attributes: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
prm.Attributes = append(prm.Attributes, attrs...)
|
prm.Attributes = append(prm.Attributes, attrs...)
|
||||||
|
@ -191,7 +191,7 @@ func (n *layer) getCORS(ctx context.Context, bkt *data.BucketInfo, sysName strin
|
||||||
cors := &data.CORSConfiguration{}
|
cors := &data.CORSConfiguration{}
|
||||||
|
|
||||||
if err = xml.Unmarshal(obj.Payload(), &cors); err != nil {
|
if err = xml.Unmarshal(obj.Payload(), &cors); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal cors: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = n.systemCache.PutCORS(systemObjectKey(bkt, sysName), cors); err != nil {
|
if err = n.systemCache.PutCORS(systemObjectKey(bkt, sysName), cors); err != nil {
|
||||||
|
@ -262,7 +262,7 @@ func (n *layer) GetBucketSettings(ctx context.Context, bktInfo *data.BucketInfo)
|
||||||
}
|
}
|
||||||
settings.IsNoneStatus = true
|
settings.IsNoneStatus = true
|
||||||
} else if err = json.Unmarshal(obj.Payload(), settings); err != nil {
|
} else if err = json.Unmarshal(obj.Payload(), settings); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal settings: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = n.systemCache.PutSettings(systemKey, settings); err != nil {
|
if err = n.systemCache.PutSettings(systemKey, settings); err != nil {
|
||||||
|
@ -308,7 +308,7 @@ func (n *layer) attributesFromLock(ctx context.Context, lock *data.ObjectLock) (
|
||||||
if !lock.Until.IsZero() {
|
if !lock.Until.IsZero() {
|
||||||
_, exp, err := n.neoFS.TimeToEpoch(ctx, lock.Until)
|
_, exp, err := n.neoFS.TimeToEpoch(ctx, lock.Until)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("fetch time to epoch: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
attrs := [][2]string{
|
attrs := [][2]string{
|
||||||
|
|
|
@ -115,12 +115,12 @@ func NewController(p *Options, l *zap.Logger) (*Controller, error) {
|
||||||
|
|
||||||
nc, err := nats.Connect(p.URL, ncopts...)
|
nc, err := nats.Connect(p.URL, ncopts...)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("connect to nats: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
js, err := nc.JetStream()
|
js, err := nc.JetStream()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get jet stream: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Controller{
|
return &Controller{
|
||||||
|
@ -141,7 +141,7 @@ func (c *Controller) Subscribe(ctx context.Context, topic string, handler layer.
|
||||||
c.mu.RUnlock()
|
c.mu.RUnlock()
|
||||||
|
|
||||||
if _, err := c.jsClient.AddStream(&nats.StreamConfig{Name: topic}); err != nil {
|
if _, err := c.jsClient.AddStream(&nats.StreamConfig{Name: topic}); err != nil {
|
||||||
return err
|
return fmt.Errorf("add stream: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if _, err := c.jsClient.ChanSubscribe(topic, ch); err != nil {
|
if _, err := c.jsClient.ChanSubscribe(topic, ch); err != nil {
|
||||||
|
|
|
@ -44,9 +44,9 @@ func (r *BucketResolver) Resolve(ctx context.Context, name string) (*cid.ID, err
|
||||||
if r.next != nil {
|
if r.next != nil {
|
||||||
return r.next.Resolve(ctx, name)
|
return r.next.Resolve(ctx, name)
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, fmt.Errorf("failed resolve: %w", err)
|
||||||
}
|
}
|
||||||
return cnrID, err
|
return cnrID, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func NewResolver(order []string, cfg *Config) (*BucketResolver, error) {
|
func NewResolver(order []string, cfg *Config) (*BucketResolver, error) {
|
||||||
|
@ -56,7 +56,7 @@ func NewResolver(order []string, cfg *Config) (*BucketResolver, error) {
|
||||||
|
|
||||||
bucketResolver, err := newResolver(order[len(order)-1], cfg, nil)
|
bucketResolver, err := newResolver(order[len(order)-1], cfg, nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create resolver: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
for i := len(order) - 2; i >= 0; i-- {
|
for i := len(order) - 2; i >= 0; i-- {
|
||||||
|
@ -65,7 +65,7 @@ func NewResolver(order []string, cfg *Config) (*BucketResolver, error) {
|
||||||
|
|
||||||
bucketResolver, err = newResolver(resolverName, cfg, next)
|
bucketResolver, err = newResolver(resolverName, cfg, next)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create resolver: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -192,9 +192,9 @@ func EncodeToResponse(w http.ResponseWriter, response interface{}) error {
|
||||||
w.WriteHeader(http.StatusOK)
|
w.WriteHeader(http.StatusOK)
|
||||||
|
|
||||||
if _, err := w.Write(xmlHeader); err != nil {
|
if _, err := w.Write(xmlHeader); err != nil {
|
||||||
return err
|
return fmt.Errorf("write headers: %w", err)
|
||||||
} else if err = xml.NewEncoder(w).Encode(response); err != nil {
|
} else if err = xml.NewEncoder(w).Encode(response); err != nil {
|
||||||
return err
|
return fmt.Errorf("encode xml response: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
|
|
|
@ -189,7 +189,7 @@ func preparePolicy(policy ContainerPolicies) ([]*accessbox.AccessBox_ContainerPo
|
||||||
for locationConstraint, placementPolicy := range policy {
|
for locationConstraint, placementPolicy := range policy {
|
||||||
parsedPolicy, err := checkPolicy(placementPolicy)
|
parsedPolicy, err := checkPolicy(placementPolicy)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("check placement policy: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
result = append(result, &accessbox.AccessBox_ContainerPolicy{
|
result = append(result, &accessbox.AccessBox_ContainerPolicy{
|
||||||
|
@ -211,22 +211,22 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
|
|
||||||
policies, err := preparePolicy(options.ContainerPolicies)
|
policies, err := preparePolicy(options.ContainerPolicies)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("prepare policies: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
lifetime.Iat, lifetime.Exp, err = a.neoFS.TimeToEpoch(ctx, time.Now().Add(options.Lifetime))
|
lifetime.Iat, lifetime.Exp, err = a.neoFS.TimeToEpoch(ctx, time.Now().Add(options.Lifetime))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("fetch time to epoch: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
gatesData, err := createTokens(options, lifetime)
|
gatesData, err := createTokens(options, lifetime)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("create tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
box, secrets, err := accessbox.PackTokens(gatesData)
|
box, secrets, err := accessbox.PackTokens(gatesData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("pack tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
box.ContainerPolicy = policies
|
box.ContainerPolicy = policies
|
||||||
|
@ -239,7 +239,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
zap.String("placement_policy", options.Container.PlacementPolicy))
|
zap.String("placement_policy", options.Container.PlacementPolicy))
|
||||||
id, err := a.checkContainer(ctx, options.Container, idOwner)
|
id, err := a.checkContainer(ctx, options.Container, idOwner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("check container: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
a.log.Info("store bearer token into NeoFS",
|
a.log.Info("store bearer token into NeoFS",
|
||||||
|
@ -283,7 +283,7 @@ func (a *Agent) IssueSecret(ctx context.Context, w io.Writer, options *IssueSecr
|
||||||
defer file.Close()
|
defer file.Close()
|
||||||
if _, err = file.WriteString(fmt.Sprintf("\n[%s]\naws_access_key_id = %s\naws_secret_access_key = %s\n",
|
if _, err = file.WriteString(fmt.Sprintf("\n[%s]\naws_access_key_id = %s\naws_secret_access_key = %s\n",
|
||||||
profileName, accessKeyID, secrets.AccessKey)); err != nil {
|
profileName, accessKeyID, secrets.AccessKey)); err != nil {
|
||||||
return err
|
return fmt.Errorf("fails to write to file: %w", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
|
@ -369,7 +369,7 @@ func buildBearerTokens(key *keys.PrivateKey, table *eacl.Table, lifetime lifetim
|
||||||
for _, gateKey := range gatesKeys {
|
for _, gateKey := range gatesKeys {
|
||||||
tkn, err := buildBearerToken(key, table, lifetime, gateKey)
|
tkn, err := buildBearerToken(key, table, lifetime, gateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("build bearer token: %w", err)
|
||||||
}
|
}
|
||||||
bearerTokens = append(bearerTokens, tkn)
|
bearerTokens = append(bearerTokens, tkn)
|
||||||
}
|
}
|
||||||
|
@ -400,7 +400,7 @@ func buildSessionTokens(key *keys.PrivateKey, lifetime lifetimeOptions, ctxs []s
|
||||||
for i, ctx := range ctxs {
|
for i, ctx := range ctxs {
|
||||||
tkn, err := buildSessionToken(key, lifetime, ctx, gateKey)
|
tkn, err := buildSessionToken(key, lifetime, ctx, gateKey)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("build session token: %w", err)
|
||||||
}
|
}
|
||||||
tkns[i] = tkn
|
tkns[i] = tkn
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,7 +25,7 @@ func (c *sessionTokenContext) UnmarshalJSON(data []byte) (err error) {
|
||||||
var m sessionTokenModel
|
var m sessionTokenModel
|
||||||
|
|
||||||
if err = json.Unmarshal(data, &m); err != nil {
|
if err = json.Unmarshal(data, &m); err != nil {
|
||||||
return err
|
return fmt.Errorf("unmarshal session token context: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
switch m.Verb {
|
switch m.Verb {
|
||||||
|
|
|
@ -101,7 +101,7 @@ func prepare() (context.Context, *zap.Logger) {
|
||||||
}
|
}
|
||||||
|
|
||||||
if log, err = zapConfig.Build(); err != nil {
|
if log, err = zapConfig.Build(); err != nil {
|
||||||
panic(err)
|
panic(fmt.Errorf("create logger: %w", err))
|
||||||
}
|
}
|
||||||
|
|
||||||
return ctx, log
|
return ctx, log
|
||||||
|
@ -414,14 +414,14 @@ It will be ceil rounded to the nearest amount of epoch.`,
|
||||||
signer := v4.NewSigner(sess.Config.Credentials)
|
signer := v4.NewSigner(sess.Config.Credentials)
|
||||||
req, err := http.NewRequest(strings.ToUpper(methodFlag), fmt.Sprintf("%s/%s/%s", endpointFlag, bucketFlag, objectFlag), nil)
|
req, err := http.NewRequest(strings.ToUpper(methodFlag), fmt.Sprintf("%s/%s/%s", endpointFlag, bucketFlag, objectFlag), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("failed to create new request: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
date := time.Now().UTC()
|
date := time.Now().UTC()
|
||||||
req.Header.Set(api.AmzDate, date.Format("20060102T150405Z"))
|
req.Header.Set(api.AmzDate, date.Format("20060102T150405Z"))
|
||||||
|
|
||||||
if _, err = signer.Presign(req, nil, "s3", *sess.Config.Region, lifetimeFlag, date); err != nil {
|
if _, err = signer.Presign(req, nil, "s3", *sess.Config.Region, lifetimeFlag, date); err != nil {
|
||||||
return err
|
return fmt.Errorf("presign: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
res := &struct{ URL string }{
|
res := &struct{ URL string }{
|
||||||
|
@ -447,7 +447,7 @@ func parsePolicies(val string) (authmate.ContainerPolicies, error) {
|
||||||
|
|
||||||
var policies authmate.ContainerPolicies
|
var policies authmate.ContainerPolicies
|
||||||
if err = json.Unmarshal(data, &policies); err != nil {
|
if err = json.Unmarshal(data, &policies); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal policies: %w", err)
|
||||||
}
|
}
|
||||||
if _, ok := policies[api.DefaultLocationConstraint]; ok {
|
if _, ok := policies[api.DefaultLocationConstraint]; ok {
|
||||||
return nil, fmt.Errorf("config overrides %s location constraint", api.DefaultLocationConstraint)
|
return nil, fmt.Errorf("config overrides %s location constraint", api.DefaultLocationConstraint)
|
||||||
|
@ -591,11 +591,11 @@ func createNeoFS(ctx context.Context, log *zap.Logger, key *ecdsa.PrivateKey, pe
|
||||||
|
|
||||||
p, err := pool.NewPool(prm)
|
p, err := pool.NewPool(prm)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create pool: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = p.Dial(ctx); err != nil {
|
if err = p.Dial(ctx); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("dial pool: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return neofs.NewAuthmateNeoFS(p), nil
|
return neofs.NewAuthmateNeoFS(p), nil
|
||||||
|
|
|
@ -99,7 +99,7 @@ func PackTokens(gatesData []*GateData) (*AccessBox, *Secrets, error) {
|
||||||
box := &AccessBox{}
|
box := &AccessBox{}
|
||||||
ephemeralKey, err := keys.NewPrivateKey()
|
ephemeralKey, err := keys.NewPrivateKey()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, nil, err
|
return nil, nil, fmt.Errorf("create ephemeral key: %w", err)
|
||||||
}
|
}
|
||||||
box.OwnerPublicKey = ephemeralKey.PublicKey().Bytes()
|
box.OwnerPublicKey = ephemeralKey.PublicKey().Bytes()
|
||||||
|
|
||||||
|
@ -143,7 +143,7 @@ func (x *AccessBox) GetPlacementPolicy() ([]*ContainerPolicy, error) {
|
||||||
for _, policy := range x.ContainerPolicy {
|
for _, policy := range x.ContainerPolicy {
|
||||||
var cnrPolicy ContainerPolicy
|
var cnrPolicy ContainerPolicy
|
||||||
if err := cnrPolicy.Policy.Unmarshal(policy.Policy); err != nil {
|
if err := cnrPolicy.Policy.Unmarshal(policy.Policy); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal placement policy: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
cnrPolicy.LocationConstraint = policy.LocationConstraint
|
cnrPolicy.LocationConstraint = policy.LocationConstraint
|
||||||
|
@ -158,12 +158,12 @@ func (x *AccessBox) GetPlacementPolicy() ([]*ContainerPolicy, error) {
|
||||||
func (x *AccessBox) GetBox(owner *keys.PrivateKey) (*Box, error) {
|
func (x *AccessBox) GetBox(owner *keys.PrivateKey) (*Box, error) {
|
||||||
tokens, err := x.GetTokens(owner)
|
tokens, err := x.GetTokens(owner)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
policy, err := x.GetPlacementPolicy()
|
policy, err := x.GetPlacementPolicy()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get policy: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &Box{
|
return &Box{
|
||||||
|
@ -187,7 +187,7 @@ func (x *AccessBox) addTokens(gatesData []*GateData, ephemeralKey *keys.PrivateK
|
||||||
|
|
||||||
boxGate, err := encodeGate(ephemeralKey, gate.GateKey, tokens)
|
boxGate, err := encodeGate(ephemeralKey, gate.GateKey, tokens)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return fmt.Errorf("encode gate: %w", err)
|
||||||
}
|
}
|
||||||
x.Gates = append(x.Gates, boxGate)
|
x.Gates = append(x.Gates, boxGate)
|
||||||
}
|
}
|
||||||
|
@ -197,12 +197,12 @@ func (x *AccessBox) addTokens(gatesData []*GateData, ephemeralKey *keys.PrivateK
|
||||||
func encodeGate(ephemeralKey *keys.PrivateKey, ownerKey *keys.PublicKey, tokens *Tokens) (*AccessBox_Gate, error) {
|
func encodeGate(ephemeralKey *keys.PrivateKey, ownerKey *keys.PublicKey, tokens *Tokens) (*AccessBox_Gate, error) {
|
||||||
data, err := proto.Marshal(tokens)
|
data, err := proto.Marshal(tokens)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("encode tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
encrypted, err := encrypt(ephemeralKey, ownerKey, data)
|
encrypted, err := encrypt(ephemeralKey, ownerKey, data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("ecrypt tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
gate := new(AccessBox_Gate)
|
gate := new(AccessBox_Gate)
|
||||||
|
@ -214,23 +214,23 @@ func encodeGate(ephemeralKey *keys.PrivateKey, ownerKey *keys.PublicKey, tokens
|
||||||
func decodeGate(gate *AccessBox_Gate, owner *keys.PrivateKey, sender *keys.PublicKey) (*GateData, error) {
|
func decodeGate(gate *AccessBox_Gate, owner *keys.PrivateKey, sender *keys.PublicKey) (*GateData, error) {
|
||||||
data, err := decrypt(owner, sender, gate.Tokens)
|
data, err := decrypt(owner, sender, gate.Tokens)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("decrypt tokens: %w", err)
|
||||||
}
|
}
|
||||||
tokens := new(Tokens)
|
tokens := new(Tokens)
|
||||||
if err := proto.Unmarshal(data, tokens); err != nil {
|
if err = proto.Unmarshal(data, tokens); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal tokens: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var bearerTkn bearer.Token
|
var bearerTkn bearer.Token
|
||||||
if err = bearerTkn.Unmarshal(tokens.BearerToken); err != nil {
|
if err = bearerTkn.Unmarshal(tokens.BearerToken); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal bearer token: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
sessionTkns := make([]*session.Container, len(tokens.SessionTokens))
|
sessionTkns := make([]*session.Container, len(tokens.SessionTokens))
|
||||||
for i, encSessionToken := range tokens.SessionTokens {
|
for i, encSessionToken := range tokens.SessionTokens {
|
||||||
sessionTkn := new(session.Container)
|
sessionTkn := new(session.Container)
|
||||||
if err := sessionTkn.Unmarshal(encSessionToken); err != nil {
|
if err = sessionTkn.Unmarshal(encSessionToken); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarshal session token: %w", err)
|
||||||
}
|
}
|
||||||
sessionTkns[i] = sessionTkn
|
sessionTkns[i] = sessionTkn
|
||||||
}
|
}
|
||||||
|
@ -268,12 +268,12 @@ func deriveKey(secret []byte) ([]byte, error) {
|
||||||
func encrypt(owner *keys.PrivateKey, sender *keys.PublicKey, data []byte) ([]byte, error) {
|
func encrypt(owner *keys.PrivateKey, sender *keys.PublicKey, data []byte) ([]byte, error) {
|
||||||
enc, err := getCipher(owner, sender)
|
enc, err := getCipher(owner, sender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get chiper: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
nonce := make([]byte, enc.NonceSize(), enc.NonceSize()+len(data)+enc.Overhead())
|
nonce := make([]byte, enc.NonceSize(), enc.NonceSize()+len(data)+enc.Overhead())
|
||||||
if _, err := rand.Read(nonce); err != nil {
|
if _, err = rand.Read(nonce); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("generate random nonce: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return enc.Seal(nonce, nonce, data, nil), nil
|
return enc.Seal(nonce, nonce, data, nil), nil
|
||||||
|
@ -282,7 +282,7 @@ func encrypt(owner *keys.PrivateKey, sender *keys.PublicKey, data []byte) ([]byt
|
||||||
func decrypt(owner *keys.PrivateKey, sender *keys.PublicKey, data []byte) ([]byte, error) {
|
func decrypt(owner *keys.PrivateKey, sender *keys.PublicKey, data []byte) ([]byte, error) {
|
||||||
dec, err := getCipher(owner, sender)
|
dec, err := getCipher(owner, sender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("get chiper: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if ld, ns := len(data), dec.NonceSize(); ld < ns {
|
if ld, ns := len(data), dec.NonceSize(); ld < ns {
|
||||||
|
@ -296,12 +296,12 @@ func decrypt(owner *keys.PrivateKey, sender *keys.PublicKey, data []byte) ([]byt
|
||||||
func getCipher(owner *keys.PrivateKey, sender *keys.PublicKey) (cipher.AEAD, error) {
|
func getCipher(owner *keys.PrivateKey, sender *keys.PublicKey) (cipher.AEAD, error) {
|
||||||
secret, err := generateShared256(owner, sender)
|
secret, err := generateShared256(owner, sender)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("generate shared key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
key, err := deriveKey(secret)
|
key, err := deriveKey(secret)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("derive key: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return chacha20poly1305.NewX(key)
|
return chacha20poly1305.NewX(key)
|
||||||
|
|
|
@ -87,16 +87,16 @@ func (c *cred) GetBox(ctx context.Context, addr oid.Address) (*accessbox.Box, er
|
||||||
|
|
||||||
box, err := c.getAccessBox(ctx, addr)
|
box, err := c.getAccessBox(ctx, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return 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, err
|
return nil, fmt.Errorf("get box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if err = c.cache.Put(addr, cachedBox); err != nil {
|
if err = c.cache.Put(addr, cachedBox); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("put box into cache: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return cachedBox, nil
|
return cachedBox, nil
|
||||||
|
@ -111,7 +111,7 @@ func (c *cred) getAccessBox(ctx context.Context, addr oid.Address) (*accessbox.A
|
||||||
// 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(data); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("unmarhal access box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &box, nil
|
return &box, nil
|
||||||
|
@ -125,7 +125,7 @@ func (c *cred) Put(ctx context.Context, idCnr cid.ID, issuer user.ID, box *acces
|
||||||
}
|
}
|
||||||
data, err := box.Marshal()
|
data, err := box.Marshal()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("marshall box: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
idObj, err := c.neoFS.CreateObject(ctx, PrmObjectCreate{
|
||||||
|
@ -136,7 +136,7 @@ func (c *cred) Put(ctx context.Context, idCnr cid.ID, issuer user.ID, box *acces
|
||||||
Payload: data,
|
Payload: data,
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("create object: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var addr oid.Address
|
var addr oid.Address
|
||||||
|
|
|
@ -132,7 +132,7 @@ func (x *NeoFS) CreateContainer(ctx context.Context, prm layer.PrmContainerCreat
|
||||||
// environment without hh disabling feature will ignore this attribute
|
// environment without hh disabling feature will ignore this attribute
|
||||||
// environment with hh disabling feature will set disabling = true if network config says so
|
// environment with hh disabling feature will set disabling = true if network config says so
|
||||||
if hhDisabled, err := isHomomorphicHashDisabled(ctx, x.pool); err != nil {
|
if hhDisabled, err := isHomomorphicHashDisabled(ctx, x.pool); err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("check homomorphic hash enabled: %w", err)
|
||||||
} else if hhDisabled {
|
} else if hhDisabled {
|
||||||
cnrOptions = append(cnrOptions, container.WithAttribute(
|
cnrOptions = append(cnrOptions, container.WithAttribute(
|
||||||
"__NEOFS__DISABLE_HOMOMORPHIC_HASHING", "true"))
|
"__NEOFS__DISABLE_HOMOMORPHIC_HASHING", "true"))
|
||||||
|
@ -583,7 +583,7 @@ func (x *AuthmateNeoFS) CreateObject(ctx context.Context, prm tokens.PrmObjectCr
|
||||||
func isHomomorphicHashDisabled(ctx context.Context, p *pool.Pool) (bool, error) {
|
func isHomomorphicHashDisabled(ctx context.Context, p *pool.Pool) (bool, error) {
|
||||||
ni, err := p.NetworkInfo(ctx)
|
ni, err := p.NetworkInfo(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false, err
|
return false, fmt.Errorf("network info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// FIXME(@cthulhu-rider): parameter format hasn't been fixed in the protocol yet,
|
// FIXME(@cthulhu-rider): parameter format hasn't been fixed in the protocol yet,
|
||||||
|
|
|
@ -28,7 +28,7 @@ func GetKeyFromPath(walletPath, addrStr string, password *string) (*keys.Private
|
||||||
}
|
}
|
||||||
w, err := wallet.NewWalletFromFile(walletPath)
|
w, err := wallet.NewWalletFromFile(walletPath)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, fmt.Errorf("parse wallet: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var addr util.Uint160
|
var addr util.Uint160
|
||||||
|
|
Loading…
Reference in a new issue