diff --git a/client/api.go b/client/api.go index b16f757..dfad9ea 100644 --- a/client/api.go +++ b/client/api.go @@ -7,10 +7,13 @@ import ( v2netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap" rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/session" ) // interface of NeoFS API server. Exists for test purposes only. type neoFSAPIServer interface { + createSession(cli *client.Client, req *session.CreateRequest, opts ...client.CallOption) (*session.CreateResponse, error) + netMapSnapshot(context.Context, v2netmap.SnapshotRequest) (*v2netmap.SnapshotResponse, error) } @@ -33,3 +36,12 @@ func (x *coreServer) netMapSnapshot(ctx context.Context, req v2netmap.SnapshotRe return resp, nil } + +func (x *coreServer) createSession(cli *client.Client, req *session.CreateRequest, opts ...client.CallOption) (*session.CreateResponse, error) { + resp, err := rpcapi.CreateSession(cli, req, opts...) + if err != nil { + return nil, rpcErr(err) + } + + return resp, nil +} diff --git a/client/errors.go b/client/errors.go index 19949f4..369a5f2 100644 --- a/client/errors.go +++ b/client/errors.go @@ -4,9 +4,30 @@ import ( "fmt" ) +var ( + errMissingResponseField missingResponseFieldErr +) + +type missingResponseFieldErr struct { + name string +} + +func (e missingResponseFieldErr) Error() string { + return fmt.Sprintf("missing %s field in the response", e.name) +} + +func (e missingResponseFieldErr) Is(target error) bool { + switch target.(type) { + default: + return false + case missingResponseFieldErr, *missingResponseFieldErr: + return true + } +} + // returns error describing missing field with the given name. func newErrMissingResponseField(name string) error { - return fmt.Errorf("missing %s field in the response", name) + return missingResponseFieldErr{name: name} } // returns error describing invalid field (according to the NeoFS protocol) diff --git a/client/netmap_test.go b/client/netmap_test.go index fda66c8..353ee47 100644 --- a/client/netmap_test.go +++ b/client/netmap_test.go @@ -7,6 +7,7 @@ import ( "testing" v2netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" "github.com/nspcc-dev/neofs-api-go/v2/session" apistatus "github.com/nspcc-dev/neofs-sdk-go/client/status" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" @@ -28,7 +29,11 @@ type serverNetMap struct { signer neofscrypto.Signer } -func (x *serverNetMap) netMapSnapshot(ctx context.Context, req v2netmap.SnapshotRequest) (*v2netmap.SnapshotResponse, error) { +func (x *serverNetMap) createSession(*client.Client, *session.CreateRequest, ...client.CallOption) (*session.CreateResponse, error) { + return nil, nil +} + +func (x *serverNetMap) netMapSnapshot(_ context.Context, req v2netmap.SnapshotRequest) (*v2netmap.SnapshotResponse, error) { err := verifyServiceMessage(&req) if err != nil { return nil, err diff --git a/client/session.go b/client/session.go index c7465dc..35123c3 100644 --- a/client/session.go +++ b/client/session.go @@ -4,7 +4,6 @@ import ( "context" "github.com/nspcc-dev/neofs-api-go/v2/refs" - rpcapi "github.com/nspcc-dev/neofs-api-go/v2/rpc" "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" v2session "github.com/nspcc-dev/neofs-api-go/v2/session" neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" @@ -116,13 +115,23 @@ func (c *Client) SessionCreate(ctx context.Context, prm PrmSessionCreate) (*ResS cc.req = &req cc.statusRes = &res cc.call = func() (responseV2, error) { - return rpcapi.CreateSession(&c.c, &req, client.WithContext(ctx)) + return c.server.createSession(&c.c, &req, client.WithContext(ctx)) } cc.result = func(r responseV2) { resp := r.(*v2session.CreateResponse) body := resp.GetBody() + if len(body.GetID()) == 0 { + cc.err = newErrMissingResponseField("session id") + return + } + + if len(body.GetSessionKey()) == 0 { + cc.err = newErrMissingResponseField("session key") + return + } + res.setID(body.GetID()) res.setSessionKey(body.GetSessionKey()) } diff --git a/client/session_test.go b/client/session_test.go new file mode 100644 index 0000000..d2fb26a --- /dev/null +++ b/client/session_test.go @@ -0,0 +1,74 @@ +package client + +import ( + "context" + "testing" + + v2netmap "github.com/nspcc-dev/neofs-api-go/v2/netmap" + "github.com/nspcc-dev/neofs-api-go/v2/rpc/client" + "github.com/nspcc-dev/neofs-api-go/v2/session" + neofscrypto "github.com/nspcc-dev/neofs-sdk-go/crypto" + "github.com/nspcc-dev/neofs-sdk-go/crypto/test" + "github.com/stretchr/testify/require" +) + +type sessionAPIServer struct { + signer neofscrypto.Signer + setBody func(body *session.CreateResponseBody) +} + +func (m sessionAPIServer) netMapSnapshot(context.Context, v2netmap.SnapshotRequest) (*v2netmap.SnapshotResponse, error) { + return nil, nil +} + +func (m sessionAPIServer) createSession(*client.Client, *session.CreateRequest, ...client.CallOption) (*session.CreateResponse, error) { + var body session.CreateResponseBody + m.setBody(&body) + + var resp session.CreateResponse + resp.SetBody(&body) + + if err := signServiceMessage(m.signer, &resp); err != nil { + return nil, err + } + + return &resp, nil +} + +func TestClient_SessionCreate(t *testing.T) { + ctx := context.Background() + signer := test.RandomSignerRFC6979(t) + + var prmInit PrmInit + prmInit.SetDefaultSigner(signer) + prmInit.ResolveNeoFSFailures() + + var c Client + c.Init(prmInit) + + var prmSessionCreate PrmSessionCreate + prmSessionCreate.UseSigner(signer) + prmSessionCreate.SetExp(1) + + t.Run("missing session id", func(t *testing.T) { + c.setNeoFSAPIServer(&sessionAPIServer{signer: signer, setBody: func(body *session.CreateResponseBody) { + body.SetSessionKey([]byte{1}) + }}) + + result, err := c.SessionCreate(ctx, prmSessionCreate) + require.Nil(t, result) + require.ErrorIs(t, err, errMissingResponseField) + require.Equal(t, "missing session id field in the response", err.Error()) + }) + + t.Run("missing session key", func(t *testing.T) { + c.setNeoFSAPIServer(&sessionAPIServer{signer: signer, setBody: func(body *session.CreateResponseBody) { + body.SetID([]byte{1}) + }}) + + result, err := c.SessionCreate(ctx, prmSessionCreate) + require.Nil(t, result) + require.ErrorIs(t, err, errMissingResponseField) + require.Equal(t, "missing session key field in the response", err.Error()) + }) +}