object: Validate attribute EXPIRATION_EPOCH
on put
#1188
2 changed files with 28 additions and 30 deletions
|
@ -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)
|
||||
dstepanov-yadro marked this conversation as resolved
Outdated
|
||||
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() {
|
||||
fyrchik marked this conversation as resolved
Outdated
fyrchik
commented
Also, `else if !unprepared`?
Also, `checkExpiration` now contains a single `if`, we could move it here and rename `checkExpiration` to `checkIfExpired`. And checking whether `expiration epoch` is less than the current epoch is valid for both types of objects, the only check that is specific is `IsLocked` (because not-yet-created object cannot be locked).
acid-ant
commented
OMG, updated. Thanks. OMG, updated. Thanks.
|
||||
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
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue
Also it could happen, that user has defined both of attributes:
objectV2.SysAttributeExpEpoch
andobjectV2.SysAttributeExpEpochNeoFS
. Maybe it has to be an error too?It definitely should be, but we will eventually remove NeoFS attribute, and currently we have deterministic behaviour, so I would leave it as is.