From 40b68bcb6c16331fd8036a0b730ee7442025ccdb Mon Sep 17 00:00:00 2001 From: Anton Nikiforov Date: Tue, 18 Jun 2024 15:06:54 +0300 Subject: [PATCH] [#1109] object: Validate attribute `EXPIRATION_EPOCH` on `put` Signed-off-by: Anton Nikiforov --- pkg/core/object/fmt.go | 56 +++++++++++++++++-------------------- pkg/core/object/fmt_test.go | 2 ++ 2 files changed, 28 insertions(+), 30 deletions(-) diff --git a/pkg/core/object/fmt.go b/pkg/core/object/fmt.go index fa1e40dd0..b997aa182 100644 --- a/pkg/core/object/fmt.go +++ b/pkg/core/object/fmt.go @@ -124,15 +124,22 @@ func (v *FormatValidator) Validate(ctx context.Context, obj *objectSDK.Object, u return fmt.Errorf("invalid attributes: %w", err) } + exp, err := expirationEpochAttribute(obj) + if err != nil { + if !errors.Is(err, errNoExpirationEpoch) { + return fmt.Errorf("object did not pass expiration check: %w", err) + } + } else if !unprepared && exp < v.netState.CurrentEpoch() { + if err := v.checkIfExpired(ctx, obj); err != nil { + return fmt.Errorf("object did not pass expiration check: %w", err) + } + } + if !unprepared { if err := v.validateSignatureKey(obj); err != nil { return fmt.Errorf("(%T) could not validate signature key: %w", v, err) } - if err := v.checkExpiration(ctx, obj); err != nil { - return fmt.Errorf("object did not pass expiration check: %w", err) - } - if err := objectSDK.CheckHeaderVerificationFields(obj); err != nil { return fmt.Errorf("(%T) could not validate header fields: %w", v, err) } @@ -348,35 +355,24 @@ func (v *FormatValidator) fillAndValidateTombstoneMeta(o *objectSDK.Object, meta var errExpired = errors.New("object has expired") -func (v *FormatValidator) checkExpiration(ctx context.Context, obj *objectSDK.Object) error { - exp, err := expirationEpochAttribute(obj) - if err != nil { - if errors.Is(err, errNoExpirationEpoch) { - return nil // objects without expiration attribute are valid - } +func (v *FormatValidator) checkIfExpired(ctx context.Context, obj *objectSDK.Object) error { + // an object could be expired but locked; + // put such an object is a correct operation - return err + cID, _ := obj.ContainerID() + oID, _ := obj.ID() + + var addr oid.Address + addr.SetContainer(cID) + addr.SetObject(oID) + + locked, err := v.e.IsLocked(ctx, addr) + if err != nil { + return fmt.Errorf("locking status check for an expired object: %w", err) } - if exp < v.netState.CurrentEpoch() { - // an object could be expired but locked; - // put such an object is a correct operation - - cID, _ := obj.ContainerID() - oID, _ := obj.ID() - - var addr oid.Address - addr.SetContainer(cID) - addr.SetObject(oID) - - locked, err := v.e.IsLocked(ctx, addr) - if err != nil { - return fmt.Errorf("locking status check for an expired object: %w", err) - } - - if !locked { - return errExpired - } + if !locked { + return errExpired } return nil diff --git a/pkg/core/object/fmt_test.go b/pkg/core/object/fmt_test.go index a8901ad6d..77afbfc45 100644 --- a/pkg/core/object/fmt_test.go +++ b/pkg/core/object/fmt_test.go @@ -195,6 +195,8 @@ func TestFormatValidator_Validate(t *testing.T) { val := "text" err := v.Validate(context.Background(), fn(val), false) require.Error(t, err) + err = v.Validate(context.Background(), fn(val), true) + require.Error(t, err) }) t.Run("expired object", func(t *testing.T) {