Bare auth
This commit is contained in:
parent
83b43f3378
commit
fdc7834dae
|
@ -1,37 +1,23 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/cosmos/cosmos-sdk/errors"
|
||||
)
|
||||
|
||||
//nolint
|
||||
const (
|
||||
NameSigs = "sigs"
|
||||
)
|
||||
type CheckSignatures struct{}
|
||||
|
||||
// Signatures parses out go-crypto signatures and adds permissions to the
|
||||
// context for use inside the application
|
||||
type Signatures struct{}
|
||||
|
||||
var _ sdk.Decorator = Signatures{}
|
||||
|
||||
// SigPerm takes the binary address from PubKey.Address and makes it an Actor
|
||||
func SigPerm(addr []byte) sdk.Actor {
|
||||
return sdk.NewActor(NameSigs, addr)
|
||||
}
|
||||
var _ sdk.Decorator = CheckSignatures{}
|
||||
|
||||
// CheckTx verifies the signatures are correct - fulfills Middlware interface
|
||||
func (Signatures) CheckTx(ctx sdk.Context, store sdk.SimpleDB,
|
||||
tx interface{}, next sdk.Checker) (res sdk.CheckResult, err error) {
|
||||
|
||||
sigs, err := getSigners(tx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx2 := addSigners(ctx, sigs)
|
||||
// Check that signatures match
|
||||
// TODO
|
||||
|
||||
// Add info to context
|
||||
// TODO
|
||||
|
||||
return next.CheckTx(ctx2, store, tx)
|
||||
}
|
||||
|
||||
|
@ -39,28 +25,11 @@ func (Signatures) CheckTx(ctx sdk.Context, store sdk.SimpleDB,
|
|||
func (Signatures) DeliverTx(ctx sdk.Context, store sdk.SimpleDB,
|
||||
tx interface{}, next sdk.Deliverer) (res sdk.DeliverResult, err error) {
|
||||
|
||||
sigs, err := getSigners(tx)
|
||||
if err != nil {
|
||||
return res, err
|
||||
}
|
||||
ctx2 := addSigners(ctx, sigs)
|
||||
// Check that signatures match
|
||||
// TODO
|
||||
|
||||
// Add info to context
|
||||
// TODO
|
||||
|
||||
return next.DeliverTx(ctx2, store, tx)
|
||||
}
|
||||
|
||||
func addSigners(ctx sdk.Context, sigs []crypto.PubKey) sdk.Context {
|
||||
perms := make([]sdk.Actor, len(sigs))
|
||||
for i, s := range sigs {
|
||||
perms[i] = SigPerm(s.Address())
|
||||
}
|
||||
// add the signers to the context and continue
|
||||
return ctx.WithPermissions(perms...)
|
||||
}
|
||||
|
||||
func getSigners(tx interface{}) ([]crypto.PubKey, error) {
|
||||
stx, ok := tx.(Signable)
|
||||
if !ok {
|
||||
return nil, errors.ErrUnauthorized()
|
||||
}
|
||||
sig, err := stx.Signers()
|
||||
return sig, err
|
||||
}
|
||||
|
|
|
@ -1,84 +0,0 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
"github.com/tendermint/go-crypto/keys"
|
||||
wire "github.com/tendermint/go-wire"
|
||||
|
||||
sdk "github.com/cosmos/cosmos-sdk"
|
||||
"github.com/cosmos/cosmos-sdk/util"
|
||||
)
|
||||
|
||||
type oneSig struct {
|
||||
// Data is the payload
|
||||
Data util.RawTx
|
||||
// NamedSig holds credentials and exposes Sign
|
||||
*NamedSig
|
||||
}
|
||||
|
||||
var _ Signable = oneSig{}
|
||||
var _ sdk.Msg = oneSig{}
|
||||
var _ keys.Signable = oneSig{}
|
||||
|
||||
func (o oneSig) SignBytes() []byte {
|
||||
return wire.BinaryBytes(o.Data)
|
||||
}
|
||||
|
||||
func (o oneSig) TxBytes() ([]byte, error) {
|
||||
// if o.NamedSig.Empty() {
|
||||
// return nil, errors.ErrMissingSignature()
|
||||
// }
|
||||
return wire.BinaryBytes(o), nil
|
||||
}
|
||||
|
||||
func (o oneSig) Signers() ([]crypto.PubKey, error) {
|
||||
return o.NamedSig.Signers(o.SignBytes())
|
||||
}
|
||||
|
||||
func (o oneSig) GetTx() interface{} {
|
||||
return o.Data
|
||||
}
|
||||
|
||||
func newSingle(data []byte) oneSig {
|
||||
return oneSig{
|
||||
Data: util.NewRawTx(data),
|
||||
NamedSig: NewSig(),
|
||||
}
|
||||
}
|
||||
|
||||
type multiSig struct {
|
||||
// Data is the payload
|
||||
Data util.RawTx
|
||||
// NamedSig holds credentials and exposes Sign
|
||||
*NamedSigs
|
||||
}
|
||||
|
||||
var _ Signable = oneSig{}
|
||||
var _ sdk.Msg = oneSig{}
|
||||
var _ keys.Signable = oneSig{}
|
||||
|
||||
func (m multiSig) SignBytes() []byte {
|
||||
return wire.BinaryBytes(m.Data)
|
||||
}
|
||||
|
||||
func (m multiSig) TxBytes() ([]byte, error) {
|
||||
// if m.NamedSigs.Empty() {
|
||||
// return nil, errors.ErrMissingSignature()
|
||||
// }
|
||||
return wire.BinaryBytes(m), nil
|
||||
}
|
||||
|
||||
func (m multiSig) Signers() ([]crypto.PubKey, error) {
|
||||
return m.NamedSigs.Signers(m.SignBytes())
|
||||
}
|
||||
|
||||
func (m multiSig) GetTx() interface{} {
|
||||
return m.Data
|
||||
}
|
||||
|
||||
func newMulti(data []byte) multiSig {
|
||||
return multiSig{
|
||||
Data: util.NewRawTx(data),
|
||||
NamedSigs: NewMultiSig(),
|
||||
}
|
||||
}
|
|
@ -1,97 +0,0 @@
|
|||
package auth
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
crypto "github.com/tendermint/go-crypto"
|
||||
|
||||
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)
|
||||
|
||||
// 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())
|
||||
|
||||
// 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},
|
||||
|
||||
// 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)
|
||||
|
||||
// make the stack check for the given permission
|
||||
app := sdk.ChainDecorators(
|
||||
Signatures{},
|
||||
util.CheckDecorator{Required: tc.check},
|
||||
).WithHandler(
|
||||
util.OKHandler{},
|
||||
)
|
||||
|
||||
var tx interface{}
|
||||
// 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
|
||||
} else {
|
||||
otx := newSingle(raw)
|
||||
for _, k := range tc.keys {
|
||||
err := Sign(otx, k)
|
||||
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.DeliverTx(ctx, store, tx)
|
||||
if tc.valid {
|
||||
assert.Nil(err, "%d: %+v", i, err)
|
||||
} else {
|
||||
assert.NotNil(err, idx)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,15 @@
|
|||
package auth
|
||||
|
||||
import crypto "github.com/tendermint/go-crypto"
|
||||
|
||||
type Account interface {
|
||||
Get(key interface{}) (value interface{})
|
||||
|
||||
Address() []byte
|
||||
PubKey() crypto.PubKey
|
||||
}
|
||||
|
||||
type AccountStore interface {
|
||||
GetAccount(addr []byte) Account
|
||||
SetAccount(acc Account)
|
||||
}
|
Loading…
Reference in New Issue