forked from TrueCloudLab/frostfs-node
[#1219] Remove Container.SetEACL method
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
74842e7f43
commit
91bed3b0ba
8 changed files with 8 additions and 338 deletions
|
@ -254,17 +254,3 @@ func (m morphContainerWriter) Put(cnr containerCore.Container) (*cid.ID, error)
|
|||
func (m morphContainerWriter) Delete(witness containerCore.RemovalWitness) error {
|
||||
return cntClient.Delete(m.neoClient, witness)
|
||||
}
|
||||
|
||||
func (m morphContainerWriter) PutEACL(eaclInfo containerCore.EACL) error {
|
||||
err := cntClient.PutEACL(m.neoClient, eaclInfo)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if m.cacheEnabled {
|
||||
id, _ := eaclInfo.Value.CID()
|
||||
m.eacls.InvalidateEACL(id)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ const (
|
|||
InterruptPlacementIterationByContext = "interrupt placement iteration by context"
|
||||
|
||||
Notification = "notification"
|
||||
|
||||
SkipDeprecatedNotification = "skip deprecated notification"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
@ -49,21 +49,6 @@ func (cp *Processor) handleDelete(ev event.Event) {
|
|||
}
|
||||
}
|
||||
|
||||
func (cp *Processor) handleSetEACL(ev event.Event) {
|
||||
e := ev.(containerEvent.SetEACL)
|
||||
|
||||
cp.log.Info(logs.Notification,
|
||||
zap.String("type", "set EACL"),
|
||||
)
|
||||
|
||||
// send an event to the worker pool
|
||||
|
||||
err := processors.SubmitEvent(cp.pool, cp.metrics, "container_set_eacl", func() bool {
|
||||
return cp.processSetEACL(e)
|
||||
})
|
||||
if err != nil {
|
||||
// there system can be moved into controlled degradation stage
|
||||
cp.log.Warn(logs.ContainerContainerProcessorWorkerPoolDrained,
|
||||
zap.Int("capacity", cp.pool.Cap()))
|
||||
}
|
||||
func (cp *Processor) handleSetEACL(_ event.Event) {
|
||||
cp.log.Warn(logs.SkipDeprecatedNotification, zap.String("type", "set EACL"))
|
||||
}
|
||||
|
|
|
@ -18,10 +18,8 @@ import (
|
|||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
frostfscrypto "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto"
|
||||
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/netmap"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/version"
|
||||
"github.com/nspcc-dev/neo-go/pkg/core/transaction"
|
||||
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
|
||||
"github.com/nspcc-dev/neo-go/pkg/network/payload"
|
||||
|
@ -159,91 +157,6 @@ func TestDeleteEvent(t *testing.T) {
|
|||
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
||||
}
|
||||
|
||||
func TestSetEACLEvent(t *testing.T) {
|
||||
t.Parallel()
|
||||
nst := &testNetworkState{
|
||||
homHashDisabled: true,
|
||||
epoch: 100,
|
||||
}
|
||||
cc := &testContainerClient{
|
||||
get: make(map[string]*containercore.Container),
|
||||
}
|
||||
mc := &testMorphClient{}
|
||||
|
||||
proc, err := New(&Params{
|
||||
Log: test.NewLogger(t),
|
||||
PoolSize: 2,
|
||||
AlphabetState: &testAlphabetState{isAlphabet: true},
|
||||
NetworkState: nst,
|
||||
ContainerClient: cc,
|
||||
MorphClient: mc,
|
||||
FrostFSIDClient: &testFrostFSIDClient{},
|
||||
})
|
||||
require.NoError(t, err, "failed to create processor")
|
||||
|
||||
p, err := keys.NewPrivateKey()
|
||||
require.NoError(t, err)
|
||||
|
||||
var usr user.ID
|
||||
user.IDFromKey(&usr, (ecdsa.PublicKey)(*p.PublicKey()))
|
||||
|
||||
var pp netmap.PlacementPolicy
|
||||
pp.AddReplicas(netmap.ReplicaDescriptor{})
|
||||
|
||||
var cnr containerSDK.Container
|
||||
cnr.Init()
|
||||
cnr.SetOwner(usr)
|
||||
cnr.SetPlacementPolicy(pp)
|
||||
cnr.SetBasicACL(acl.PrivateExtended)
|
||||
containerSDK.DisableHomomorphicHashing(&cnr)
|
||||
|
||||
var cid cid.ID
|
||||
containerSDK.CalculateID(&cid, cnr)
|
||||
cidBytes := make([]byte, 32)
|
||||
cid.Encode(cidBytes)
|
||||
|
||||
var signature frostfscrypto.Signature
|
||||
signer := frostfsecdsa.Signer(p.PrivateKey)
|
||||
require.NoError(t, signature.Calculate(signer, cidBytes), "failed to calculate signature")
|
||||
|
||||
cc.get[hex.EncodeToString(cidBytes)] = &containercore.Container{
|
||||
Value: cnr,
|
||||
Signature: signature,
|
||||
}
|
||||
|
||||
table := eacl.NewTable()
|
||||
table.SetCID(cid)
|
||||
table.SetVersion(version.Current())
|
||||
|
||||
r := &eacl.Record{}
|
||||
r.AddObjectContainerIDFilter(eacl.MatchStringEqual, cid)
|
||||
|
||||
table.AddRecord(r)
|
||||
|
||||
nr := &payload.P2PNotaryRequest{
|
||||
MainTransaction: &transaction.Transaction{},
|
||||
}
|
||||
event := containerEvent.SetEACL{
|
||||
TableValue: table.ToV2().StableMarshal(nil),
|
||||
PublicKeyValue: p.PublicKey().Bytes(),
|
||||
SignatureValue: p.Sign(table.ToV2().StableMarshal(nil)),
|
||||
NotaryRequestValue: nr,
|
||||
}
|
||||
|
||||
proc.handleSetEACL(event)
|
||||
|
||||
for proc.pool.Running() > 0 {
|
||||
time.Sleep(10 * time.Millisecond)
|
||||
}
|
||||
|
||||
var expectedPutEACL cntClient.PutEACLPrm
|
||||
expectedPutEACL.SetTable(table.ToV2().StableMarshal(nil))
|
||||
expectedPutEACL.SetKey(p.PublicKey().Bytes())
|
||||
expectedPutEACL.SetSignature(p.Sign(table.ToV2().StableMarshal(nil)))
|
||||
|
||||
require.EqualValues(t, []*transaction.Transaction{nr.MainTransaction}, mc.transactions, "invalid notary requests")
|
||||
}
|
||||
|
||||
type testAlphabetState struct {
|
||||
isAlphabet bool
|
||||
}
|
||||
|
|
|
@ -1,82 +0,0 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
cntClient "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client/container"
|
||||
containerEvent "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/event/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"go.uber.org/zap"
|
||||
)
|
||||
|
||||
func (cp *Processor) processSetEACL(e containerEvent.SetEACL) bool {
|
||||
if !cp.alphabetState.IsAlphabet() {
|
||||
cp.log.Info(logs.ContainerNonAlphabetModeIgnoreSetEACL)
|
||||
return true
|
||||
}
|
||||
|
||||
err := cp.checkSetEACL(e)
|
||||
if err != nil {
|
||||
cp.log.Error(logs.ContainerSetEACLCheckFailed,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
if err := cp.morphClient.NotarySignAndInvokeTX(e.NotaryRequest().MainTransaction); err != nil {
|
||||
cp.log.Error(logs.ContainerCouldNotApproveSetEACL,
|
||||
zap.String("error", err.Error()),
|
||||
)
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (cp *Processor) checkSetEACL(e containerEvent.SetEACL) error {
|
||||
binTable := e.Table()
|
||||
|
||||
// unmarshal table
|
||||
table := eacl.NewTable()
|
||||
|
||||
err := table.Unmarshal(binTable)
|
||||
if err != nil {
|
||||
return fmt.Errorf("invalid binary table: %w", err)
|
||||
}
|
||||
|
||||
idCnr, ok := table.CID()
|
||||
if !ok {
|
||||
return errors.New("missing container ID in eACL table")
|
||||
}
|
||||
|
||||
// receive owner of the related container
|
||||
cnr, err := cntClient.Get(cp.cnrClient, idCnr)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not receive the container: %w", err)
|
||||
}
|
||||
|
||||
// ACL extensions can be disabled by basic ACL, check it
|
||||
if !cnr.Value.BasicACL().Extendable() {
|
||||
return errors.New("ACL extension disabled by container basic ACL")
|
||||
}
|
||||
|
||||
err = cp.verifySignature(signatureVerificationData{
|
||||
ownerContainer: cnr.Value.Owner(),
|
||||
verb: session.VerbContainerSetEACL,
|
||||
idContainerSet: true,
|
||||
idContainer: idCnr,
|
||||
binTokenSession: e.SessionToken(),
|
||||
binPublicKey: e.PublicKey(),
|
||||
signature: e.Signature(),
|
||||
signedData: binTable,
|
||||
})
|
||||
if err != nil {
|
||||
return fmt.Errorf("auth eACL table setting: %w", err)
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
|
@ -1,93 +0,0 @@
|
|||
package container
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/refs"
|
||||
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/morph/client"
|
||||
)
|
||||
|
||||
// PutEACL marshals table, and passes it to Wrapper's PutEACLBinary method
|
||||
// along with sig.Key() and sig.Sign().
|
||||
//
|
||||
// Returns error if table is nil.
|
||||
//
|
||||
// If TryNotary is provided, calls notary contract.
|
||||
func PutEACL(c *Client, eaclInfo containercore.EACL) error {
|
||||
if eaclInfo.Value == nil {
|
||||
return errNilArgument
|
||||
}
|
||||
|
||||
data, err := eaclInfo.Value.Marshal()
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't marshal eacl table: %w", err)
|
||||
}
|
||||
|
||||
var prm PutEACLPrm
|
||||
prm.SetTable(data)
|
||||
|
||||
if eaclInfo.Session != nil {
|
||||
prm.SetToken(eaclInfo.Session.Marshal())
|
||||
}
|
||||
|
||||
// TODO(@cthulhu-rider): #468 implement and use another approach to avoid conversion
|
||||
var sigV2 refs.Signature
|
||||
eaclInfo.Signature.WriteToV2(&sigV2)
|
||||
|
||||
prm.SetKey(sigV2.GetKey())
|
||||
prm.SetSignature(sigV2.GetSign())
|
||||
|
||||
return c.PutEACL(prm)
|
||||
}
|
||||
|
||||
// PutEACLPrm groups parameters of PutEACL operation.
|
||||
type PutEACLPrm struct {
|
||||
table []byte
|
||||
key []byte
|
||||
sig []byte
|
||||
token []byte
|
||||
|
||||
client.InvokePrmOptional
|
||||
}
|
||||
|
||||
// SetTable sets table.
|
||||
func (p *PutEACLPrm) SetTable(table []byte) {
|
||||
p.table = table
|
||||
}
|
||||
|
||||
// SetKey sets key.
|
||||
func (p *PutEACLPrm) SetKey(key []byte) {
|
||||
p.key = key
|
||||
}
|
||||
|
||||
// SetSignature sets signature.
|
||||
func (p *PutEACLPrm) SetSignature(sig []byte) {
|
||||
p.sig = sig
|
||||
}
|
||||
|
||||
// SetToken sets session token.
|
||||
func (p *PutEACLPrm) SetToken(token []byte) {
|
||||
p.token = token
|
||||
}
|
||||
|
||||
// PutEACL saves binary eACL table with its session token, key and signature
|
||||
// in FrostFS system through Container contract call.
|
||||
//
|
||||
// Returns any error encountered that caused the saving to interrupt.
|
||||
func (c *Client) PutEACL(p PutEACLPrm) error {
|
||||
if len(p.sig) == 0 || len(p.key) == 0 {
|
||||
return errNilArgument
|
||||
}
|
||||
|
||||
prm := client.InvokePrm{}
|
||||
prm.SetMethod(setEACLMethod)
|
||||
prm.SetArgs(p.table, p.sig, p.key, p.token)
|
||||
prm.InvokePrmOptional = p.InvokePrmOptional
|
||||
|
||||
_, err := c.client.Invoke(prm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("could not invoke method (%s): %w", setEACLMethod, err)
|
||||
}
|
||||
return nil
|
||||
}
|
|
@ -11,9 +11,10 @@ import (
|
|||
containercore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/container"
|
||||
containerSvc "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/services/container"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
eaclSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/user"
|
||||
"google.golang.org/grpc/codes"
|
||||
"google.golang.org/grpc/status"
|
||||
)
|
||||
|
||||
var errMissingUserID = errors.New("missing user ID")
|
||||
|
@ -40,8 +41,6 @@ type Writer interface {
|
|||
Put(containercore.Container) (*cid.ID, error)
|
||||
// Delete removes specified container from the side chain.
|
||||
Delete(containercore.RemovalWitness) error
|
||||
// PutEACL updates extended ACL table of specified container in the side chain.
|
||||
PutEACL(containercore.EACL) error
|
||||
}
|
||||
|
||||
func NewExecutor(rdr Reader, wrt Writer) containerSvc.ServiceExecutor {
|
||||
|
@ -205,37 +204,8 @@ func (s *morphExecutor) List(_ context.Context, body *container.ListRequestBody)
|
|||
return res, nil
|
||||
}
|
||||
|
||||
func (s *morphExecutor) SetExtendedACL(_ context.Context, tokV2 *sessionV2.Token, body *container.SetExtendedACLRequestBody) (*container.SetExtendedACLResponseBody, error) {
|
||||
sigV2 := body.GetSignature()
|
||||
if sigV2 == nil {
|
||||
// TODO(@cthulhu-rider): #468 use "const" error
|
||||
return nil, errors.New("missing signature")
|
||||
}
|
||||
|
||||
eaclInfo := containercore.EACL{
|
||||
Value: eaclSDK.NewTableFromV2(body.GetEACL()),
|
||||
}
|
||||
|
||||
err := eaclInfo.Signature.ReadFromV2(*sigV2)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("can't read signature: %w", err)
|
||||
}
|
||||
|
||||
if tokV2 != nil {
|
||||
eaclInfo.Session = new(session.Container)
|
||||
|
||||
err := eaclInfo.Session.ReadFromV2(*tokV2)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("invalid session token: %w", err)
|
||||
}
|
||||
}
|
||||
|
||||
err = s.wrt.PutEACL(eaclInfo)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return new(container.SetExtendedACLResponseBody), nil
|
||||
func (s *morphExecutor) SetExtendedACL(_ context.Context, _ *sessionV2.Token, _ *container.SetExtendedACLRequestBody) (*container.SetExtendedACLResponseBody, error) {
|
||||
return nil, status.Errorf(codes.Unimplemented, "method SetExtendedACL not implemented")
|
||||
}
|
||||
|
||||
func (s *morphExecutor) GetExtendedACL(_ context.Context, body *container.GetExtendedACLRequestBody) (*container.GetExtendedACLResponseBody, error) {
|
||||
|
|
|
@ -96,17 +96,6 @@ func TestInvalidToken(t *testing.T) {
|
|||
return
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "setEACL",
|
||||
op: func(e containerSvc.ServiceExecutor, tokV2 *session.Token) (err error) {
|
||||
var reqBody container.SetExtendedACLRequestBody
|
||||
reqBody.SetSignature(new(refs.Signature))
|
||||
sign(&reqBody)
|
||||
|
||||
_, err = e.SetExtendedACL(context.TODO(), tokV2, &reqBody)
|
||||
return
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for _, test := range tests {
|
||||
|
|
Loading…
Reference in a new issue