forked from TrueCloudLab/frostfs-s3-gw
319 lines
8.1 KiB
Go
319 lines
8.1 KiB
Go
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, false)
|
|
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, false)
|
|
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, false)
|
|
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, false)
|
|
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, false)
|
|
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, true)
|
|
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, false)
|
|
require.Error(t, err)
|
|
|
|
_, err = accessBox.GetBox(randomKey, false)
|
|
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, false)
|
|
require.Error(t, err)
|
|
})
|
|
|
|
t.Run("empty seed key", func(t *testing.T) {
|
|
accessBox.SeedKey = nil
|
|
|
|
_, err = accessBox.GetTokens(cred, false)
|
|
require.Error(t, err)
|
|
|
|
_, err = accessBox.GetBox(cred, false)
|
|
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)
|
|
})
|
|
}
|