mirror of https://github.com/poanetwork/quorum.git
permissions: converted permissions to a service registered in line with other services at node level
This commit is contained in:
commit
53d580fb6c
|
@ -20,6 +20,9 @@ import (
|
|||
"bufio"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/permission"
|
||||
"io"
|
||||
"os"
|
||||
"reflect"
|
||||
|
@ -167,6 +170,10 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
|||
utils.RegisterDashboardService(stack, &cfg.Dashboard, gitCommit)
|
||||
}
|
||||
|
||||
if utils.IsPermissionEnabled(ctx) {
|
||||
RegisterPermissionService(ctx, stack)
|
||||
}
|
||||
|
||||
// Whisper must be explicitly enabled by specifying at least 1 whisper flag or in dev mode
|
||||
shhEnabled := enableWhisper(ctx)
|
||||
shhAutoEnabled := !ctx.GlobalIsSet(utils.WhisperEnabledFlag.Name) && ctx.GlobalIsSet(utils.DeveloperFlag.Name)
|
||||
|
@ -190,6 +197,28 @@ func makeFullNode(ctx *cli.Context) *node.Node {
|
|||
return stack
|
||||
}
|
||||
|
||||
func RegisterPermissionService(ctx *cli.Context, stack *node.Node) {
|
||||
if err := stack.Register(func(sctx *node.ServiceContext) (node.Service, error) {
|
||||
dataDir := ctx.GlobalString(utils.DataDirFlag.Name)
|
||||
var permissionConfig types.PermissionConfig
|
||||
var err error
|
||||
if permissionConfig, err = permission.ParsePermissionConifg(dataDir); err != nil {
|
||||
utils.Fatalf("loading of permission-config.json failed", "error", err)
|
||||
}
|
||||
|
||||
// start the permissions management service
|
||||
pc, err := permission.NewQuorumPermissionCtrl(stack, &permissionConfig)
|
||||
if err != nil {
|
||||
utils.Fatalf("Failed to load the permission contracts as given in permissions-config.json %v", err)
|
||||
}
|
||||
log.Info("permission service created")
|
||||
return pc, nil
|
||||
}); err != nil {
|
||||
utils.Fatalf("Failed to register the permission service: %v", err)
|
||||
}
|
||||
log.Info("permission service registered")
|
||||
}
|
||||
|
||||
// dumpConfig is the dumpconfig command.
|
||||
func dumpConfig(ctx *cli.Context) error {
|
||||
_, cfg := makeConfigNode(ctx)
|
||||
|
|
|
@ -343,14 +343,10 @@ func startNode(ctx *cli.Context, stack *node.Node) {
|
|||
}
|
||||
}()
|
||||
|
||||
//START - QUORUM permission service
|
||||
go func() {
|
||||
if ctx.GlobalBool(utils.EnableNodePermissionFlag.Name) {
|
||||
if err := permission.StartQuorumPermissionService(ctx, stack); err != nil {
|
||||
utils.Fatalf("Failed to start permissions service %v", err)
|
||||
}
|
||||
}
|
||||
}()
|
||||
//initialize permission as we can create eth client only after the node and RPC are started
|
||||
if utils.IsPermissionEnabled(ctx) {
|
||||
permission.StartPermissionService(stack)
|
||||
}
|
||||
|
||||
// Start auxiliary services if enabled
|
||||
if ctx.GlobalBool(utils.MiningEnabledFlag.Name) || ctx.GlobalBool(utils.DeveloperFlag.Name) {
|
||||
|
|
|
@ -20,9 +20,11 @@ package utils
|
|||
import (
|
||||
"compress/gzip"
|
||||
"fmt"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"io"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
"runtime"
|
||||
"strings"
|
||||
"syscall"
|
||||
|
@ -63,7 +65,21 @@ func Fatalf(format string, args ...interface{}) {
|
|||
os.Exit(1)
|
||||
}
|
||||
|
||||
func IsPermissionEnabled(ctx *cli.Context) bool {
|
||||
if ctx.GlobalBool(EnableNodePermissionFlag.Name) {
|
||||
fileName := "permission-config.json"
|
||||
fullPath := filepath.Join(ctx.GlobalString(DataDirFlag.Name), fileName)
|
||||
if _, err := os.Stat(fullPath); err != nil {
|
||||
log.Warn("permission-config.json file is missing. permission service will be disabled", "err", err)
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func StartNode(stack *node.Node) {
|
||||
|
||||
if err := stack.Start(); err != nil {
|
||||
Fatalf("Error starting protocol stack: %v", err)
|
||||
}
|
||||
|
|
|
@ -88,11 +88,6 @@ type OrgDetailInfo struct {
|
|||
SubOrgList []string `json:"subOrgList"`
|
||||
}
|
||||
|
||||
type OrgStruct struct {
|
||||
OrgId string
|
||||
Keys []string
|
||||
}
|
||||
|
||||
// permission config for bootstrapping
|
||||
type PermissionConfig struct {
|
||||
UpgrdAddress common.Address
|
||||
|
@ -178,8 +173,6 @@ var orgAdminRole string
|
|||
|
||||
const defaultMapLimit = 100
|
||||
|
||||
//var OrgKeyMap, _ = lru.New(orgKeyMapLimit)
|
||||
|
||||
var OrgInfoMap = NewOrgCache()
|
||||
var NodeInfoMap = NewNodeCache()
|
||||
var RoleInfoMap = NewRoleCache()
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 797 KiB |
Binary file not shown.
After Width: | Height: | Size: 340 KiB |
|
@ -35,7 +35,6 @@ import (
|
|||
istanbulBackend "github.com/ethereum/go-ethereum/consensus/istanbul/backend"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/bloombits"
|
||||
"github.com/ethereum/go-ethereum/core/quorum"
|
||||
"github.com/ethereum/go-ethereum/core/rawdb"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/core/vm"
|
||||
|
@ -335,12 +334,6 @@ func (s *Ethereum) APIs() []rpc.API {
|
|||
Service: s.netRPCService,
|
||||
Public: true,
|
||||
},
|
||||
{
|
||||
Namespace: "quorumPermission",
|
||||
Version: "1.0",
|
||||
Service: quorum.NewQuorumControlsAPI(s.txPool, s.accountManager),
|
||||
Public: true,
|
||||
},
|
||||
}...)
|
||||
return apis
|
||||
}
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
package quorum
|
||||
package permission
|
||||
|
||||
import (
|
||||
"crypto/ecdsa"
|
||||
"errors"
|
||||
"fmt"
|
||||
"math/big"
|
||||
|
@ -10,9 +9,7 @@ import (
|
|||
"github.com/ethereum/go-ethereum/accounts"
|
||||
"github.com/ethereum/go-ethereum/accounts/abi/bind"
|
||||
"github.com/ethereum/go-ethereum/common"
|
||||
"github.com/ethereum/go-ethereum/core"
|
||||
"github.com/ethereum/go-ethereum/core/types"
|
||||
"github.com/ethereum/go-ethereum/ethclient"
|
||||
"github.com/ethereum/go-ethereum/internal/ethapi"
|
||||
"github.com/ethereum/go-ethereum/log"
|
||||
"github.com/ethereum/go-ethereum/p2p/enode"
|
||||
|
@ -65,20 +62,9 @@ const (
|
|||
Inactive
|
||||
)
|
||||
|
||||
type PermissionContracts struct {
|
||||
PermInterf *pbind.PermInterface
|
||||
}
|
||||
|
||||
// QuorumControlsAPI provides an API to access Quorum's node permission and org key management related services
|
||||
type QuorumControlsAPI struct {
|
||||
txPool *core.TxPool
|
||||
ethClnt *ethclient.Client
|
||||
acntMgr *accounts.Manager
|
||||
txOpt *bind.TransactOpts
|
||||
key *ecdsa.PrivateKey
|
||||
permEnabled bool
|
||||
permConfig *types.PermissionConfig
|
||||
permInterf *pbind.PermInterface
|
||||
permCtrl *PermissionCtrl
|
||||
}
|
||||
|
||||
// txArgs holds arguments required for execute functions
|
||||
|
@ -152,25 +138,8 @@ var (
|
|||
)
|
||||
|
||||
// NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services
|
||||
func NewQuorumControlsAPI(tp *core.TxPool, am *accounts.Manager) *QuorumControlsAPI {
|
||||
return &QuorumControlsAPI{tp, nil, am, nil, nil, false, nil, nil}
|
||||
}
|
||||
|
||||
//Init initializes QuorumControlsAPI with eth client, permission contract and org key management control
|
||||
func (q *QuorumControlsAPI) Init(ethClnt *ethclient.Client, key *ecdsa.PrivateKey, apiName string, pconfig *types.PermissionConfig, pc *pbind.PermInterface) error {
|
||||
// check if the interface contract is deployed or not. if not
|
||||
// permissions apis will not work. return error
|
||||
q.ethClnt = ethClnt
|
||||
q.permConfig = pconfig
|
||||
|
||||
if _, err := pbind.NewPermInterface(q.permConfig.InterfAddress, q.ethClnt); err != nil {
|
||||
return err
|
||||
}
|
||||
q.permEnabled = true
|
||||
q.key = key
|
||||
q.permInterf = pc
|
||||
|
||||
return nil
|
||||
func NewQuorumControlsAPI(p *PermissionCtrl) *QuorumControlsAPI {
|
||||
return &QuorumControlsAPI{p}
|
||||
}
|
||||
|
||||
func (q *QuorumControlsAPI) OrgList() []types.OrgInfo {
|
||||
|
@ -215,9 +184,6 @@ func (q *QuorumControlsAPI) GetOrgDetails(orgId string) (types.OrgDetailInfo, er
|
|||
}
|
||||
|
||||
func (q *QuorumControlsAPI) initOp(txa ethapi.SendTxArgs) (*pbind.PermInterfaceSession, ExecStatus) {
|
||||
if !q.permEnabled {
|
||||
return nil, ErrPermissionDisabled
|
||||
}
|
||||
var err error
|
||||
var w accounts.Wallet
|
||||
|
||||
|
@ -511,7 +477,7 @@ func (q *QuorumControlsAPI) UpdateAccountStatus(orgId string, acct common.Addres
|
|||
// check if the account is network admin
|
||||
func (q *QuorumControlsAPI) isNetworkAdmin(account common.Address) bool {
|
||||
ac := types.AcctInfoMap.GetAccount(account)
|
||||
return ac != nil && ac.RoleId == q.permConfig.NwAdminRole
|
||||
return ac != nil && ac.RoleId == q.permCtrl.permConfig.NwAdminRole
|
||||
}
|
||||
|
||||
func (q *QuorumControlsAPI) isOrgAdmin(account common.Address, orgId string) (ExecStatus, error) {
|
||||
|
@ -626,7 +592,7 @@ func (q *QuorumControlsAPI) valAccountStatusChange(orgId string, account common.
|
|||
return ErrAccountNotThere, errors.New("account not there")
|
||||
}
|
||||
|
||||
if ac.IsOrgAdmin && (ac.RoleId == q.permConfig.NwAdminRole || ac.RoleId == q.permConfig.OrgAdminRole) && (op == 1 || op == 3) {
|
||||
if ac.IsOrgAdmin && (ac.RoleId == q.permCtrl.permConfig.NwAdminRole || ac.RoleId == q.permCtrl.permConfig.OrgAdminRole) && (op == 1 || op == 3) {
|
||||
return ErrOpNotAllowed, errors.New("operation not allowed on org admin account")
|
||||
}
|
||||
|
||||
|
@ -656,7 +622,7 @@ func (q *QuorumControlsAPI) checkOrgAdminExists(orgId, roleId string, account co
|
|||
if ac.OrgId != orgId {
|
||||
return ErrAccountInUse, errors.New("account part of another org")
|
||||
}
|
||||
if roleId != "" && roleId == q.permConfig.OrgAdminRole && ac.IsOrgAdmin {
|
||||
if roleId != "" && roleId == q.permCtrl.permConfig.OrgAdminRole && ac.IsOrgAdmin {
|
||||
return ErrAccountOrgAdmin, errors.New("account already org admin for the org")
|
||||
}
|
||||
}
|
||||
|
@ -666,11 +632,11 @@ func (q *QuorumControlsAPI) checkOrgAdminExists(orgId, roleId string, account co
|
|||
func (q *QuorumControlsAPI) valSubOrgBreadthDepth(porgId string) (ExecStatus, error) {
|
||||
org := types.OrgInfoMap.GetOrg(porgId)
|
||||
|
||||
if q.permConfig.SubOrgDepth.Cmp(org.Level) == 0 {
|
||||
if q.permCtrl.permConfig.SubOrgDepth.Cmp(org.Level) == 0 {
|
||||
return ErrMaxDepth, errors.New("max depth for sub orgs reached")
|
||||
}
|
||||
|
||||
if q.permConfig.SubOrgBreadth.Cmp(big.NewInt(int64(len(org.SubOrgList)))) == 0 {
|
||||
if q.permCtrl.permConfig.SubOrgBreadth.Cmp(big.NewInt(int64(len(org.SubOrgList)))) == 0 {
|
||||
return ErrMaxBreadth, errors.New("max breadth for sub orgs reached")
|
||||
}
|
||||
|
||||
|
@ -725,7 +691,7 @@ func (q *QuorumControlsAPI) valAddOrg(args txArgs, pinterf *pbind.PermInterfaceS
|
|||
}
|
||||
|
||||
// check if any previous op is pending approval for network admin
|
||||
if q.checkPendingOp(q.permConfig.NwAdminOrg, pinterf) {
|
||||
if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
|
||||
return ErrPendingApprovals
|
||||
}
|
||||
// check if org already exists
|
||||
|
@ -751,7 +717,7 @@ func (q *QuorumControlsAPI) valApproveOrg(args txArgs, pinterf *pbind.PermInterf
|
|||
return ErrNotNetworkAdmin
|
||||
}
|
||||
// check if anything pending approval
|
||||
if !q.validatePendingOp(q.permConfig.NwAdminOrg, args.orgId, args.url, args.acctId, 1, pinterf) {
|
||||
if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, args.url, args.acctId, 1, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
return ExecSuccess
|
||||
|
@ -796,7 +762,7 @@ func (q *QuorumControlsAPI) valUpdateOrgStatus(args txArgs, pinterf *pbind.PermI
|
|||
}
|
||||
|
||||
//check if passed org id is network admin org. update should not be allowed
|
||||
if args.orgId == q.permConfig.NwAdminOrg {
|
||||
if args.orgId == q.permCtrl.permConfig.NwAdminOrg {
|
||||
return ErrOpNotAllowed
|
||||
}
|
||||
// check if status update can be performed. Org should be approved for suspension
|
||||
|
@ -820,7 +786,7 @@ func (q *QuorumControlsAPI) valApproveOrgStatus(args txArgs, pinterf *pbind.Perm
|
|||
} else {
|
||||
return ErrOpNotAllowed
|
||||
}
|
||||
if !q.validatePendingOp(q.permConfig.NwAdminOrg, args.orgId, "", common.Address{}, pendingOp, pinterf) {
|
||||
if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, "", common.Address{}, pendingOp, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
return ExecSuccess
|
||||
|
@ -860,7 +826,7 @@ func (q *QuorumControlsAPI) valAssignAdminRole(args txArgs, pinterf *pbind.PermI
|
|||
return ErrInvalidInput
|
||||
}
|
||||
// check if caller is network admin
|
||||
if args.roleId != q.permConfig.OrgAdminRole && args.roleId != q.permConfig.NwAdminRole {
|
||||
if args.roleId != q.permCtrl.permConfig.OrgAdminRole && args.roleId != q.permCtrl.permConfig.NwAdminRole {
|
||||
return ErrOpNotAllowed
|
||||
}
|
||||
|
||||
|
@ -892,7 +858,7 @@ func (q *QuorumControlsAPI) valApproveAdminRole(args txArgs, pinterf *pbind.Perm
|
|||
return ErrInvalidAccount
|
||||
}
|
||||
// validate pending op
|
||||
if !q.validatePendingOp(q.permConfig.NwAdminOrg, ac.OrgId, "", args.acctId, 4, pinterf) {
|
||||
if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, ac.OrgId, "", args.acctId, 4, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
return ExecSuccess
|
||||
|
@ -920,7 +886,7 @@ func (q *QuorumControlsAPI) valRemoveRole(args txArgs, pinterf *pbind.PermInterf
|
|||
}
|
||||
|
||||
// admin roles cannot be removed
|
||||
if args.roleId == q.permConfig.OrgAdminRole || args.roleId == q.permConfig.NwAdminRole {
|
||||
if args.roleId == q.permCtrl.permConfig.OrgAdminRole || args.roleId == q.permCtrl.permConfig.NwAdminRole {
|
||||
return ErrAdminRoles
|
||||
}
|
||||
|
||||
|
@ -943,7 +909,7 @@ func (q *QuorumControlsAPI) valAssignRole(args txArgs, pinterf *pbind.PermInterf
|
|||
if args.acctId == (common.Address{0}) {
|
||||
return ErrInvalidInput
|
||||
}
|
||||
if args.roleId == q.permConfig.OrgAdminRole || args.roleId == q.permConfig.NwAdminRole {
|
||||
if args.roleId == q.permCtrl.permConfig.OrgAdminRole || args.roleId == q.permCtrl.permConfig.NwAdminRole {
|
||||
return ErrInvalidRole
|
||||
}
|
||||
// check if caller is network admin
|
||||
|
@ -980,7 +946,7 @@ func (q *QuorumControlsAPI) valUpdateAccountStatus(args txArgs, pinterf *pbind.P
|
|||
// validateAccount validates the account and returns the wallet associated with that for signing the transaction
|
||||
func (q *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Wallet, error) {
|
||||
acct := accounts.Account{Address: from}
|
||||
w, err := q.acntMgr.Find(acct)
|
||||
w, err := q.permCtrl.eth.AccountManager().Find(acct)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
@ -990,7 +956,7 @@ func (q *QuorumControlsAPI) validateAccount(from common.Address) (accounts.Walle
|
|||
func (q *QuorumControlsAPI) newPermInterfaceSession(w accounts.Wallet, txa ethapi.SendTxArgs) *pbind.PermInterfaceSession {
|
||||
frmAcct, transactOpts, gasLimit, gasPrice, nonce := q.getTxParams(txa, w)
|
||||
ps := &pbind.PermInterfaceSession{
|
||||
Contract: q.permInterf,
|
||||
Contract: q.permCtrl.permInterf,
|
||||
CallOpts: bind.CallOpts{
|
||||
Pending: true,
|
||||
},
|
||||
|
@ -1021,7 +987,7 @@ func (q *QuorumControlsAPI) getTxParams(txa ethapi.SendTxArgs, w accounts.Wallet
|
|||
if txa.Nonce != nil {
|
||||
nonce = new(big.Int).SetUint64(uint64(*txa.Nonce))
|
||||
} else {
|
||||
nonce = new(big.Int).SetUint64(q.txPool.Nonce(frmAcct.Address))
|
||||
nonce = new(big.Int).SetUint64(q.permCtrl.eth.TxPool().Nonce(frmAcct.Address))
|
||||
}
|
||||
return frmAcct, transactOpts, gasLimit, gasPrice, nonce
|
||||
}
|
|
@ -5,9 +5,8 @@ import (
|
|||
"encoding/json"
|
||||
"errors"
|
||||
"github.com/ethereum/go-ethereum/cmd/utils"
|
||||
"github.com/ethereum/go-ethereum/core/quorum"
|
||||
"github.com/ethereum/go-ethereum/raft"
|
||||
"gopkg.in/urfave/cli.v1"
|
||||
"github.com/ethereum/go-ethereum/rpc"
|
||||
"io/ioutil"
|
||||
"math/big"
|
||||
"os"
|
||||
|
@ -55,74 +54,23 @@ type PermissionLocalConfig struct {
|
|||
}
|
||||
|
||||
type PermissionCtrl struct {
|
||||
node *node.Node
|
||||
ethClnt *ethclient.Client
|
||||
eth *eth.Ethereum
|
||||
permissionedMode bool
|
||||
key *ecdsa.PrivateKey
|
||||
dataDir string
|
||||
permUpgr *pbind.PermUpgr
|
||||
permInterf *pbind.PermInterface
|
||||
permNode *pbind.NodeManager
|
||||
permAcct *pbind.AcctManager
|
||||
permRole *pbind.RoleManager
|
||||
permOrg *pbind.OrgManager
|
||||
permConfig *types.PermissionConfig
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
func (p *PermissionCtrl) Interface() *pbind.PermInterface {
|
||||
return p.permInterf
|
||||
}
|
||||
|
||||
// Starts the permission services. services will come up only when
|
||||
// geth is brought up in --permissioned mode and permission-config.json is present
|
||||
func StartQuorumPermissionService(ctx *cli.Context, stack *node.Node) error {
|
||||
|
||||
var quorumApis []string
|
||||
dataDir := ctx.GlobalString(utils.DataDirFlag.Name)
|
||||
|
||||
var permissionConfig types.PermissionConfig
|
||||
var err error
|
||||
|
||||
if permissionConfig, err = ParsePermissionConifg(dataDir); err != nil {
|
||||
log.Error("loading of permission-config.json failed", "error", err)
|
||||
return nil
|
||||
}
|
||||
|
||||
// start the permissions management service
|
||||
pc, err := NewQuorumPermissionCtrl(stack, ctx.GlobalBool(utils.EnableNodePermissionFlag.Name), &permissionConfig)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
if err = pc.Start(); err == nil {
|
||||
quorumApis = []string{"quorumPermission"}
|
||||
} else {
|
||||
return err
|
||||
}
|
||||
|
||||
rpcClient, err := stack.Attach()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
stateReader := ethclient.NewClient(rpcClient)
|
||||
|
||||
for _, apiName := range quorumApis {
|
||||
v := stack.GetRPC(apiName)
|
||||
if v == nil {
|
||||
return errors.New("failed to start quorum permission api")
|
||||
}
|
||||
qapi := v.(*quorum.QuorumControlsAPI)
|
||||
|
||||
err = qapi.Init(stateReader, stack.GetNodeKey(), apiName, &permissionConfig, pc.Interface())
|
||||
if err != nil {
|
||||
log.Info("Failed to starts API", "apiName", apiName)
|
||||
} else {
|
||||
log.Info("API started", "apiName", apiName)
|
||||
}
|
||||
}
|
||||
return nil
|
||||
node *node.Node
|
||||
ethClnt *ethclient.Client
|
||||
eth *eth.Ethereum
|
||||
key *ecdsa.PrivateKey
|
||||
dataDir string
|
||||
permUpgr *pbind.PermUpgr
|
||||
permInterf *pbind.PermInterface
|
||||
permNode *pbind.NodeManager
|
||||
permAcct *pbind.AcctManager
|
||||
permRole *pbind.RoleManager
|
||||
permOrg *pbind.OrgManager
|
||||
permConfig *types.PermissionConfig
|
||||
orgChan chan struct{}
|
||||
nodeChan chan struct{}
|
||||
roleChan chan struct{}
|
||||
acctChan chan struct{}
|
||||
mux sync.Mutex
|
||||
}
|
||||
|
||||
// converts local permissions data to global permissions config
|
||||
|
@ -198,74 +146,103 @@ func waitForSync(e *eth.Ethereum) {
|
|||
}
|
||||
}
|
||||
|
||||
// Creates the controls structure for permissions
|
||||
func NewQuorumPermissionCtrl(stack *node.Node, permissionedMode bool, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
|
||||
// Create a new eth client to for interfacing with the contract
|
||||
stateReader, e, err := CreateEthClient(stack)
|
||||
waitForSync(e)
|
||||
if err != nil {
|
||||
log.Error("Unable to create ethereum client for permissions check", "err", err)
|
||||
return nil, err
|
||||
func StartPermissionService(stack *node.Node) {
|
||||
//initialize permission as we can create eth client only after the node and RPC are started
|
||||
var permissionService *PermissionCtrl
|
||||
if err := stack.Service(&permissionService); err != nil {
|
||||
utils.Fatalf("cannot access permissions service %v", err)
|
||||
}
|
||||
|
||||
if pconfig.IsEmpty() && permissionedMode {
|
||||
log.Error("permission-config.json is missing contract address")
|
||||
return nil, errors.New("permission-config.json is missing contract address")
|
||||
if permissionService == nil {
|
||||
utils.Fatalf("permission service unavailable")
|
||||
}
|
||||
pu, err := pbind.NewPermUpgr(pconfig.UpgrdAddress, stateReader)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
//initialize the service to create eth client and get ethereum service
|
||||
if err := permissionService.InitializeService(); err != nil {
|
||||
utils.Fatalf("permissions service initialization failed %v", err)
|
||||
}
|
||||
// check if permissioning contract is there at address. If not return from here
|
||||
pm, err := pbind.NewPermInterface(pconfig.InterfAddress, stateReader)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
if err := permissionService.Start(stack.Server()); err != nil {
|
||||
utils.Fatalf("permissions service start failed %v", err)
|
||||
}
|
||||
|
||||
pmAcct, err := pbind.NewAcctManager(pconfig.AccountAddress, stateReader)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pmNode, err := pbind.NewNodeManager(pconfig.NodeAddress, stateReader)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pmRole, err := pbind.NewRoleManager(pconfig.RoleAddress, stateReader)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
pmOrg, err := pbind.NewOrgManager(pconfig.OrgAddress, stateReader)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return nil, err
|
||||
}
|
||||
return &PermissionCtrl{
|
||||
node: stack,
|
||||
ethClnt: stateReader,
|
||||
eth: e,
|
||||
permissionedMode: permissionedMode,
|
||||
key: stack.GetNodeKey(),
|
||||
dataDir: stack.DataDir(),
|
||||
permUpgr: pu,
|
||||
permInterf: pm,
|
||||
permNode: pmNode,
|
||||
permAcct: pmAcct,
|
||||
permRole: pmRole,
|
||||
permOrg: pmOrg,
|
||||
permConfig: pconfig,
|
||||
}, nil
|
||||
}
|
||||
|
||||
// Starts monitoring service for permissions events at contract level
|
||||
func (p *PermissionCtrl) Start() error {
|
||||
// Creates the controls structure for permissions
|
||||
func NewQuorumPermissionCtrl(stack *node.Node, pconfig *types.PermissionConfig) (*PermissionCtrl, error) {
|
||||
// Create a new ethclient to for interfacing with the contract
|
||||
return &PermissionCtrl{stack, nil, nil, stack.GetNodeKey(), stack.DataDir(), nil, nil, nil, nil, nil, nil, pconfig, make(chan struct{}), make(chan struct{}), make(chan struct{}), make(chan struct{}), sync.Mutex{}}, nil
|
||||
}
|
||||
|
||||
func (p *PermissionCtrl) InitializeService() error {
|
||||
clnt, ethereum, err := CreateEthClient(p.node)
|
||||
if err != nil {
|
||||
log.Error("creating eth client failed")
|
||||
return err
|
||||
}
|
||||
waitFor
|
||||
Sync(ethereum)
|
||||
if err != nil {
|
||||
log.Error("Unable to create ethereum client for permissions check", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
if p.permConfig.IsEmpty() {
|
||||
log.Error("permission-config.json is missing contract address")
|
||||
return errors.New("permission-config.json is missing contract address")
|
||||
}
|
||||
pu, err := pbind.NewPermUpgr(p.permConfig.UpgrdAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return err
|
||||
}
|
||||
// check if permissioning contract is there at address. If not return from here
|
||||
pm, err := pbind.NewPermInterface(p.permConfig.InterfAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
pmAcct, err := pbind.NewAcctManager(p.permConfig.AccountAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
pmNode, err := pbind.NewNodeManager(p.permConfig.NodeAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
pmRole, err := pbind.NewRoleManager(p.permConfig.RoleAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return err
|
||||
}
|
||||
|
||||
pmOrg, err := pbind.NewOrgManager(p.permConfig.OrgAddress, clnt)
|
||||
if err != nil {
|
||||
log.Error("Permissions not enabled for the network", "err", err)
|
||||
return err
|
||||
}
|
||||
p.permUpgr = pu
|
||||
p.permInterf = pm
|
||||
p.permAcct = pmAcct
|
||||
p.permNode = pmNode
|
||||
p.permRole = pmRole
|
||||
p.permOrg = pmOrg
|
||||
p.ethClnt = clnt
|
||||
p.eth = ethereum
|
||||
log.Info("permission service initalized")
|
||||
return nil
|
||||
}
|
||||
|
||||
// Starts the node permissioning and event monitoring for permissions
|
||||
// smart contracts
|
||||
func (p *PermissionCtrl) Start(srvr *p2p.Server) error {
|
||||
|
||||
if p.ethClnt == nil || p.eth == nil {
|
||||
log.Info("permission service not initialized")
|
||||
return nil
|
||||
}
|
||||
log.Info("permission service start...")
|
||||
// Permissions initialization
|
||||
if err := p.init(); err != nil {
|
||||
log.Error("Permissions init failed", "err", err)
|
||||
|
@ -283,7 +260,36 @@ func (p *PermissionCtrl) Start() error {
|
|||
|
||||
// monitor org level account management events
|
||||
go p.manageAccountPermissions()
|
||||
log.Info("permission service started")
|
||||
return nil
|
||||
}
|
||||
|
||||
func (s *PermissionCtrl) APIs() []rpc.API {
|
||||
log.Info("permission rpc API called")
|
||||
return []rpc.API{
|
||||
{
|
||||
Namespace: "quorumPermission",
|
||||
Version: "1.0",
|
||||
Service: NewQuorumControlsAPI(s),
|
||||
Public: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func (s *PermissionCtrl) Protocols() []p2p.Protocol {
|
||||
return []p2p.Protocol{}
|
||||
}
|
||||
|
||||
func (p *PermissionCtrl) Stop() error {
|
||||
if p.eth == nil || p.ethClnt == nil {
|
||||
return nil
|
||||
}
|
||||
log.Info("stopping permission service...")
|
||||
p.roleChan <- struct{}{}
|
||||
p.orgChan <- struct{}{}
|
||||
p.acctChan <- struct{}{}
|
||||
p.nodeChan <- struct{}{}
|
||||
log.Info("stopped permission service")
|
||||
return nil
|
||||
}
|
||||
|
||||
|
@ -347,6 +353,9 @@ func (p *PermissionCtrl) manageOrgPermissions() {
|
|||
|
||||
case evtOrgReactivated = <-chOrgReactivated:
|
||||
types.OrgInfoMap.UpsertOrg(evtOrgReactivated.OrgId, evtOrgReactivated.PorgId, evtOrgReactivated.UltParent, evtOrgReactivated.Level, types.OrgApproved)
|
||||
case <-p.orgChan:
|
||||
log.Info("quit org contract watch")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -409,6 +418,9 @@ func (p *PermissionCtrl) manageNodePermissions() {
|
|||
p.updatePermissionedNodes(evtNodeBlacklisted.EnodeId, NodeDelete)
|
||||
p.updateDisallowedNodes(evtNodeBlacklisted.EnodeId)
|
||||
types.NodeInfoMap.UpsertNode(evtNodeBlacklisted.OrgId, evtNodeBlacklisted.EnodeId, types.NodeBlackListed)
|
||||
case <-p.nodeChan:
|
||||
log.Info("quit node contract watch")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -547,6 +559,9 @@ func (p *PermissionCtrl) manageAccountPermissions() {
|
|||
case evtStatusChanged = <-chStatusChanged:
|
||||
ac := types.AcctInfoMap.GetAccount(evtStatusChanged.Account)
|
||||
types.AcctInfoMap.UpsertAccount(evtStatusChanged.OrgId, ac.RoleId, evtStatusChanged.Account, ac.IsOrgAdmin, types.AcctStatus(int(evtStatusChanged.Status.Uint64())))
|
||||
case <-p.acctChan:
|
||||
log.Info("quit account contract watch")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -829,6 +844,9 @@ func (p *PermissionCtrl) manageRolePermissions() {
|
|||
} else {
|
||||
log.Error("Revoke role - cache is missing role", "org", evtRoleRevoked.OrgId, "role", evtRoleRevoked.RoleId)
|
||||
}
|
||||
case <-p.roleChan:
|
||||
log.Info("quit role contract watch")
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue