More functioning auth tests

This commit is contained in:
Ethan Frey 2017-10-24 16:56:16 +02:00
parent 3aeab43acb
commit d2ed8c8871
5 changed files with 138 additions and 86 deletions

View File

@ -39,7 +39,7 @@ func (o oneSig) GetTx() interface{} {
return o.Data
}
func OneSig(data []byte) keys.Signable {
func newSingle(data []byte) oneSig {
return oneSig{
Data: util.NewRawTx(data),
NamedSig: NewSig(),
@ -76,7 +76,7 @@ func (m multiSig) GetTx() interface{} {
return m.Data
}
func MultiSig(data []byte) keys.Signable {
func newMulti(data []byte) multiSig {
return multiSig{
Data: util.NewRawTx(data),
NamedSigs: NewMultiSig(),

View File

@ -1,97 +1,97 @@
package auth
// import (
// "strconv"
// "testing"
import (
"strconv"
"testing"
// "github.com/stretchr/testify/assert"
"github.com/stretchr/testify/assert"
// crypto "github.com/tendermint/go-crypto"
crypto "github.com/tendermint/go-crypto"
// sdk "github.com/cosmos/cosmos-sdk"
// "github.com/cosmos/cosmos-sdk/state"
// "github.com/cosmos/cosmos-sdk/util"
// )
sdk "github.com/cosmos/cosmos-sdk"
"github.com/cosmos/cosmos-sdk/state"
"github.com/cosmos/cosmos-sdk/util"
)
// func TestSignatureChecks(t *testing.T) {
// assert := assert.New(t)
func TestSignatureChecks(t *testing.T) {
assert := assert.New(t)
// // generic args
// ctx := util.MockContext("test-chain", 100)
// store := state.NewMemKVStore()
// raw := util.NewRawTx([]byte{1, 2, 3, 4})
// generic args
ctx := util.MockContext("test-chain", 100)
store := state.NewMemKVStore()
raw := []byte{1, 2, 3, 4}
// // let's make some keys....
// priv1 := crypto.GenPrivKeyEd25519().Wrap()
// actor1 := SigPerm(priv1.PubKey().Address())
// priv2 := crypto.GenPrivKeySecp256k1().Wrap()
// actor2 := SigPerm(priv2.PubKey().Address())
// let's make some keys....
priv1 := crypto.GenPrivKeyEd25519().Wrap()
actor1 := SigPerm(priv1.PubKey().Address())
priv2 := crypto.GenPrivKeySecp256k1().Wrap()
actor2 := SigPerm(priv2.PubKey().Address())
// // test cases to make sure signature checks are solid
// cases := []struct {
// useMultiSig bool
// keys []crypto.PrivKey
// check sdk.Actor
// valid bool
// }{
// // test with single sigs
// {false, []crypto.PrivKey{priv1}, actor1, true},
// {false, []crypto.PrivKey{priv1}, actor2, false},
// {false, []crypto.PrivKey{priv2}, actor2, true},
// {false, []crypto.PrivKey{}, actor2, false},
// test cases to make sure signature checks are solid
cases := []struct {
useMultiSig bool
keys []crypto.PrivKey
check sdk.Actor
valid bool
}{
// test with single sigs
{false, []crypto.PrivKey{priv1}, actor1, true},
{false, []crypto.PrivKey{priv1}, actor2, false},
{false, []crypto.PrivKey{priv2}, actor2, true},
{false, []crypto.PrivKey{}, actor2, false},
// // same with multi sigs
// {true, []crypto.PrivKey{priv1}, actor1, true},
// {true, []crypto.PrivKey{priv1}, actor2, false},
// {true, []crypto.PrivKey{priv2}, actor2, true},
// {true, []crypto.PrivKey{}, actor2, false},
// same with multi sigs
{true, []crypto.PrivKey{priv1}, actor1, true},
{true, []crypto.PrivKey{priv1}, actor2, false},
{true, []crypto.PrivKey{priv2}, actor2, true},
{true, []crypto.PrivKey{}, actor2, false},
// // make sure both match on a multisig
// {true, []crypto.PrivKey{priv1, priv2}, actor1, true},
// {true, []crypto.PrivKey{priv1, priv2}, actor2, true},
// }
// make sure both match on a multisig
{true, []crypto.PrivKey{priv1, priv2}, actor1, true},
{true, []crypto.PrivKey{priv1, priv2}, actor2, true},
}
// for i, tc := range cases {
// idx := strconv.Itoa(i)
for i, tc := range cases {
idx := strconv.Itoa(i)
// // make the stack check for the given permission
// app := sdk.ChainDecorators(
// Signatures{},
// util.CheckMiddleware{Required: tc.check},
// ).WithHandler(
// util.OKHandler{},
// )
// make the stack check for the given permission
app := sdk.ChainDecorators(
Signatures{},
util.CheckDecorator{Required: tc.check},
).WithHandler(
util.OKHandler{},
)
// var tx sdk.Tx
// // this does the signing as needed
// if tc.useMultiSig {
// mtx := NewMulti(raw)
// for _, k := range tc.keys {
// err := Sign(mtx, k)
// assert.Nil(err, "%d: %+v", i, err)
// }
// tx = mtx.Wrap()
// } else {
// otx := NewSig(raw)
// for _, k := range tc.keys {
// err := Sign(otx, k)
// assert.Nil(err, "%d: %+v", i, err)
// }
// tx = otx.Wrap()
// }
var tx interface{}
// this does the signing as needed
if tc.useMultiSig {
mtx := newMulti(raw)
for _, k := range tc.keys {
err := Sign(mtx.SignBytes(), k, mtx.NamedSigs)
assert.Nil(err, "%d: %+v", i, err)
}
tx = mtx
} else {
otx := newSingle(raw)
for _, k := range tc.keys {
err := Sign(otx.SignBytes(), k, otx.NamedSig)
assert.Nil(err, "%d: %+v", i, err)
}
tx = otx
}
// _, err := app.CheckTx(ctx, store, tx)
// if tc.valid {
// assert.Nil(err, "%d: %+v", i, err)
// } else {
// assert.NotNil(err, idx)
// }
_, err := app.CheckTx(ctx, store, tx)
if tc.valid {
assert.Nil(err, "%d: %+v", i, err)
} else {
assert.NotNil(err, idx)
}
// _, err = app.DeliverTx(ctx, store, tx)
// if tc.valid {
// assert.Nil(err, "%d: %+v", i, err)
// } else {
// assert.NotNil(err, idx)
// }
// }
// }
_, err = app.DeliverTx(ctx, store, tx)
if tc.valid {
assert.Nil(err, "%d: %+v", i, err)
} else {
assert.NotNil(err, idx)
}
}
}

View File

@ -25,7 +25,6 @@ import (
// Credential can be combined with message data
// to create a keys.Signable
type Credential interface {
Empty() bool
Sign(pubkey crypto.PubKey, sig crypto.Signature) error
Signers(signBytes []byte) ([]crypto.PubKey, error)
}

View File

@ -52,7 +52,7 @@ func TestOneSig(t *testing.T) {
}
for _, tc := range cases {
tx := OneSig([]byte(tc.data))
tx := newSingle([]byte(tc.data))
// unsigned version
_, err = tx.Signers()
assert.NotNil(err)
@ -117,7 +117,7 @@ func TestMultiSig(t *testing.T) {
}
for _, tc := range cases {
tx := MultiSig([]byte(tc.data))
tx := newMulti([]byte(tc.data))
// unsigned version
_, err = tx.Signers()
assert.NotNil(err)

53
util/decorators.go Normal file
View File

@ -0,0 +1,53 @@
package util
import (
sdk "github.com/cosmos/cosmos-sdk"
"github.com/cosmos/cosmos-sdk/errors"
)
// CheckDecorator returns an error if the tx doesn't have auth of this
// Required Actor, otherwise passes along the call untouched
type CheckDecorator struct {
Required sdk.Actor
}
var _ sdk.Decorator = CheckDecorator{}
func (p CheckDecorator) CheckTx(ctx sdk.Context, store sdk.SimpleDB,
tx interface{}, next sdk.Checker) (res sdk.CheckResult, err error) {
if !ctx.HasPermission(p.Required) {
return res, errors.ErrUnauthorized()
}
return next.CheckTx(ctx, store, tx)
}
func (p CheckDecorator) DeliverTx(ctx sdk.Context, store sdk.SimpleDB,
tx interface{}, next sdk.Deliverer) (res sdk.DeliverResult, err error) {
if !ctx.HasPermission(p.Required) {
return res, errors.ErrUnauthorized()
}
return next.DeliverTx(ctx, store, tx)
}
// GrantDecorator tries to set the permission to this Actor, which may be prohibited
type GrantDecorator struct {
Auth sdk.Actor
}
var _ sdk.Decorator = GrantDecorator{}
func (g GrantDecorator) CheckTx(ctx sdk.Context, store sdk.SimpleDB,
tx interface{}, next sdk.Checker) (res sdk.CheckResult, err error) {
ctx = ctx.WithPermissions(g.Auth)
return next.CheckTx(ctx, store, tx)
}
func (g GrantDecorator) DeliverTx(ctx sdk.Context, store sdk.SimpleDB,
tx interface{}, next sdk.Deliverer) (res sdk.DeliverResult, err error) {
ctx = ctx.WithPermissions(g.Auth)
return next.DeliverTx(ctx, store, tx)
}