forked from TrueCloudLab/frostfs-s3-gw
[#604] Add support of MFADelete argument and x-amz-mfa header
Signed-off-by: Pavel Pogodaev <p.pogodaev@yadro.com>
This commit is contained in:
parent
13fce51021
commit
7fbc69f4f5
28 changed files with 906 additions and 118 deletions
|
@ -15,6 +15,7 @@ import (
|
|||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/TrueCloudLab/policy-engine/pkg/chain"
|
||||
"github.com/pquerna/otp/totp"
|
||||
)
|
||||
|
||||
// limitation of AWS https://docs.aws.amazon.com/AmazonS3/latest/API/API_DeleteObjects.html
|
||||
|
@ -84,6 +85,26 @@ func (h *handler) DeleteObjectHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
if len(versionID) > 0 && bktSettings.MFADeleteEnabled() {
|
||||
serialNumber, token, err := h.getMFAHeader(r)
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get mfa header", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
device, err := h.mfa.GetMFADevice(ctx, reqInfo.Namespace, nameFromArn(serialNumber))
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get mfa device", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
validate := totp.Validate(token, device.Key.Secret())
|
||||
if !validate {
|
||||
h.logAndSendError(ctx, w, "could not validate token", reqInfo, fmt.Errorf("mfa Authentication must be used for this request"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
networkInfo, err := h.obj.GetNetworkInfo(ctx)
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get network info", reqInfo, err)
|
||||
|
@ -186,6 +207,26 @@ func (h *handler) DeleteMultipleObjectsHandler(w http.ResponseWriter, r *http.Re
|
|||
return
|
||||
}
|
||||
|
||||
if haveVersionedObjects(requested.Objects) && bktSettings.MFADeleteEnabled() {
|
||||
serialNumber, token, err := h.getMFAHeader(r)
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get mfa header", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
device, err := h.mfa.GetMFADevice(ctx, reqInfo.Namespace, nameFromArn(serialNumber))
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get mfa device", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
validate := totp.Validate(token, device.Key.Secret())
|
||||
if !validate {
|
||||
h.logAndSendError(ctx, w, "could not validate token", reqInfo, fmt.Errorf("mfa Authentication must be used for this request"))
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
networkInfo, err := h.obj.GetNetworkInfo(ctx)
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get network info", reqInfo, err)
|
||||
|
@ -245,6 +286,12 @@ func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
return
|
||||
}
|
||||
|
||||
bktSettings, err := h.obj.GetBucketSettings(ctx, bktInfo)
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "could not get bucket settings", reqInfo, err)
|
||||
return
|
||||
}
|
||||
|
||||
if err = checkOwner(bktInfo, reqInfo.User); err != nil {
|
||||
h.logAndSendError(ctx, w, "request owner id does not match bucket owner id", reqInfo, err)
|
||||
return
|
||||
|
@ -260,7 +307,7 @@ func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
skipObjCheck := false
|
||||
if value, ok := r.Header[api.AmzForceBucketDelete]; ok {
|
||||
s := value[0]
|
||||
if s == "true" {
|
||||
if s == "true" && !bktSettings.MFADeleteEnabled() {
|
||||
skipObjCheck = true
|
||||
}
|
||||
}
|
||||
|
@ -287,3 +334,12 @@ func (h *handler) DeleteBucketHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
w.WriteHeader(http.StatusNoContent)
|
||||
}
|
||||
|
||||
func haveVersionedObjects(objects []ObjectIdentifier) bool {
|
||||
for _, o := range objects {
|
||||
if len(o.VersionID) > 0 {
|
||||
return true
|
||||
}
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue