forked from TrueCloudLab/frostfs-s3-gw
[#216] Add bucket owner check
Signed-off-by: Denis Kirillov <denis@nspcc.ru>
This commit is contained in:
parent
68e4e1bbc3
commit
d81a3d7b45
7 changed files with 78 additions and 10 deletions
|
@ -71,6 +71,15 @@ func (h *handler) CopyObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, srcBucket, r.Header.Get(api.AmzSourceExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "source expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if inf, err = h.obj.GetObjectInfo(r.Context(), srcBucket, srcObject); err != nil {
|
||||
h.logAndSendError(w, "could not find object", reqInfo, err)
|
||||
return
|
||||
|
|
|
@ -44,6 +44,11 @@ type DeleteObjectsResponse struct {
|
|||
func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err := h.obj.DeleteObject(r.Context(), reqInfo.BucketName, reqInfo.ObjectName); err != nil {
|
||||
h.log.Error("could not delete object",
|
||||
zap.String("request_id", reqInfo.RequestID),
|
||||
|
@ -100,6 +105,11 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
|||
DeletedObjects: make([]ObjectIdentifier, 0, len(toRemove)),
|
||||
}
|
||||
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if errs := h.obj.DeleteObjects(r.Context(), reqInfo.BucketName, toRemove); errs != nil && !requested.Quiet {
|
||||
additional := []zap.Field{
|
||||
zap.Strings("objects_name", toRemove),
|
||||
|
@ -135,6 +145,10 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
|||
|
||||
func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
||||
reqInfo := api.GetReqInfo(r.Context())
|
||||
if err := h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err := h.obj.DeleteBucket(r.Context(), &layer.DeleteBucketParams{Name: reqInfo.BucketName}); err != nil {
|
||||
h.logAndSendError(w, "couldn't delete bucket", reqInfo, err)
|
||||
}
|
||||
|
|
|
@ -93,6 +93,11 @@ func (h *handler) GetObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if inf, err = h.obj.GetObjectInfo(r.Context(), reqInfo.BucketName, reqInfo.ObjectName); err != nil {
|
||||
h.logAndSendError(w, "could not find object", reqInfo, err)
|
||||
return
|
||||
|
|
|
@ -31,6 +31,11 @@ func (h *handler) HeadObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
reqInfo = api.GetReqInfo(r.Context())
|
||||
)
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if inf, err = h.obj.GetObjectInfo(r.Context(), reqInfo.BucketName, reqInfo.ObjectName); err != nil {
|
||||
h.logAndSendError(w, "could not fetch object info", reqInfo, err)
|
||||
return
|
||||
|
@ -56,7 +61,11 @@ func (h *handler) HeadBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), reqInfo.BucketName)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "could not fetch object info", reqInfo, err)
|
||||
h.logAndSendError(w, "could not get bucket info", reqInfo, err)
|
||||
return
|
||||
}
|
||||
if err = checkOwner(bktInfo, r.Header.Get(api.AmzExpectedBucketOwner)); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -21,6 +21,11 @@ func (h *handler) ListObjectsV1Handler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
list, err := h.obj.ListObjectsV1(r.Context(), params)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "something went wrong", reqInfo, err)
|
||||
|
@ -60,6 +65,11 @@ func (h *handler) ListObjectsV2Handler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if err = h.checkBucketOwner(r, reqInfo.BucketName); err != nil {
|
||||
h.logAndSendError(w, "expected owner doesn't match", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
list, err := h.obj.ListObjectsV2(r.Context(), params)
|
||||
if err != nil {
|
||||
h.logAndSendError(w, "something went wrong", reqInfo, err)
|
||||
|
|
|
@ -18,3 +18,23 @@ func (h *handler) logAndSendError(w http.ResponseWriter, logText string, reqInfo
|
|||
h.log.Error(logText, fields...)
|
||||
api.WriteErrorResponse(w, reqInfo, err)
|
||||
}
|
||||
|
||||
func (h *handler) checkBucketOwner(r *http.Request, bucket string, header ...string) error {
|
||||
var expected string
|
||||
if len(header) == 0 {
|
||||
expected = r.Header.Get(api.AmzExpectedBucketOwner)
|
||||
} else {
|
||||
expected = header[0]
|
||||
}
|
||||
|
||||
if len(expected) == 0 {
|
||||
return nil
|
||||
}
|
||||
|
||||
bktInfo, err := h.obj.GetBucketInfo(r.Context(), bucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return checkOwner(bktInfo, expected)
|
||||
}
|
||||
|
|
|
@ -30,15 +30,16 @@ const (
|
|||
IfMatch = "If-Match"
|
||||
IfNoneMatch = "If-None-Match"
|
||||
|
||||
AmzCopyIfModifiedSince = "X-Amz-Copy-Source-If-Modified-Since"
|
||||
AmzCopyIfUnmodifiedSince = "X-Amz-Copy-Source-If-Unmodified-Since"
|
||||
AmzCopyIfMatch = "X-Amz-Copy-Source-If-Match"
|
||||
AmzCopyIfNoneMatch = "X-Amz-Copy-Source-If-None-Match"
|
||||
AmzACL = "X-Amz-Acl"
|
||||
AmzGrantFullControl = "X-Amz-Grant-Full-Control"
|
||||
AmzGrantRead = "X-Amz-Grant-Read"
|
||||
AmzGrantWrite = "X-Amz-Grant-Write"
|
||||
AmzExpectedBucketOwner = "X-Amz-Expected-Bucket-Owner"
|
||||
AmzCopyIfModifiedSince = "X-Amz-Copy-Source-If-Modified-Since"
|
||||
AmzCopyIfUnmodifiedSince = "X-Amz-Copy-Source-If-Unmodified-Since"
|
||||
AmzCopyIfMatch = "X-Amz-Copy-Source-If-Match"
|
||||
AmzCopyIfNoneMatch = "X-Amz-Copy-Source-If-None-Match"
|
||||
AmzACL = "X-Amz-Acl"
|
||||
AmzGrantFullControl = "X-Amz-Grant-Full-Control"
|
||||
AmzGrantRead = "X-Amz-Grant-Read"
|
||||
AmzGrantWrite = "X-Amz-Grant-Write"
|
||||
AmzExpectedBucketOwner = "X-Amz-Expected-Bucket-Owner"
|
||||
AmzSourceExpectedBucketOwner = "X-Amz-Source-Expected-Bucket-Owner"
|
||||
|
||||
ContainerID = "X-Container-Id"
|
||||
)
|
||||
|
|
Loading…
Reference in a new issue