object: Validate attribute EXPIRATION_EPOCH on put #1188

Merged
fyrchik merged 1 commit from acid-ant/frostfs-node:bugfix/1109-validate-exp-epoch into master 2024-06-19 17:19:32 +00:00
2 changed files with 28 additions and 30 deletions

View file

@ -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

View file

@ -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) {