86 lines
2.3 KiB
Go
86 lines
2.3 KiB
Go
package roles
|
|
|
|
import (
|
|
sdk "github.com/cosmos/cosmos-sdk"
|
|
"github.com/cosmos/cosmos-sdk/stack"
|
|
"github.com/cosmos/cosmos-sdk/state"
|
|
)
|
|
|
|
// Middleware allows us to add a requested role as a permission
|
|
// if the tx requests it and has sufficient authority
|
|
type Middleware struct {
|
|
stack.PassInitState
|
|
stack.PassInitValidate
|
|
}
|
|
|
|
var _ stack.Middleware = Middleware{}
|
|
|
|
// NewMiddleware creates a role-checking middleware
|
|
func NewMiddleware() Middleware {
|
|
return Middleware{}
|
|
}
|
|
|
|
// Name - return name space
|
|
func (Middleware) Name() string {
|
|
return NameRole
|
|
}
|
|
|
|
// CheckTx tries to assume the named role if requested.
|
|
// If no role is requested, do nothing.
|
|
// If insufficient authority to assume the role, return error.
|
|
func (m Middleware) CheckTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx, next sdk.Checker) (res sdk.CheckResult, err error) {
|
|
// if this is not an AssumeRoleTx, then continue
|
|
assume, ok := tx.Unwrap().(AssumeRoleTx)
|
|
if !ok { // this also breaks the recursion below
|
|
return next.CheckTx(ctx, store, tx)
|
|
}
|
|
|
|
ctx, err = assumeRole(ctx, store, assume)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
|
|
// one could add multiple role statements, repeat as needed
|
|
// charging for each level
|
|
res, err = m.CheckTx(ctx, store, assume.Tx, next)
|
|
res.GasAllocated += CostAssume
|
|
return
|
|
}
|
|
|
|
// DeliverTx tries to assume the named role if requested.
|
|
// If no role is requested, do nothing.
|
|
// If insufficient authority to assume the role, return error.
|
|
func (m Middleware) DeliverTx(ctx sdk.Context, store state.SimpleDB, tx sdk.Tx, next sdk.Deliver) (res sdk.DeliverResult, err error) {
|
|
// if this is not an AssumeRoleTx, then continue
|
|
assume, ok := tx.Unwrap().(AssumeRoleTx)
|
|
if !ok { // this also breaks the recursion below
|
|
return next.DeliverTx(ctx, store, tx)
|
|
}
|
|
|
|
ctx, err = assumeRole(ctx, store, assume)
|
|
if err != nil {
|
|
return res, err
|
|
}
|
|
|
|
// one could add multiple role statements, repeat as needed
|
|
return m.DeliverTx(ctx, store, assume.Tx, next)
|
|
}
|
|
|
|
func assumeRole(ctx sdk.Context, store state.SimpleDB, assume AssumeRoleTx) (sdk.Context, error) {
|
|
err := assume.ValidateBasic()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
role, err := loadRole(store, assume.Role)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
if !role.IsAuthorized(ctx) {
|
|
return nil, ErrInsufficientSigs()
|
|
}
|
|
ctx = ctx.WithPermissions(NewPerm(assume.Role))
|
|
return ctx, nil
|
|
}
|