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" "bytes"
abci "github.com/tendermint/abci/types" abci "github.com/tendermint/abci/types"
crypto "github.com/tendermint/go-crypto"
"github.com/tendermint/go-wire/data" "github.com/tendermint/go-wire/data"
"github.com/tendermint/basecoin/types" "github.com/tendermint/basecoin/types"
@ -22,40 +21,45 @@ type Handler interface {
// EndBlock(store types.KVStore, height uint64) abci.ResponseEndBlock // 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 // TODO: Context is a place-holder, soon we add some request data here from the
// higher-levels (like tell an app who signed). // higher-levels (like tell an app who signed).
// Trust me, we will need it like CallContext now... // Trust me, we will need it like CallContext now...
type Context struct { type Context struct {
sigs []crypto.PubKey perms []Permission
} }
// TOTALLY insecure. will redo later, but you get the point // 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{ return Context{
sigs: append(c.sigs, keys...), perms: append(c.perms, perms...),
} }
} }
func (c Context) GetSigners() []crypto.PubKey { func (c Context) HasPermission(app string, addr []byte) bool {
return c.sigs for _, p := range c.perms {
} if app == p.App && bytes.Equal(addr, p.Address) {
func (c Context) IsSignerAddr(addr []byte) bool {
for _, pk := range c.sigs {
if bytes.Equal(addr, pk.Address()) {
return true return true
} }
} }
return false return false
} }
func (c Context) IsSignerKey(key crypto.PubKey) bool { // New should give a fresh context, and know what info makes sense to carry over
for _, pk := range c.sigs { func (c Context) New() Context {
if key.Equals(pk) { return Context{}
return true
}
}
return false
} }
// Result captures any non-error abci result // 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() return res, errors.InsufficientFees()
} }
if !ctx.IsSignerAddr(feeTx.Payer) { if !ctx.HasPermission(Sigs, feeTx.Payer) {
return res, errors.Unauthorized() return res, errors.Unauthorized()
} }
@ -64,7 +64,7 @@ func (h SimpleFeeHandler) DeliverTx(ctx basecoin.Context, store types.KVStore, t
return res, errors.InsufficientFees() return res, errors.InsufficientFees()
} }
if !ctx.IsSignerAddr(feeTx.Payer) { if !ctx.HasPermission(Sigs, feeTx.Payer) {
return res, errors.Unauthorized() return res, errors.Unauthorized()
} }

View File

@ -8,6 +8,9 @@ import (
"github.com/tendermint/basecoin/types" "github.com/tendermint/basecoin/types"
) )
// app name for auth
const Sigs = "sigs"
type SignedHandler struct { type SignedHandler struct {
AllowMultiSig bool AllowMultiSig bool
Inner basecoin.Handler Inner basecoin.Handler
@ -37,8 +40,7 @@ func (h SignedHandler) CheckTx(ctx basecoin.Context, store types.KVStore, tx bas
return res, err return res, err
} }
// add the signers to the context and continue ctx2 := addSigners(ctx, sigs)
ctx2 := ctx.AddSigners(sigs...)
return h.Next().CheckTx(ctx2, store, stx.Next()) 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 // add the signers to the context and continue
ctx2 := ctx.AddSigners(sigs...) ctx2 := addSigners(ctx, sigs)
return h.Next().DeliverTx(ctx2, store, stx.Next()) 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...)
}