Abstracted out the permissions for multiple apps

This commit is contained in:
Ethan Frey 2017-06-27 18:33:35 +02:00
parent c5a62143ec
commit 52f7a47ef2
3 changed files with 39 additions and 23 deletions

View File

@ -4,7 +4,6 @@ import (
"bytes"
abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire/data"
"github.com/tendermint/basecoin/types"
@ -22,40 +21,45 @@ type Handler interface {
// EndBlock(store types.KVStore, height uint64) abci.ResponseEndBlock
}
// different apps to authorize
const (
Sigs = "sigs"
IBC = "ibc"
Role = "role"
)
// TODO: handle this in some secure way, only certain apps can add permissions
type Permission struct {
App string // Which app authorized this?
Address []byte // App-specific identifier
}
// TODO: Context is a place-holder, soon we add some request data here from the
// higher-levels (like tell an app who signed).
// Trust me, we will need it like CallContext now...
type Context struct {
sigs []crypto.PubKey
perms []Permission
}
// TOTALLY insecure. will redo later, but you get the point
func (c Context) AddSigners(keys ...crypto.PubKey) Context {
func (c Context) AddPermissions(perms ...Permission) Context {
return Context{
sigs: append(c.sigs, keys...),
perms: append(c.perms, perms...),
}
}
func (c Context) GetSigners() []crypto.PubKey {
return c.sigs
}
func (c Context) IsSignerAddr(addr []byte) bool {
for _, pk := range c.sigs {
if bytes.Equal(addr, pk.Address()) {
func (c Context) HasPermission(app string, addr []byte) bool {
for _, p := range c.perms {
if app == p.App && bytes.Equal(addr, p.Address) {
return true
}
}
return false
}
func (c Context) IsSignerKey(key crypto.PubKey) bool {
for _, pk := range c.sigs {
if key.Equals(pk) {
return true
}
}
return false
// New should give a fresh context, and know what info makes sense to carry over
func (c Context) New() Context {
return Context{}
}
// Result captures any non-error abci result

View File

@ -41,7 +41,7 @@ func (h SimpleFeeHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx
return res, errors.InsufficientFees()
}
if !ctx.IsSignerAddr(feeTx.Payer) {
if !ctx.HasPermission(Sigs, feeTx.Payer) {
return res, errors.Unauthorized()
}
@ -64,7 +64,7 @@ func (h SimpleFeeHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, t
return res, errors.InsufficientFees()
}
if !ctx.IsSignerAddr(feeTx.Payer) {
if !ctx.HasPermission(Sigs, feeTx.Payer) {
return res, errors.Unauthorized()
}

View File

@ -8,6 +8,9 @@ import (
"github.com/tendermint/basecoin/types"
)
// app name for auth
const Sigs = "sigs"
type SignedHandler struct {
AllowMultiSig bool
Inner basecoin.Handler
@ -37,8 +40,7 @@ func (h SignedHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx bas
return res, err
}
// add the signers to the context and continue
ctx2 := ctx.AddSigners(sigs...)
ctx2 := addSigners(ctx, sigs)
return h.Next().CheckTx(ctx2, store, stx.Next())
}
@ -56,6 +58,16 @@ func (h SignedHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, tx b
}
// add the signers to the context and continue
ctx2 := ctx.AddSigners(sigs...)
ctx2 := addSigners(ctx, sigs)
return h.Next().DeliverTx(ctx2, store, stx.Next())
}
func addSigners(ctx basecoin.Context, sigs []crypto.PubKey) basecoin.Context {
perms := make([]basecoin.Permission, len(sigs))
for i, s := range sigs {
perms[i] = basecoin.Permission{App: Sigs, Address: s.Address()}
}
// add the signers to the context and continue
return ctx.AddPermissions(perms...)
}