Add roles middleware and handler

This commit is contained in:
Ethan Frey
2017-07-11 13:55:28 +02:00
parent 3e52e6b959
commit 11a8c0d9a2
5 changed files with 156 additions and 4 deletions
+1 -4
View File
@@ -1,8 +1,6 @@
package coin
import (
"fmt"
"github.com/tendermint/go-wire/data"
"github.com/tendermint/tmlibs/log"
@@ -106,8 +104,7 @@ func (h Handler) SetOption(l log.Logger, store state.KVStore, module, key, value
return "Success", nil
}
msg := fmt.Sprintf("Unknown key: %s", key)
return "", errors.ErrInternal(msg)
return errors.ErrUnknownKey(key)
}
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (send SendTx, err error) {
+59
View File
@@ -1,4 +1,63 @@
package roles
import (
"github.com/tendermint/tmlibs/log"
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/state"
)
//NameRole - name space of the roles module
const NameRole = "role"
type Handler struct{}
var _ basecoin.Handler = Handler{}
// NewHandler makes a role handler to create roles
func NewHandler() Handler {
return Handler{}
}
// Name - return name space
func (Handler) Name() string {
return NameRole
}
// CheckTx checks if there is enough money in the account
func (h Handler) CheckTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
_, err = checkTx(ctx, tx)
return res, err
}
// DeliverTx moves the money
func (h Handler) DeliverTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx) (res basecoin.Result, err error) {
create, err := checkTx(ctx, tx)
if err != nil {
return res, err
}
// lets try...
role := NewRole(create.MinSigs, create.Signers)
err = createRole(store, MakeKey(create.Role), role)
return res, err
}
// SetOption - sets the genesis account balance
func (h Handler) SetOption(l log.Logger, store state.KVStore, module, key, value string) (log string, err error) {
if module != NameRole {
return "", errors.ErrUnknownModule(module)
}
return "", errors.ErrUnknownKey(key)
}
func checkTx(ctx basecoin.Context, tx basecoin.Tx) (create CreateRoleTx, err error) {
// check if the tx is proper type and valid
create, ok := tx.Unwrap().(CreateRoleTx)
if !ok {
return create, errors.ErrInvalidFormat(tx)
}
err = create.ValidateBasic()
return create, err
}
+80
View File
@@ -1 +1,81 @@
package roles
import (
"github.com/tendermint/basecoin"
"github.com/tendermint/basecoin/errors"
"github.com/tendermint/basecoin/stack"
"github.com/tendermint/basecoin/state"
)
type Middleware struct {
stack.PassOption
}
var _ stack.Middleware = Middleware{}
func NewMiddleware() Middleware {
return Middleware{}
}
// Name - return name space
func (Middleware) Name() string {
return NameRole
}
// CheckTx checks if this is valid
func (m Middleware) CheckTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx, next basecoin.Checker) (res basecoin.Result, err error) {
assume, err := checkMiddleTx(ctx, tx)
if err != nil {
return res, err
}
ctx, err = assumeRole(ctx, store, assume)
if err != nil {
return res, err
}
return next.CheckTx(ctx, store, assume.Tx)
}
// DeliverTx moves the money
func (m Middleware) DeliverTx(ctx basecoin.Context, store state.KVStore, tx basecoin.Tx, next basecoin.Deliver) (res basecoin.Result, err error) {
assume, err := checkMiddleTx(ctx, tx)
if err != nil {
return res, err
}
ctx, err = assumeRole(ctx, store, assume)
if err != nil {
return res, err
}
return next.DeliverTx(ctx, store, assume.Tx)
}
func checkMiddleTx(ctx basecoin.Context, tx basecoin.Tx) (assume AssumeRoleTx, err error) {
// check if the tx is proper type and valid
assume, ok := tx.Unwrap().(AssumeRoleTx)
if !ok {
return assume, errors.ErrInvalidFormat(tx)
}
err = assume.ValidateBasic()
if err != nil {
return assume, err
}
// load it up and check it out...
return assume, err
}
func assumeRole(ctx basecoin.Context, store state.KVStore, assume AssumeRoleTx) (basecoin.Context, error) {
role, err := loadRole(store, MakeKey(assume.Role))
if err != nil {
return nil, err
}
if !role.IsAuthorized(ctx) {
return nil, ErrInsufficientSigs()
}
ctx = ctx.WithPermissions(NewPerm(assume.Role))
return ctx, nil
}
+7
View File
@@ -9,6 +9,13 @@ import (
wire "github.com/tendermint/go-wire"
)
func NewPerm(role []byte) basecoin.Actor {
return basecoin.Actor{
App: NameRole,
Address: role,
}
}
// Role - structure to hold permissioning
type Role struct {
MinSigs uint32 `json:"min_sigs"`