From 52f7a47ef2f240eab94c42b92a39be179ca9714c Mon Sep 17 00:00:00 2001 From: Ethan Frey Date: Tue, 27 Jun 2017 18:33:35 +0200 Subject: [PATCH] Abstracted out the permissions for multiple apps --- handler.go | 40 ++++++++++++++++++++++------------------ handlers/base.go | 4 ++-- handlers/sigs.go | 18 +++++++++++++++--- 3 files changed, 39 insertions(+), 23 deletions(-) diff --git a/handler.go b/handler.go index 9484808f8..cbc88d4fe 100644 --- a/handler.go +++ b/handler.go @@ -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 diff --git a/handlers/base.go b/handlers/base.go index de71e72fa..99a9ce08a 100644 --- a/handlers/base.go +++ b/handlers/base.go @@ -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() } diff --git a/handlers/sigs.go b/handlers/sigs.go index a9c032903..28baf8f8a 100644 --- a/handlers/sigs.go +++ b/handlers/sigs.go @@ -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...) +}