mirror of
https://github.com/ethereum/go-ethereum.git
synced 2026-08-18 09:53:48 +00:00
signer/rules: implement dispatching to next handler
This commit is contained in:
parent
99dd0a1b58
commit
3ade6cb242
2 changed files with 82 additions and 21 deletions
|
|
@ -19,6 +19,7 @@ package rules
|
|||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/cmd/signer/core"
|
||||
"github.com/ethereum/go-ethereum/cmd/signer/rules/deps"
|
||||
"github.com/ethereum/go-ethereum/cmd/signer/storage"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
|
|
@ -26,7 +27,6 @@ import (
|
|||
"github.com/robertkrimen/otto"
|
||||
"os"
|
||||
"strings"
|
||||
"github.com/ethereum/go-ethereum/cmd/signer/core"
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -52,9 +52,10 @@ type rulesetUi struct {
|
|||
storage storage.Storage
|
||||
}
|
||||
|
||||
func NewRuleEvaluator() (*rulesetUi, error) {
|
||||
func NewRuleEvaluator(next core.SignerUI) (*rulesetUi, error) {
|
||||
c := &rulesetUi{
|
||||
vm: otto.New(),
|
||||
next: next,
|
||||
storage: storage.NewEphemeralStorage(),
|
||||
}
|
||||
consoleObj, _ := c.vm.Get("console")
|
||||
|
|
@ -81,32 +82,38 @@ func (r *rulesetUi) Init(javascriptRules string) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func (r *rulesetUi) checkApproval(jsfunc string, jsarg []byte, err error) error {
|
||||
func (r *rulesetUi) checkApproval(jsfunc string, jsarg []byte, err error) (bool, error) {
|
||||
if err != nil {
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
v, err := r.vm.Call(jsfunc, nil, string(jsarg))
|
||||
|
||||
if err != nil {
|
||||
log.Info("error occurred during execution", "error", err)
|
||||
return err
|
||||
return false, err
|
||||
}
|
||||
result, err := v.ToString()
|
||||
if err != nil {
|
||||
log.Info("error occurred during response unmarshalling", "error", err)
|
||||
return err
|
||||
|
||||
return false, err
|
||||
}
|
||||
if result == "Approve" {
|
||||
log.Info("Op approved")
|
||||
return nil
|
||||
return true, nil
|
||||
} else if result == "Reject" {
|
||||
log.Info("Op rejected")
|
||||
return false, nil
|
||||
}
|
||||
return fmt.Errorf("rejected")
|
||||
return false, fmt.Errorf("Unknown response")
|
||||
}
|
||||
|
||||
func (r *rulesetUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
|
||||
jsonreq, err := json.Marshal(request)
|
||||
if err = r.checkApproval("ApproveTx", jsonreq, err); err == nil {
|
||||
approved, err := r.checkApproval("ApproveTx", jsonreq, err)
|
||||
if err != nil {
|
||||
log.Info("Rule-based approval error, going to manual", "error", "err")
|
||||
return r.next.ApproveTx(request)
|
||||
}
|
||||
if approved {
|
||||
return core.SignTxResponse{Transaction: request.Transaction, Approved: true, Password: ""}, nil
|
||||
}
|
||||
return core.SignTxResponse{Approved: false}, err
|
||||
|
|
@ -114,7 +121,12 @@ func (r *rulesetUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse,
|
|||
|
||||
func (r *rulesetUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
|
||||
jsonreq, err := json.Marshal(request)
|
||||
if err = r.checkApproval("ApproveTx", jsonreq, err); err == nil {
|
||||
approved, err := r.checkApproval("ApproveSignData", jsonreq, err)
|
||||
if err != nil {
|
||||
log.Info("Rule-based approval error, going to manual", "error", "err")
|
||||
return r.next.ApproveSignData(request)
|
||||
}
|
||||
if approved {
|
||||
return core.SignDataResponse{Approved: true, Password: ""}, nil
|
||||
}
|
||||
return core.SignDataResponse{Approved: false, Password: ""}, err
|
||||
|
|
@ -122,7 +134,12 @@ func (r *rulesetUi) ApproveSignData(request *core.SignDataRequest) (core.SignDat
|
|||
|
||||
func (r *rulesetUi) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
|
||||
jsonreq, err := json.Marshal(request)
|
||||
if err = r.checkApproval("ApproveTx", jsonreq, err); err == nil {
|
||||
approved, err := r.checkApproval("ApproveExport", jsonreq, err)
|
||||
if err != nil {
|
||||
log.Info("Rule-based approval error, going to manual", "error", "err")
|
||||
return r.next.ApproveExport(request)
|
||||
}
|
||||
if approved {
|
||||
return core.ExportResponse{Approved: true}, nil
|
||||
}
|
||||
return core.ExportResponse{Approved: false}, err
|
||||
|
|
@ -136,7 +153,12 @@ func (r *rulesetUi) ApproveImport(request *core.ImportRequest) (core.ImportRespo
|
|||
|
||||
func (r *rulesetUi) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
|
||||
jsonreq, err := json.Marshal(request)
|
||||
if err = r.checkApproval("ApproveListing", jsonreq, err); err == nil {
|
||||
approved, err := r.checkApproval("ApproveListing", jsonreq, err)
|
||||
if err != nil {
|
||||
log.Info("Rule-based approval error, going to manual", "error", "err")
|
||||
return r.next.ApproveListing(request)
|
||||
}
|
||||
if approved {
|
||||
return core.ListResponse{Accounts: request.Accounts}, nil
|
||||
}
|
||||
return core.ListResponse{}, err
|
||||
|
|
@ -157,8 +179,8 @@ func (r *rulesetUi) ShowInfo(message string) {
|
|||
log.Info(message)
|
||||
r.next.ShowInfo(message)
|
||||
}
|
||||
func (r *rulesetUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
|
||||
|
||||
func (r *rulesetUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
|
||||
jsonTx, err := json.Marshal(tx)
|
||||
if err != nil {
|
||||
log.Warn("failed marshalling transaction", "tx", tx)
|
||||
|
|
@ -169,5 +191,4 @@ func (r *rulesetUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
|
|||
fmt.Printf("Error in onapprove %v", err)
|
||||
log.Warn("error occurred during execution", "error", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -53,9 +53,46 @@ func hexAddr(a string) common.Address { return common.BytesToAddress(common.Hex2
|
|||
func mixAddr(a string) (*common.MixedcaseAddress, error) {
|
||||
return common.NewMixedcaseAddressFromString(a)
|
||||
}
|
||||
type alwaysDenyUi struct{}
|
||||
|
||||
func (alwaysDenyUi) ApproveTx(request *core.SignTxRequest) (core.SignTxResponse, error) {
|
||||
return core.SignTxResponse{request.Transaction, false, ""}, nil
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ApproveSignData(request *core.SignDataRequest) (core.SignDataResponse, error) {
|
||||
return core.SignDataResponse{false, ""}, nil
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ApproveExport(request *core.ExportRequest) (core.ExportResponse, error) {
|
||||
return core.ExportResponse{false}, nil
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ApproveImport(request *core.ImportRequest) (core.ImportResponse, error) {
|
||||
return core.ImportResponse{false, "", ""}, nil
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ApproveListing(request *core.ListRequest) (core.ListResponse, error) {
|
||||
return core.ListResponse{nil}, nil
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ApproveNewAccount(request *core.NewAccountRequest) (core.NewAccountResponse, error) {
|
||||
return core.NewAccountResponse{false, ""}, nil
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ShowError(message string) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) ShowInfo(message string) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func (alwaysDenyUi) OnApprovedTx(tx ethapi.SignTransactionResult) {
|
||||
panic("implement me")
|
||||
}
|
||||
|
||||
func initRuleEngine(js string) (*rulesetUi, error) {
|
||||
r, err := NewRuleEvaluator()
|
||||
r, err := NewRuleEvaluator(&alwaysDenyUi{})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("Failed to create js engine: %v", err)
|
||||
}
|
||||
|
|
@ -154,10 +191,13 @@ func TestMissingFunc(t *testing.T) {
|
|||
t.Error("Expected error")
|
||||
}
|
||||
|
||||
if r.checkApproval("MissingMethod", nil, nil) == nil {
|
||||
t.Errorf("Expected error to resolve to 'Reject'")
|
||||
approved, err := r.checkApproval("MissingMethod", nil, nil);
|
||||
if err == nil {
|
||||
t.Errorf("Expected missing method to yield error'")
|
||||
}
|
||||
if approved{
|
||||
t.Errorf("Expected missing method to cause non-approval")
|
||||
}
|
||||
|
||||
fmt.Printf("Err %v", err)
|
||||
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue