From 8c99d9d54c5ce9a64612091e11f992fc3f13f6aa Mon Sep 17 00:00:00 2001 From: Leonard Lyubich Date: Tue, 24 Nov 2020 13:22:07 +0300 Subject: [PATCH] [#207] sdk/client: Implement GetEACLWithSignature method GetEACL method of Client receives eACL table with signature, verifies the signature and return the table. In some cases we need to receive table and signature regardless of their correctness. New method GetEACLWithSignature provides such an opportunity. Signed-off-by: Leonard Lyubich --- pkg/client/container.go | 71 +++++++++++++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 16 deletions(-) diff --git a/pkg/client/container.go b/pkg/client/container.go index a09107e..3bd61e2 100644 --- a/pkg/client/container.go +++ b/pkg/client/container.go @@ -3,6 +3,7 @@ package client import ( "context" + "github.com/nspcc-dev/neofs-api-go/pkg" "github.com/nspcc-dev/neofs-api-go/pkg/acl/eacl" "github.com/nspcc-dev/neofs-api-go/pkg/container" "github.com/nspcc-dev/neofs-api-go/pkg/owner" @@ -18,6 +19,13 @@ type delContainerSignWrapper struct { body *v2container.DeleteRequestBody } +// EACLWithSignature represents eACL table/signature pair. +type EACLWithSignature struct { + table *eacl.Table + + sig *pkg.Signature +} + var errNilReponseBody = errors.New("response body is nil") func (c delContainerSignWrapper) ReadSignedData(bytes []byte) ([]byte, error) { @@ -28,6 +36,16 @@ func (c delContainerSignWrapper) SignedDataSize() int { return len(c.body.GetContainerID().GetValue()) } +// EACL returns eACL table. +func (e EACLWithSignature) EACL() *eacl.Table { + return e.table +} + +// Signature returns table signature. +func (e EACLWithSignature) Signature() *pkg.Signature { + return e.sig +} + func (c Client) PutContainer(ctx context.Context, cnr *container.Container, opts ...CallOption) (*container.ID, error) { switch c.remoteNode.Version.Major() { case 2: @@ -77,9 +95,30 @@ func (c Client) DeleteContainer(ctx context.Context, id *container.ID, opts ...C } func (c Client) GetEACL(ctx context.Context, id *container.ID, opts ...CallOption) (*eacl.Table, error) { + v, err := c.getEACL(ctx, id, true, opts...) + if err != nil { + return nil, err + } + + return v.table, nil +} + +func (c Client) GetEACLWithSignature(ctx context.Context, id *container.ID, opts ...CallOption) (*EACLWithSignature, error) { + return c.getEACL(ctx, id, false, opts...) +} + +func (c Client) getEACL(ctx context.Context, id *container.ID, verify bool, opts ...CallOption) (*EACLWithSignature, error) { switch c.remoteNode.Version.Major() { case 2: - return c.getEACLV2(ctx, id, opts...) + resp, err := c.getEACLV2(ctx, id, verify, opts...) + if err != nil { + return nil, err + } + + return &EACLWithSignature{ + table: eacl.NewTableFromV2(resp.GetEACL()), + sig: pkg.NewSignatureFromV2(resp.GetSignature()), + }, nil default: return nil, errUnsupportedProtocol } @@ -316,7 +355,7 @@ func (c Client) delContainerV2(ctx context.Context, id *container.ID, opts ...Ca } } -func (c Client) getEACLV2(ctx context.Context, id *container.ID, opts ...CallOption) (*eacl.Table, error) { +func (c Client) getEACLV2(ctx context.Context, id *container.ID, verify bool, opts ...CallOption) (*v2container.GetExtendedACLResponseBody, error) { // apply all available options callOptions := c.defaultCallOptions() @@ -358,23 +397,23 @@ func (c Client) getEACLV2(ctx context.Context, id *container.ID, opts ...CallOpt return nil, errNilReponseBody } - if err := signature.VerifyDataWithSource( - v2signature.StableMarshalerWrapper{ - SM: body.GetEACL(), - }, - func() (key, sig []byte) { - s := body.GetSignature() + if verify { + if err := signature.VerifyDataWithSource( + v2signature.StableMarshalerWrapper{ + SM: body.GetEACL(), + }, + func() (key, sig []byte) { + s := body.GetSignature() - return s.GetKey(), s.GetSign() - }, - signature.SignWithRFC6979(), - ); err != nil { - return nil, errors.Wrap(err, "incorrect signature") + return s.GetKey(), s.GetSign() + }, + signature.SignWithRFC6979(), + ); err != nil { + return nil, errors.Wrap(err, "incorrect signature") + } } - result := eacl.NewTableFromV2(body.GetEACL()) - - return result, nil + return body, nil default: return nil, errUnsupportedProtocol }