[#283] v2/session: Support ContainerSessionContext message
Define `ContainerSessionContext` structure, implement getters / setters, JSON and binary encoders, gRPC converters. Support new type of context in SessionTokenBody message. Add test message generator and cover methods with unit tests. Signed-off-by: Leonard Lyubich <leonard@nspcc.ru>
This commit is contained in:
parent
f2be7509d3
commit
9eb567a53a
6 changed files with 261 additions and 0 deletions
|
@ -707,6 +707,8 @@ func (t *SessionTokenBody) ToGRPCMessage() grpc.Message {
|
|||
m.Context = nil
|
||||
case *ObjectSessionContext:
|
||||
m.SetObjectSessionContext(typ.ToGRPCMessage().(*session.ObjectSessionContext))
|
||||
case *ContainerSessionContext:
|
||||
m.SetContainerSessionContext(typ.ToGRPCMessage().(*session.ContainerSessionContext))
|
||||
}
|
||||
|
||||
m.SetOwnerId(t.ownerID.ToGRPCMessage().(*refsGRPC.OwnerID))
|
||||
|
@ -740,6 +742,14 @@ func (t *SessionTokenBody) FromGRPCMessage(m grpc.Message) error {
|
|||
}
|
||||
|
||||
err = ctx.FromGRPCMessage(val.Object)
|
||||
case *session.SessionToken_Body_Container:
|
||||
ctx, ok := t.ctx.(*ContainerSessionContext)
|
||||
if !ok {
|
||||
ctx = new(ContainerSessionContext)
|
||||
t.ctx = ctx
|
||||
}
|
||||
|
||||
err = ctx.FromGRPCMessage(val.Container)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
|
@ -779,3 +789,87 @@ func (t *SessionTokenBody) FromGRPCMessage(m grpc.Message) error {
|
|||
|
||||
return nil
|
||||
}
|
||||
|
||||
// ContainerSessionVerbToGRPCField converts ContainerSessionVerb
|
||||
// to gRPC-generated session.ContainerSessionContext_Verb.
|
||||
//
|
||||
// If v is outside of the ContainerSessionVerb enum,
|
||||
// session.ContainerSessionContext_VERB_UNSPECIFIED is returned.
|
||||
func ContainerSessionVerbToGRPCField(v ContainerSessionVerb) session.ContainerSessionContext_Verb {
|
||||
switch v {
|
||||
default:
|
||||
return session.ContainerSessionContext_VERB_UNSPECIFIED
|
||||
case ContainerVerbPut:
|
||||
return session.ContainerSessionContext_PUT
|
||||
case ContainerVerbDelete:
|
||||
return session.ContainerSessionContext_DELETE
|
||||
case ContainerVerbSetEACL:
|
||||
return session.ContainerSessionContext_SETEACL
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerSessionVerbFromGRPCField converts gRPC-generated
|
||||
// session.ContainerSessionContext_Verb to ContainerSessionVerb.
|
||||
//
|
||||
// If v is outside of the session.ContainerSessionContext_Verb enum,
|
||||
// ContainerVerbUnknown is returned.
|
||||
func ContainerSessionVerbFromGRPCField(v session.ContainerSessionContext_Verb) ContainerSessionVerb {
|
||||
switch v {
|
||||
default:
|
||||
return ContainerVerbUnknown
|
||||
case session.ContainerSessionContext_PUT:
|
||||
return ContainerVerbPut
|
||||
case session.ContainerSessionContext_DELETE:
|
||||
return ContainerVerbDelete
|
||||
case session.ContainerSessionContext_SETEACL:
|
||||
return ContainerVerbSetEACL
|
||||
}
|
||||
}
|
||||
|
||||
// ToGRPCMessage converts ContainerSessionContext to gRPC-generated
|
||||
// session.ContainerSessionContext message.
|
||||
func (x *ContainerSessionContext) ToGRPCMessage() grpc.Message {
|
||||
var m *session.ContainerSessionContext
|
||||
|
||||
if x != nil {
|
||||
m = new(session.ContainerSessionContext)
|
||||
|
||||
m.SetVerb(ContainerSessionVerbToGRPCField(x.verb))
|
||||
m.SetWildcard(x.wildcard)
|
||||
m.SetContainerId(x.cid.ToGRPCMessage().(*refsGRPC.ContainerID))
|
||||
}
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
// FromGRPCMessage tries to restore ContainerSessionContext from grpc.Message.
|
||||
//
|
||||
// Returns message.ErrUnexpectedMessageType if m is not
|
||||
// a gRPC-generated session.ContainerSessionContext message.
|
||||
func (x *ContainerSessionContext) FromGRPCMessage(m grpc.Message) error {
|
||||
v, ok := m.(*session.ContainerSessionContext)
|
||||
if !ok {
|
||||
return message.NewUnexpectedMessageType(m, v)
|
||||
}
|
||||
|
||||
var err error
|
||||
|
||||
cid := v.GetContainerId()
|
||||
if cid == nil {
|
||||
x.cid = nil
|
||||
} else {
|
||||
if x.cid == nil {
|
||||
x.cid = new(refs.ContainerID)
|
||||
}
|
||||
|
||||
err = x.cid.FromGRPCMessage(cid)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
x.verb = ContainerSessionVerbFromGRPCField(v.GetVerb())
|
||||
x.wildcard = v.GetWildcard()
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -119,3 +119,11 @@ func (r *ResponseVerificationHeader) UnmarshalJSON(data []byte) error {
|
|||
|
||||
return r.FromGRPCMessage(msg)
|
||||
}
|
||||
|
||||
func (x *ContainerSessionContext) MarshalJSON() ([]byte, error) {
|
||||
return message.MarshalJSON(x)
|
||||
}
|
||||
|
||||
func (x *ContainerSessionContext) UnmarshalJSON(data []byte) error {
|
||||
return message.UnmarshalJSON(x, data, new(session.ContainerSessionContext))
|
||||
}
|
||||
|
|
|
@ -29,6 +29,7 @@ const (
|
|||
sessionTokenBodyLifetimeField = 3
|
||||
sessionTokenBodyKeyField = 4
|
||||
sessionTokenBodyObjectCtxField = 5
|
||||
sessionTokenBodyCnrCtxField = 6
|
||||
|
||||
sessionTokenBodyField = 1
|
||||
sessionTokenSignatureField = 2
|
||||
|
@ -301,6 +302,65 @@ func (c *ObjectSessionContext) Unmarshal(data []byte) error {
|
|||
return c.FromGRPCMessage(m)
|
||||
}
|
||||
|
||||
const (
|
||||
_ = iota
|
||||
cnrCtxVerbFNum
|
||||
cnrCtxWildcardFNum
|
||||
cnrCtxCidFNum
|
||||
)
|
||||
|
||||
func (x *ContainerSessionContext) StableMarshal(buf []byte) ([]byte, error) {
|
||||
if x == nil {
|
||||
return []byte{}, nil
|
||||
}
|
||||
|
||||
if buf == nil {
|
||||
buf = make([]byte, x.StableSize())
|
||||
}
|
||||
|
||||
var (
|
||||
offset, n int
|
||||
err error
|
||||
)
|
||||
|
||||
n, err = proto.EnumMarshal(cnrCtxVerbFNum, buf[offset:], int32(ContainerSessionVerbToGRPCField(x.verb)))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
offset += n
|
||||
|
||||
n, err = proto.BoolMarshal(cnrCtxWildcardFNum, buf[offset:], x.wildcard)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
offset += n
|
||||
|
||||
_, err = proto.NestedStructureMarshal(cnrCtxCidFNum, buf[offset:], x.cid)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return buf, nil
|
||||
}
|
||||
|
||||
func (x *ContainerSessionContext) StableSize() (size int) {
|
||||
if x == nil {
|
||||
return 0
|
||||
}
|
||||
|
||||
size += proto.EnumSize(cnrCtxVerbFNum, int32(ContainerSessionVerbToGRPCField(x.verb)))
|
||||
size += proto.BoolSize(cnrCtxWildcardFNum, x.wildcard)
|
||||
size += proto.NestedStructureSize(cnrCtxCidFNum, x.cid)
|
||||
|
||||
return size
|
||||
}
|
||||
|
||||
func (x *ContainerSessionContext) Unmarshal(data []byte) error {
|
||||
return message.Unmarshal(x, data, new(session.ContainerSessionContext))
|
||||
}
|
||||
|
||||
func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) {
|
||||
if t == nil {
|
||||
return []byte{}, nil
|
||||
|
@ -350,6 +410,11 @@ func (t *SessionTokenBody) StableMarshal(buf []byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
case *ContainerSessionContext:
|
||||
_, err = proto.NestedStructureMarshal(sessionTokenBodyCnrCtxField, buf[offset:], v)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
default:
|
||||
panic("cannot marshal unknown session token context")
|
||||
}
|
||||
|
@ -372,6 +437,8 @@ func (t *SessionTokenBody) StableSize() (size int) {
|
|||
switch v := t.ctx.(type) {
|
||||
case *ObjectSessionContext:
|
||||
size += proto.NestedStructureSize(sessionTokenBodyObjectCtxField, v)
|
||||
case *ContainerSessionContext:
|
||||
size += proto.NestedStructureSize(sessionTokenBodyCnrCtxField, v)
|
||||
default:
|
||||
panic("cannot marshal unknown session token context")
|
||||
}
|
||||
|
|
|
@ -22,5 +22,6 @@ func TestMessageConvert(t *testing.T) {
|
|||
func(empty bool) message.Message { return sessiontest.GenerateRequestVerificationHeader(empty) },
|
||||
func(empty bool) message.Message { return sessiontest.GenerateResponseMetaHeader(empty) },
|
||||
func(empty bool) message.Message { return sessiontest.GenerateResponseVerificationHeader(empty) },
|
||||
func(empty bool) message.Message { return sessiontest.GenerateContainerSessionContext(empty) },
|
||||
)
|
||||
}
|
||||
|
|
|
@ -179,6 +179,19 @@ func GenerateObjectSessionContext(empty bool) *session.ObjectSessionContext {
|
|||
return m
|
||||
}
|
||||
|
||||
func GenerateContainerSessionContext(empty bool) *session.ContainerSessionContext {
|
||||
m := new(session.ContainerSessionContext)
|
||||
|
||||
if !empty {
|
||||
m.SetVerb(session.ContainerVerbDelete)
|
||||
m.SetWildcard(true)
|
||||
}
|
||||
|
||||
m.SetContainerID(refstest.GenerateContainerID(empty))
|
||||
|
||||
return m
|
||||
}
|
||||
|
||||
func GenerateXHeader(empty bool) *session.XHeader {
|
||||
m := new(session.XHeader)
|
||||
|
||||
|
|
|
@ -735,3 +735,81 @@ func (t *SessionToken) SetSignature(v *refs.Signature) {
|
|||
t.sig = v
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerSessionVerb represents NeoFS API v2
|
||||
// session.ContainerSessionContext.Verb enumeration.
|
||||
type ContainerSessionVerb uint32
|
||||
|
||||
const (
|
||||
// ContainerVerbUnknown corresponds to VERB_UNSPECIFIED enum value.
|
||||
ContainerVerbUnknown ContainerSessionVerb = iota
|
||||
|
||||
// ContainerVerbPut corresponds to PUT enum value.
|
||||
ContainerVerbPut
|
||||
|
||||
// ContainerVerbDelete corresponds to DELETE enum value.
|
||||
ContainerVerbDelete
|
||||
|
||||
// ContainerVerbSetEACL corresponds to SETEACL enum value.
|
||||
ContainerVerbSetEACL
|
||||
)
|
||||
|
||||
// ContainerSessionContext represents structure of the
|
||||
// NeoFS API v2 session.ContainerSessionContext message.
|
||||
type ContainerSessionContext struct {
|
||||
verb ContainerSessionVerb
|
||||
|
||||
wildcard bool
|
||||
|
||||
cid *refs.ContainerID
|
||||
}
|
||||
|
||||
func (x *ContainerSessionContext) sessionTokenContext() {}
|
||||
|
||||
// Verb returns type of request for which the token is issued.
|
||||
func (x *ContainerSessionContext) Verb() ContainerSessionVerb {
|
||||
if x != nil {
|
||||
return x.verb
|
||||
}
|
||||
|
||||
return ContainerVerbUnknown
|
||||
}
|
||||
|
||||
// SetVerb sets type of request for which the token is issued.
|
||||
func (x *ContainerSessionContext) SetVerb(v ContainerSessionVerb) {
|
||||
if x != nil {
|
||||
x.verb = v
|
||||
}
|
||||
}
|
||||
|
||||
// Wildcard returns wildcard flag of the container session.
|
||||
func (x *ContainerSessionContext) Wildcard() bool {
|
||||
if x != nil {
|
||||
return x.wildcard
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// SetWildcard sets wildcard flag of the container session.
|
||||
func (x *ContainerSessionContext) SetWildcard(v bool) {
|
||||
if x != nil {
|
||||
x.wildcard = v
|
||||
}
|
||||
}
|
||||
|
||||
// ContainerID returns identifier of the container related to the session.
|
||||
func (x *ContainerSessionContext) ContainerID() *refs.ContainerID {
|
||||
if x != nil {
|
||||
return x.cid
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
// SetContainerID sets identifier of the container related to the session.
|
||||
func (x *ContainerSessionContext) SetContainerID(v *refs.ContainerID) {
|
||||
if x != nil {
|
||||
x.cid = v
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue