[#48] frostfsid: Support empty namespaces
Require ns to create subject. Since we don't allow move subject from one ns to another - drop add/remove subject to/from namespace Signed-off-by: Denis Kirillov <d.kirillov@yadro.com>
This commit is contained in:
parent
a0b73150c6
commit
3fb511ac15
5 changed files with 202 additions and 364 deletions
|
@ -101,13 +101,11 @@ const (
|
|||
deleteSubjectKVMethod = "deleteSubjectKV"
|
||||
deleteSubjectMethod = "deleteSubject"
|
||||
|
||||
createNamespaceMethod = "createNamespace"
|
||||
getNamespaceMethod = "getNamespace"
|
||||
getNamespaceExtendedMethod = "getNamespaceExtended"
|
||||
listNamespacesMethod = "listNamespaces"
|
||||
addSubjectToNamespaceMethod = "addSubjectToNamespace"
|
||||
removeSubjectFromNamespaceMethod = "removeSubjectFromNamespace"
|
||||
listNamespaceSubjectsMethod = "listNamespaceSubjects"
|
||||
createNamespaceMethod = "createNamespace"
|
||||
getNamespaceMethod = "getNamespace"
|
||||
getNamespaceExtendedMethod = "getNamespaceExtended"
|
||||
listNamespacesMethod = "listNamespaces"
|
||||
listNamespaceSubjectsMethod = "listNamespaceSubjects"
|
||||
|
||||
createGroupMethod = "createGroup"
|
||||
getGroupMethod = "getGroup"
|
||||
|
@ -199,16 +197,16 @@ func (c Client) GetAdmin() (util.Uint160, bool, error) {
|
|||
return u, true, err
|
||||
}
|
||||
|
||||
// CreateSubject creates new subject using public key.
|
||||
// CreateSubject creates new subject using public key and namespace.
|
||||
// Must be invoked by contract owner.
|
||||
func (c Client) CreateSubject(key *keys.PublicKey) (tx util.Uint256, vub uint32, err error) {
|
||||
method, args := c.CreateSubjectCall(key)
|
||||
func (c Client) CreateSubject(ns string, key *keys.PublicKey) (tx util.Uint256, vub uint32, err error) {
|
||||
method, args := c.CreateSubjectCall(ns, key)
|
||||
return c.act.SendCall(c.contract, method, args...)
|
||||
}
|
||||
|
||||
// CreateSubjectCall provides args for CreateSubject to use in commonclient.Transaction.
|
||||
func (c Client) CreateSubjectCall(key *keys.PublicKey) (method string, args []any) {
|
||||
return createSubjectMethod, []any{key.Bytes()}
|
||||
func (c Client) CreateSubjectCall(ns string, key *keys.PublicKey) (method string, args []any) {
|
||||
return createSubjectMethod, []any{ns, key.Bytes()}
|
||||
}
|
||||
|
||||
// GetSubject gets subject by address.
|
||||
|
@ -366,30 +364,6 @@ func (c Client) ListNamespaces() ([]*Namespace, error) {
|
|||
return parseNamespaces(items)
|
||||
}
|
||||
|
||||
// AddSubjectToNamespace adds a subject to namespace.
|
||||
// Must be invoked by contract owner.
|
||||
func (c Client) AddSubjectToNamespace(addr util.Uint160, namespace string) (tx util.Uint256, vub uint32, err error) {
|
||||
method, args := c.AddSubjectToNamespaceCall(addr, namespace)
|
||||
return c.act.SendCall(c.contract, method, args...)
|
||||
}
|
||||
|
||||
// AddSubjectToNamespaceCall provides args for AddSubjectToNamespace to use in commonclient.Transaction.
|
||||
func (c Client) AddSubjectToNamespaceCall(addr util.Uint160, namespace string) (method string, args []any) {
|
||||
return addSubjectToNamespaceMethod, []any{addr, namespace}
|
||||
}
|
||||
|
||||
// RemoveSubjectFromNamespace removes a subject from namespace.
|
||||
// Must be invoked by contract owner.
|
||||
func (c Client) RemoveSubjectFromNamespace(addr util.Uint160) (tx util.Uint256, vub uint32, err error) {
|
||||
method, args := c.RemoveSubjectFromNamespaceCall(addr)
|
||||
return c.act.SendCall(c.contract, method, args...)
|
||||
}
|
||||
|
||||
// RemoveSubjectFromNamespaceCall provides args for RemoveSubjectFromNamespace to use in commonclient.Transaction.
|
||||
func (c Client) RemoveSubjectFromNamespaceCall(addr util.Uint160) (method string, args []any) {
|
||||
return removeSubjectFromNamespaceMethod, []any{addr}
|
||||
}
|
||||
|
||||
// ListNamespaceSubjects gets all subjects from namespace.
|
||||
func (c Client) ListNamespaceSubjects(namespace string) ([]util.Uint160, error) {
|
||||
return unwrapArrayOfUint160(commonclient.ReadIteratorItems(c.act, iteratorBatchSize, c.contract, listNamespaceSubjectsMethod, namespace))
|
||||
|
|
|
@ -85,6 +85,7 @@ func _deploy(data any, isUpdate bool) {
|
|||
}
|
||||
|
||||
storage.Put(ctx, groupCounterKey, 0)
|
||||
storage.Put(ctx, namespaceKey(""), std.Serialize(Namespace{}))
|
||||
|
||||
runtime.Log("frostfsid contract initialized")
|
||||
}
|
||||
|
@ -128,7 +129,7 @@ func Version() int {
|
|||
return common.Version
|
||||
}
|
||||
|
||||
func CreateSubject(key interop.PublicKey) {
|
||||
func CreateSubject(ns string, key interop.PublicKey) {
|
||||
ctx := storage.GetContext()
|
||||
checkContractOwner(ctx)
|
||||
|
||||
|
@ -149,11 +150,22 @@ func CreateSubject(key interop.PublicKey) {
|
|||
panic("key is occupied")
|
||||
}
|
||||
|
||||
nsKey := namespaceKey(ns)
|
||||
data = storage.Get(ctx, nsKey).([]byte)
|
||||
if data == nil {
|
||||
panic("namespace not found")
|
||||
}
|
||||
|
||||
subj := Subject{
|
||||
PrimaryKey: key,
|
||||
Namespace: ns,
|
||||
}
|
||||
|
||||
storage.Put(ctx, sKey, std.Serialize(subj))
|
||||
|
||||
nsSubjKey := namespaceSubjectKey(ns, addr)
|
||||
storage.Put(ctx, nsSubjKey, []byte{1})
|
||||
|
||||
runtime.Notify("CreateSubject", interop.Hash160(addr))
|
||||
}
|
||||
|
||||
|
@ -315,9 +327,7 @@ func DeleteSubject(addr interop.Hash160) {
|
|||
}
|
||||
storage.Delete(ctx, sKey)
|
||||
|
||||
if subj.Namespace != "" {
|
||||
removeSubjectFromNamespace(ctx, subj.Namespace, addr)
|
||||
}
|
||||
removeSubjectFromNamespace(ctx, subj.Namespace, addr)
|
||||
deleteNamespaceSubjectName(ctx, subj.Namespace, subj.Name)
|
||||
|
||||
runtime.Notify("DeleteSubject", addr)
|
||||
|
@ -339,33 +349,21 @@ func GetSubject(addr interop.Hash160) Subject {
|
|||
}
|
||||
|
||||
func GetSubjectExtended(addr interop.Hash160) SubjectExtended {
|
||||
if len(addr) != interop.Hash160Len {
|
||||
panic("incorrect address length")
|
||||
}
|
||||
|
||||
subj := GetSubject(addr)
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
sKey := subjectKeyFromAddr(addr)
|
||||
data := storage.Get(ctx, sKey).([]byte)
|
||||
if data == nil {
|
||||
panic("subject not found")
|
||||
}
|
||||
|
||||
subj := std.Deserialize(data).(Subject)
|
||||
|
||||
var groups []Group
|
||||
if subj.Namespace != "" {
|
||||
nsHash := ripemd160Hash(subj.Namespace)
|
||||
it := storage.Find(ctx, groupPrefixFromHash(nsHash), storage.KeysOnly|storage.RemovePrefix)
|
||||
for iterator.Next(it) {
|
||||
groupHash := iterator.Value(it).([]byte)
|
||||
data = storage.Get(ctx, groupSubjectKeyFromHashes(nsHash, groupHash, addr)).([]byte)
|
||||
if data != nil {
|
||||
data = storage.Get(ctx, groupKeyFromHashes(nsHash, groupHash)).([]byte)
|
||||
if data == nil {
|
||||
panic("group not found")
|
||||
}
|
||||
groups = append(groups, std.Deserialize(data).(Group))
|
||||
nsHash := ripemd160Hash(subj.Namespace)
|
||||
it := storage.Find(ctx, groupPrefixFromHash(nsHash), storage.KeysOnly|storage.RemovePrefix)
|
||||
for iterator.Next(it) {
|
||||
groupHash := iterator.Value(it).([]byte)
|
||||
data := storage.Get(ctx, groupSubjectKeyFromHashes(nsHash, groupHash, addr)).([]byte)
|
||||
if data != nil {
|
||||
data = storage.Get(ctx, groupKeyFromHashes(nsHash, groupHash)).([]byte)
|
||||
if data == nil {
|
||||
panic("group not found")
|
||||
}
|
||||
groups = append(groups, std.Deserialize(data).(Group))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -410,8 +408,8 @@ func GetSubjectByKey(key interop.PublicKey) Subject {
|
|||
}
|
||||
|
||||
func GetSubjectKeyByName(ns, name string) interop.PublicKey {
|
||||
if ns == "" || name == "" {
|
||||
panic("invalid namespace or name")
|
||||
if name == "" {
|
||||
panic("invalid or name")
|
||||
}
|
||||
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
|
@ -434,10 +432,6 @@ func CreateNamespace(ns string) {
|
|||
ctx := storage.GetContext()
|
||||
checkContractOwner(ctx)
|
||||
|
||||
if ns == "" {
|
||||
panic("invalid namespace name")
|
||||
}
|
||||
|
||||
nsKey := namespaceKey(ns)
|
||||
data := storage.Get(ctx, nsKey).([]byte)
|
||||
if data != nil {
|
||||
|
@ -494,76 +488,6 @@ func ListNamespaces() iterator.Iterator {
|
|||
return storage.Find(ctx, []byte{namespaceKeysPrefix}, storage.ValuesOnly|storage.DeserializeValues)
|
||||
}
|
||||
|
||||
func AddSubjectToNamespace(addr interop.Hash160, ns string) {
|
||||
ctx := storage.GetContext()
|
||||
checkContractOwner(ctx)
|
||||
|
||||
if ns == "" {
|
||||
panic("invalid namespace name")
|
||||
}
|
||||
|
||||
if len(addr) != interop.Hash160Len {
|
||||
panic("invalid address length")
|
||||
}
|
||||
|
||||
sKey := subjectKeyFromAddr(addr)
|
||||
data := storage.Get(ctx, sKey).([]byte)
|
||||
if data == nil {
|
||||
panic("subject not found")
|
||||
}
|
||||
subject := std.Deserialize(data).(Subject)
|
||||
|
||||
if subject.Namespace == ns {
|
||||
panic("subject already added")
|
||||
}
|
||||
if subject.Namespace != "" {
|
||||
panic("subject cannot be moved to another namespace")
|
||||
}
|
||||
|
||||
subject.Namespace = ns
|
||||
storage.Put(ctx, sKey, std.Serialize(subject))
|
||||
|
||||
data = storage.Get(ctx, namespaceKey(ns)).([]byte)
|
||||
if data == nil {
|
||||
panic("namespace not found")
|
||||
}
|
||||
|
||||
nsSubjKey := namespaceSubjectKey(ns, addr)
|
||||
storage.Put(ctx, nsSubjKey, []byte{1})
|
||||
|
||||
setNamespaceSubjectName(ctx, subject)
|
||||
|
||||
runtime.Notify("AddSubjectToNamespace", addr, ns)
|
||||
}
|
||||
|
||||
func RemoveSubjectFromNamespace(addr interop.Hash160) {
|
||||
ctx := storage.GetContext()
|
||||
checkContractOwner(ctx)
|
||||
|
||||
if len(addr) != interop.Hash160Len {
|
||||
panic("invalid address length")
|
||||
}
|
||||
|
||||
sKey := subjectKeyFromAddr(addr)
|
||||
data := storage.Get(ctx, sKey).([]byte)
|
||||
if data == nil {
|
||||
panic("subject not found")
|
||||
}
|
||||
subject := std.Deserialize(data).(Subject)
|
||||
|
||||
if subject.Namespace == "" {
|
||||
panic("subject does not belong to any namespace")
|
||||
}
|
||||
|
||||
removeSubjectFromNamespace(ctx, subject.Namespace, addr)
|
||||
deleteNamespaceSubjectName(ctx, subject.Namespace, subject.Name)
|
||||
|
||||
subject.Namespace = ""
|
||||
storage.Put(ctx, sKey, std.Serialize(subject))
|
||||
|
||||
runtime.Notify("RemoveSubjectFromNamespace", addr, subject.Namespace)
|
||||
}
|
||||
|
||||
func ListNamespaceSubjects(ns string) iterator.Iterator {
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
return storage.Find(ctx, namespaceSubjectPrefix(ns), storage.KeysOnly|storage.RemovePrefix)
|
||||
|
@ -573,9 +497,6 @@ func CreateGroup(ns, group string) int {
|
|||
ctx := storage.GetContext()
|
||||
checkContractOwner(ctx)
|
||||
|
||||
if ns == "" {
|
||||
panic("invalid namespace name")
|
||||
}
|
||||
if group == "" {
|
||||
panic("invalid group name")
|
||||
}
|
||||
|
@ -643,8 +564,8 @@ func GetGroupExtended(ns string, groupID int) GroupExtended {
|
|||
}
|
||||
|
||||
func GetGroupIDByName(ns, name string) int {
|
||||
if ns == "" || name == "" {
|
||||
panic("invalid namespace or name")
|
||||
if name == "" {
|
||||
panic("invalid name")
|
||||
}
|
||||
|
||||
ctx := storage.GetReadOnlyContext()
|
||||
|
@ -735,18 +656,16 @@ func AddSubjectToGroup(addr interop.Hash160, groupID int) {
|
|||
}
|
||||
subject := std.Deserialize(data).(Subject)
|
||||
|
||||
if subject.Namespace == "" {
|
||||
panic("subject does not belong to any namespace")
|
||||
}
|
||||
|
||||
nSubjKey := namespaceSubjectKey(subject.Namespace, addr)
|
||||
storage.Put(ctx, nSubjKey, []byte{1})
|
||||
|
||||
gKey := groupKey(subject.Namespace, groupID)
|
||||
data = storage.Get(ctx, gKey).([]byte)
|
||||
if data == nil {
|
||||
panic("group not found")
|
||||
}
|
||||
group := std.Deserialize(data).(Group)
|
||||
|
||||
if group.Namespace != subject.Namespace {
|
||||
panic("subject and group must be in the same namespace")
|
||||
}
|
||||
|
||||
gsKey := groupSubjectKey(subject.Namespace, groupID, addr)
|
||||
storage.Put(ctx, gsKey, []byte{1})
|
||||
|
@ -769,15 +688,17 @@ func RemoveSubjectFromGroup(addr interop.Hash160, groupID int) {
|
|||
}
|
||||
|
||||
subject := std.Deserialize(data).(Subject)
|
||||
if subject.Namespace == "" {
|
||||
panic("subject doesn't belong to any namespace")
|
||||
}
|
||||
|
||||
gKey := groupKey(subject.Namespace, groupID)
|
||||
data = storage.Get(ctx, gKey).([]byte)
|
||||
if data == nil {
|
||||
panic("group not found")
|
||||
}
|
||||
group := std.Deserialize(data).(Group)
|
||||
|
||||
if group.Namespace != subject.Namespace {
|
||||
panic("subject and group must be in the same namespace")
|
||||
}
|
||||
|
||||
gsKey := groupSubjectKey(subject.Namespace, groupID, addr)
|
||||
storage.Delete(ctx, gsKey)
|
||||
|
|
|
@ -336,28 +336,6 @@ func (c *Contract) AddSubjectToGroupUnsigned(addr util.Uint160, groupID *big.Int
|
|||
return c.actor.MakeUnsignedCall(c.hash, "addSubjectToGroup", nil, addr, groupID)
|
||||
}
|
||||
|
||||
// AddSubjectToNamespace creates a transaction invoking `addSubjectToNamespace` method of the contract.
|
||||
// This transaction is signed and immediately sent to the network.
|
||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||
func (c *Contract) AddSubjectToNamespace(addr util.Uint160, ns string) (util.Uint256, uint32, error) {
|
||||
return c.actor.SendCall(c.hash, "addSubjectToNamespace", addr, ns)
|
||||
}
|
||||
|
||||
// AddSubjectToNamespaceTransaction creates a transaction invoking `addSubjectToNamespace` method of the contract.
|
||||
// This transaction is signed, but not sent to the network, instead it's
|
||||
// returned to the caller.
|
||||
func (c *Contract) AddSubjectToNamespaceTransaction(addr util.Uint160, ns string) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeCall(c.hash, "addSubjectToNamespace", addr, ns)
|
||||
}
|
||||
|
||||
// AddSubjectToNamespaceUnsigned creates a transaction invoking `addSubjectToNamespace` method of the contract.
|
||||
// This transaction is not signed, it's simply returned to the caller.
|
||||
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
||||
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
||||
func (c *Contract) AddSubjectToNamespaceUnsigned(addr util.Uint160, ns string) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeUnsignedCall(c.hash, "addSubjectToNamespace", nil, addr, ns)
|
||||
}
|
||||
|
||||
// ClearAdmin creates a transaction invoking `clearAdmin` method of the contract.
|
||||
// This transaction is signed and immediately sent to the network.
|
||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||
|
@ -427,23 +405,23 @@ func (c *Contract) CreateNamespaceUnsigned(ns string) (*transaction.Transaction,
|
|||
// CreateSubject creates a transaction invoking `createSubject` method of the contract.
|
||||
// This transaction is signed and immediately sent to the network.
|
||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||
func (c *Contract) CreateSubject(key *keys.PublicKey) (util.Uint256, uint32, error) {
|
||||
return c.actor.SendCall(c.hash, "createSubject", key)
|
||||
func (c *Contract) CreateSubject(ns string, key *keys.PublicKey) (util.Uint256, uint32, error) {
|
||||
return c.actor.SendCall(c.hash, "createSubject", ns, key)
|
||||
}
|
||||
|
||||
// CreateSubjectTransaction creates a transaction invoking `createSubject` method of the contract.
|
||||
// This transaction is signed, but not sent to the network, instead it's
|
||||
// returned to the caller.
|
||||
func (c *Contract) CreateSubjectTransaction(key *keys.PublicKey) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeCall(c.hash, "createSubject", key)
|
||||
func (c *Contract) CreateSubjectTransaction(ns string, key *keys.PublicKey) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeCall(c.hash, "createSubject", ns, key)
|
||||
}
|
||||
|
||||
// CreateSubjectUnsigned creates a transaction invoking `createSubject` method of the contract.
|
||||
// This transaction is not signed, it's simply returned to the caller.
|
||||
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
||||
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
||||
func (c *Contract) CreateSubjectUnsigned(key *keys.PublicKey) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeUnsignedCall(c.hash, "createSubject", nil, key)
|
||||
func (c *Contract) CreateSubjectUnsigned(ns string, key *keys.PublicKey) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeUnsignedCall(c.hash, "createSubject", nil, ns, key)
|
||||
}
|
||||
|
||||
// DeleteGroup creates a transaction invoking `deleteGroup` method of the contract.
|
||||
|
@ -556,28 +534,6 @@ func (c *Contract) RemoveSubjectFromGroupUnsigned(addr util.Uint160, groupID *bi
|
|||
return c.actor.MakeUnsignedCall(c.hash, "removeSubjectFromGroup", nil, addr, groupID)
|
||||
}
|
||||
|
||||
// RemoveSubjectFromNamespace creates a transaction invoking `removeSubjectFromNamespace` method of the contract.
|
||||
// This transaction is signed and immediately sent to the network.
|
||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||
func (c *Contract) RemoveSubjectFromNamespace(addr util.Uint160) (util.Uint256, uint32, error) {
|
||||
return c.actor.SendCall(c.hash, "removeSubjectFromNamespace", addr)
|
||||
}
|
||||
|
||||
// RemoveSubjectFromNamespaceTransaction creates a transaction invoking `removeSubjectFromNamespace` method of the contract.
|
||||
// This transaction is signed, but not sent to the network, instead it's
|
||||
// returned to the caller.
|
||||
func (c *Contract) RemoveSubjectFromNamespaceTransaction(addr util.Uint160) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeCall(c.hash, "removeSubjectFromNamespace", addr)
|
||||
}
|
||||
|
||||
// RemoveSubjectFromNamespaceUnsigned creates a transaction invoking `removeSubjectFromNamespace` method of the contract.
|
||||
// This transaction is not signed, it's simply returned to the caller.
|
||||
// Any fields of it that do not affect fees can be changed (ValidUntilBlock,
|
||||
// Nonce), fee values (NetworkFee, SystemFee) can be increased as well.
|
||||
func (c *Contract) RemoveSubjectFromNamespaceUnsigned(addr util.Uint160) (*transaction.Transaction, error) {
|
||||
return c.actor.MakeUnsignedCall(c.hash, "removeSubjectFromNamespace", nil, addr)
|
||||
}
|
||||
|
||||
// RemoveSubjectKey creates a transaction invoking `removeSubjectKey` method of the contract.
|
||||
// This transaction is signed and immediately sent to the network.
|
||||
// The values returned are its hash, ValidUntilBlock value and error if any.
|
||||
|
|
|
@ -11,6 +11,7 @@ import (
|
|||
"git.frostfs.info/TrueCloudLab/frostfs-contract/frostfsid/client"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient"
|
||||
"github.com/nspcc-dev/neo-go/pkg/rpcclient/unwrap"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util"
|
||||
"github.com/nspcc-dev/neo-go/pkg/vm/stackitem"
|
||||
"github.com/nspcc-dev/neo-go/pkg/wallet"
|
||||
|
@ -115,7 +116,7 @@ func TestFrostFSID_Client_SubjectManagement(t *testing.T) {
|
|||
subjLogin := "subj-login"
|
||||
iamPathKV := "iam/path"
|
||||
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(subjKey.PublicKey()))
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(defaultNamespace, subjKey.PublicKey()))
|
||||
ffsid.a.await(ffsid.cli.SetSubjectName(subjAddr, subjLogin))
|
||||
ffsid.a.await(ffsid.cli.SetSubjectKV(subjAddr, client.IAMPathKey, iamPathKV))
|
||||
ffsid.a.await(ffsid.cli.AddSubjectKey(subjAddr, extraKey.PublicKey()))
|
||||
|
@ -157,25 +158,22 @@ func TestFrostFSID_Client_NamespaceManagement(t *testing.T) {
|
|||
ffsid, cancel := initFrostfsIFClientTest(t)
|
||||
defer cancel()
|
||||
|
||||
subjKey, subjAddr := newKey(t)
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(subjKey.PublicKey()))
|
||||
|
||||
namespace := "namespace"
|
||||
subjKey, subjAddr := newKey(t)
|
||||
|
||||
ffsid.a.await(ffsid.cli.CreateNamespace(namespace))
|
||||
_, _, err := ffsid.cli.CreateNamespace(namespace)
|
||||
require.ErrorContains(t, err, "already exists")
|
||||
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(namespace, subjKey.PublicKey()))
|
||||
|
||||
ns, err := ffsid.cli.GetNamespace(namespace)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, namespace, ns.Name)
|
||||
|
||||
namespaces, err := ffsid.cli.ListNamespaces()
|
||||
require.NoError(t, err)
|
||||
require.ElementsMatch(t, []*client.Namespace{ns}, namespaces)
|
||||
|
||||
ffsid.a.await(ffsid.cli.AddSubjectToNamespace(subjAddr, namespace))
|
||||
_, _, err = ffsid.cli.AddSubjectToNamespace(subjAddr, namespace)
|
||||
require.ErrorContains(t, err, "already added")
|
||||
require.ElementsMatch(t, []*client.Namespace{{}, ns}, namespaces)
|
||||
|
||||
subj, err := ffsid.cli.GetSubject(subjAddr)
|
||||
require.NoError(t, err)
|
||||
|
@ -185,26 +183,57 @@ func TestFrostFSID_Client_NamespaceManagement(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.ElementsMatch(t, []util.Uint160{subjAddr}, subjects)
|
||||
|
||||
ffsid.a.await(ffsid.cli.RemoveSubjectFromNamespace(subjAddr))
|
||||
|
||||
subj, err = ffsid.cli.GetSubject(subjAddr)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, subj.Namespace)
|
||||
ffsid.a.await(ffsid.cli.DeleteSubject(subjAddr))
|
||||
|
||||
subjects, err = ffsid.cli.ListNamespaceSubjects(namespace)
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, subjects)
|
||||
}
|
||||
|
||||
func TestFrostFSID_Client_DefaultNamespace(t *testing.T) {
|
||||
ffsid, cancel := initFrostfsIFClientTest(t)
|
||||
defer cancel()
|
||||
|
||||
group := "group"
|
||||
subjKey, subjAddr := newKey(t)
|
||||
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(defaultNamespace, subjKey.PublicKey()))
|
||||
groupID, err := ffsid.cli.ParseGroupID(ffsid.cli.Wait(ffsid.cli.CreateGroup(defaultNamespace, group)))
|
||||
require.NoError(t, err)
|
||||
ffsid.a.await(ffsid.cli.AddSubjectToGroup(subjAddr, groupID))
|
||||
|
||||
namespaces, err := ffsid.cli.ListNamespaces()
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, []*client.Namespace{{}}, namespaces)
|
||||
|
||||
groups, err := ffsid.cli.ListGroups(defaultNamespace)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, []*client.Group{{ID: groupID, Name: group, Namespace: defaultNamespace}}, groups)
|
||||
|
||||
subjects, err := ffsid.cli.ListNamespaceSubjects(defaultNamespace)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, []util.Uint160{subjAddr}, subjects)
|
||||
|
||||
subjects, err = ffsid.cli.ListGroupSubjects(defaultNamespace, groupID)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, []util.Uint160{subjAddr}, subjects)
|
||||
|
||||
subject, err := ffsid.cli.GetSubjectExtended(subjAddr)
|
||||
require.NoError(t, err)
|
||||
require.True(t, subjKey.PublicKey().Equal(subject.PrimaryKey))
|
||||
require.Equal(t, defaultNamespace, subject.Namespace)
|
||||
require.EqualValues(t, []*client.Group{{ID: groupID, Name: group, Namespace: defaultNamespace}}, subject.Groups)
|
||||
}
|
||||
|
||||
func TestFrostFSID_Client_GroupManagement(t *testing.T) {
|
||||
ffsid, cancel := initFrostfsIFClientTest(t)
|
||||
defer cancel()
|
||||
|
||||
subjKey, subjAddr := newKey(t)
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(subjKey.PublicKey()))
|
||||
|
||||
namespace := "namespace"
|
||||
subjKey, subjAddr := newKey(t)
|
||||
|
||||
ffsid.a.await(ffsid.cli.CreateNamespace(namespace))
|
||||
ffsid.a.await(ffsid.cli.CreateSubject(namespace, subjKey.PublicKey()))
|
||||
|
||||
groupName := "group"
|
||||
groupID := int64(1)
|
||||
|
@ -229,7 +258,6 @@ func TestFrostFSID_Client_GroupManagement(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
require.Zero(t, groupExt.SubjectsCount)
|
||||
|
||||
ffsid.a.await(ffsid.cli.AddSubjectToNamespace(subjAddr, namespace))
|
||||
ffsid.a.await(ffsid.cli.AddSubjectToGroup(subjAddr, groupID))
|
||||
|
||||
subjExt, err := ffsid.cli.GetSubjectExtended(subjAddr)
|
||||
|
@ -276,73 +304,17 @@ func TestFrostFSID_Client_Lists(t *testing.T) {
|
|||
ffsid, cancel := initFrostfsIFClientTest(t)
|
||||
defer cancel()
|
||||
|
||||
namespaces := []string{"empty-ns0", "ns1", "ns2", "ns3"}
|
||||
namespaces := append([]string{defaultNamespace}, createNamespaces(t, ffsid, 3)...)
|
||||
|
||||
tx := ffsid.cli.StartTx()
|
||||
for _, namespace := range namespaces {
|
||||
err := tx.WrapCall(ffsid.cli.CreateNamespaceCall(namespace))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
subjects := createSubjectsInNS(t, ffsid, namespaces[1], 3)
|
||||
subjects = append(subjects, createSubjectsInNS(t, ffsid, namespaces[2], 2)...)
|
||||
subjects = append(subjects, createSubjectsInNS(t, ffsid, namespaces[3], 5)...)
|
||||
|
||||
subjects := make([]testSubject, 10)
|
||||
tx = ffsid.cli.StartTx()
|
||||
for i := range subjects {
|
||||
subjects[i].key, subjects[i].addr = newKey(t)
|
||||
err := tx.WrapCall(ffsid.cli.CreateSubjectCall(subjects[i].key.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
groups := createGroupsInNS(t, ffsid, namespaces[0], 1)
|
||||
groups = append(groups, createGroupsInNS(t, ffsid, namespaces[1], 2)...)
|
||||
groups = append(groups, createGroupsInNS(t, ffsid, namespaces[2], 1)...)
|
||||
groups = append(groups, createGroupsInNS(t, ffsid, namespaces[3], 2)...)
|
||||
|
||||
groups := []client.Group{
|
||||
{
|
||||
ID: 1,
|
||||
Name: "empty-group0",
|
||||
Namespace: namespaces[0],
|
||||
},
|
||||
{
|
||||
ID: 2,
|
||||
Name: "empty-group1",
|
||||
Namespace: namespaces[1],
|
||||
},
|
||||
{
|
||||
ID: 3,
|
||||
Name: "group2",
|
||||
Namespace: namespaces[1],
|
||||
},
|
||||
{
|
||||
ID: 4,
|
||||
Name: "group3",
|
||||
Namespace: namespaces[2],
|
||||
},
|
||||
{
|
||||
ID: 5,
|
||||
Name: "group4",
|
||||
Namespace: namespaces[3],
|
||||
},
|
||||
{
|
||||
ID: 6,
|
||||
Name: "group5",
|
||||
Namespace: namespaces[3],
|
||||
},
|
||||
}
|
||||
|
||||
tx = ffsid.cli.StartTx()
|
||||
for _, group := range groups[:3] {
|
||||
err := tx.WrapCall(ffsid.cli.CreateGroupCall(group.Namespace, group.Name))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
|
||||
// we split into two tx because of gas limit exceeded error
|
||||
tx = ffsid.cli.StartTx()
|
||||
for _, group := range groups[3:] {
|
||||
err := tx.WrapCall(ffsid.cli.CreateGroupCall(group.Namespace, group.Name))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
|
||||
addSubjectsToNamespaces(t, ffsid, namespaces, subjects)
|
||||
addSubjectsToGroups(t, ffsid, groups, subjects)
|
||||
|
||||
nsList, err := ffsid.cli.ListNamespaces()
|
||||
|
@ -370,29 +342,55 @@ func TestFrostFSID_Client_Lists(t *testing.T) {
|
|||
checkGroupSubjects(t, ffsid.cli, groups[5], subjects, 8, 10)
|
||||
}
|
||||
|
||||
func addSubjectsToNamespaces(t *testing.T, ffsid *testFrostFSIDClientInvoker, namespaces []string, subjects []testSubject) {
|
||||
cli := ffsid.cli
|
||||
func createSubjectsInNS(t *testing.T, ffsid *testFrostFSIDClientInvoker, ns string, count int) []testSubject {
|
||||
subjects := make([]testSubject, count)
|
||||
|
||||
tx := cli.StartTx()
|
||||
for _, subject := range subjects[:3] {
|
||||
err := tx.WrapCall(cli.AddSubjectToNamespaceCall(subject.addr, namespaces[1]))
|
||||
tx := ffsid.cli.StartTx()
|
||||
for i := range subjects {
|
||||
subjects[i].key, subjects[i].addr = newKey(t)
|
||||
err := tx.WrapCall(ffsid.cli.CreateSubjectCall(ns, subjects[i].key.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(cli.SendTx(tx))
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
|
||||
tx = cli.StartTx()
|
||||
for _, subject := range subjects[3:5] {
|
||||
err := tx.WrapCall(cli.AddSubjectToNamespaceCall(subject.addr, namespaces[2]))
|
||||
return subjects
|
||||
}
|
||||
|
||||
func createGroupsInNS(t *testing.T, ffsid *testFrostFSIDClientInvoker, ns string, count int) []client.Group {
|
||||
groups := make([]client.Group, count)
|
||||
|
||||
tx := ffsid.cli.StartTx()
|
||||
for i := range groups {
|
||||
groups[i].Namespace = ns
|
||||
groups[i].Name = ns + "/group" + strconv.Itoa(i+1)
|
||||
|
||||
err := tx.WrapCall(ffsid.cli.CreateGroupCall(ns, groups[i].Name))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(cli.SendTx(tx))
|
||||
res := ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
|
||||
tx = cli.StartTx()
|
||||
for _, subject := range subjects[5:] {
|
||||
err := tx.WrapCall(cli.AddSubjectToNamespaceCall(subject.addr, namespaces[3]))
|
||||
ids, err := unwrap.ArrayOfBigInts(makeValidRes(stackitem.NewArray(res.Stack)), nil)
|
||||
require.NoError(t, err)
|
||||
|
||||
for i, id := range ids {
|
||||
groups[i].ID = id.Int64()
|
||||
}
|
||||
|
||||
return groups
|
||||
}
|
||||
|
||||
func createNamespaces(t *testing.T, ffsid *testFrostFSIDClientInvoker, count int) []string {
|
||||
namespaces := make([]string, count)
|
||||
|
||||
tx := ffsid.cli.StartTx()
|
||||
for i := range namespaces {
|
||||
namespaces[i] = "ns" + strconv.Itoa(i+1)
|
||||
err := tx.WrapCall(ffsid.cli.CreateNamespaceCall(namespaces[i]))
|
||||
require.NoError(t, err)
|
||||
}
|
||||
ffsid.a.await(cli.SendTx(tx))
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
|
||||
return namespaces
|
||||
}
|
||||
|
||||
func addSubjectsToGroups(t *testing.T, ffsid *testFrostFSIDClientInvoker, groups []client.Group, subjects []testSubject) {
|
||||
|
@ -457,14 +455,12 @@ func TestFrostFSID_Client_UseCaseWithS3GW(t *testing.T) {
|
|||
tx := ffsid.cli.StartTx()
|
||||
err := tx.WrapCall(ffsid.cli.CreateNamespaceCall(namespace))
|
||||
require.NoError(t, err)
|
||||
err = tx.WrapCall(ffsid.cli.CreateSubjectCall(dataUserKey.PublicKey()))
|
||||
err = tx.WrapCall(ffsid.cli.CreateSubjectCall(namespace, dataUserKey.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
err = tx.WrapCall(ffsid.cli.SetSubjectNameCall(dataUserAddr, login))
|
||||
require.NoError(t, err)
|
||||
err = tx.WrapCall(ffsid.cli.AddSubjectKeyCall(dataUserAddr, extraDataUserKey.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
err = tx.WrapCall(ffsid.cli.AddSubjectToNamespaceCall(dataUserAddr, namespace))
|
||||
require.NoError(t, err)
|
||||
ffsid.a.await(ffsid.cli.SendTx(tx))
|
||||
|
||||
// s3-gw
|
||||
|
@ -497,12 +493,10 @@ func TestFrostFSID_Client_UseCaseListNSSubjects(t *testing.T) {
|
|||
for i := range subjects {
|
||||
tx = ffsid.cli.StartTx()
|
||||
subjects[i].key, subjects[i].addr = newKey(t)
|
||||
err = tx.WrapCall(ffsid.cli.CreateSubjectCall(subjects[i].key.PublicKey()))
|
||||
err = tx.WrapCall(ffsid.cli.CreateSubjectCall(namespace, subjects[i].key.PublicKey()))
|
||||
require.NoError(t, err)
|
||||
err = tx.WrapCall(ffsid.cli.SetSubjectNameCall(subjects[i].addr, "login"+strconv.Itoa(i)))
|
||||
require.NoError(t, err)
|
||||
err = tx.WrapCall(ffsid.cli.AddSubjectToNamespaceCall(subjects[i].addr, namespace))
|
||||
require.NoError(t, err)
|
||||
|
||||
if i > len(subjects)/2 {
|
||||
err = tx.WrapCall(ffsid.cli.AddSubjectToGroupCall(subjects[i].addr, groupID))
|
||||
|
|
|
@ -22,6 +22,8 @@ import (
|
|||
|
||||
const frostfsidPath = "../frostfsid"
|
||||
|
||||
const defaultNamespace = ""
|
||||
|
||||
const (
|
||||
setAdminMethod = "setAdmin"
|
||||
getAdminMethod = "getAdmin"
|
||||
|
@ -39,13 +41,11 @@ const (
|
|||
deleteSubjectKVMethod = "deleteSubjectKV"
|
||||
deleteSubjectMethod = "deleteSubject"
|
||||
|
||||
createNamespaceMethod = "createNamespace"
|
||||
getNamespaceMethod = "getNamespace"
|
||||
getNamespaceExtendedMethod = "getNamespaceExtended"
|
||||
listNamespacesMethod = "listNamespaces"
|
||||
addSubjectToNamespaceMethod = "addSubjectToNamespace"
|
||||
removeSubjectFromNamespaceMethod = "removeSubjectFromNamespace"
|
||||
listNamespaceSubjectsMethod = "listNamespaceSubjects"
|
||||
createNamespaceMethod = "createNamespace"
|
||||
getNamespaceMethod = "getNamespace"
|
||||
getNamespaceExtendedMethod = "getNamespaceExtended"
|
||||
listNamespacesMethod = "listNamespaces"
|
||||
listNamespaceSubjectsMethod = "listNamespaceSubjects"
|
||||
|
||||
createGroupMethod = "createGroup"
|
||||
getGroupMethod = "getGroup"
|
||||
|
@ -174,6 +174,26 @@ func checkOwner(t *testing.T, invoker *neotest.ContractInvoker, owner ...util.Ui
|
|||
require.Equal(t, bs, owner[0].BytesBE())
|
||||
}
|
||||
|
||||
func TestFrostFSID_DefaultNamespace(t *testing.T) {
|
||||
f := newFrostFSIDInvoker(t)
|
||||
|
||||
subjKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
subjKeyAddr := subjKey.PublicKey().GetScriptHash()
|
||||
|
||||
invoker := f.OwnerInvoker()
|
||||
|
||||
groupID := int64(1)
|
||||
groupName := "group"
|
||||
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Make(groupID), createGroupMethod, defaultNamespace, groupName)
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToGroupMethod, subjKeyAddr, groupID)
|
||||
invoker.Invoke(t, stackitem.Null{}, removeSubjectFromGroupMethod, subjKeyAddr, groupID)
|
||||
invoker.Invoke(t, stackitem.Null{}, deleteGroupMethod, defaultNamespace, groupID)
|
||||
invoker.Invoke(t, stackitem.Null{}, deleteSubjectMethod, subjKeyAddr)
|
||||
}
|
||||
|
||||
func TestFrostFSID_SubjectManagement(t *testing.T) {
|
||||
f := newFrostFSIDInvoker(t)
|
||||
|
||||
|
@ -184,9 +204,9 @@ func TestFrostFSID_SubjectManagement(t *testing.T) {
|
|||
anonInvoker := f.AnonInvoker(t)
|
||||
invoker := f.OwnerInvoker()
|
||||
|
||||
anonInvoker.InvokeFail(t, notWitnessedError, createSubjectMethod, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, subjKey.PublicKey().Bytes())
|
||||
invoker.InvokeFail(t, "already exists", createSubjectMethod, subjKey.PublicKey().Bytes())
|
||||
anonInvoker.InvokeFail(t, notWitnessedError, createSubjectMethod, defaultNamespace, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, subjKey.PublicKey().Bytes())
|
||||
invoker.InvokeFail(t, "already exists", createSubjectMethod, defaultNamespace, subjKey.PublicKey().Bytes())
|
||||
|
||||
s, err := anonInvoker.TestInvoke(t, getSubjectMethod, subjKeyAddr)
|
||||
require.NoError(t, err)
|
||||
|
@ -263,7 +283,7 @@ func TestFrostFSID_SubjectManagement(t *testing.T) {
|
|||
newSubjKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, newSubjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, defaultNamespace, newSubjKey.PublicKey().Bytes())
|
||||
|
||||
s, err = anonInvoker.TestInvoke(t, listSubjectsMethod)
|
||||
require.NoError(t, err)
|
||||
|
@ -293,20 +313,22 @@ func TestFrostFSIS_SubjectNameRelatedInvariants(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
subjKeyAddr2 := subjKey2.PublicKey().GetScriptHash()
|
||||
|
||||
subjName3 := "subj3"
|
||||
subjKey3, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
subjKeyAddr3 := subjKey3.PublicKey().GetScriptHash()
|
||||
|
||||
invoker := f.OwnerInvoker()
|
||||
|
||||
ns1, ns2 := "ns1", "ns2"
|
||||
|
||||
// Create two subject (one of them with name)
|
||||
// Create two namespace.
|
||||
// Add these subjects to ns1
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, subjKey1.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, setSubjectNameMethod, subjKeyAddr1, subjName1)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, subjKey2.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createNamespaceMethod, ns1)
|
||||
invoker.Invoke(t, stackitem.Null{}, createNamespaceMethod, ns2)
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToNamespaceMethod, subjKeyAddr1, ns1)
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToNamespaceMethod, subjKeyAddr2, ns1)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, ns1, subjKey1.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, setSubjectNameMethod, subjKeyAddr1, subjName1)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, ns1, subjKey2.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, ns2, subjKey3.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, setSubjectNameMethod, subjKeyAddr3, subjName3)
|
||||
|
||||
// Check that we can find public key by name for subj1 (with name)
|
||||
// and cannot find key for subj2 (without name)
|
||||
|
@ -323,25 +345,17 @@ func TestFrostFSIS_SubjectNameRelatedInvariants(t *testing.T) {
|
|||
// Check that we cannot set for second subject name that the first subject has already taken
|
||||
invoker.InvokeFail(t, "not available", setSubjectNameMethod, subjKeyAddr2, subjName1)
|
||||
|
||||
// Check that we cannot move subject from one namespace to another
|
||||
invoker.InvokeFail(t, "cannot be moved", addSubjectToNamespaceMethod, subjKeyAddr2, ns2)
|
||||
|
||||
// Check that we cannot find public key by name for subject that was removed from namespace
|
||||
invoker.Invoke(t, stackitem.Null{}, removeSubjectFromNamespaceMethod, subjKeyAddr2)
|
||||
// Check that we cannot find public key by name for subject that was removed
|
||||
invoker.Invoke(t, stackitem.Null{}, deleteSubjectMethod, subjKeyAddr2)
|
||||
s, err = invoker.TestInvoke(t, getSubjectKeyByNameMethod, ns1, subjName2)
|
||||
checkPublicKeyResult(t, s, err, nil)
|
||||
|
||||
// Check that we can find public key by name for subject in new namespace
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToNamespaceMethod, subjKeyAddr2, ns2)
|
||||
s, err = invoker.TestInvoke(t, getSubjectKeyByNameMethod, ns2, subjName2)
|
||||
checkPublicKeyResult(t, s, err, subjKey2)
|
||||
|
||||
// Check that subj2 can have the same name as subj1 if they belong to different namespaces
|
||||
// Check that subj3 can have the same name as subj1 if they belong to different namespaces
|
||||
// Also check that after subject renaming its key cannot be found by old name
|
||||
invoker.Invoke(t, stackitem.Null{}, setSubjectNameMethod, subjKeyAddr2, subjName1)
|
||||
invoker.Invoke(t, stackitem.Null{}, setSubjectNameMethod, subjKeyAddr3, subjName1)
|
||||
s, err = invoker.TestInvoke(t, getSubjectKeyByNameMethod, ns2, subjName1)
|
||||
checkPublicKeyResult(t, s, err, subjKey2)
|
||||
s, err = invoker.TestInvoke(t, getSubjectKeyByNameMethod, ns2, subjName2)
|
||||
checkPublicKeyResult(t, s, err, subjKey3)
|
||||
s, err = invoker.TestInvoke(t, getSubjectKeyByNameMethod, ns2, subjName3)
|
||||
checkPublicKeyResult(t, s, err, nil)
|
||||
}
|
||||
|
||||
|
@ -414,16 +428,12 @@ func TestFrostFSID_NamespaceManagement(t *testing.T) {
|
|||
t.Run("add user to namespace", func(t *testing.T) {
|
||||
subjKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, ns.Name, subjKey.PublicKey().Bytes())
|
||||
|
||||
subjName := "name"
|
||||
subjAddress := subjKey.PublicKey().GetScriptHash()
|
||||
invoker.Invoke(t, stackitem.Null{}, setSubjectNameMethod, subjAddress, subjName)
|
||||
|
||||
anonInvoker.InvokeFail(t, notWitnessedError, addSubjectToNamespaceMethod, subjAddress, namespace)
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToNamespaceMethod, subjAddress, namespace)
|
||||
invoker.InvokeFail(t, "already added", addSubjectToNamespaceMethod, subjAddress, namespace)
|
||||
|
||||
s, err := anonInvoker.TestInvoke(t, getSubjectMethod, subjAddress)
|
||||
require.NoError(t, err)
|
||||
subj := parseSubject(t, s)
|
||||
|
@ -456,7 +466,7 @@ func TestFrostFSID_NamespaceManagement(t *testing.T) {
|
|||
|
||||
namespaces := parseNamespaces(t, readIteratorAll(s))
|
||||
require.NoError(t, err)
|
||||
require.ElementsMatch(t, namespaces, []Namespace{{Name: namespace}, {Name: namespace2}})
|
||||
require.ElementsMatch(t, namespaces, []Namespace{{Name: defaultNamespace}, {Name: namespace}, {Name: namespace2}})
|
||||
|
||||
t.Run("find namespaces with some subjects", func(t *testing.T) {
|
||||
for _, ns := range namespaces {
|
||||
|
@ -468,21 +478,6 @@ func TestFrostFSID_NamespaceManagement(t *testing.T) {
|
|||
require.Equal(t, namespace, nsExt.Name)
|
||||
}
|
||||
}
|
||||
|
||||
t.Run("remove subject from namespace", func(t *testing.T) {
|
||||
anonInvoker.InvokeFail(t, notWitnessedError, removeSubjectFromNamespaceMethod, subjAddress)
|
||||
invoker.Invoke(t, stackitem.Null{}, removeSubjectFromNamespaceMethod, subjAddress)
|
||||
|
||||
s, err := anonInvoker.TestInvoke(t, getSubjectMethod, subjAddress)
|
||||
require.NoError(t, err)
|
||||
subj := parseSubject(t, s)
|
||||
require.Empty(t, subj.Namespace)
|
||||
|
||||
s, err = anonInvoker.TestInvoke(t, getNamespaceExtendedMethod, namespace)
|
||||
require.NoError(t, err)
|
||||
nsExt := parseNamespaceExtended(t, s.Pop().Item())
|
||||
require.Zero(t, nsExt.SubjectsCount)
|
||||
})
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -516,10 +511,9 @@ func TestFrostFSID_GroupManagement(t *testing.T) {
|
|||
t.Run("add subjects to group", func(t *testing.T) {
|
||||
subjKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, nsName, subjKey.PublicKey().Bytes())
|
||||
|
||||
subjAddress := subjKey.PublicKey().GetScriptHash()
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToNamespaceMethod, subjAddress, nsName)
|
||||
anonInvoker.InvokeFail(t, "not witnessed", addSubjectToGroupMethod, subjAddress, groupID)
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToGroupMethod, subjAddress, groupID)
|
||||
|
||||
|
@ -546,8 +540,7 @@ func TestFrostFSID_GroupManagement(t *testing.T) {
|
|||
for i := 0; i < subjectsCount; i++ {
|
||||
subjKey, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToNamespaceMethod, subjKey.PublicKey().GetScriptHash(), nsName)
|
||||
invoker.Invoke(t, stackitem.Null{}, createSubjectMethod, nsName, subjKey.PublicKey().Bytes())
|
||||
invoker.Invoke(t, stackitem.Null{}, addSubjectToGroupMethod, subjKey.PublicKey().GetScriptHash(), groupID)
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue