[#58] core/object: Add content validation to FormatValidator
Add content validation step to FormatValidator. Check tombstone payload correctness. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
017afbf0e3
commit
107f3097e4
2 changed files with 73 additions and 11 deletions
|
@ -35,6 +35,10 @@ func (v *FormatValidator) Validate(obj *Object) error {
|
||||||
return errNilCID
|
return errNilCID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := v.validateContent(obj.GetType(), obj.GetPayload()); err != nil {
|
||||||
|
return errors.Wrapf(err, "(%T) incorrect content", v)
|
||||||
|
}
|
||||||
|
|
||||||
if err := v.validateSignatureKey(obj); err != nil {
|
if err := v.validateSignatureKey(obj); err != nil {
|
||||||
return errors.Wrapf(err, "(%T) could not validate signature key", v)
|
return errors.Wrapf(err, "(%T) could not validate signature key", v)
|
||||||
}
|
}
|
||||||
|
@ -83,3 +87,23 @@ func (v *FormatValidator) checkOwnerKey(id *owner.ID, key []byte) error {
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (v *FormatValidator) validateContent(t object.Type, payload []byte) error {
|
||||||
|
switch t {
|
||||||
|
case object.TypeTombstone:
|
||||||
|
if len(payload) == 0 {
|
||||||
|
return errors.Errorf("(%T) empty payload in tombstone", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
addr, err := object.AddressFromBytes(payload)
|
||||||
|
if err != nil {
|
||||||
|
return errors.Wrapf(err, "(%T) could not parse object address from tombstone", v)
|
||||||
|
}
|
||||||
|
|
||||||
|
if addr.GetContainerID() == nil || addr.GetObjectID() == nil {
|
||||||
|
return errors.Errorf("(%T) empty address reference in tombstone", v)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package object
|
package object
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"crypto/ecdsa"
|
||||||
"crypto/rand"
|
"crypto/rand"
|
||||||
"crypto/sha256"
|
"crypto/sha256"
|
||||||
"testing"
|
"testing"
|
||||||
|
@ -38,9 +39,25 @@ func testObjectID(t *testing.T) *object.ID {
|
||||||
return id
|
return id
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func blankValidObject(t *testing.T, key *ecdsa.PrivateKey) *RawObject {
|
||||||
|
wallet, err := owner.NEO3WalletFromPublicKey(&key.PublicKey)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
ownerID := owner.NewID()
|
||||||
|
ownerID.SetNeo3Wallet(wallet)
|
||||||
|
|
||||||
|
obj := NewRaw()
|
||||||
|
obj.SetContainerID(testContainerID(t))
|
||||||
|
obj.SetOwnerID(ownerID)
|
||||||
|
|
||||||
|
return obj
|
||||||
|
}
|
||||||
|
|
||||||
func TestFormatValidator_Validate(t *testing.T) {
|
func TestFormatValidator_Validate(t *testing.T) {
|
||||||
v := NewFormatValidator()
|
v := NewFormatValidator()
|
||||||
|
|
||||||
|
ownerKey := test.DecodeKey(-1)
|
||||||
|
|
||||||
t.Run("nil input", func(t *testing.T) {
|
t.Run("nil input", func(t *testing.T) {
|
||||||
require.Error(t, v.Validate(nil))
|
require.Error(t, v.Validate(nil))
|
||||||
})
|
})
|
||||||
|
@ -67,32 +84,53 @@ func TestFormatValidator_Validate(t *testing.T) {
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("correct w/ session token", func(t *testing.T) {
|
t.Run("correct w/ session token", func(t *testing.T) {
|
||||||
sessionKey := test.DecodeKey(-1)
|
|
||||||
|
|
||||||
tok := token.NewSessionToken()
|
tok := token.NewSessionToken()
|
||||||
tok.SetSessionKey(crypto.MarshalPublicKey(&sessionKey.PublicKey))
|
tok.SetSessionKey(crypto.MarshalPublicKey(&ownerKey.PublicKey))
|
||||||
|
|
||||||
obj := NewRaw()
|
obj := NewRaw()
|
||||||
obj.SetContainerID(testContainerID(t))
|
obj.SetContainerID(testContainerID(t))
|
||||||
obj.SetSessionToken(tok)
|
obj.SetSessionToken(tok)
|
||||||
|
|
||||||
require.NoError(t, object.SetIDWithSignature(sessionKey, obj.SDK()))
|
require.NoError(t, object.SetIDWithSignature(ownerKey, obj.SDK()))
|
||||||
|
|
||||||
require.NoError(t, v.Validate(obj.Object()))
|
require.NoError(t, v.Validate(obj.Object()))
|
||||||
})
|
})
|
||||||
|
|
||||||
t.Run("correct w/o session token", func(t *testing.T) {
|
t.Run("correct w/o session token", func(t *testing.T) {
|
||||||
ownerKey := test.DecodeKey(-1)
|
obj := blankValidObject(t, ownerKey)
|
||||||
|
|
||||||
wallet, err := owner.NEO3WalletFromPublicKey(&ownerKey.PublicKey)
|
require.NoError(t, object.SetIDWithSignature(ownerKey, obj.SDK()))
|
||||||
|
|
||||||
|
require.NoError(t, v.Validate(obj.Object()))
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("tombstone content", func(t *testing.T) {
|
||||||
|
obj := blankValidObject(t, ownerKey)
|
||||||
|
|
||||||
|
obj.SetType(object.TypeTombstone)
|
||||||
|
|
||||||
|
require.NoError(t, object.SetIDWithSignature(ownerKey, obj.SDK()))
|
||||||
|
|
||||||
|
require.Error(t, v.Validate(obj.Object()))
|
||||||
|
|
||||||
|
addr := object.NewAddress()
|
||||||
|
|
||||||
|
data, err := addr.ToV2().StableMarshal(nil)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
ownerID := owner.NewID()
|
obj.SetPayload(data)
|
||||||
ownerID.SetNeo3Wallet(wallet)
|
|
||||||
|
|
||||||
obj := NewRaw()
|
require.NoError(t, object.SetIDWithSignature(ownerKey, obj.SDK()))
|
||||||
obj.SetContainerID(testContainerID(t))
|
|
||||||
obj.SetOwnerID(ownerID)
|
require.Error(t, v.Validate(obj.Object()))
|
||||||
|
|
||||||
|
addr.SetContainerID(testContainerID(t))
|
||||||
|
addr.SetObjectID(testObjectID(t))
|
||||||
|
|
||||||
|
data, err = addr.ToV2().StableMarshal(nil)
|
||||||
|
require.NoError(t, err)
|
||||||
|
|
||||||
|
obj.SetPayload(data)
|
||||||
|
|
||||||
require.NoError(t, object.SetIDWithSignature(ownerKey, obj.SDK()))
|
require.NoError(t, object.SetIDWithSignature(ownerKey, obj.SDK()))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue