[#347] Add setEACL session token checks

Signed-off-by: Angira Kekteeva <kira@nspcc.ru>
This commit is contained in:
Angira Kekteeva 2022-04-18 19:35:25 +04:00 committed by Kirillov Denis
parent f274747e83
commit a0a04a73bd
4 changed files with 127 additions and 45 deletions

View file

@ -20,6 +20,7 @@ import (
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/object"
oid "github.com/nspcc-dev/neofs-sdk-go/object/id"
"github.com/nspcc-dev/neofs-sdk-go/session"
)
var (
@ -168,6 +169,12 @@ func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
return
}
token, err := getSessionTokenSetEACL(r.Context())
if err != nil {
h.logAndSendError(w, "couldn't get eacl token", reqInfo, err)
return
}
list := &AccessControlPolicy{}
if r.ContentLength == 0 {
list, err = parseACLHeaders(r.Header, key)
@ -193,14 +200,14 @@ func (h *handler) PutBucketACLHandler(w http.ResponseWriter, r *http.Request) {
return
}
if err = h.updateBucketACL(r, astBucket, bktInfo); err != nil {
if err = h.updateBucketACL(r, astBucket, bktInfo, token); err != nil {
h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
return
}
w.WriteHeader(http.StatusOK)
}
func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bktInfo *data.BucketInfo) error {
func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bktInfo *data.BucketInfo, sessionToken *session.Token) error {
bucketACL, err := h.obj.GetBucketACL(r.Context(), bktInfo)
if err != nil {
return fmt.Errorf("could not get bucket eacl: %w", err)
@ -223,6 +230,8 @@ func (h *handler) updateBucketACL(r *http.Request, astChild *ast, bktInfo *data.
return fmt.Errorf("could not translate ast to table: %w", err)
}
table.SetSessionToken(sessionToken)
p := &layer.PutBucketACLParams{
BktInfo: bktInfo,
EACL: table,
@ -264,6 +273,12 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
return
}
token, err := getSessionTokenSetEACL(r.Context())
if err != nil {
h.logAndSendError(w, "couldn't get eacl token", reqInfo, err)
return
}
list := &AccessControlPolicy{}
if r.ContentLength == 0 {
list, err = parseACLHeaders(r.Header, key)
@ -305,7 +320,7 @@ func (h *handler) PutObjectACLHandler(w http.ResponseWriter, r *http.Request) {
return
}
if err = h.updateBucketACL(r, astObject, bktInfo); err != nil {
if err = h.updateBucketACL(r, astObject, bktInfo, token); err != nil {
h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
return
}
@ -359,6 +374,12 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
return
}
token, err := getSessionTokenSetEACL(r.Context())
if err == nil {
h.logAndSendError(w, "couldn't get eacl token", reqInfo, err)
return
}
bktPolicy := &bucketPolicy{Bucket: reqInfo.BucketName}
if err := json.NewDecoder(r.Body).Decode(bktPolicy); err != nil {
h.logAndSendError(w, "could not parse bucket policy", reqInfo, err)
@ -371,7 +392,7 @@ func (h *handler) PutBucketPolicyHandler(w http.ResponseWriter, r *http.Request)
return
}
if err = h.updateBucketACL(r, astPolicy, bktInfo); err != nil {
if err = h.updateBucketACL(r, astPolicy, bktInfo, token); err != nil {
h.logAndSendError(w, "could not update bucket acl", reqInfo, err)
return
}

View file

@ -14,6 +14,7 @@ import (
"github.com/nspcc-dev/neofs-s3-gw/api/data"
"github.com/nspcc-dev/neofs-s3-gw/api/errors"
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
"github.com/nspcc-dev/neofs-sdk-go/session"
"go.uber.org/zap"
)
@ -345,6 +346,8 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
}
var (
sessionTokenSetEACL *session.Token
uploadID = r.URL.Query().Get(uploadIDHeaderName)
uploadInfo = &layer.UploadInfoParams{
UploadID: uploadID,
@ -352,6 +355,7 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
Key: reqInfo.ObjectName,
}
additional = []zap.Field{zap.String("uploadID", uploadID), zap.String("Key", reqInfo.ObjectName)}
uploadData = &UploadData{}
)
reqBody := new(CompleteMultipartUpload)
@ -371,16 +375,6 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
return
}
c := &layer.CompleteMultipartParams{
Info: uploadInfo,
Parts: reqBody.Parts,
}
objInfo, err := h.obj.CompleteMultipartUpload(r.Context(), c)
if err != nil {
h.logAndSendError(w, "could not complete multipart upload", reqInfo, err, additional...)
return
}
if initPart.Size > 0 {
initPartPayload := bytes.NewBuffer(make([]byte, 0, initPart.Size))
p := &layer.GetObjectParams{
@ -392,37 +386,53 @@ func (h *handler) CompleteMultipartUploadHandler(w http.ResponseWriter, r *http.
return
}
uploadData := &UploadData{}
if err = json.Unmarshal(initPartPayload.Bytes(), uploadData); err != nil {
h.logAndSendError(w, "could not unmarshal multipart upload acl and/or tagging", reqInfo, err, additional...)
return
}
if len(uploadData.TagSet) != 0 {
t := &layer.PutTaggingParams{
ObjectInfo: objInfo,
TagSet: uploadData.TagSet,
}
if err = h.obj.PutObjectTagging(r.Context(), t); err != nil {
h.logAndSendError(w, "could not put tagging file of completed multipart upload", reqInfo, err, additional...)
if uploadData.ACL != nil {
if sessionTokenSetEACL, err = getSessionTokenSetEACL(r.Context()); err != nil {
h.logAndSendError(w, "couldn't get eacl token", reqInfo, err)
return
}
}
}
if uploadData.ACL != nil {
resInfo := &resourceInfo{
Bucket: objInfo.Bucket,
Object: objInfo.Name,
}
astObject, err := aclToAst(uploadData.ACL, resInfo)
if err != nil {
h.logAndSendError(w, "could not translate acl of completed multipart upload to ast", reqInfo, err, additional...)
return
}
if err = h.updateBucketACL(r, astObject, bktInfo); err != nil {
h.logAndSendError(w, "could not update bucket acl while completing multipart upload", reqInfo, err, additional...)
return
}
c := &layer.CompleteMultipartParams{
Info: uploadInfo,
Parts: reqBody.Parts,
}
objInfo, err := h.obj.CompleteMultipartUpload(r.Context(), c)
if err != nil {
h.logAndSendError(w, "could not complete multipart upload", reqInfo, err, additional...)
return
}
if len(uploadData.TagSet) != 0 {
t := &layer.PutTaggingParams{
ObjectInfo: objInfo,
TagSet: uploadData.TagSet,
}
if err = h.obj.PutObjectTagging(r.Context(), t); err != nil {
h.logAndSendError(w, "could not put tagging file of completed multipart upload", reqInfo, err, additional...)
return
}
}
if uploadData.ACL != nil {
resInfo := &resourceInfo{
Bucket: objInfo.Bucket,
Object: objInfo.Name,
}
astObject, err := aclToAst(uploadData.ACL, resInfo)
if err != nil {
h.logAndSendError(w, "could not translate acl of completed multipart upload to ast", reqInfo, err, additional...)
return
}
if err = h.updateBucketACL(r, astObject, bktInfo, sessionTokenSetEACL); err != nil {
h.logAndSendError(w, "could not update bucket acl while completing multipart upload", reqInfo, err, additional...)
return
}
}

View file

@ -21,6 +21,7 @@ import (
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
"github.com/nspcc-dev/neofs-s3-gw/creds/accessbox"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/session"
"go.uber.org/zap"
)
@ -172,8 +173,21 @@ type createBucketParams struct {
}
func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
var newEaclTable *eacl.Table
reqInfo := api.GetReqInfo(r.Context())
var (
err error
newEaclTable *eacl.Table
sessionTokenEACL *session.Token
containsACL = containsACLHeaders(r)
reqInfo = api.GetReqInfo(r.Context())
)
if containsACL {
if sessionTokenEACL, err = getSessionTokenSetEACL(r.Context()); err != nil {
h.logAndSendError(w, "could not get eacl session token from a box", reqInfo, err)
return
}
}
tagSet, err := parseTaggingHeader(r.Header)
if err != nil {
h.logAndSendError(w, "could not parse tagging header", reqInfo, err)
@ -233,11 +247,12 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
h.log.Error("couldn't send notification: %w", zap.Error(err))
}
if containsACLHeaders(r) {
if containsACL {
if newEaclTable, err = h.getNewEAclTable(r, bktInfo, info); err != nil {
h.logAndSendError(w, "could not get new eacl table", reqInfo, err)
return
}
newEaclTable.SetSessionToken(sessionTokenEACL)
}
if tagSet != nil {
@ -269,10 +284,12 @@ func (h *handler) PutObjectHandler(w http.ResponseWriter, r *http.Request) {
func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
var (
newEaclTable *eacl.Table
tagSet map[string]string
reqInfo = api.GetReqInfo(r.Context())
metadata = make(map[string]string)
newEaclTable *eacl.Table
tagSet map[string]string
sessionTokenEACL *session.Token
reqInfo = api.GetReqInfo(r.Context())
metadata = make(map[string]string)
containsACL = containsACLHeaders(r)
)
policy, err := checkPostPolicy(r, reqInfo, metadata)
@ -290,6 +307,13 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
}
}
if containsACL {
if sessionTokenEACL, err = getSessionTokenSetEACL(r.Context()); err != nil {
h.logAndSendError(w, "could not get eacl session token from a box", reqInfo, err)
return
}
}
var contentReader io.Reader
var size int64
if content, ok := r.MultipartForm.Value["file"]; ok {
@ -360,6 +384,8 @@ func (h *handler) PostObject(w http.ResponseWriter, r *http.Request) {
}
if newEaclTable != nil {
newEaclTable.SetSessionToken(sessionTokenEACL)
p := &layer.PutBucketACLParams{
BktInfo: bktInfo,
EACL: newEaclTable,
@ -582,6 +608,17 @@ func (h *handler) CreateBucketHandler(w http.ResponseWriter, r *http.Request) {
if err == nil {
policies = boxData.Policies
p.SessionToken = boxData.Gate.SessionTokenForPut()
p.EACL.SetSessionToken(boxData.Gate.SessionTokenForSetEACL())
}
if p.SessionToken == nil {
h.logAndSendError(w, "couldn't find session token for put", reqInfo, errors.GetAPIError(errors.ErrAccessDenied))
return
}
if p.EACL.SessionToken() == nil {
h.logAndSendError(w, "couldn't find session token for setEACL", reqInfo, errors.GetAPIError(errors.ErrAccessDenied))
return
}
if createParams.LocationConstraint != "" {

View file

@ -1,15 +1,16 @@
package handler
import (
"context"
"net/http"
"strconv"
"strings"
"github.com/nspcc-dev/neofs-s3-gw/api/data"
"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/errors"
"github.com/nspcc-dev/neofs-s3-gw/api/layer"
"github.com/nspcc-dev/neofs-sdk-go/session"
"go.uber.org/zap"
)
@ -80,3 +81,16 @@ func parseRange(s string) (*layer.RangeParams, error) {
End: values[1],
}, nil
}
func getSessionTokenSetEACL(ctx context.Context) (*session.Token, error) {
boxData, err := layer.GetBoxData(ctx)
if err != nil {
return nil, err
}
sessionToken := boxData.Gate.SessionTokenForSetEACL()
if sessionToken == nil {
return nil, errors.GetAPIError(errors.ErrAccessDenied)
}
return sessionToken, nil
}