Skip to content

Commit

Permalink
[#1045] Provide sanity check of session token in container service
Browse files Browse the repository at this point in the history
Without sanity check, container service provides successful response,
even though such request will never be approved by Alphabet nodes.

Signed-off-by: Alex Vanin <[email protected]>
  • Loading branch information
alexvanin committed Dec 20, 2021
1 parent acb4a9e commit e610d1e
Show file tree
Hide file tree
Showing 2 changed files with 122 additions and 6 deletions.
27 changes: 21 additions & 6 deletions pkg/services/container/morph/executor.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package container

import (
"context"
"errors"

"github.com/nspcc-dev/neofs-api-go/v2/container"
"github.com/nspcc-dev/neofs-api-go/v2/refs"
Expand Down Expand Up @@ -42,6 +43,10 @@ type Writer interface {
PutEACL(*eaclSDK.Table) error
}

// ErrInvalidContext is thrown by morph ServiceExecutor when provided session
// token does not contain expected container context.
var ErrInvalidContext = errors.New("session token does not contain container context")

func NewExecutor(rdr Reader, wrt Writer) containerSvc.ServiceExecutor {
return &morphExecutor{
rdr: rdr,
Expand All @@ -56,9 +61,12 @@ func (s *morphExecutor) Put(ctx containerSvc.ContextWithToken, body *container.P
signature.NewFromV2(body.GetSignature()),
)

cnr.SetSessionToken(
session.NewTokenFromV2(ctx.SessionToken),
)
tok := session.NewTokenFromV2(ctx.SessionToken)
if ctx.SessionToken != nil && session.GetContainerContext(tok) == nil {
return nil, ErrInvalidContext
}

cnr.SetSessionToken(tok)

cid, err := s.wrt.Put(cnr)
if err != nil {
Expand All @@ -74,7 +82,11 @@ func (s *morphExecutor) Put(ctx containerSvc.ContextWithToken, body *container.P
func (s *morphExecutor) Delete(ctx containerSvc.ContextWithToken, body *container.DeleteRequestBody) (*container.DeleteResponseBody, error) {
id := cid.NewFromV2(body.GetContainerID())
sig := body.GetSignature().GetSign()

tok := session.NewTokenFromV2(ctx.SessionToken)
if ctx.SessionToken != nil && session.GetContainerContext(tok) == nil {
return nil, ErrInvalidContext
}

var rmWitness containercore.RemovalWitness

Expand Down Expand Up @@ -131,9 +143,12 @@ func (s *morphExecutor) SetExtendedACL(ctx containerSvc.ContextWithToken, body *

table.SetSignature(sign)

table.SetSessionToken(
session.NewTokenFromV2(ctx.SessionToken),
)
tok := session.NewTokenFromV2(ctx.SessionToken)
if ctx.SessionToken != nil && session.GetContainerContext(tok) == nil {
return nil, ErrInvalidContext
}

table.SetSessionToken(tok)

err := s.wrt.PutEACL(table)
if err != nil {
Expand Down
101 changes: 101 additions & 0 deletions pkg/services/container/morph/executor_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
package container_test

import (
"context"
"testing"

"github.com/nspcc-dev/neofs-api-go/v2/container"
"github.com/nspcc-dev/neofs-api-go/v2/session"
containerCore "github.com/nspcc-dev/neofs-node/pkg/core/container"
containerSvc "github.com/nspcc-dev/neofs-node/pkg/services/container"
containerSvcMorph "github.com/nspcc-dev/neofs-node/pkg/services/container/morph"
containerSDK "github.com/nspcc-dev/neofs-sdk-go/container"
cid "github.com/nspcc-dev/neofs-sdk-go/container/id"
"github.com/nspcc-dev/neofs-sdk-go/eacl"
"github.com/nspcc-dev/neofs-sdk-go/owner"
"github.com/stretchr/testify/require"
)

type mock struct{}

func (m mock) Put(c *containerSDK.Container) (*cid.ID, error) {
return new(cid.ID), nil
}

func (m mock) Delete(witness containerCore.RemovalWitness) error {
return nil
}

func (m mock) PutEACL(table *eacl.Table) error {
return nil
}

func (m mock) Get(id *cid.ID) (*containerSDK.Container, error) {
panic("implement me")
}

func (m mock) GetEACL(id *cid.ID) (*eacl.Table, error) {
panic("implement me")
}

func (m mock) List(id *owner.ID) ([]*cid.ID, error) {
panic("implement me")
}

func TestInvalidToken(t *testing.T) {
m := mock{}
e := containerSvcMorph.NewExecutor(m, m)

tests := []struct {
name string
op func(e containerSvc.ServiceExecutor, ctx containerSvc.ContextWithToken) error
}{
{
name: "put",
op: func(e containerSvc.ServiceExecutor, ctx containerSvc.ContextWithToken) (err error) {
_, err = e.Put(ctx, new(container.PutRequestBody))
return
},
},
{
name: "delete",
op: func(e containerSvc.ServiceExecutor, ctx containerSvc.ContextWithToken) (err error) {
_, err = e.Delete(ctx, new(container.DeleteRequestBody))
return
},
},
{
name: "setEACL",
op: func(e containerSvc.ServiceExecutor, ctx containerSvc.ContextWithToken) (err error) {
_, err = e.SetExtendedACL(ctx, new(container.SetExtendedACLRequestBody))
return
},
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
ctx := containerSvc.ContextWithToken{
Context: context.Background(),
SessionToken: generateToken(new(session.ObjectSessionContext)),
}
require.Error(t, test.op(e, ctx), containerSvcMorph.ErrInvalidContext)

ctx.SessionToken = generateToken(new(session.ContainerSessionContext))
require.NoError(t, test.op(e, ctx))

ctx.SessionToken = nil
require.NoError(t, test.op(e, ctx))
})
}
}

func generateToken(ctx session.SessionTokenContext) *session.SessionToken {
body := new(session.SessionTokenBody)
body.SetContext(ctx)

tok := new(session.SessionToken)
tok.SetBody(body)

return tok
}

0 comments on commit e610d1e

Please sign in to comment.