forked from TrueCloudLab/frostfs-s3-gw
[#535] Support public access block operations
Signed-off-by: Marina Biryukova <m.biryukova@yadro.com>
This commit is contained in:
parent
4f0f2ca7bd
commit
a7ce40d745
23 changed files with 940 additions and 87 deletions
|
@ -88,7 +88,7 @@ func Auth(center Center, log *zap.Logger) Func {
|
|||
}
|
||||
|
||||
type FrostFSIDValidator interface {
|
||||
ValidatePublicKey(key *keys.PublicKey) error
|
||||
GetUserNamespace(key *keys.PublicKey) (string, error)
|
||||
}
|
||||
|
||||
func FrostfsIDValidation(frostfsID FrostFSIDValidator, log *zap.Logger) Func {
|
||||
|
@ -104,7 +104,8 @@ func FrostfsIDValidation(frostfsID FrostFSIDValidator, log *zap.Logger) Func {
|
|||
return
|
||||
}
|
||||
|
||||
if err = validateBearerToken(frostfsID, bd.Gate.BearerToken); err != nil {
|
||||
namespace, err := getNamespaceFromBearerToken(frostfsID, bd.Gate.BearerToken)
|
||||
if err != nil {
|
||||
reqLogOrDefault(ctx, log).Error(logs.FrostfsIDValidationFailed, zap.Error(err), logs.TagField(logs.TagDatapath))
|
||||
if _, wrErr := WriteErrorResponse(w, GetReqInfo(ctx), err); wrErr != nil {
|
||||
reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr), logs.TagField(logs.TagDatapath))
|
||||
|
@ -112,25 +113,58 @@ func FrostfsIDValidation(frostfsID FrostFSIDValidator, log *zap.Logger) Func {
|
|||
span.End()
|
||||
return
|
||||
}
|
||||
reqInfo := GetReqInfo(r.Context())
|
||||
reqInfo.UserNamespace = &namespace
|
||||
|
||||
span.End()
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func getNamespaceFromBearerToken(frostfsID FrostFSIDValidator, bt *bearer.Token) (string, error) {
|
||||
m := new(acl.BearerToken)
|
||||
bt.WriteToV2(m)
|
||||
|
||||
pk, err := keys.NewPublicKeyFromBytes(m.GetSignature().GetKey(), elliptic.P256())
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("invalid bearer token public key: %w", err)
|
||||
}
|
||||
|
||||
namespace, err := frostfsID.GetUserNamespace(pk)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("get user namespace: %w", err)
|
||||
}
|
||||
|
||||
return namespace, nil
|
||||
}
|
||||
|
||||
type PublicAccessBlockChecker interface {
|
||||
CheckRestrictPublicBuckets(context.Context) error
|
||||
}
|
||||
|
||||
func RestrictPublicBuckets(checker PublicAccessBlockChecker, log *zap.Logger) Func {
|
||||
return func(h http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
ctx, span := tracing.StartSpanFromContext(r.Context(), "middleware.RestrictPublicBuckets")
|
||||
|
||||
if r.Method == http.MethodOptions {
|
||||
span.End()
|
||||
h.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
if err := checker.CheckRestrictPublicBuckets(ctx); err != nil {
|
||||
reqLogOrDefault(ctx, log).Error(logs.RestrictPublicBucketsCheckFailed, zap.Error(err), logs.TagField(logs.TagDatapath))
|
||||
if _, wrErr := WriteErrorResponse(w, GetReqInfo(ctx), err); wrErr != nil {
|
||||
reqLogOrDefault(ctx, log).Error(logs.FailedToWriteResponse, zap.Error(wrErr), logs.TagField(logs.TagDatapath))
|
||||
}
|
||||
span.End()
|
||||
return
|
||||
}
|
||||
|
||||
span.End()
|
||||
h.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func validateBearerToken(frostfsID FrostFSIDValidator, bt *bearer.Token) error {
|
||||
m := new(acl.BearerToken)
|
||||
bt.WriteToV2(m)
|
||||
|
||||
pk, err := keys.NewPublicKeyFromBytes(m.GetSignature().GetKey(), elliptic.P256())
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid bearer token public key: %w", err)
|
||||
}
|
||||
|
||||
if err = frostfsID.ValidatePublicKey(pk); err != nil {
|
||||
return fmt.Errorf("validation data user key failed: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue