[#368] object: Reject expired objects

The lifetime of an object can be limited by specifying a correspondin
well-known attribute. Node should refuse to save expired objects.

Checking objects in FormatValidator is extended with an expiration attribute
parsing step.

Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
Leonard Lyubich 2021-02-15 11:28:42 +03:00 committed by Alex Vanin
parent a2c2241356
commit 38727c2930
3 changed files with 94 additions and 1 deletions

View file

@ -2,11 +2,14 @@ package object
import (
"bytes"
"strconv"
"github.com/nspcc-dev/neofs-api-go/pkg/object"
"github.com/nspcc-dev/neofs-api-go/pkg/owner"
"github.com/nspcc-dev/neofs-api-go/pkg/storagegroup"
objectV2 "github.com/nspcc-dev/neofs-api-go/v2/object"
crypto "github.com/nspcc-dev/neofs-crypto"
"github.com/nspcc-dev/neofs-node/pkg/core/netmap"
"github.com/pkg/errors"
)
@ -20,6 +23,8 @@ type FormatValidatorOption func(*cfg)
type cfg struct {
deleteHandler DeleteHandler
netState netmap.State
}
// DeleteHandler is an interface of delete queue processor.
@ -69,6 +74,11 @@ func (v *FormatValidator) Validate(obj *Object) error {
return errors.Wrapf(err, "(%T) could not validate signature key", v)
}
// TODO: combine small checks
if err := v.checkExpiration(obj); err != nil {
return errors.Wrapf(err, "object did not pass expiration check")
}
if err := object.CheckHeaderVerificationFields(obj.SDK()); err != nil {
return errors.Wrapf(err, "(%T) could not validate header fields", v)
}
@ -164,6 +174,38 @@ func (v *FormatValidator) ValidateContent(o *Object) error {
return nil
}
var errExpired = errors.New("object has expired")
func (v *FormatValidator) checkExpiration(obj *Object) error {
for _, a := range obj.Attributes() {
if a.Key() != objectV2.SysAttributeExpEpoch {
continue
}
exp, err := strconv.ParseUint(a.Value(), 10, 64)
if err != nil {
return err
}
if exp < v.netState.CurrentEpoch() {
return errExpired
}
break
}
return nil
}
// WithNetState returns options to set network state interface.
//
// FIXME: network state is a required parameter.
func WithNetState(netState netmap.State) FormatValidatorOption {
return func(c *cfg) {
c.netState = netState
}
}
// WithDeleteHandler returns option to set delete queue processor.
func WithDeleteHandler(v DeleteHandler) FormatValidatorOption {
return func(c *cfg) {