2017-07-06 07:00:54 -07:00
|
|
|
package auth
|
2017-06-01 11:26:43 -07:00
|
|
|
|
|
|
|
import (
|
|
|
|
crypto "github.com/tendermint/go-crypto"
|
|
|
|
|
|
|
|
"github.com/tendermint/basecoin"
|
|
|
|
"github.com/tendermint/basecoin/errors"
|
2017-07-06 07:00:54 -07:00
|
|
|
"github.com/tendermint/basecoin/stack"
|
2017-07-06 05:23:38 -07:00
|
|
|
"github.com/tendermint/basecoin/state"
|
2017-06-01 11:26:43 -07:00
|
|
|
)
|
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
//nolint
|
2017-06-27 10:22:25 -07:00
|
|
|
const (
|
|
|
|
NameSigs = "sigs"
|
|
|
|
)
|
2017-06-27 09:33:35 -07:00
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
// Signatures parses out go-crypto signatures and adds permissions to the
|
|
|
|
// context for use inside the application
|
2017-07-03 09:10:46 -07:00
|
|
|
type Signatures struct {
|
2017-07-06 07:00:54 -07:00
|
|
|
stack.PassOption
|
2017-07-03 09:10:46 -07:00
|
|
|
}
|
2017-06-01 11:26:43 -07:00
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
// Name of the module - fulfills Middleware interface
|
|
|
|
func (Signatures) Name() string {
|
2017-06-27 10:22:25 -07:00
|
|
|
return NameSigs
|
|
|
|
}
|
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
var _ stack.Middleware = Signatures{}
|
2017-06-01 11:26:43 -07:00
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
// SigPerm takes the binary address from PubKey.Address and makes it an Actor
|
2017-06-29 06:29:36 -07:00
|
|
|
func SigPerm(addr []byte) basecoin.Actor {
|
|
|
|
return basecoin.NewActor(NameSigs, addr)
|
2017-06-27 11:53:06 -07:00
|
|
|
}
|
|
|
|
|
2017-07-06 07:33:38 -07:00
|
|
|
// Signable allows us to use txs.OneSig and txs.MultiSig (and others??)
|
|
|
|
type Signable interface {
|
2017-06-01 11:26:43 -07:00
|
|
|
basecoin.TxLayer
|
|
|
|
Signers() ([]crypto.PubKey, error)
|
|
|
|
}
|
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
// CheckTx verifies the signatures are correct - fulfills Middlware interface
|
2017-07-26 16:55:05 -07:00
|
|
|
func (Signatures) CheckTx(ctx basecoin.Context, store state.SimpleDB, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) {
|
2017-06-27 10:40:48 -07:00
|
|
|
sigs, tnext, err := getSigners(tx)
|
2017-06-01 11:26:43 -07:00
|
|
|
if err != nil {
|
|
|
|
return res, err
|
|
|
|
}
|
2017-06-27 09:33:35 -07:00
|
|
|
ctx2 := addSigners(ctx, sigs)
|
2017-06-27 10:40:48 -07:00
|
|
|
return next.CheckTx(ctx2, store, tnext)
|
2017-06-01 11:26:43 -07:00
|
|
|
}
|
|
|
|
|
2017-07-06 07:00:54 -07:00
|
|
|
// DeliverTx verifies the signatures are correct - fulfills Middlware interface
|
2017-07-26 16:55:05 -07:00
|
|
|
func (Signatures) DeliverTx(ctx basecoin.Context, store state.SimpleDB, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) {
|
2017-06-27 10:40:48 -07:00
|
|
|
sigs, tnext, err := getSigners(tx)
|
2017-06-01 11:26:43 -07:00
|
|
|
if err != nil {
|
|
|
|
return res, err
|
|
|
|
}
|
2017-06-27 09:33:35 -07:00
|
|
|
ctx2 := addSigners(ctx, sigs)
|
2017-06-27 10:40:48 -07:00
|
|
|
return next.DeliverTx(ctx2, store, tnext)
|
2017-06-01 11:26:43 -07:00
|
|
|
}
|
2017-06-27 09:33:35 -07:00
|
|
|
|
|
|
|
func addSigners(ctx basecoin.Context, sigs []crypto.PubKey) basecoin.Context {
|
2017-06-29 06:29:36 -07:00
|
|
|
perms := make([]basecoin.Actor, len(sigs))
|
2017-06-27 09:33:35 -07:00
|
|
|
for i, s := range sigs {
|
2017-06-27 11:53:06 -07:00
|
|
|
perms[i] = SigPerm(s.Address())
|
2017-06-27 09:33:35 -07:00
|
|
|
}
|
|
|
|
// add the signers to the context and continue
|
2017-06-27 11:53:06 -07:00
|
|
|
return ctx.WithPermissions(perms...)
|
2017-06-27 09:33:35 -07:00
|
|
|
}
|
2017-06-27 10:40:48 -07:00
|
|
|
|
|
|
|
func getSigners(tx basecoin.Tx) ([]crypto.PubKey, basecoin.Tx, error) {
|
2017-07-06 07:33:38 -07:00
|
|
|
stx, ok := tx.Unwrap().(Signable)
|
2017-06-27 10:40:48 -07:00
|
|
|
if !ok {
|
2017-07-03 05:50:33 -07:00
|
|
|
return nil, basecoin.Tx{}, errors.ErrUnauthorized()
|
2017-06-27 10:40:48 -07:00
|
|
|
}
|
|
|
|
sig, err := stx.Signers()
|
|
|
|
return sig, stx.Next(), err
|
|
|
|
}
|