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
|
@ -1,6 +1,7 @@
|
|||
package handler
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
|
@ -8,6 +9,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/errors"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/layer"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-s3-gw/api/middleware"
|
||||
"github.com/pquerna/otp/totp"
|
||||
)
|
||||
|
||||
func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Request) {
|
||||
|
@ -15,6 +17,7 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
|
|||
defer span.End()
|
||||
|
||||
reqInfo := middleware.GetReqInfo(ctx)
|
||||
var serialNumber, token string
|
||||
|
||||
configuration := new(VersioningConfiguration)
|
||||
if err := h.cfg.NewXMLDecoder(r.Body, r.UserAgent()).Decode(configuration); err != nil {
|
||||
|
@ -34,14 +37,49 @@ func (h *handler) PutBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
|
|||
return
|
||||
}
|
||||
|
||||
newMfa := len(configuration.MfaDelete) > 0
|
||||
|
||||
if settings.MFADeleteEnabled() || newMfa {
|
||||
serialNumber, token, err = h.getMFAHeader(r)
|
||||
if err != nil {
|
||||
h.logAndSendError(ctx, w, "invalid x-amz-mfa header", reqInfo, errors.GetAPIError(errors.ErrBadRequest))
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
// settings pointer is stored in the cache, so modify a copy of the settings
|
||||
newSettings := *settings
|
||||
|
||||
if newMfa {
|
||||
switch configuration.MfaDelete {
|
||||
case data.MFADeleteEnabled:
|
||||
newSettings.Versioning.MFADeleteStatus = data.MFADeleteEnabled
|
||||
newSettings.Versioning.MFASerialNumber = serialNumber
|
||||
case data.MFADeleteDisabled:
|
||||
newSettings.Versioning.MFADeleteStatus = data.MFADeleteDisabled
|
||||
default:
|
||||
h.logAndSendError(ctx, w, "failed to get mfa configuration", reqInfo, nil)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if configuration.Status != data.VersioningEnabled && configuration.Status != data.VersioningSuspended {
|
||||
h.logAndSendError(ctx, w, "invalid versioning configuration", reqInfo, errors.GetAPIError(errors.ErrMalformedXML))
|
||||
return
|
||||
}
|
||||
|
||||
// settings pointer is stored in the cache, so modify a copy of the settings
|
||||
newSettings := *settings
|
||||
newSettings.Versioning = configuration.Status
|
||||
newSettings.Versioning.VersioningStatus = configuration.Status
|
||||
|
||||
p := &layer.PutSettingsParams{
|
||||
BktInfo: bktInfo,
|
||||
|
@ -85,7 +123,10 @@ func (h *handler) GetBucketVersioningHandler(w http.ResponseWriter, r *http.Requ
|
|||
func formVersioningConfiguration(settings *data.BucketSettings) *VersioningConfiguration {
|
||||
res := &VersioningConfiguration{}
|
||||
if !settings.Unversioned() {
|
||||
res.Status = settings.Versioning
|
||||
res.Status = settings.Versioning.VersioningStatus
|
||||
}
|
||||
if settings.MFADeleteEnabled() {
|
||||
res.MfaDelete = data.MFADeleteEnabled
|
||||
}
|
||||
|
||||
return res
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue