2018-10-29 19:41:01 -07:00
package permission
2018-07-12 03:00:19 -07:00
import (
2018-10-30 23:42:29 -07:00
"crypto/ecdsa"
2018-07-16 03:34:20 -07:00
"encoding/json"
2019-08-14 08:55:42 -07:00
"fmt"
2019-09-26 00:38:45 -07:00
"github.com/ethereum/go-ethereum/core"
2019-05-20 08:23:12 -07:00
"io/ioutil"
"math/big"
"os"
"path/filepath"
2019-08-21 13:55:58 -07:00
"reflect"
2019-05-20 08:23:12 -07:00
"sync"
"time"
2019-08-23 06:49:04 -07:00
"github.com/ethereum/go-ethereum/ethclient"
2019-08-20 06:33:54 -07:00
"github.com/ethereum/go-ethereum/event"
2019-08-14 08:55:42 -07:00
"github.com/ethereum/go-ethereum/raft"
"github.com/ethereum/go-ethereum/rpc"
2018-07-12 03:00:19 -07:00
"github.com/ethereum/go-ethereum/accounts/abi/bind"
2018-10-31 22:45:16 -07:00
"github.com/ethereum/go-ethereum/core/types"
2018-10-24 03:21:21 -07:00
"github.com/ethereum/go-ethereum/eth"
2018-07-12 03:00:19 -07:00
"github.com/ethereum/go-ethereum/log"
"github.com/ethereum/go-ethereum/node"
2018-10-24 03:21:21 -07:00
"github.com/ethereum/go-ethereum/p2p"
2019-04-30 03:28:09 -07:00
"github.com/ethereum/go-ethereum/p2p/enode"
2018-10-31 22:45:16 -07:00
"github.com/ethereum/go-ethereum/params"
2019-05-12 23:15:09 -07:00
pbind "github.com/ethereum/go-ethereum/permission/bind"
2018-07-12 03:00:19 -07:00
)
2018-10-29 19:41:01 -07:00
2018-08-12 19:00:35 -07:00
type NodeOperation uint8
2018-10-29 19:41:01 -07:00
2018-08-12 19:00:35 -07:00
const (
NodeAdd NodeOperation = iota
NodeDelete
)
2018-10-29 19:41:01 -07:00
type PermissionCtrl struct {
2019-05-08 07:55:03 -07:00
node * node . Node
2019-08-19 06:39:18 -07:00
ethClnt bind . ContractBackend
2019-05-08 07:55:03 -07:00
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
2019-08-20 06:33:54 -07:00
2019-08-21 13:55:58 -07:00
startWaitGroup * sync . WaitGroup // waitgroup to make sure all dependenies are ready before we start the service
stopFeed event . Feed // broadcasting stopEvent when service is being stopped
errorChan chan error // channel to capture error when starting aysnc
2019-08-20 06:33:54 -07:00
mux sync . Mutex
}
// to signal all watches when service is stopped
type stopEvent struct {
2019-06-06 23:51:21 -07:00
}
2019-05-10 00:17:01 -07:00
// function reads the permissions config file passed and populates the
2019-05-15 02:12:11 -07:00
// config structure accordingly
2019-08-14 08:55:42 -07:00
func ParsePermissionConfig ( dir string ) ( types . PermissionConfig , error ) {
fullPath := filepath . Join ( dir , params . PERMISSION_MODEL_CONFIG )
f , err := os . Open ( fullPath )
2019-03-11 20:18:20 -07:00
if err != nil {
2019-08-14 08:55:42 -07:00
log . Error ( "can't open file" , "file" , fullPath , "error" , err )
2019-03-11 20:18:20 -07:00
return types . PermissionConfig { } , err
}
2019-08-14 08:55:42 -07:00
defer func ( ) {
_ = f . Close ( )
} ( )
2019-09-09 00:53:15 -07:00
var permConfig types . PermissionConfig
blob , err := ioutil . ReadFile ( fullPath )
if err != nil {
log . Error ( "error reading file" , "err" , err , "file" , fullPath )
}
err = json . Unmarshal ( blob , & permConfig )
if err != nil {
log . Error ( "error unmarshalling the file" , "err" , err , "file" , fullPath )
2019-03-11 20:18:20 -07:00
}
2019-03-31 23:33:44 -07:00
2019-04-01 02:48:37 -07:00
if len ( permConfig . Accounts ) == 0 {
2019-08-14 08:55:42 -07:00
return types . PermissionConfig { } , fmt . Errorf ( "no accounts given in %s. Network cannot boot up" , params . PERMISSION_MODEL_CONFIG )
2019-04-01 02:48:37 -07:00
}
2019-04-14 21:32:06 -07:00
if permConfig . SubOrgDepth . Cmp ( big . NewInt ( 0 ) ) == 0 || permConfig . SubOrgBreadth . Cmp ( big . NewInt ( 0 ) ) == 0 {
2019-08-14 08:55:42 -07:00
return types . PermissionConfig { } , fmt . Errorf ( "sub org breadth depth not passed in %s. Network cannot boot up" , params . PERMISSION_MODEL_CONFIG )
2019-04-14 21:32:06 -07:00
}
2019-08-21 13:55:58 -07:00
if permConfig . IsEmpty ( ) {
return types . PermissionConfig { } , fmt . Errorf ( "missing contract addresses in %s" , params . PERMISSION_MODEL_CONFIG )
}
2019-09-09 00:53:15 -07:00
2019-03-11 20:18:20 -07:00
return permConfig , nil
2018-10-25 21:33:23 -07:00
}
2019-08-21 13:55:58 -07:00
// Create a service instance for permissioning
//
// Permission Service depends on the following:
// 1. EthService to be ready
// 2. Downloader to sync up blocks
// 3. InProc RPC server to be ready
func NewQuorumPermissionCtrl ( stack * node . Node , pconfig * types . PermissionConfig ) ( * PermissionCtrl , error ) {
wg := & sync . WaitGroup { }
wg . Add ( 1 )
p := & PermissionCtrl {
node : stack ,
key : stack . GetNodeKey ( ) ,
dataDir : stack . DataDir ( ) ,
permConfig : pconfig ,
startWaitGroup : wg ,
errorChan : make ( chan error ) ,
}
go func ( _wg * sync . WaitGroup ) {
log . Debug ( "permission service: waiting for InProcRPC Server" )
stopChan , stopSubscription := p . subscribeStopEvent ( )
inProcRPCServerSub := stack . EventMux ( ) . Subscribe ( rpc . InProcServerReadyEvent { } )
defer func ( start time . Time ) {
log . Debug ( "permission service: InProcRPC server is ready" , "took" , time . Since ( start ) )
stopSubscription . Unsubscribe ( )
inProcRPCServerSub . Unsubscribe ( )
_wg . Done ( )
} ( time . Now ( ) )
select {
case <- inProcRPCServerSub . Chan ( ) :
case <- stopChan :
}
} ( wg ) // wait for inproc RPC to be ready
return p , nil
2019-04-30 03:28:09 -07:00
}
2019-08-21 13:55:58 -07:00
func ( p * PermissionCtrl ) bindContract ( contractInstance interface { } , bindFunc func ( ) ( interface { } , error ) ) error {
element := reflect . ValueOf ( contractInstance ) . Elem ( )
instance , err := bindFunc ( )
if err != nil {
return err
2019-07-23 23:00:49 -07:00
}
2019-08-21 13:55:58 -07:00
element . Set ( reflect . ValueOf ( instance ) )
2019-08-14 09:01:29 -07:00
return nil
2019-07-23 23:00:49 -07:00
}
2019-08-21 13:55:58 -07:00
// This is to make sure all contract instances are ready and initialized
2019-08-20 06:33:54 -07:00
//
2019-08-21 13:55:58 -07:00
// Required to be call after standard service start lifecycle
2019-08-20 06:33:54 -07:00
func ( p * PermissionCtrl ) AfterStart ( ) error {
2019-08-21 13:55:58 -07:00
log . Debug ( "permission service: binding contracts" )
err := <- p . errorChan // capture any error happened during asyncStart. Also wait here if asyncStart is not yet finish
2019-05-08 07:55:03 -07:00
if err != nil {
return err
}
2019-08-21 13:55:58 -07:00
if err := p . bindContract ( & p . permUpgr , func ( ) ( interface { } , error ) { return pbind . NewPermUpgr ( p . permConfig . UpgrdAddress , p . ethClnt ) } ) ; err != nil {
2019-05-08 07:55:03 -07:00
return err
2019-03-08 01:09:24 -08:00
}
2019-08-21 13:55:58 -07:00
if err := p . bindContract ( & p . permInterf , func ( ) ( interface { } , error ) { return pbind . NewPermInterface ( p . permConfig . InterfAddress , p . ethClnt ) } ) ; err != nil {
2019-05-08 07:55:03 -07:00
return err
2019-03-26 08:20:06 -07:00
}
2019-08-21 13:55:58 -07:00
if err := p . bindContract ( & p . permAcct , func ( ) ( interface { } , error ) { return pbind . NewAcctManager ( p . permConfig . AccountAddress , p . ethClnt ) } ) ; err != nil {
2019-05-08 07:55:03 -07:00
return err
2019-03-22 04:34:15 -07:00
}
2019-08-21 13:55:58 -07:00
if err := p . bindContract ( & p . permNode , func ( ) ( interface { } , error ) { return pbind . NewNodeManager ( p . permConfig . NodeAddress , p . ethClnt ) } ) ; err != nil {
2019-05-08 07:55:03 -07:00
return err
2018-10-29 19:41:01 -07:00
}
2019-08-21 13:55:58 -07:00
if err := p . bindContract ( & p . permRole , func ( ) ( interface { } , error ) { return pbind . NewRoleManager ( p . permConfig . RoleAddress , p . ethClnt ) } ) ; err != nil {
2019-05-08 07:55:03 -07:00
return err
2019-03-22 04:34:15 -07:00
}
2019-08-21 13:55:58 -07:00
if err := p . bindContract ( & p . permOrg , func ( ) ( interface { } , error ) { return pbind . NewOrgManager ( p . permConfig . OrgAddress , p . ethClnt ) } ) ; err != nil {
2019-05-08 07:55:03 -07:00
return err
2019-03-27 04:07:01 -07:00
}
2019-08-21 13:55:58 -07:00
// populate the initial list of permissioned nodes and account accesses
if err := p . populateInitPermissions ( ) ; err != nil {
return fmt . Errorf ( "populateInitPermissions failed: %v" , err )
2019-03-27 04:07:01 -07:00
}
2018-11-02 03:42:14 -07:00
2019-08-21 13:55:58 -07:00
// set the default access to ReadOnly
types . SetDefaults ( p . permConfig . NwAdminRole , p . permConfig . OrgAdminRole )
2019-05-08 07:55:03 -07:00
2019-08-21 13:55:58 -07:00
for _ , f := range [ ] func ( ) error {
2019-09-26 00:38:45 -07:00
p . monitorQIP714Block , // monitor block number to activate new permissions controls
2019-08-21 13:55:58 -07:00
p . manageOrgPermissions , // monitor org management related events
p . manageNodePermissions , // monitor org level node management events
p . manageRolePermissions , // monitor org level role management events
p . manageAccountPermissions , // monitor org level account management events
} {
if err := f ( ) ; err != nil {
return err
2019-08-20 06:33:54 -07:00
}
2018-11-02 03:42:14 -07:00
}
2019-03-31 23:33:44 -07:00
2019-08-21 13:55:58 -07:00
log . Info ( "permission service: is now ready" )
return nil
2019-08-20 06:33:54 -07:00
}
2019-03-31 23:33:44 -07:00
2019-08-21 13:55:58 -07:00
// start service asynchronously due to dependencies
func ( p * PermissionCtrl ) asyncStart ( ) {
2019-08-20 06:33:54 -07:00
var ethereum * eth . Ethereum
2019-08-21 13:55:58 -07:00
// will be blocked here until node is up
2019-08-20 06:33:54 -07:00
if err := p . node . Service ( & ethereum ) ; err != nil {
2019-08-21 13:55:58 -07:00
p . errorChan <- fmt . Errorf ( "dependent ethereum service not started" )
return
2018-11-02 03:42:14 -07:00
}
2019-08-21 13:55:58 -07:00
defer func ( ) {
p . errorChan <- nil
} ( )
// for cases where the node is joining an existing network, permission service
// can be brought up only after block syncing is complete. This function
// waits for block syncing before the starting permissions
p . startWaitGroup . Add ( 1 )
go func ( _wg * sync . WaitGroup ) {
log . Debug ( "permission service: waiting for downloader" )
stopChan , stopSubscription := p . subscribeStopEvent ( )
pollingTicker := time . NewTicker ( 10 * time . Millisecond )
defer func ( start time . Time ) {
log . Debug ( "permission service: downloader completed" , "took" , time . Since ( start ) )
stopSubscription . Unsubscribe ( )
pollingTicker . Stop ( )
_wg . Done ( )
} ( time . Now ( ) )
for {
select {
case <- pollingTicker . C :
if types . GetSyncStatus ( ) && ! ethereum . Downloader ( ) . Synchronising ( ) {
return
}
case <- stopChan :
return
}
}
} ( p . startWaitGroup ) // wait for downloader to sync if any
2019-03-31 23:33:44 -07:00
2019-08-21 13:55:58 -07:00
log . Debug ( "permission service: waiting for all dependencies to be ready" )
p . startWaitGroup . Wait ( )
2019-08-23 06:49:04 -07:00
client , err := p . node . Attach ( )
if err != nil {
p . errorChan <- fmt . Errorf ( "unable to create rpc client: %v" , err )
return
}
p . ethClnt = ethclient . NewClient ( client )
2019-08-21 13:55:58 -07:00
p . eth = ethereum
}
2019-03-31 23:33:44 -07:00
2019-08-21 13:55:58 -07:00
func ( p * PermissionCtrl ) Start ( srvr * p2p . Server ) error {
log . Debug ( "permission service: starting" )
go func ( ) {
2019-08-22 08:27:38 -07:00
log . Debug ( "permission service: starting async" )
2019-08-21 13:55:58 -07:00
p . asyncStart ( )
} ( )
2018-08-12 19:00:35 -07:00
return nil
}
2018-07-13 18:22:43 -07:00
2019-08-20 06:33:54 -07:00
func ( p * PermissionCtrl ) APIs ( ) [ ] rpc . API {
2019-05-07 23:07:23 -07:00
return [ ] rpc . API {
{
Namespace : "quorumPermission" ,
Version : "1.0" ,
2019-08-20 06:33:54 -07:00
Service : NewQuorumControlsAPI ( p ) ,
2019-05-07 23:07:23 -07:00
Public : true ,
} ,
}
}
2018-11-02 03:42:14 -07:00
2019-08-20 06:33:54 -07:00
func ( p * PermissionCtrl ) Protocols ( ) [ ] p2p . Protocol {
2019-05-07 23:07:23 -07:00
return [ ] p2p . Protocol { }
}
func ( p * PermissionCtrl ) Stop ( ) error {
2019-08-21 13:55:58 -07:00
log . Info ( "permission service: stopping" )
2019-08-20 06:33:54 -07:00
p . stopFeed . Send ( stopEvent { } )
2019-08-21 13:55:58 -07:00
log . Info ( "permission service: stopped" )
2018-10-25 22:38:56 -07:00
return nil
}
2019-09-26 20:40:59 -07:00
// monitors QIP714Block and set default access
2019-09-26 00:38:45 -07:00
func ( p * PermissionCtrl ) monitorQIP714Block ( ) error {
// if QIP714block is not given, set the default access
// to readonly
if p . eth . ChainConfig ( ) . QIP714Block == nil {
types . SetDefaultAccess ( )
return nil
}
//QIP714block is given, monitor block count
go func ( ) {
chainHeadCh := make ( chan core . ChainHeadEvent , 1 )
headSub := p . eth . BlockChain ( ) . SubscribeChainHeadEvent ( chainHeadCh )
defer headSub . Unsubscribe ( )
stopChan , stopSubscription := p . subscribeStopEvent ( )
defer stopSubscription . Unsubscribe ( )
for {
select {
case head := <- chainHeadCh :
if p . eth . ChainConfig ( ) . IsQIP714 ( head . Block . Number ( ) ) {
types . SetDefaultAccess ( )
return
}
case <- stopChan :
return
}
}
} ( )
return nil
}
2019-05-10 00:17:01 -07:00
// monitors org management related events happening via smart contracts
// and updates cache accordingly
2019-08-21 13:55:58 -07:00
func ( p * PermissionCtrl ) manageOrgPermissions ( ) error {
2019-04-01 02:48:37 -07:00
chPendingApproval := make ( chan * pbind . OrgManagerOrgPendingApproval , 1 )
chOrgApproved := make ( chan * pbind . OrgManagerOrgApproved , 1 )
chOrgSuspended := make ( chan * pbind . OrgManagerOrgSuspended , 1 )
chOrgReactivated := make ( chan * pbind . OrgManagerOrgSuspensionRevoked , 1 )
2019-03-28 03:00:17 -07:00
2019-04-01 02:48:37 -07:00
opts := & bind . WatchOpts { }
var blockNumber uint64 = 1
opts . Start = & blockNumber
if _ , err := p . permOrg . OrgManagerFilterer . WatchOrgPendingApproval ( opts , chPendingApproval ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodePendingApproval: %v" , err )
2019-04-01 02:48:37 -07:00
}
if _ , err := p . permOrg . OrgManagerFilterer . WatchOrgApproved ( opts , chOrgApproved ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodePendingApproval: %v" , err )
2019-04-01 02:48:37 -07:00
}
if _ , err := p . permOrg . OrgManagerFilterer . WatchOrgSuspended ( opts , chOrgSuspended ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodePendingApproval: %v" , err )
2019-04-01 02:48:37 -07:00
}
if _ , err := p . permOrg . OrgManagerFilterer . WatchOrgSuspensionRevoked ( opts , chOrgReactivated ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodePendingApproval: %v" , err )
2019-04-01 02:48:37 -07:00
}
2019-08-21 13:55:58 -07:00
go func ( ) {
stopChan , stopSubscription := p . subscribeStopEvent ( )
defer stopSubscription . Unsubscribe ( )
for {
select {
case evtPendingApproval := <- chPendingApproval :
types . OrgInfoMap . UpsertOrg ( evtPendingApproval . OrgId , evtPendingApproval . PorgId , evtPendingApproval . UltParent , evtPendingApproval . Level , types . OrgStatus ( evtPendingApproval . Status . Uint64 ( ) ) )
2019-04-01 02:48:37 -07:00
2019-08-21 13:55:58 -07:00
case evtOrgApproved := <- chOrgApproved :
types . OrgInfoMap . UpsertOrg ( evtOrgApproved . OrgId , evtOrgApproved . PorgId , evtOrgApproved . UltParent , evtOrgApproved . Level , types . OrgApproved )
2019-04-01 02:48:37 -07:00
2019-08-21 13:55:58 -07:00
case evtOrgSuspended := <- chOrgSuspended :
types . OrgInfoMap . UpsertOrg ( evtOrgSuspended . OrgId , evtOrgSuspended . PorgId , evtOrgSuspended . UltParent , evtOrgSuspended . Level , types . OrgSuspended )
2019-04-01 02:48:37 -07:00
2019-08-21 13:55:58 -07:00
case evtOrgReactivated := <- chOrgReactivated :
types . OrgInfoMap . UpsertOrg ( evtOrgReactivated . OrgId , evtOrgReactivated . PorgId , evtOrgReactivated . UltParent , evtOrgReactivated . Level , types . OrgApproved )
case <- stopChan :
log . Info ( "quit org contract watch" )
return
}
2019-04-01 02:48:37 -07:00
}
2019-08-21 13:55:58 -07:00
} ( )
return nil
2019-03-28 03:00:17 -07:00
}
2019-08-20 06:33:54 -07:00
func ( p * PermissionCtrl ) subscribeStopEvent ( ) ( chan stopEvent , event . Subscription ) {
c := make ( chan stopEvent )
s := p . stopFeed . Subscribe ( c )
return c , s
2019-03-28 03:00:17 -07:00
}
2019-04-01 23:13:23 -07:00
// Monitors node management events and updates cache accordingly
2019-08-21 13:55:58 -07:00
func ( p * PermissionCtrl ) manageNodePermissions ( ) error {
2019-04-01 23:13:23 -07:00
chNodeApproved := make ( chan * pbind . NodeManagerNodeApproved , 1 )
chNodeProposed := make ( chan * pbind . NodeManagerNodeProposed , 1 )
chNodeDeactivated := make ( chan * pbind . NodeManagerNodeDeactivated , 1 )
chNodeActivated := make ( chan * pbind . NodeManagerNodeActivated , 1 )
chNodeBlacklisted := make ( chan * pbind . NodeManagerNodeBlacklisted )
2019-08-01 00:19:40 -07:00
chNodeRecoveryInit := make ( chan * pbind . NodeManagerNodeRecoveryInitiated , 1 )
chNodeRecoveryDone := make ( chan * pbind . NodeManagerNodeRecoveryCompleted , 1 )
2019-04-01 23:13:23 -07:00
2018-07-13 18:22:43 -07:00
opts := & bind . WatchOpts { }
var blockNumber uint64 = 1
opts . Start = & blockNumber
2019-04-01 23:13:23 -07:00
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeApproved ( opts , chNodeApproved ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodeApproved: %v" , err )
2019-03-28 03:00:17 -07:00
}
2019-03-29 02:49:46 -07:00
2019-04-01 23:13:23 -07:00
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeProposed ( opts , chNodeProposed ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodeProposed: %v" , err )
2019-03-28 03:00:17 -07:00
}
2018-07-26 00:46:53 -07:00
2019-04-01 23:13:23 -07:00
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeDeactivated ( opts , chNodeDeactivated ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed NodeDeactivated: %v" , err )
2018-08-16 20:20:33 -07:00
}
2019-04-01 23:13:23 -07:00
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeActivated ( opts , chNodeActivated ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchNodeActivated: %v" , err )
2018-08-16 20:20:33 -07:00
}
2018-08-05 22:26:29 -07:00
2019-04-01 23:13:23 -07:00
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeBlacklisted ( opts , chNodeBlacklisted ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed NodeBlacklisting: %v" , err )
2018-11-02 03:42:14 -07:00
}
2018-08-31 04:35:35 -07:00
2019-08-01 00:19:40 -07:00
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeRecoveryInitiated ( opts , chNodeRecoveryInit ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed NodeRecoveryInitiated: %v" , err )
2019-08-01 00:19:40 -07:00
}
if _ , err := p . permNode . NodeManagerFilterer . WatchNodeRecoveryCompleted ( opts , chNodeRecoveryDone ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed NodeRecoveryCompleted: %v" , err )
2019-07-31 20:10:50 -07:00
}
2019-08-21 13:55:58 -07:00
go func ( ) {
stopChan , stopSubscription := p . subscribeStopEvent ( )
defer stopSubscription . Unsubscribe ( )
for {
select {
case evtNodeApproved := <- chNodeApproved :
p . updatePermissionedNodes ( evtNodeApproved . EnodeId , NodeAdd )
types . NodeInfoMap . UpsertNode ( evtNodeApproved . OrgId , evtNodeApproved . EnodeId , types . NodeApproved )
2019-04-01 23:13:23 -07:00
2019-08-21 13:55:58 -07:00
case evtNodeProposed := <- chNodeProposed :
types . NodeInfoMap . UpsertNode ( evtNodeProposed . OrgId , evtNodeProposed . EnodeId , types . NodePendingApproval )
2019-04-01 23:13:23 -07:00
2019-08-21 13:55:58 -07:00
case evtNodeDeactivated := <- chNodeDeactivated :
p . updatePermissionedNodes ( evtNodeDeactivated . EnodeId , NodeDelete )
types . NodeInfoMap . UpsertNode ( evtNodeDeactivated . OrgId , evtNodeDeactivated . EnodeId , types . NodeDeactivated )
2019-04-01 23:13:23 -07:00
2019-08-21 13:55:58 -07:00
case evtNodeActivated := <- chNodeActivated :
p . updatePermissionedNodes ( evtNodeActivated . EnodeId , NodeAdd )
types . NodeInfoMap . UpsertNode ( evtNodeActivated . OrgId , evtNodeActivated . EnodeId , types . NodeApproved )
2019-04-01 23:13:23 -07:00
2019-08-21 13:55:58 -07:00
case evtNodeBlacklisted := <- chNodeBlacklisted :
types . NodeInfoMap . UpsertNode ( evtNodeBlacklisted . OrgId , evtNodeBlacklisted . EnodeId , types . NodeBlackListed )
p . updateDisallowedNodes ( evtNodeBlacklisted . EnodeId , NodeAdd )
p . updatePermissionedNodes ( evtNodeBlacklisted . EnodeId , NodeDelete )
2019-07-31 20:10:50 -07:00
2019-08-21 13:55:58 -07:00
case evtNodeRecoveryInit := <- chNodeRecoveryInit :
types . NodeInfoMap . UpsertNode ( evtNodeRecoveryInit . OrgId , evtNodeRecoveryInit . EnodeId , types . NodeRecoveryInitiated )
2019-08-01 00:19:40 -07:00
2019-08-21 13:55:58 -07:00
case evtNodeRecoveryDone := <- chNodeRecoveryDone :
types . NodeInfoMap . UpsertNode ( evtNodeRecoveryDone . OrgId , evtNodeRecoveryDone . EnodeId , types . NodeApproved )
p . updateDisallowedNodes ( evtNodeRecoveryDone . EnodeId , NodeDelete )
p . updatePermissionedNodes ( evtNodeRecoveryDone . EnodeId , NodeAdd )
2019-07-31 20:10:50 -07:00
2019-08-21 13:55:58 -07:00
case <- stopChan :
log . Info ( "quit node contract watch" )
return
}
2018-08-31 04:35:35 -07:00
}
2019-08-21 13:55:58 -07:00
} ( )
return nil
2018-08-31 04:35:35 -07:00
}
2018-11-07 04:50:49 -08:00
2019-08-01 00:19:40 -07:00
// adds or deletes and entry from a given file
func ( p * PermissionCtrl ) updateFile ( fileName , enodeId string , operation NodeOperation , createFile bool ) {
2018-11-19 23:43:56 -08:00
// Load the nodes from the config file
2019-05-17 01:12:53 -07:00
var nodeList [ ] string
2019-01-23 21:35:46 -08:00
index := 0
2019-08-01 00:19:40 -07:00
// if createFile is false means the file is already existing. read the file
if ! createFile {
blob , err := ioutil . ReadFile ( fileName )
if err != nil && ! createFile {
log . Error ( "Failed to access the file" , "fileName" , fileName , "err" , err )
return
}
if err := json . Unmarshal ( blob , & nodeList ) ; err != nil {
log . Error ( "Failed to load nodes list from file" , "fileName" , fileName , "err" , err )
return
}
// logic to update the permissioned-nodes.json file based on action
recExists := false
for i , eid := range nodeList {
if eid == enodeId {
index = i
recExists = true
break
}
}
if ( operation == NodeAdd && recExists ) || ( operation == NodeDelete && ! recExists ) {
return
2019-01-23 21:35:46 -08:00
}
2019-05-17 01:12:53 -07:00
}
2018-11-20 05:29:03 -08:00
if operation == NodeAdd {
2019-05-17 01:12:53 -07:00
nodeList = append ( nodeList , enodeId )
2019-01-23 21:35:46 -08:00
} else {
2019-05-17 01:12:53 -07:00
nodeList = append ( nodeList [ : index ] , nodeList [ index + 1 : ] ... )
2018-07-26 00:46:53 -07:00
}
2019-08-01 00:19:40 -07:00
blob , _ := json . Marshal ( nodeList )
2018-07-16 03:34:20 -07:00
2019-05-09 19:49:16 -07:00
p . mux . Lock ( )
defer p . mux . Unlock ( )
2019-08-01 00:19:40 -07:00
if err := ioutil . WriteFile ( fileName , blob , 0644 ) ; err != nil {
log . Error ( "Error writing new node info to file" , "fileName" , fileName , "err" , err )
}
}
// updates node information in the permissioned-nodes.json file based on node
// management activities in smart contract
func ( p * PermissionCtrl ) updatePermissionedNodes ( enodeId string , operation NodeOperation ) {
log . Debug ( "updatePermissionedNodes" , "DataDir" , p . dataDir , "file" , params . PERMISSIONED_CONFIG )
path := filepath . Join ( p . dataDir , params . PERMISSIONED_CONFIG )
if _ , err := os . Stat ( path ) ; err != nil {
log . Error ( "Read Error for permissioned-nodes.json file. This is because 'permissioned' flag is specified but no permissioned-nodes.json file is present" , "err" , err )
return
2018-11-19 23:43:56 -08:00
}
2019-08-01 00:19:40 -07:00
p . updateFile ( path , enodeId , operation , false )
2019-08-16 07:52:23 -07:00
if operation == NodeDelete {
p . disconnectNode ( enodeId )
}
2018-08-12 19:00:35 -07:00
}
2018-08-31 04:35:35 -07:00
2019-02-12 20:31:11 -08:00
//this function populates the black listed node information into the disallowed-nodes.json file
2019-08-01 00:19:40 -07:00
func ( p * PermissionCtrl ) updateDisallowedNodes ( url string , operation NodeOperation ) {
2019-02-13 18:24:32 -08:00
log . Debug ( "updateDisallowedNodes" , "DataDir" , p . dataDir , "file" , params . BLACKLIST_CONFIG )
2018-08-31 04:35:35 -07:00
2019-08-01 00:19:40 -07:00
fileExists := true
2019-02-13 18:24:32 -08:00
path := filepath . Join ( p . dataDir , params . BLACKLIST_CONFIG )
2018-09-02 23:59:45 -07:00
// Check if the file is existing. If the file is not existing create the file
2018-08-31 04:35:35 -07:00
if _ , err := os . Stat ( path ) ; err != nil {
2019-02-13 01:42:59 -08:00
log . Error ( "Read Error for disallowed-nodes.json file" , "err" , err )
2018-08-31 04:35:35 -07:00
if _ , err := os . OpenFile ( path , os . O_CREATE | os . O_RDWR , 0644 ) ; err != nil {
2019-02-13 01:42:59 -08:00
log . Error ( "Failed to create disallowed-nodes.json file" , "err" , err )
2018-10-29 19:41:01 -07:00
return
2018-08-31 04:35:35 -07:00
}
2019-08-01 00:19:40 -07:00
fileExists = false
2018-08-31 04:35:35 -07:00
}
2019-08-01 00:19:40 -07:00
if fileExists {
p . updateFile ( path , url , operation , false )
} else {
p . updateFile ( path , url , operation , true )
2018-08-31 04:35:35 -07:00
}
}
2019-04-01 23:13:23 -07:00
// Monitors account access related events and updates the cache accordingly
2019-08-21 13:55:58 -07:00
func ( p * PermissionCtrl ) manageAccountPermissions ( ) error {
2019-04-01 23:13:23 -07:00
chAccessModified := make ( chan * pbind . AcctManagerAccountAccessModified )
chAccessRevoked := make ( chan * pbind . AcctManagerAccountAccessRevoked )
2019-04-15 00:09:05 -07:00
chStatusChanged := make ( chan * pbind . AcctManagerAccountStatusChanged )
2019-04-01 23:13:23 -07:00
opts := & bind . WatchOpts { }
var blockNumber uint64 = 1
opts . Start = & blockNumber
if _ , err := p . permAcct . AcctManagerFilterer . WatchAccountAccessModified ( opts , chAccessModified ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed AccountAccessModified: %v" , err )
2019-04-01 23:13:23 -07:00
}
if _ , err := p . permAcct . AcctManagerFilterer . WatchAccountAccessRevoked ( opts , chAccessRevoked ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed AccountAccessRevoked: %v" , err )
2019-04-01 23:13:23 -07:00
}
2019-04-15 00:09:05 -07:00
if _ , err := p . permAcct . AcctManagerFilterer . WatchAccountStatusChanged ( opts , chStatusChanged ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed AccountStatusChanged: %v" , err )
}
go func ( ) {
stopChan , stopSubscription := p . subscribeStopEvent ( )
defer stopSubscription . Unsubscribe ( )
for {
select {
case evtAccessModified := <- chAccessModified :
types . AcctInfoMap . UpsertAccount ( evtAccessModified . OrgId , evtAccessModified . RoleId , evtAccessModified . Account , evtAccessModified . OrgAdmin , types . AcctStatus ( int ( evtAccessModified . Status . Uint64 ( ) ) ) )
case evtAccessRevoked := <- chAccessRevoked :
types . AcctInfoMap . UpsertAccount ( evtAccessRevoked . OrgId , evtAccessRevoked . RoleId , evtAccessRevoked . Account , evtAccessRevoked . OrgAdmin , types . AcctActive )
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 <- stopChan :
log . Info ( "quit account contract watch" )
return
}
2019-04-01 23:13:23 -07:00
}
2019-08-21 13:55:58 -07:00
} ( )
return nil
2018-08-12 19:00:35 -07:00
}
2018-10-29 19:41:01 -07:00
2018-09-19 18:51:36 -07:00
// Disconnect the node from the network
2018-10-29 19:41:01 -07:00
func ( p * PermissionCtrl ) disconnectNode ( enodeId string ) {
2019-05-30 23:25:56 -07:00
if p . eth . ChainConfig ( ) . Istanbul == nil && p . eth . ChainConfig ( ) . Clique == nil {
2018-09-19 18:51:36 -07:00
var raftService * raft . RaftService
2018-10-29 19:41:01 -07:00
if err := p . node . Service ( & raftService ) ; err == nil {
2018-09-19 18:51:36 -07:00
raftApi := raft . NewPublicRaftAPI ( raftService )
//get the raftId for the given enodeId
raftId , err := raftApi . GetRaftId ( enodeId )
if err == nil {
raftApi . RemovePeer ( raftId )
2019-05-17 01:12:53 -07:00
} else {
log . Error ( "failed to get raft id" , "err" , err , "enodeId" , enodeId )
2018-09-19 18:51:36 -07:00
}
}
} else {
2019-05-30 23:25:56 -07:00
// Istanbul or clique - disconnect the peer
2018-10-29 19:41:01 -07:00
server := p . node . Server ( )
2018-09-19 18:51:36 -07:00
if server != nil {
2019-03-08 01:09:24 -08:00
node , err := enode . ParseV4 ( enodeId )
2018-09-19 18:51:36 -07:00
if err == nil {
server . RemovePeer ( node )
2019-05-17 01:12:53 -07:00
} else {
log . Error ( "failed parse node id" , "err" , err , "enodeId" , enodeId )
2018-09-19 18:51:36 -07:00
}
}
}
2019-05-30 23:25:56 -07:00
2018-09-19 18:51:36 -07:00
}
2018-09-19 22:55:57 -07:00
2019-05-10 00:17:01 -07:00
// Thus function checks if the initial network boot up status and if no
2019-05-15 02:12:11 -07:00
// populates permissions model with details from permission-config.json
2019-03-26 08:20:06 -07:00
func ( p * PermissionCtrl ) populateInitPermissions ( ) error {
auth := bind . NewKeyedTransactor ( p . key )
permInterfSession := & pbind . PermInterfaceSession {
2019-03-22 04:34:15 -07:00
Contract : p . permInterf ,
2018-10-24 03:21:21 -07:00
CallOpts : bind . CallOpts {
Pending : true ,
} ,
TransactOpts : bind . TransactOpts {
From : auth . From ,
Signer : auth . Signer ,
2019-03-22 04:34:15 -07:00
GasLimit : 47000000 ,
2018-10-24 03:21:21 -07:00
GasPrice : big . NewInt ( 0 ) ,
} ,
}
2019-03-26 08:20:06 -07:00
networkInitialized , err := permInterfSession . GetNetworkBootStatus ( )
2018-10-25 22:38:56 -07:00
if err != nil {
2019-01-21 00:18:59 -08:00
// handle the scenario of no contract code.
log . Warn ( "Failed to retrieve network boot status " , "err" , err )
2019-03-27 21:44:47 -07:00
return err
2018-10-25 22:38:56 -07:00
}
2018-11-02 03:42:14 -07:00
2019-03-27 21:44:47 -07:00
if ! networkInitialized {
if err := p . bootupNetwork ( permInterfSession ) ; err != nil {
2018-11-02 03:42:14 -07:00
return err
}
2019-03-26 08:20:06 -07:00
} else {
2019-03-27 21:44:47 -07:00
//populate orgs, nodes, roles and accounts from contract
2019-08-21 13:55:58 -07:00
for _ , f := range [ ] func ( auth * bind . TransactOpts ) error {
p . populateOrgsFromContract ,
p . populateNodesFromContract ,
p . populateRolesFromContract ,
p . populateAccountsFromContract ,
} {
if err := f ( auth ) ; err != nil {
return err
}
2019-05-17 01:12:53 -07:00
}
2019-03-26 08:20:06 -07:00
}
2019-02-06 20:45:29 -08:00
2019-03-27 21:44:47 -07:00
return nil
}
2019-03-31 23:33:44 -07:00
// initialize the permissions model and populate initial values
2019-03-27 21:44:47 -07:00
func ( p * PermissionCtrl ) bootupNetwork ( permInterfSession * pbind . PermInterfaceSession ) error {
if _ , err := permInterfSession . SetPolicy ( p . permConfig . NwAdminOrg , p . permConfig . NwAdminRole , p . permConfig . OrgAdminRole ) ; err != nil {
2019-03-31 23:33:44 -07:00
log . Error ( "bootupNetwork SetPolicy failed" , "err" , err )
2019-03-27 21:44:47 -07:00
return err
}
2019-09-09 00:53:15 -07:00
if _ , err := permInterfSession . Init ( p . permConfig . SubOrgBreadth , p . permConfig . SubOrgDepth ) ; err != nil {
2019-03-31 23:33:44 -07:00
log . Error ( "bootupNetwork init failed" , "err" , err )
2019-03-27 21:44:47 -07:00
return err
}
2019-05-20 20:57:10 -07:00
types . OrgInfoMap . UpsertOrg ( p . permConfig . NwAdminOrg , "" , p . permConfig . NwAdminOrg , big . NewInt ( 1 ) , types . OrgApproved )
2019-04-26 01:35:51 -07:00
types . RoleInfoMap . UpsertRole ( p . permConfig . NwAdminOrg , p . permConfig . NwAdminRole , true , true , types . FullAccess , true )
2019-03-27 21:44:47 -07:00
// populate the initial node list from static-nodes.json
2019-04-01 02:48:37 -07:00
if err := p . populateStaticNodesToContract ( permInterfSession ) ; err != nil {
2019-03-27 21:44:47 -07:00
return err
}
// populate initial account access to full access
2019-04-01 02:48:37 -07:00
if err := p . populateInitAccountAccess ( permInterfSession ) ; err != nil {
2019-03-27 21:44:47 -07:00
return err
}
// update network status to boot completed
2019-04-01 02:48:37 -07:00
if err := p . updateNetworkStatus ( permInterfSession ) ; err != nil {
log . Error ( "failed to updated network boot status" , "error" , err )
2019-03-27 21:44:47 -07:00
return err
}
return nil
}
2019-04-01 23:13:23 -07:00
// populates the account access details from contract into cache
2019-05-17 01:12:53 -07:00
func ( p * PermissionCtrl ) populateAccountsFromContract ( auth * bind . TransactOpts ) error {
2019-03-27 21:44:47 -07:00
//populate accounts
permAcctSession := & pbind . AcctManagerSession {
Contract : p . permAcct ,
2019-03-27 04:07:01 -07:00
CallOpts : bind . CallOpts {
Pending : true ,
} ,
}
2019-05-17 01:12:53 -07:00
2019-04-01 02:48:37 -07:00
if numberOfRoles , err := permAcctSession . GetNumberOfAccounts ( ) ; err == nil {
2019-03-27 21:44:47 -07:00
iOrgNum := numberOfRoles . Uint64 ( )
2019-03-27 04:07:01 -07:00
for k := uint64 ( 0 ) ; k < iOrgNum ; k ++ {
2019-04-01 02:48:37 -07:00
if addr , org , role , status , orgAdmin , err := permAcctSession . GetAccountDetailsFromIndex ( big . NewInt ( int64 ( k ) ) ) ; err == nil {
2019-03-28 21:28:11 -07:00
types . AcctInfoMap . UpsertAccount ( org , role , addr , orgAdmin , types . AcctStatus ( int ( status . Int64 ( ) ) ) )
2019-03-27 04:07:01 -07:00
}
}
2019-05-17 01:12:53 -07:00
} else {
return err
2019-03-27 04:07:01 -07:00
}
2019-05-17 01:12:53 -07:00
return nil
2019-03-27 21:44:47 -07:00
}
2019-03-27 04:07:01 -07:00
2019-04-01 23:13:23 -07:00
// populates the role details from contract into cache
2019-05-17 01:12:53 -07:00
func ( p * PermissionCtrl ) populateRolesFromContract ( auth * bind . TransactOpts ) error {
2019-03-27 21:44:47 -07:00
//populate roles
permRoleSession := & pbind . RoleManagerSession {
Contract : p . permRole ,
2019-03-27 04:07:01 -07:00
CallOpts : bind . CallOpts {
Pending : true ,
} ,
}
2019-04-01 02:48:37 -07:00
if numberOfRoles , err := permRoleSession . GetNumberOfRoles ( ) ; err == nil {
2019-03-27 21:44:47 -07:00
iOrgNum := numberOfRoles . Uint64 ( )
2019-03-27 04:07:01 -07:00
for k := uint64 ( 0 ) ; k < iOrgNum ; k ++ {
2019-04-01 02:48:37 -07:00
if roleStruct , err := permRoleSession . GetRoleDetailsFromIndex ( big . NewInt ( int64 ( k ) ) ) ; err == nil {
2019-04-26 01:35:51 -07:00
types . RoleInfoMap . UpsertRole ( roleStruct . OrgId , roleStruct . RoleId , roleStruct . Voter , roleStruct . Admin , types . AccessType ( int ( roleStruct . AccessType . Int64 ( ) ) ) , roleStruct . Active )
2019-03-27 04:07:01 -07:00
}
}
2019-05-17 01:12:53 -07:00
} else {
return err
2019-03-27 04:07:01 -07:00
}
2019-05-17 01:12:53 -07:00
return nil
2019-03-27 21:44:47 -07:00
}
2019-03-27 04:07:01 -07:00
2019-04-01 23:13:23 -07:00
// populates the node details from contract into cache
2019-05-17 01:12:53 -07:00
func ( p * PermissionCtrl ) populateNodesFromContract ( auth * bind . TransactOpts ) error {
2019-03-27 21:44:47 -07:00
//populate nodes
permNodeSession := & pbind . NodeManagerSession {
Contract : p . permNode ,
2019-03-27 04:07:01 -07:00
CallOpts : bind . CallOpts {
Pending : true ,
} ,
}
2019-04-01 02:48:37 -07:00
if numberOfNodes , err := permNodeSession . GetNumberOfNodes ( ) ; err == nil {
2019-03-27 21:44:47 -07:00
iOrgNum := numberOfNodes . Uint64 ( )
2019-03-27 04:07:01 -07:00
for k := uint64 ( 0 ) ; k < iOrgNum ; k ++ {
2019-04-01 02:48:37 -07:00
if nodeStruct , err := permNodeSession . GetNodeDetailsFromIndex ( big . NewInt ( int64 ( k ) ) ) ; err == nil {
2019-03-28 21:28:11 -07:00
types . NodeInfoMap . UpsertNode ( nodeStruct . OrgId , nodeStruct . EnodeId , types . NodeStatus ( int ( nodeStruct . NodeStatus . Int64 ( ) ) ) )
2019-03-27 04:07:01 -07:00
}
}
2019-05-17 01:12:53 -07:00
} else {
return err
2019-03-27 04:07:01 -07:00
}
2019-05-17 01:12:53 -07:00
return nil
2019-03-27 21:44:47 -07:00
}
2019-03-27 04:07:01 -07:00
2019-04-01 23:13:23 -07:00
// populates the org details from contract into cache
2019-05-17 01:12:53 -07:00
func ( p * PermissionCtrl ) populateOrgsFromContract ( auth * bind . TransactOpts ) error {
2019-03-27 21:44:47 -07:00
//populate orgs
permOrgSession := & pbind . OrgManagerSession {
Contract : p . permOrg ,
2019-03-27 04:07:01 -07:00
CallOpts : bind . CallOpts {
Pending : true ,
} ,
}
2019-04-01 02:48:37 -07:00
if numberOfOrgs , err := permOrgSession . GetNumberOfOrgs ( ) ; err == nil {
2019-03-27 21:44:47 -07:00
iOrgNum := numberOfOrgs . Uint64 ( )
2019-03-27 04:07:01 -07:00
for k := uint64 ( 0 ) ; k < iOrgNum ; k ++ {
2019-04-09 02:52:06 -07:00
if orgId , porgId , ultParent , level , status , err := permOrgSession . GetOrgInfo ( big . NewInt ( int64 ( k ) ) ) ; err == nil {
types . OrgInfoMap . UpsertOrg ( orgId , porgId , ultParent , level , types . OrgStatus ( int ( status . Int64 ( ) ) ) )
2019-03-27 04:07:01 -07:00
}
}
2019-05-17 01:12:53 -07:00
} else {
return err
2019-03-27 04:07:01 -07:00
}
2019-05-17 01:12:53 -07:00
return nil
2018-11-02 03:42:14 -07:00
}
// Reads the node list from static-nodes.json and populates into the contract
2019-03-26 08:20:06 -07:00
func ( p * PermissionCtrl ) populateStaticNodesToContract ( permissionsSession * pbind . PermInterfaceSession ) error {
2019-09-30 02:12:06 -07:00
nodes := p . node . Server ( ) . Config . StaticNodes
2018-11-02 03:42:14 -07:00
for _ , node := range nodes {
2019-07-19 01:16:50 -07:00
_ , err := permissionsSession . AddAdminNode ( node . String ( ) )
2018-11-02 03:42:14 -07:00
if err != nil {
2019-08-26 05:39:29 -07:00
log . Warn ( "Failed to propose node" , "err" , err , "enode" , node . EnodeID ( ) )
2018-11-02 03:42:14 -07:00
return err
}
2019-03-27 21:44:47 -07:00
types . NodeInfoMap . UpsertNode ( p . permConfig . NwAdminOrg , node . String ( ) , 2 )
2018-11-02 03:42:14 -07:00
}
return nil
}
2018-10-24 03:21:21 -07:00
2019-02-12 20:31:11 -08:00
// Invokes the initAccounts function of smart contract to set the initial
// set of accounts access to full access
2019-03-26 08:20:06 -07:00
func ( p * PermissionCtrl ) populateInitAccountAccess ( permissionsSession * pbind . PermInterfaceSession ) error {
2019-04-01 02:48:37 -07:00
for _ , a := range p . permConfig . Accounts {
2019-07-19 01:16:50 -07:00
_ , er := permissionsSession . AddAdminAccount ( a )
2019-04-01 02:48:37 -07:00
if er != nil {
log . Warn ( "Error adding permission initial account list" , "err" , er , "account" , a )
return er
2019-03-19 00:29:53 -07:00
}
2019-04-01 02:48:37 -07:00
types . AcctInfoMap . UpsertAccount ( p . permConfig . NwAdminOrg , p . permConfig . NwAdminRole , a , true , 2 )
2019-03-19 00:29:53 -07:00
}
2018-11-02 03:42:14 -07:00
return nil
}
2018-10-24 03:21:21 -07:00
2019-02-12 20:31:11 -08:00
// updates network boot status to true
2019-03-26 08:20:06 -07:00
func ( p * PermissionCtrl ) updateNetworkStatus ( permissionsSession * pbind . PermInterfaceSession ) error {
2018-11-02 03:42:14 -07:00
_ , err := permissionsSession . UpdateNetworkBootStatus ( )
if err != nil {
log . Warn ( "Failed to udpate network boot status " , "err" , err )
return err
2018-10-24 03:21:21 -07:00
}
2018-11-02 03:42:14 -07:00
return nil
2018-10-24 03:21:21 -07:00
}
2019-03-28 03:00:17 -07:00
2019-04-01 23:13:23 -07:00
// monitors role management related events and updated cache
2019-08-21 13:55:58 -07:00
func ( p * PermissionCtrl ) manageRolePermissions ( ) error {
2019-04-01 23:13:23 -07:00
chRoleCreated := make ( chan * pbind . RoleManagerRoleCreated , 1 )
chRoleRevoked := make ( chan * pbind . RoleManagerRoleRevoked , 1 )
2019-03-28 03:00:17 -07:00
opts := & bind . WatchOpts { }
var blockNumber uint64 = 1
opts . Start = & blockNumber
2019-04-01 23:13:23 -07:00
if _ , err := p . permRole . RoleManagerFilterer . WatchRoleCreated ( opts , chRoleCreated ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchRoleCreated: %v" , err )
2019-03-28 03:00:17 -07:00
}
2019-03-28 03:59:30 -07:00
2019-04-01 23:13:23 -07:00
if _ , err := p . permRole . RoleManagerFilterer . WatchRoleRevoked ( opts , chRoleRevoked ) ; err != nil {
2019-08-21 13:55:58 -07:00
return fmt . Errorf ( "failed WatchRoleRemoved: %v" , err )
}
go func ( ) {
stopChan , stopSubscription := p . subscribeStopEvent ( )
defer stopSubscription . Unsubscribe ( )
for {
select {
case evtRoleCreated := <- chRoleCreated :
types . RoleInfoMap . UpsertRole ( evtRoleCreated . OrgId , evtRoleCreated . RoleId , evtRoleCreated . IsVoter , evtRoleCreated . IsAdmin , types . AccessType ( int ( evtRoleCreated . BaseAccess . Uint64 ( ) ) ) , true )
case evtRoleRevoked := <- chRoleRevoked :
if r := types . RoleInfoMap . GetRole ( evtRoleRevoked . OrgId , evtRoleRevoked . RoleId ) ; r != nil {
types . RoleInfoMap . UpsertRole ( evtRoleRevoked . OrgId , evtRoleRevoked . RoleId , r . IsVoter , r . IsAdmin , r . Access , false )
} else {
log . Error ( "Revoke role - cache is missing role" , "org" , evtRoleRevoked . OrgId , "role" , evtRoleRevoked . RoleId )
}
case <- stopChan :
log . Info ( "quit role contract watch" )
return
2019-03-28 21:28:11 -07:00
}
2019-03-28 03:59:30 -07:00
}
2019-08-21 13:55:58 -07:00
} ( )
return nil
2019-03-28 03:00:17 -07:00
}