2020-08-18 09:01:08 +00:00
|
|
|
package session_test
|
|
|
|
|
|
|
|
import (
|
2020-08-20 10:32:02 +00:00
|
|
|
"fmt"
|
2020-08-18 09:01:08 +00:00
|
|
|
"testing"
|
|
|
|
|
2020-08-20 10:32:02 +00:00
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/acl"
|
2020-08-18 09:01:08 +00:00
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/refs"
|
|
|
|
"github.com/nspcc-dev/neofs-api-go/v2/session"
|
|
|
|
grpc "github.com/nspcc-dev/neofs-api-go/v2/session/grpc"
|
|
|
|
"github.com/stretchr/testify/require"
|
2020-10-19 18:51:59 +00:00
|
|
|
goproto "google.golang.org/protobuf/proto"
|
2020-08-18 09:01:08 +00:00
|
|
|
)
|
|
|
|
|
|
|
|
func TestCreateRequestBody_StableMarshal(t *testing.T) {
|
|
|
|
requestFrom := generateCreateSessionRequestBody("Owner ID")
|
|
|
|
transport := new(grpc.CreateRequest_Body)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := requestFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-18 09:01:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
requestTo := session.CreateRequestBodyFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, requestFrom, requestTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestCreateResponseBody_StableMarshal(t *testing.T) {
|
|
|
|
responseFrom := generateCreateSessionResponseBody("ID", "Session Public Key")
|
|
|
|
transport := new(grpc.CreateResponse_Body)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := responseFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-18 09:01:08 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
responseTo := session.CreateResponseBodyFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, responseFrom, responseTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-08-20 10:32:02 +00:00
|
|
|
func TestXHeader_StableMarshal(t *testing.T) {
|
|
|
|
xheaderFrom := generateXHeader("X-Header-Key", "X-Header-Value")
|
|
|
|
transport := new(grpc.XHeader)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := xheaderFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
xheaderTo := session.XHeaderFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, xheaderFrom, xheaderTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTokenLifetime_StableMarshal(t *testing.T) {
|
|
|
|
lifetimeFrom := generateLifetime(10, 20, 30)
|
|
|
|
transport := new(grpc.SessionToken_Body_TokenLifetime)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := lifetimeFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
lifetimeTo := session.TokenLifetimeFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, lifetimeFrom, lifetimeTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestObjectSessionContext_StableMarshal(t *testing.T) {
|
|
|
|
objectCtxFrom := generateObjectCtx("Object ID")
|
|
|
|
transport := new(grpc.ObjectSessionContext)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := objectCtxFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
objectCtxTo := session.ObjectSessionContextFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, objectCtxFrom, objectCtxTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSessionTokenBody_StableMarshal(t *testing.T) {
|
|
|
|
sessionTokenBodyFrom := generateSessionTokenBody("Session Token Body")
|
|
|
|
transport := new(grpc.SessionToken_Body)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := sessionTokenBodyFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
sessionTokenBodyTo := session.SessionTokenBodyFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, sessionTokenBodyFrom, sessionTokenBodyTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestSessionToken_StableMarshal(t *testing.T) {
|
|
|
|
sessionTokenFrom := generateSessionToken("Session Token")
|
|
|
|
transport := new(grpc.SessionToken)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := sessionTokenFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
sessionTokenTo := session.SessionTokenFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, sessionTokenFrom, sessionTokenTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRequestMetaHeader_StableMarshal(t *testing.T) {
|
|
|
|
metaHeaderOrigin := generateRequestMetaHeader(10, "Bearer One", "Session One")
|
|
|
|
metaHeaderFrom := generateRequestMetaHeader(20, "Bearer Two", "Session Two")
|
|
|
|
metaHeaderFrom.SetOrigin(metaHeaderOrigin)
|
|
|
|
transport := new(grpc.RequestMetaHeader)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := metaHeaderFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
metaHeaderTo := session.RequestMetaHeaderFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, metaHeaderFrom, metaHeaderTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestRequestVerificationHeader_StableMarshal(t *testing.T) {
|
|
|
|
verifHeaderOrigin := generateRequestVerificationHeader("Key", "Inside")
|
|
|
|
verifHeaderFrom := generateRequestVerificationHeader("Value", "Outside")
|
|
|
|
verifHeaderFrom.SetOrigin(verifHeaderOrigin)
|
|
|
|
transport := new(grpc.RequestVerificationHeader)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := verifHeaderFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
verifHeaderTo := session.RequestVerificationHeaderFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, verifHeaderFrom, verifHeaderTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestResponseMetaHeader_StableMarshal(t *testing.T) {
|
|
|
|
metaHeaderOrigin := generateResponseMetaHeader(10)
|
|
|
|
metaHeaderFrom := generateResponseMetaHeader(20)
|
|
|
|
metaHeaderFrom.SetOrigin(metaHeaderOrigin)
|
|
|
|
transport := new(grpc.ResponseMetaHeader)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := metaHeaderFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
metaHeaderTo := session.ResponseMetaHeaderFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, metaHeaderFrom, metaHeaderTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestResponseVerificationHeader_StableMarshal(t *testing.T) {
|
|
|
|
verifHeaderOrigin := generateResponseVerificationHeader("Key", "Inside")
|
|
|
|
verifHeaderFrom := generateResponseVerificationHeader("Value", "Outside")
|
|
|
|
verifHeaderFrom.SetOrigin(verifHeaderOrigin)
|
|
|
|
transport := new(grpc.ResponseVerificationHeader)
|
|
|
|
|
|
|
|
t.Run("non empty", func(t *testing.T) {
|
|
|
|
wire, err := verifHeaderFrom.StableMarshal(nil)
|
|
|
|
require.NoError(t, err)
|
|
|
|
|
2020-10-19 18:51:59 +00:00
|
|
|
err = goproto.Unmarshal(wire, transport)
|
2020-08-20 10:32:02 +00:00
|
|
|
require.NoError(t, err)
|
|
|
|
|
|
|
|
verifHeaderTo := session.ResponseVerificationHeaderFromGRPCMessage(transport)
|
|
|
|
require.Equal(t, verifHeaderFrom, verifHeaderTo)
|
|
|
|
})
|
|
|
|
}
|
|
|
|
|
2020-08-18 09:01:08 +00:00
|
|
|
func generateCreateSessionRequestBody(id string) *session.CreateRequestBody {
|
2020-08-20 10:32:02 +00:00
|
|
|
lifetime := new(session.TokenLifetime)
|
2020-08-18 09:01:08 +00:00
|
|
|
lifetime.SetIat(1)
|
|
|
|
lifetime.SetNbf(2)
|
|
|
|
lifetime.SetExp(3)
|
|
|
|
|
|
|
|
owner := new(refs.OwnerID)
|
|
|
|
owner.SetValue([]byte(id))
|
|
|
|
|
|
|
|
s := new(session.CreateRequestBody)
|
|
|
|
s.SetOwnerID(owner)
|
2020-08-20 10:32:02 +00:00
|
|
|
s.SetExpiration(10)
|
2020-08-18 09:01:08 +00:00
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateCreateSessionResponseBody(id, key string) *session.CreateResponseBody {
|
|
|
|
s := new(session.CreateResponseBody)
|
|
|
|
s.SetID([]byte(id))
|
|
|
|
s.SetSessionKey([]byte(key))
|
|
|
|
|
|
|
|
return s
|
|
|
|
}
|
2020-08-20 10:32:02 +00:00
|
|
|
|
|
|
|
func generateSignature(k, v string) *refs.Signature {
|
|
|
|
sig := new(refs.Signature)
|
|
|
|
sig.SetKey([]byte(k))
|
|
|
|
sig.SetSign([]byte(v))
|
|
|
|
|
|
|
|
return sig
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateVersion(maj, min uint32) *refs.Version {
|
|
|
|
version := new(refs.Version)
|
|
|
|
version.SetMajor(maj)
|
|
|
|
version.SetMinor(min)
|
|
|
|
|
|
|
|
return version
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateXHeader(k, v string) *session.XHeader {
|
|
|
|
xheader := new(session.XHeader)
|
|
|
|
xheader.SetKey(k)
|
|
|
|
xheader.SetValue(v)
|
|
|
|
|
|
|
|
return xheader
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateLifetime(exp, nbf, iat uint64) *session.TokenLifetime {
|
|
|
|
lifetime := new(session.TokenLifetime)
|
|
|
|
lifetime.SetExp(exp)
|
|
|
|
lifetime.SetNbf(nbf)
|
|
|
|
lifetime.SetIat(iat)
|
|
|
|
|
|
|
|
return lifetime
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateBearerLifetime(exp, nbf, iat uint64) *acl.TokenLifetime {
|
|
|
|
lifetime := new(acl.TokenLifetime)
|
|
|
|
lifetime.SetExp(exp)
|
|
|
|
lifetime.SetNbf(nbf)
|
|
|
|
lifetime.SetIat(iat)
|
|
|
|
|
|
|
|
return lifetime
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateObjectCtx(id string) *session.ObjectSessionContext {
|
|
|
|
objectCtx := new(session.ObjectSessionContext)
|
|
|
|
objectCtx.SetVerb(session.ObjectVerbPut)
|
|
|
|
|
|
|
|
cid := new(refs.ContainerID)
|
|
|
|
cid.SetValue([]byte("ContainerID"))
|
|
|
|
|
|
|
|
oid := new(refs.ObjectID)
|
|
|
|
oid.SetValue([]byte(id))
|
|
|
|
|
|
|
|
addr := new(refs.Address)
|
|
|
|
addr.SetContainerID(cid)
|
|
|
|
addr.SetObjectID(oid)
|
|
|
|
|
|
|
|
objectCtx.SetAddress(addr)
|
|
|
|
|
|
|
|
return objectCtx
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateEACL(n int, k, v string) *acl.Table {
|
2020-09-10 10:01:31 +00:00
|
|
|
target := new(acl.Target)
|
2020-09-04 07:50:36 +00:00
|
|
|
target.SetRole(acl.RoleUser)
|
2020-08-20 10:32:02 +00:00
|
|
|
|
|
|
|
keys := make([][]byte, n)
|
|
|
|
|
|
|
|
for i := 0; i < n; i++ {
|
|
|
|
s := fmt.Sprintf("Public Key %d", i+1)
|
|
|
|
keys[i] = []byte(s)
|
|
|
|
}
|
|
|
|
|
|
|
|
filter := new(acl.HeaderFilter)
|
|
|
|
filter.SetHeaderType(acl.HeaderTypeObject)
|
|
|
|
filter.SetMatchType(acl.MatchTypeStringEqual)
|
|
|
|
filter.SetName(k)
|
|
|
|
filter.SetValue(v)
|
|
|
|
|
|
|
|
record := new(acl.Record)
|
|
|
|
record.SetOperation(acl.OperationHead)
|
|
|
|
record.SetAction(acl.ActionDeny)
|
2020-09-10 10:01:31 +00:00
|
|
|
record.SetTargets([]*acl.Target{target})
|
2020-08-20 10:32:02 +00:00
|
|
|
record.SetFilters([]*acl.HeaderFilter{filter})
|
|
|
|
|
|
|
|
table := new(acl.Table)
|
|
|
|
cid := new(refs.ContainerID)
|
|
|
|
cid.SetValue([]byte("Container ID"))
|
|
|
|
|
|
|
|
table.SetContainerID(cid)
|
|
|
|
table.SetRecords([]*acl.Record{record})
|
|
|
|
|
|
|
|
return table
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateSessionTokenBody(id string) *session.SessionTokenBody {
|
|
|
|
owner := new(refs.OwnerID)
|
|
|
|
owner.SetValue([]byte("Owner ID"))
|
|
|
|
|
|
|
|
tokenBody := new(session.SessionTokenBody)
|
|
|
|
tokenBody.SetID([]byte(id))
|
|
|
|
tokenBody.SetOwnerID(owner)
|
|
|
|
tokenBody.SetSessionKey([]byte(id))
|
|
|
|
tokenBody.SetLifetime(generateLifetime(1, 2, 3))
|
|
|
|
tokenBody.SetContext(generateObjectCtx(id))
|
|
|
|
|
|
|
|
return tokenBody
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateSessionToken(id string) *session.SessionToken {
|
|
|
|
sessionToken := new(session.SessionToken)
|
|
|
|
sessionToken.SetBody(generateSessionTokenBody(id))
|
|
|
|
sessionToken.SetSignature(generateSignature("id", id))
|
|
|
|
|
|
|
|
return sessionToken
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateBearerTokenBody(id string) *acl.BearerTokenBody {
|
|
|
|
owner := new(refs.OwnerID)
|
|
|
|
owner.SetValue([]byte(id))
|
|
|
|
|
|
|
|
tokenBody := new(acl.BearerTokenBody)
|
|
|
|
tokenBody.SetOwnerID(owner)
|
|
|
|
tokenBody.SetLifetime(generateBearerLifetime(1, 2, 3))
|
|
|
|
tokenBody.SetEACL(generateEACL(10, "id", id))
|
|
|
|
|
|
|
|
return tokenBody
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateBearerToken(id string) *acl.BearerToken {
|
|
|
|
bearerToken := new(acl.BearerToken)
|
|
|
|
bearerToken.SetBody(generateBearerTokenBody(id))
|
|
|
|
bearerToken.SetSignature(generateSignature("id", id))
|
|
|
|
|
|
|
|
return bearerToken
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateRequestMetaHeader(n int, b, s string) *session.RequestMetaHeader {
|
|
|
|
reqMetaHeader := new(session.RequestMetaHeader)
|
|
|
|
reqMetaHeader.SetVersion(generateVersion(2, 0))
|
|
|
|
reqMetaHeader.SetEpoch(uint64(n))
|
|
|
|
reqMetaHeader.SetTTL(uint32(n))
|
|
|
|
reqMetaHeader.SetXHeaders([]*session.XHeader{
|
|
|
|
generateXHeader("key-one", "val-one"),
|
|
|
|
generateXHeader("key-two", "val-two"),
|
|
|
|
})
|
|
|
|
reqMetaHeader.SetBearerToken(generateBearerToken(b))
|
|
|
|
reqMetaHeader.SetSessionToken(generateSessionToken(s))
|
|
|
|
|
|
|
|
return reqMetaHeader
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateRequestVerificationHeader(k, v string) *session.RequestVerificationHeader {
|
|
|
|
reqVerifHeader := new(session.RequestVerificationHeader)
|
|
|
|
reqVerifHeader.SetBodySignature(generateSignature(k+"body", v+"body"))
|
|
|
|
reqVerifHeader.SetMetaSignature(generateSignature(k+"meta", v+"meta"))
|
|
|
|
reqVerifHeader.SetOriginSignature(generateSignature(k+"orig", v+"orig"))
|
|
|
|
|
|
|
|
return reqVerifHeader
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateResponseMetaHeader(n int) *session.ResponseMetaHeader {
|
|
|
|
respMetaHeader := new(session.ResponseMetaHeader)
|
|
|
|
respMetaHeader.SetVersion(generateVersion(2, 0))
|
|
|
|
respMetaHeader.SetEpoch(uint64(n))
|
|
|
|
respMetaHeader.SetTTL(uint32(n))
|
|
|
|
respMetaHeader.SetXHeaders([]*session.XHeader{
|
|
|
|
generateXHeader("key-one", "val-one"),
|
|
|
|
generateXHeader("key-two", "val-two"),
|
|
|
|
})
|
|
|
|
|
|
|
|
return respMetaHeader
|
|
|
|
}
|
|
|
|
|
|
|
|
func generateResponseVerificationHeader(k, v string) *session.ResponseVerificationHeader {
|
|
|
|
respVerifHeader := new(session.ResponseVerificationHeader)
|
|
|
|
respVerifHeader.SetBodySignature(generateSignature(k+"body", v+"body"))
|
|
|
|
respVerifHeader.SetMetaSignature(generateSignature(k+"meta", v+"meta"))
|
|
|
|
respVerifHeader.SetOriginSignature(generateSignature(k+"orig", v+"orig"))
|
|
|
|
|
|
|
|
return respVerifHeader
|
|
|
|
}
|