frostfs-s3-gw/creds/accessbox/accessbox_test.go

320 lines
8 KiB
Go
Raw Permalink Normal View History

package accessbox
import (
"encoding/hex"
"testing"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/bearer"
frostfsecdsa "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/crypto/ecdsa"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/eacl"
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/session"
"github.com/google/uuid"
"github.com/nspcc-dev/neo-go/pkg/crypto/keys"
"github.com/stretchr/testify/require"
)
func assertBearerToken(t *testing.T, exp, act bearer.Token) {
// compare binary representations since deep equal is not guaranteed
require.Equal(t, exp.Marshal(), act.Marshal())
}
func TestTokensEncryptDecrypt(t *testing.T) {
var (
tkn bearer.Token
tkn2 bearer.Token
)
sec, err := keys.NewPrivateKey()
require.NoError(t, err)
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
tkn.SetEACLTable(*eacl.NewTable())
require.NoError(t, tkn.Sign(sec.PrivateKey))
data, err := encrypt(cred, cred.PublicKey(), tkn.Marshal())
require.NoError(t, err)
rawTkn2, err := decrypt(cred, cred.PublicKey(), data)
require.NoError(t, err)
err = tkn2.Unmarshal(rawTkn2)
require.NoError(t, err)
assertBearerToken(t, tkn, tkn2)
}
func TestBearerTokenInAccessBox(t *testing.T) {
var (
box *AccessBox
box2 AccessBox
tkn bearer.Token
)
sec, err := keys.NewPrivateKey()
require.NoError(t, err)
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
tkn.SetEACLTable(*eacl.NewTable())
require.NoError(t, tkn.Sign(sec.PrivateKey))
gate := NewGateData(cred.PublicKey(), &tkn)
box, _, err = PackTokens([]*GateData{gate}, nil, false)
require.NoError(t, err)
data, err := box.Marshal()
require.NoError(t, err)
err = box2.Unmarshal(data)
require.NoError(t, err)
tkns, err := box2.GetTokens(cred)
require.NoError(t, err)
assertBearerToken(t, tkn, *tkns.BearerToken)
}
func TestSessionTokenInAccessBox(t *testing.T) {
var (
box *AccessBox
box2 AccessBox
tkn = new(session.Container)
)
sec, err := keys.NewPrivateKey()
require.NoError(t, err)
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
tkn.SetID(uuid.New())
tkn.SetAuthKey((*frostfsecdsa.PublicKey)(sec.PublicKey()))
require.NoError(t, tkn.Sign(sec.PrivateKey))
var newTkn bearer.Token
gate := NewGateData(cred.PublicKey(), &newTkn)
gate.SessionTokens = []*session.Container{tkn}
box, _, err = PackTokens([]*GateData{gate}, nil, false)
require.NoError(t, err)
data, err := box.Marshal()
require.NoError(t, err)
err = box2.Unmarshal(data)
require.NoError(t, err)
tkns, err := box2.GetTokens(cred)
require.NoError(t, err)
require.Equal(t, []*session.Container{tkn}, tkns.SessionTokens)
}
func TestAccessboxMultipleKeys(t *testing.T) {
var (
box *AccessBox
tkn bearer.Token
)
sec, err := keys.NewPrivateKey()
require.NoError(t, err)
tkn.SetEACLTable(*eacl.NewTable())
require.NoError(t, tkn.Sign(sec.PrivateKey))
count := 10
gates := make([]*GateData, 0, count)
privateKeys := make([]*keys.PrivateKey, 0, count)
{ // generate keys
for i := 0; i < count; i++ {
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
gates = append(gates, NewGateData(cred.PublicKey(), &tkn))
privateKeys = append(privateKeys, cred)
}
}
box, _, err = PackTokens(gates, nil, false)
require.NoError(t, err)
for i, k := range privateKeys {
tkns, err := box.GetTokens(k)
require.NoError(t, err, "key #%d: %s failed", i, k)
assertBearerToken(t, tkn, *tkns.BearerToken)
}
}
func TestUnknownKey(t *testing.T) {
var (
box *AccessBox
tkn bearer.Token
)
sec, err := keys.NewPrivateKey()
require.NoError(t, err)
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
wrongCred, err := keys.NewPrivateKey()
require.NoError(t, err)
tkn.SetEACLTable(*eacl.NewTable())
require.NoError(t, tkn.Sign(sec.PrivateKey))
gate := NewGateData(cred.PublicKey(), &tkn)
box, _, err = PackTokens([]*GateData{gate}, nil, false)
require.NoError(t, err)
_, err = box.GetTokens(wrongCred)
require.Error(t, err)
}
func TestGateDataSessionToken(t *testing.T) {
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
var tkn bearer.Token
gate := NewGateData(cred.PublicKey(), &tkn)
require.Equal(t, cred.PublicKey(), gate.GateKey)
assertBearerToken(t, tkn, *gate.BearerToken)
t.Run("session token for put", func(t *testing.T) {
gate.SessionTokens = []*session.Container{}
sessionTkn := gate.SessionTokenForPut()
require.Nil(t, sessionTkn)
sessionTknPut := new(session.Container)
sessionTknPut.ForVerb(session.VerbContainerPut)
gate.SessionTokens = []*session.Container{sessionTknPut}
sessionTkn = gate.SessionTokenForPut()
require.Equal(t, sessionTknPut, sessionTkn)
})
t.Run("session token for delete", func(t *testing.T) {
gate.SessionTokens = []*session.Container{}
sessionTkn := gate.SessionTokenForDelete()
require.Nil(t, sessionTkn)
sessionTknDelete := new(session.Container)
sessionTknDelete.ForVerb(session.VerbContainerDelete)
gate.SessionTokens = []*session.Container{sessionTknDelete}
sessionTkn = gate.SessionTokenForDelete()
require.Equal(t, sessionTknDelete, sessionTkn)
})
t.Run("session token", func(t *testing.T) {
gate.SessionTokens = []*session.Container{}
sessionTkn := gate.SessionToken()
require.Nil(t, sessionTkn)
sessionTknPut := new(session.Container)
sessionTknPut.ForVerb(session.VerbContainerPut)
gate.SessionTokens = []*session.Container{sessionTknPut}
sessionTkn = gate.SessionToken()
require.Equal(t, sessionTkn, sessionTknPut)
})
}
func TestGetBox(t *testing.T) {
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
var tkn bearer.Token
gate := NewGateData(cred.PublicKey(), &tkn)
secret := []byte("secret")
t.Run("regular secret", func(t *testing.T) {
accessBox, secrets, err := PackTokens([]*GateData{gate}, secret, false)
require.NoError(t, err)
require.Equal(t, hex.EncodeToString(secret), secrets.SecretKey)
box, err := accessBox.GetBox(cred)
require.NoError(t, err)
require.Equal(t, hex.EncodeToString(secret), box.Gate.SecretKey)
})
t.Run("custom secret", func(t *testing.T) {
accessBox, secrets, err := PackTokens([]*GateData{gate}, secret, true)
require.NoError(t, err)
require.Equal(t, string(secret), secrets.SecretKey)
box, err := accessBox.GetBox(cred)
require.NoError(t, err)
require.Equal(t, string(secret), box.Gate.SecretKey)
})
}
func TestAccessBox(t *testing.T) {
cred, err := keys.NewPrivateKey()
require.NoError(t, err)
var tkn bearer.Token
gate := NewGateData(cred.PublicKey(), &tkn)
accessBox, _, err := PackTokens([]*GateData{gate}, nil, false)
require.NoError(t, err)
t.Run("invalid owner", func(t *testing.T) {
randomKey, err := keys.NewPrivateKey()
require.NoError(t, err)
_, err = accessBox.GetTokens(randomKey)
require.Error(t, err)
_, err = accessBox.GetBox(randomKey)
require.Error(t, err)
})
t.Run("empty placement policy", func(t *testing.T) {
policy, err := accessBox.GetPlacementPolicy()
require.NoError(t, err)
require.Nil(t, policy)
})
t.Run("get correct placement policy", func(t *testing.T) {
policy := &AccessBox_ContainerPolicy{LocationConstraint: "locationConstraint"}
accessBox.ContainerPolicy = []*AccessBox_ContainerPolicy{policy}
policies, err := accessBox.GetPlacementPolicy()
require.NoError(t, err)
require.Len(t, policies, 1)
require.Equal(t, policy.LocationConstraint, policies[0].LocationConstraint)
})
t.Run("get incorrect placement policy", func(t *testing.T) {
policy := &AccessBox_ContainerPolicy{
LocationConstraint: "locationConstraint",
Policy: []byte("policy"),
}
accessBox.ContainerPolicy = []*AccessBox_ContainerPolicy{policy}
_, err = accessBox.GetPlacementPolicy()
require.Error(t, err)
_, err = accessBox.GetBox(cred)
require.Error(t, err)
})
t.Run("empty seed key", func(t *testing.T) {
accessBox.SeedKey = nil
_, err = accessBox.GetTokens(cred)
require.Error(t, err)
_, err = accessBox.GetBox(cred)
require.Error(t, err)
})
t.Run("invalid gate key", func(t *testing.T) {
gate = &GateData{
BearerToken: &tkn,
GateKey: &keys.PublicKey{},
}
_, _, err = PackTokens([]*GateData{gate}, nil, false)
require.Error(t, err)
})
}