From 933bcf300f0a4109ac3b60397764bd59cb4a5c24 Mon Sep 17 00:00:00 2001 From: Alex Vanin Date: Thu, 20 Aug 2020 13:07:35 +0300 Subject: [PATCH] Move bearer token to acl package Signed-off-by: Alex Vanin --- v2/acl/convert.go | 108 ++++++++++++++++++++++++++++++ v2/acl/grpc/types.go | 56 ++++++++++++++++ v2/acl/marshal.go | 147 +++++++++++++++++++++++++++++++++++++++++ v2/acl/marshal_test.go | 96 +++++++++++++++++++++++++++ v2/acl/types.go | 130 ++++++++++++++++++++++++++++++++++++ 5 files changed, 537 insertions(+) diff --git a/v2/acl/convert.go b/v2/acl/convert.go index bf65685..7bf1684 100644 --- a/v2/acl/convert.go +++ b/v2/acl/convert.go @@ -348,3 +348,111 @@ func TableFromGRPCMessage(m *acl.EACLTable) *Table { return t } + +func TokenLifetimeToGRPCMessage(tl *TokenLifetime) *acl.BearerToken_Body_TokenLifetime { + if tl == nil { + return nil + } + + m := new(acl.BearerToken_Body_TokenLifetime) + + m.SetExp(tl.GetExp()) + m.SetNbf(tl.GetNbf()) + m.SetIat(tl.GetIat()) + + return m +} + +func TokenLifetimeFromGRPCMessage(m *acl.BearerToken_Body_TokenLifetime) *TokenLifetime { + if m == nil { + return nil + } + + tl := new(TokenLifetime) + + tl.SetExp(m.GetExp()) + tl.SetNbf(m.GetNbf()) + tl.SetIat(m.GetIat()) + + return tl +} + +func BearerTokenBodyToGRPCMessage(v *BearerTokenBody) *acl.BearerToken_Body { + if v == nil { + return nil + } + + m := new(acl.BearerToken_Body) + + m.SetEaclTable( + TableToGRPCMessage(v.GetEACL()), + ) + + m.SetOwnerId( + refs.OwnerIDToGRPCMessage(v.GetOwnerID()), + ) + + m.SetLifetime( + TokenLifetimeToGRPCMessage(v.GetLifetime()), + ) + + return m +} + +func BearerTokenBodyFromGRPCMessage(m *acl.BearerToken_Body) *BearerTokenBody { + if m == nil { + return nil + } + + bt := new(BearerTokenBody) + + bt.SetEACL( + TableFromGRPCMessage(m.GetEaclTable()), + ) + + bt.SetOwnerID( + refs.OwnerIDFromGRPCMessage(m.GetOwnerId()), + ) + + bt.SetLifetime( + TokenLifetimeFromGRPCMessage(m.GetLifetime()), + ) + + return bt +} + +func BearerTokenToGRPCMessage(t *BearerToken) *acl.BearerToken { + if t == nil { + return nil + } + + m := new(acl.BearerToken) + + m.SetBody( + BearerTokenBodyToGRPCMessage(t.GetBody()), + ) + + m.SetSignature( + refs.SignatureToGRPCMessage(t.GetSignature()), + ) + + return m +} + +func BearerTokenFromGRPCMessage(m *acl.BearerToken) *BearerToken { + if m == nil { + return nil + } + + bt := new(BearerToken) + + bt.SetBody( + BearerTokenBodyFromGRPCMessage(m.GetBody()), + ) + + bt.SetSignature( + refs.SignatureFromGRPCMessage(m.GetSignature()), + ) + + return bt +} diff --git a/v2/acl/grpc/types.go b/v2/acl/grpc/types.go index da83e24..875efa3 100644 --- a/v2/acl/grpc/types.go +++ b/v2/acl/grpc/types.go @@ -87,3 +87,59 @@ func (m *EACLRecord_TargetInfo) SetKeyList(v [][]byte) { m.KeyList = v } } + +// SetEaclTable sets eACL table of the bearer token. +func (m *BearerToken_Body) SetEaclTable(v *EACLTable) { + if m != nil { + m.EaclTable = v + } +} + +// SetOwnerId sets identifier of the bearer token owner. +func (m *BearerToken_Body) SetOwnerId(v *refs.OwnerID) { + if m != nil { + m.OwnerId = v + } +} + +// SetLifetime sets lifetime of the bearer token. +func (m *BearerToken_Body) SetLifetime(v *BearerToken_Body_TokenLifetime) { + if m != nil { + m.Lifetime = v + } +} + +// SetBody sets bearer token body. +func (m *BearerToken) SetBody(v *BearerToken_Body) { + if m != nil { + m.Body = v + } +} + +// SetSignature sets bearer token signature. +func (m *BearerToken) SetSignature(v *refs.Signature) { + if m != nil { + m.Signature = v + } +} + +// SetExp sets epoch number of the token expiration. +func (m *BearerToken_Body_TokenLifetime) SetExp(v uint64) { + if m != nil { + m.Exp = v + } +} + +// SetNbf sets starting epoch number of the token. +func (m *BearerToken_Body_TokenLifetime) SetNbf(v uint64) { + if m != nil { + m.Nbf = v + } +} + +// SetIat sets the number of the epoch in which the token was issued. +func (m *BearerToken_Body_TokenLifetime) SetIat(v uint64) { + if m != nil { + m.Iat = v + } +} diff --git a/v2/acl/marshal.go b/v2/acl/marshal.go index e596c0e..ccf5760 100644 --- a/v2/acl/marshal.go +++ b/v2/acl/marshal.go @@ -20,6 +20,17 @@ const ( tableContainerIDField = 1 tableRecordsField = 2 + + lifetimeExpirationField = 1 + lifetimeNotValidBeforeField = 2 + lifetimeIssuedAtField = 3 + + bearerTokenBodyACLField = 1 + bearerTokenBodyOwnerField = 2 + bearerTokenBodyLifetimeField = 3 + + bearerTokenBodyField = 1 + bearerTokenSignatureField = 2 ) // StableMarshal marshals unified acl table structure in a protobuf @@ -244,3 +255,139 @@ func (t *TargetInfo) StableSize() (size int) { return size } + +func (l *TokenLifetime) StableMarshal(buf []byte) ([]byte, error) { + if l == nil { + return []byte{}, nil + } + + if buf == nil { + buf = make([]byte, l.StableSize()) + } + + var ( + offset, n int + err error + ) + + n, err = proto.UInt64Marshal(lifetimeExpirationField, buf[offset:], l.exp) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.UInt64Marshal(lifetimeNotValidBeforeField, buf[offset:], l.nbf) + if err != nil { + return nil, err + } + + offset += n + + _, err = proto.UInt64Marshal(lifetimeIssuedAtField, buf[offset:], l.iat) + if err != nil { + return nil, err + } + + return buf, nil +} + +func (l *TokenLifetime) StableSize() (size int) { + if l == nil { + return 0 + } + + size += proto.UInt64Size(lifetimeExpirationField, l.exp) + size += proto.UInt64Size(lifetimeNotValidBeforeField, l.nbf) + size += proto.UInt64Size(lifetimeIssuedAtField, l.iat) + + return size +} + +func (bt *BearerTokenBody) StableMarshal(buf []byte) ([]byte, error) { + if bt == nil { + return []byte{}, nil + } + + if buf == nil { + buf = make([]byte, bt.StableSize()) + } + + var ( + offset, n int + err error + ) + + n, err = proto.NestedStructureMarshal(bearerTokenBodyACLField, buf[offset:], bt.eacl) + if err != nil { + return nil, err + } + + offset += n + + n, err = proto.NestedStructureMarshal(bearerTokenBodyOwnerField, buf[offset:], bt.ownerID) + if err != nil { + return nil, err + } + + offset += n + + _, err = proto.NestedStructureMarshal(bearerTokenBodyLifetimeField, buf[offset:], bt.lifetime) + if err != nil { + return nil, err + } + + return buf, nil +} + +func (bt *BearerTokenBody) StableSize() (size int) { + if bt == nil { + return 0 + } + + size += proto.NestedStructureSize(bearerTokenBodyACLField, bt.eacl) + size += proto.NestedStructureSize(bearerTokenBodyOwnerField, bt.ownerID) + size += proto.NestedStructureSize(bearerTokenBodyLifetimeField, bt.lifetime) + + return size +} + +func (bt *BearerToken) StableMarshal(buf []byte) ([]byte, error) { + if bt == nil { + return []byte{}, nil + } + + if buf == nil { + buf = make([]byte, bt.StableSize()) + } + + var ( + offset, n int + err error + ) + + n, err = proto.NestedStructureMarshal(bearerTokenBodyField, buf[offset:], bt.body) + if err != nil { + return nil, err + } + + offset += n + + _, err = proto.NestedStructureMarshal(bearerTokenSignatureField, buf[offset:], bt.sig) + if err != nil { + return nil, err + } + + return buf, nil +} + +func (bt *BearerToken) StableSize() (size int) { + if bt == nil { + return 0 + } + + size += proto.NestedStructureSize(bearerTokenBodyField, bt.body) + size += proto.NestedStructureSize(bearerTokenSignatureField, bt.sig) + + return size +} diff --git a/v2/acl/marshal_test.go b/v2/acl/marshal_test.go index c5de1c8..cd471d7 100644 --- a/v2/acl/marshal_test.go +++ b/v2/acl/marshal_test.go @@ -61,6 +61,54 @@ func generateRecord(another bool) *acl.Record { return record } +func generateEACL() *acl.Table { + cid := new(refs.ContainerID) + cid.SetValue([]byte("Container ID")) + + table := new(acl.Table) + table.SetContainerID(cid) + table.SetRecords([]*acl.Record{generateRecord(true)}) + + return table +} + +func generateSignature(k, v string) *refs.Signature { + sig := new(refs.Signature) + sig.SetKey([]byte(k)) + sig.SetSign([]byte(v)) + + return sig +} + +func generateLifetime(exp, nbf, iat uint64) *acl.TokenLifetime { + lifetime := new(acl.TokenLifetime) + lifetime.SetExp(exp) + lifetime.SetNbf(nbf) + lifetime.SetIat(iat) + + return lifetime +} + +func generateBearerTokenBody(id string) *acl.BearerTokenBody { + owner := new(refs.OwnerID) + owner.SetValue([]byte(id)) + + tokenBody := new(acl.BearerTokenBody) + tokenBody.SetOwnerID(owner) + tokenBody.SetLifetime(generateLifetime(1, 2, 3)) + tokenBody.SetEACL(generateEACL()) + + return tokenBody +} + +func generateBearerToken(id string) *acl.BearerToken { + bearerToken := new(acl.BearerToken) + bearerToken.SetBody(generateBearerTokenBody(id)) + bearerToken.SetSignature(generateSignature("id", id)) + + return bearerToken +} + func TestHeaderFilter_StableMarshal(t *testing.T) { filterFrom := generateFilter(acl.HeaderTypeObject, "CID", "Container ID Value") transport := new(grpc.EACLRecord_FilterInfo) @@ -144,3 +192,51 @@ func TestTable_StableMarshal(t *testing.T) { require.Equal(t, tableFrom, tableTo) }) } + +func TestTokenLifetime_StableMarshal(t *testing.T) { + lifetimeFrom := generateLifetime(10, 20, 30) + transport := new(grpc.BearerToken_Body_TokenLifetime) + + t.Run("non empty", func(t *testing.T) { + wire, err := lifetimeFrom.StableMarshal(nil) + require.NoError(t, err) + + err = transport.Unmarshal(wire) + require.NoError(t, err) + + lifetimeTo := acl.TokenLifetimeFromGRPCMessage(transport) + require.Equal(t, lifetimeFrom, lifetimeTo) + }) +} + +func TestBearerTokenBody_StableMarshal(t *testing.T) { + bearerTokenBodyFrom := generateBearerTokenBody("Bearer Token Body") + transport := new(grpc.BearerToken_Body) + + t.Run("non empty", func(t *testing.T) { + wire, err := bearerTokenBodyFrom.StableMarshal(nil) + require.NoError(t, err) + + err = transport.Unmarshal(wire) + require.NoError(t, err) + + bearerTokenBodyTo := acl.BearerTokenBodyFromGRPCMessage(transport) + require.Equal(t, bearerTokenBodyFrom, bearerTokenBodyTo) + }) +} + +func TestBearerToken_StableMarshal(t *testing.T) { + bearerTokenFrom := generateBearerToken("Bearer Token") + transport := new(grpc.BearerToken) + + t.Run("non empty", func(t *testing.T) { + wire, err := bearerTokenFrom.StableMarshal(nil) + require.NoError(t, err) + + err = transport.Unmarshal(wire) + require.NoError(t, err) + + bearerTokenTo := acl.BearerTokenFromGRPCMessage(transport) + require.Equal(t, bearerTokenFrom, bearerTokenTo) + }) +} diff --git a/v2/acl/types.go b/v2/acl/types.go index 5fb1b6b..5a50b88 100644 --- a/v2/acl/types.go +++ b/v2/acl/types.go @@ -40,6 +40,24 @@ type Table struct { records []*Record } +type TokenLifetime struct { + exp, nbf, iat uint64 +} + +type BearerTokenBody struct { + eacl *Table + + ownerID *refs.OwnerID + + lifetime *TokenLifetime +} + +type BearerToken struct { + body *BearerTokenBody + + sig *refs.Signature +} + // TargetInfo is a unified enum of MatchType enum from proto definition. type MatchType uint32 @@ -258,3 +276,115 @@ func (t *Table) SetRecords(v []*Record) { t.records = v } } + +func (l *TokenLifetime) GetExp() uint64 { + if l != nil { + return l.exp + } + + return 0 +} + +func (l *TokenLifetime) SetExp(v uint64) { + if l != nil { + l.exp = v + } +} + +func (l *TokenLifetime) GetNbf() uint64 { + if l != nil { + return l.nbf + } + + return 0 +} + +func (l *TokenLifetime) SetNbf(v uint64) { + if l != nil { + l.nbf = v + } +} + +func (l *TokenLifetime) GetIat() uint64 { + if l != nil { + return l.iat + } + + return 0 +} + +func (l *TokenLifetime) SetIat(v uint64) { + if l != nil { + l.iat = v + } +} + +func (bt *BearerTokenBody) GetEACL() *Table { + if bt != nil { + return bt.eacl + } + + return nil +} + +func (bt *BearerTokenBody) SetEACL(v *Table) { + if bt != nil { + bt.eacl = v + } +} + +func (bt *BearerTokenBody) GetOwnerID() *refs.OwnerID { + if bt != nil { + return bt.ownerID + } + + return nil +} + +func (bt *BearerTokenBody) SetOwnerID(v *refs.OwnerID) { + if bt != nil { + bt.ownerID = v + } +} + +func (bt *BearerTokenBody) GetLifetime() *TokenLifetime { + if bt != nil { + return bt.lifetime + } + + return nil +} + +func (bt *BearerTokenBody) SetLifetime(v *TokenLifetime) { + if bt != nil { + bt.lifetime = v + } +} + +func (bt *BearerToken) GetBody() *BearerTokenBody { + if bt != nil { + return bt.body + } + + return nil +} + +func (bt *BearerToken) SetBody(v *BearerTokenBody) { + if bt != nil { + bt.body = v + } +} + +func (bt *BearerToken) GetSignature() *refs.Signature { + if bt != nil { + return bt.sig + } + + return nil +} + +func (bt *BearerToken) SetSignature(v *refs.Signature) { + if bt != nil { + bt.sig = v + } +}