github.com/kisexp/xdchain@v0.0.0-20211206025815-490d6b732aa7/permission/api.go (about)

     1  package permission
     2  
     3  import (
     4  	"errors"
     5  	"fmt"
     6  	"math/big"
     7  	"regexp"
     8  
     9  	"github.com/kisexp/xdchain/common"
    10  	"github.com/kisexp/xdchain/internal/ethapi"
    11  	"github.com/kisexp/xdchain/log"
    12  	"github.com/kisexp/xdchain/p2p/enode"
    13  	"github.com/kisexp/xdchain/permission/core"
    14  	ptype "github.com/kisexp/xdchain/permission/core/types"
    15  )
    16  
    17  var isStringAlphaNumeric = regexp.MustCompile(`^[a-zA-Z0-9_-]*$`).MatchString
    18  
    19  //default gas limit to use if not passed in sendTxArgs
    20  var defaultGasLimit = uint64(4712384)
    21  
    22  //default gas price to use if not passed in sendTxArgs
    23  var defaultGasPrice = big.NewInt(0)
    24  
    25  // PermAction represents actions in permission contract
    26  type PermAction int
    27  
    28  const (
    29  	AddOrg PermAction = iota
    30  	ApproveOrg
    31  	AddSubOrg
    32  	UpdateOrgStatus
    33  	ApproveOrgStatus
    34  	AddNode
    35  	UpdateNodeStatus
    36  	AssignAdminRole
    37  	ApproveAdminRole
    38  	AddNewRole
    39  	RemoveRole
    40  	AddAccountToOrg
    41  	ChangeAccountRole
    42  	UpdateAccountStatus
    43  	InitiateNodeRecovery
    44  	InitiateAccountRecovery
    45  	ApproveNodeRecovery
    46  	ApproveAccountRecovery
    47  )
    48  
    49  type AccountUpdateAction int
    50  
    51  const (
    52  	SuspendAccount AccountUpdateAction = iota + 1
    53  	ActivateSuspendedAccount
    54  	BlacklistAccount
    55  	RecoverBlacklistedAccount
    56  	ApproveBlacklistedAccountRecovery
    57  )
    58  
    59  type NodeUpdateAction int
    60  
    61  const (
    62  	SuspendNode NodeUpdateAction = iota + 1
    63  	ActivateSuspendedNode
    64  	BlacklistNode
    65  	RecoverBlacklistedNode
    66  	ApproveBlacklistedNodeRecovery
    67  )
    68  
    69  type OrgUpdateAction int
    70  
    71  const (
    72  	SuspendOrg OrgUpdateAction = iota + 1
    73  	ActivateSuspendedOrg
    74  )
    75  
    76  // QuorumControlsAPI provides an API to access Quorum's enterprise permissions related services
    77  type QuorumControlsAPI struct {
    78  	permCtrl *PermissionCtrl
    79  }
    80  
    81  type PendingOpInfo struct {
    82  	PendingKey string `json:"pendingKey"`
    83  	PendingOp  string `json:"pendingOp"`
    84  }
    85  
    86  var actionSuccess = "Action completed successfully"
    87  
    88  // NewQuorumControlsAPI creates a new QuorumControlsAPI to access quorum services
    89  func NewQuorumControlsAPI(p *PermissionCtrl) *QuorumControlsAPI {
    90  	return &QuorumControlsAPI{p}
    91  }
    92  
    93  func (q *QuorumControlsAPI) OrgList() []core.OrgInfo {
    94  	return core.OrgInfoMap.GetOrgList()
    95  }
    96  
    97  func (q *QuorumControlsAPI) NodeList() []core.NodeInfo {
    98  	return core.NodeInfoMap.GetNodeList()
    99  }
   100  
   101  func (q *QuorumControlsAPI) RoleList() []core.RoleInfo {
   102  	return core.RoleInfoMap.GetRoleList()
   103  }
   104  
   105  func (q *QuorumControlsAPI) AcctList() []core.AccountInfo {
   106  	return core.AcctInfoMap.GetAcctList()
   107  }
   108  
   109  func (q *QuorumControlsAPI) GetOrgDetails(orgId string) (core.OrgDetailInfo, error) {
   110  	o, err := core.OrgInfoMap.GetOrg(orgId)
   111  	if err != nil {
   112  		return core.OrgDetailInfo{}, err
   113  	}
   114  
   115  	if o == nil {
   116  		return core.OrgDetailInfo{}, errors.New("org does not exist")
   117  	}
   118  	var acctList []core.AccountInfo
   119  	var roleList []core.RoleInfo
   120  	var nodeList []core.NodeInfo
   121  	for _, a := range q.AcctList() {
   122  		if a.OrgId == orgId {
   123  			acctList = append(acctList, a)
   124  		}
   125  	}
   126  	for _, a := range q.RoleList() {
   127  		if a.OrgId == orgId {
   128  			roleList = append(roleList, a)
   129  		}
   130  	}
   131  	for _, a := range q.NodeList() {
   132  		if a.OrgId == orgId {
   133  			nodeList = append(nodeList, a)
   134  		}
   135  	}
   136  	orgRec, err := core.OrgInfoMap.GetOrg(orgId)
   137  	if err != nil {
   138  		return core.OrgDetailInfo{}, err
   139  	}
   140  
   141  	if orgRec == nil {
   142  		return core.OrgDetailInfo{NodeList: nodeList, RoleList: roleList, AcctList: acctList}, nil
   143  	}
   144  	return core.OrgDetailInfo{NodeList: nodeList, RoleList: roleList, AcctList: acctList, SubOrgList: orgRec.SubOrgList}, nil
   145  }
   146  
   147  func reportExecError(action PermAction, err error) (string, error) {
   148  	log.Error("Failed to execute permission action", "action", action, "err", err)
   149  	msg := fmt.Sprintf("failed to execute permissions action: %v", err)
   150  	return "", errors.New(msg)
   151  }
   152  
   153  func (q *QuorumControlsAPI) AddOrg(orgId string, url string, acct common.Address, txa ethapi.SendTxArgs) (string, error) {
   154  	orgService, err := q.permCtrl.NewPermissionOrgService(txa)
   155  
   156  	if err != nil {
   157  		return "", err
   158  	}
   159  	args := ptype.TxArgs{OrgId: orgId, Url: url, AcctId: acct, Txa: txa}
   160  
   161  	if err := q.valAddOrg(args); err != nil {
   162  		return "", err
   163  	}
   164  	tx, err := orgService.AddOrg(args)
   165  	if err != nil {
   166  		return reportExecError(AddOrg, err)
   167  	}
   168  	log.Debug("executed permission action", "action", AddOrg, "tx", tx)
   169  	return actionSuccess, nil
   170  }
   171  
   172  func (q *QuorumControlsAPI) AddSubOrg(porgId, orgId string, url string, txa ethapi.SendTxArgs) (string, error) {
   173  	orgService, err := q.permCtrl.NewPermissionOrgService(txa)
   174  	if err != nil {
   175  		return "", err
   176  	}
   177  	args := ptype.TxArgs{POrgId: porgId, OrgId: orgId, Url: url, Txa: txa}
   178  
   179  	if err := q.valAddSubOrg(args); err != nil {
   180  		return "", err
   181  	}
   182  	tx, err := orgService.AddSubOrg(args)
   183  	if err != nil {
   184  		return reportExecError(AddSubOrg, err)
   185  	}
   186  	log.Debug("executed permission action", "action", AddSubOrg, "tx", tx)
   187  	return actionSuccess, nil
   188  }
   189  
   190  func (q *QuorumControlsAPI) ApproveOrg(orgId string, url string, acct common.Address, txa ethapi.SendTxArgs) (string, error) {
   191  	orgService, err := q.permCtrl.NewPermissionOrgService(txa)
   192  	if err != nil {
   193  		return "", err
   194  	}
   195  	args := ptype.TxArgs{OrgId: orgId, Url: url, AcctId: acct, Txa: txa}
   196  	if err := q.valApproveOrg(args); err != nil {
   197  		return "", err
   198  	}
   199  	tx, err := orgService.ApproveOrg(args)
   200  	if err != nil {
   201  		return reportExecError(ApproveOrg, err)
   202  	}
   203  	log.Debug("executed permission action", "action", ApproveOrg, "tx", tx)
   204  	return actionSuccess, nil
   205  }
   206  
   207  func (q *QuorumControlsAPI) UpdateOrgStatus(orgId string, status uint8, txa ethapi.SendTxArgs) (string, error) {
   208  	orgService, err := q.permCtrl.NewPermissionOrgService(txa)
   209  	if err != nil {
   210  		return "", err
   211  	}
   212  	args := ptype.TxArgs{OrgId: orgId, Action: status, Txa: txa}
   213  	if err := q.valUpdateOrgStatus(args); err != nil {
   214  		return "", err
   215  	}
   216  	// and in suspended state for suspension revoke
   217  	tx, err := orgService.UpdateOrgStatus(args)
   218  	if err != nil {
   219  		return reportExecError(UpdateOrgStatus, err)
   220  	}
   221  	log.Debug("executed permission action", "action", UpdateOrgStatus, "tx", tx)
   222  	return actionSuccess, nil
   223  }
   224  
   225  func (q *QuorumControlsAPI) AddNode(orgId string, url string, txa ethapi.SendTxArgs) (string, error) {
   226  	nodeService, err := q.permCtrl.NewPermissionNodeService(txa)
   227  	if err != nil {
   228  		return "", err
   229  	}
   230  	args := ptype.TxArgs{OrgId: orgId, Url: url, Txa: txa}
   231  	if err := q.valAddNode(args); err != nil {
   232  		return "", err
   233  	}
   234  	// check if node is already there
   235  	tx, err := nodeService.AddNode(args)
   236  	if err != nil {
   237  		return reportExecError(AddNode, err)
   238  	}
   239  	log.Debug("executed permission action", "action", AddNode, "tx", tx)
   240  	return actionSuccess, nil
   241  }
   242  
   243  func (q *QuorumControlsAPI) UpdateNodeStatus(orgId string, url string, action uint8, txa ethapi.SendTxArgs) (string, error) {
   244  	nodeService, err := q.permCtrl.NewPermissionNodeService(txa)
   245  	if err != nil {
   246  		return "", err
   247  	}
   248  	args := ptype.TxArgs{OrgId: orgId, Url: url, Action: action, Txa: txa}
   249  	if err := q.valUpdateNodeStatus(args, UpdateNodeStatus); err != nil {
   250  		return "", err
   251  	}
   252  	// check node status for operation
   253  	tx, err := nodeService.UpdateNodeStatus(args)
   254  	if err != nil {
   255  		return reportExecError(UpdateNodeStatus, err)
   256  	}
   257  	log.Debug("executed permission action", "action", UpdateNodeStatus, "tx", tx)
   258  	return actionSuccess, nil
   259  }
   260  
   261  func (q *QuorumControlsAPI) ApproveOrgStatus(orgId string, status uint8, txa ethapi.SendTxArgs) (string, error) {
   262  	orgService, err := q.permCtrl.NewPermissionOrgService(txa)
   263  	if err != nil {
   264  		return "", err
   265  	}
   266  	args := ptype.TxArgs{OrgId: orgId, Action: status, Txa: txa}
   267  	if err := q.valApproveOrgStatus(args); err != nil {
   268  		return "", err
   269  	}
   270  	// validate that status change is pending approval
   271  	tx, err := orgService.ApproveOrgStatus(args)
   272  	if err != nil {
   273  		return reportExecError(ApproveOrgStatus, err)
   274  	}
   275  	log.Debug("executed permission action", "action", ApproveOrgStatus, "tx", tx)
   276  	return actionSuccess, nil
   277  }
   278  
   279  func (q *QuorumControlsAPI) AssignAdminRole(orgId string, acct common.Address, roleId string, txa ethapi.SendTxArgs) (string, error) {
   280  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   281  	if err != nil {
   282  		return "", err
   283  	}
   284  	args := ptype.TxArgs{OrgId: orgId, AcctId: acct, RoleId: roleId, Txa: txa}
   285  	if err := q.valAssignAdminRole(args); err != nil {
   286  		return "", err
   287  	}
   288  	// check if account is already in use in another org
   289  	tx, err := accountService.AssignAdminRole(args)
   290  	if err != nil {
   291  		return reportExecError(AssignAdminRole, err)
   292  	}
   293  	log.Debug("executed permission action", "action", AssignAdminRole, "tx", tx)
   294  	return actionSuccess, nil
   295  }
   296  
   297  func (q *QuorumControlsAPI) ApproveAdminRole(orgId string, acct common.Address, txa ethapi.SendTxArgs) (string, error) {
   298  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   299  	if err != nil {
   300  		return "", err
   301  	}
   302  	args := ptype.TxArgs{OrgId: orgId, AcctId: acct, Txa: txa}
   303  	if err := q.valApproveAdminRole(args); err != nil {
   304  		return "", err
   305  	}
   306  	// check if anything is pending approval
   307  	tx, err := accountService.ApproveAdminRole(args)
   308  	if err != nil {
   309  		return reportExecError(ApproveAdminRole, err)
   310  	}
   311  	log.Debug("executed permission action", "action", ApproveAdminRole, "tx", tx)
   312  	return actionSuccess, nil
   313  }
   314  
   315  func (q *QuorumControlsAPI) AddNewRole(orgId string, roleId string, access uint8, isVoter bool, isAdmin bool, txa ethapi.SendTxArgs) (string, error) {
   316  	roleService, err := q.permCtrl.NewPermissionRoleService(txa)
   317  	if err != nil {
   318  		return "", err
   319  	}
   320  	args := ptype.TxArgs{OrgId: orgId, RoleId: roleId, AccessType: access, IsVoter: isVoter, IsAdmin: isAdmin, Txa: txa}
   321  	if err := q.valAddNewRole(args); err != nil {
   322  		return "", err
   323  	}
   324  	// check if role is already there in the org
   325  	tx, err := roleService.AddNewRole(args)
   326  	if err != nil {
   327  		return reportExecError(AddNewRole, err)
   328  	}
   329  	log.Debug("executed permission action", "action", AddNewRole, "tx", tx)
   330  	return actionSuccess, nil
   331  }
   332  
   333  func (q *QuorumControlsAPI) RemoveRole(orgId string, roleId string, txa ethapi.SendTxArgs) (string, error) {
   334  	roleService, err := q.permCtrl.NewPermissionRoleService(txa)
   335  	if err != nil {
   336  		return "", err
   337  	}
   338  	args := ptype.TxArgs{OrgId: orgId, RoleId: roleId, Txa: txa}
   339  
   340  	if err := q.valRemoveRole(args); err != nil {
   341  		return "", err
   342  	}
   343  	tx, err := roleService.RemoveRole(args)
   344  	if err != nil {
   345  		return reportExecError(RemoveRole, err)
   346  	}
   347  	log.Debug("executed permission action", "action", RemoveRole, "tx", tx)
   348  	return actionSuccess, nil
   349  }
   350  
   351  func (q *QuorumControlsAPI) AddAccountToOrg(acct common.Address, orgId string, roleId string, txa ethapi.SendTxArgs) (string, error) {
   352  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   353  	if err != nil {
   354  		return "", err
   355  	}
   356  	args := ptype.TxArgs{OrgId: orgId, RoleId: roleId, AcctId: acct, Txa: txa}
   357  
   358  	if err := q.valAssignRole(args); err != nil {
   359  		return "", err
   360  	}
   361  	tx, err := accountService.AssignAccountRole(args)
   362  	if err != nil {
   363  		return reportExecError(AddAccountToOrg, err)
   364  	}
   365  	log.Debug("executed permission action", "action", AddAccountToOrg, "tx", tx)
   366  	return actionSuccess, nil
   367  }
   368  func (q *QuorumControlsAPI) ChangeAccountRole(acct common.Address, orgId string, roleId string, txa ethapi.SendTxArgs) (string, error) {
   369  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   370  	if err != nil {
   371  		return "", err
   372  	}
   373  	args := ptype.TxArgs{OrgId: orgId, RoleId: roleId, AcctId: acct, Txa: txa}
   374  
   375  	if err := q.valAssignRole(args); err != nil {
   376  		return "", err
   377  	}
   378  	tx, err := accountService.AssignAccountRole(args)
   379  	if err != nil {
   380  		return reportExecError(ChangeAccountRole, err)
   381  	}
   382  	log.Debug("executed permission action", "action", ChangeAccountRole, "tx", tx)
   383  	return actionSuccess, nil
   384  }
   385  
   386  func (q *QuorumControlsAPI) UpdateAccountStatus(orgId string, acct common.Address, status uint8, txa ethapi.SendTxArgs) (string, error) {
   387  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   388  	if err != nil {
   389  		return "", err
   390  	}
   391  	args := ptype.TxArgs{OrgId: orgId, AcctId: acct, Action: status, Txa: txa}
   392  
   393  	if err := q.valUpdateAccountStatus(args, UpdateAccountStatus); err != nil {
   394  		return "", err
   395  	}
   396  	tx, err := accountService.UpdateAccountStatus(args)
   397  	if err != nil {
   398  		return reportExecError(UpdateAccountStatus, err)
   399  	}
   400  	log.Debug("executed permission action", "action", UpdateAccountStatus, "tx", tx)
   401  	return actionSuccess, nil
   402  }
   403  
   404  func (q *QuorumControlsAPI) RecoverBlackListedNode(orgId string, enodeId string, txa ethapi.SendTxArgs) (string, error) {
   405  	nodeService, err := q.permCtrl.NewPermissionNodeService(txa)
   406  	if err != nil {
   407  		return "", err
   408  	}
   409  	args := ptype.TxArgs{OrgId: orgId, Url: enodeId, Txa: txa}
   410  
   411  	if err := q.valRecoverNode(args, InitiateNodeRecovery); err != nil {
   412  		return "", err
   413  	}
   414  	tx, err := nodeService.StartBlacklistedNodeRecovery(args)
   415  	if err != nil {
   416  		return reportExecError(InitiateNodeRecovery, err)
   417  	}
   418  	log.Debug("executed permission action", "action", InitiateNodeRecovery, "tx", tx)
   419  	return actionSuccess, nil
   420  }
   421  
   422  func (q *QuorumControlsAPI) ApproveBlackListedNodeRecovery(orgId string, enodeId string, txa ethapi.SendTxArgs) (string, error) {
   423  	nodeService, err := q.permCtrl.NewPermissionNodeService(txa)
   424  	if err != nil {
   425  		return "", err
   426  	}
   427  	args := ptype.TxArgs{OrgId: orgId, Url: enodeId, Txa: txa}
   428  
   429  	if err := q.valRecoverNode(args, ApproveNodeRecovery); err != nil {
   430  		return "", err
   431  	}
   432  	tx, err := nodeService.ApproveBlacklistedNodeRecovery(args)
   433  	if err != nil {
   434  		return reportExecError(ApproveNodeRecovery, err)
   435  	}
   436  	log.Debug("executed permission action", "action", ApproveNodeRecovery, "tx", tx)
   437  	return actionSuccess, nil
   438  }
   439  
   440  func (q *QuorumControlsAPI) RecoverBlackListedAccount(orgId string, acctId common.Address, txa ethapi.SendTxArgs) (string, error) {
   441  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   442  	if err != nil {
   443  		return "", err
   444  	}
   445  	args := ptype.TxArgs{OrgId: orgId, AcctId: acctId, Txa: txa}
   446  
   447  	if err := q.valRecoverAccount(args, InitiateAccountRecovery); err != nil {
   448  		return "", err
   449  	}
   450  	tx, err := accountService.StartBlacklistedAccountRecovery(args)
   451  	if err != nil {
   452  		return reportExecError(InitiateAccountRecovery, err)
   453  	}
   454  	log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx)
   455  	return actionSuccess, nil
   456  }
   457  
   458  func (q *QuorumControlsAPI) ApproveBlackListedAccountRecovery(orgId string, acctId common.Address, txa ethapi.SendTxArgs) (string, error) {
   459  	accountService, err := q.permCtrl.NewPermissionAccountService(txa)
   460  	if err != nil {
   461  		return "", err
   462  	}
   463  	args := ptype.TxArgs{OrgId: orgId, AcctId: acctId, Txa: txa}
   464  
   465  	if err := q.valRecoverAccount(args, ApproveAccountRecovery); err != nil {
   466  		return "", err
   467  	}
   468  	tx, err := accountService.ApproveBlacklistedAccountRecovery(args)
   469  	if err != nil {
   470  		return reportExecError(ApproveAccountRecovery, err)
   471  	}
   472  	log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx)
   473  	return actionSuccess, nil
   474  }
   475  
   476  func (q *QuorumControlsAPI) TransactionAllowed(txa ethapi.SendTxArgs) bool {
   477  	var value, gasPrice, gasLimit *big.Int
   478  	var payload []byte
   479  	var to, from common.Address
   480  	if txa.Value != nil {
   481  		value = txa.Value.ToInt()
   482  	} else {
   483  		value = big.NewInt(0)
   484  	}
   485  	from = txa.From
   486  	if txa.To == nil {
   487  		to = common.Address{}
   488  	} else {
   489  		to = *txa.To
   490  	}
   491  
   492  	if txa.GasPrice != nil {
   493  		gasPrice = txa.GasPrice.ToInt()
   494  	} else {
   495  		gasPrice = big.NewInt(0)
   496  	}
   497  
   498  	if txa.Gas != nil {
   499  		gasLimit = big.NewInt(int64(*txa.Gas))
   500  	} else {
   501  		gasLimit = big.NewInt(0)
   502  	}
   503  
   504  	if txa.Data != nil {
   505  		payload = *txa.Data
   506  	}
   507  
   508  	transactionType := core.ValueTransferTxn
   509  
   510  	if txa.To == nil {
   511  		transactionType = core.ContractDeployTxn
   512  	} else if txa.Data != nil {
   513  		transactionType = core.ContractCallTxn
   514  	}
   515  
   516  	if err := core.IsTransactionAllowed(from, to, value, gasPrice, gasLimit, payload, transactionType); err != nil {
   517  		return false
   518  	} else {
   519  		return true
   520  	}
   521  }
   522  
   523  func (q *QuorumControlsAPI) ConnectionAllowed(enodeId, ip string, port, raftPort uint16) bool {
   524  	controlService, err := q.permCtrl.NewPermissionControlService()
   525  	if err != nil {
   526  		return false
   527  	}
   528  
   529  	if allowed, err := controlService.ConnectionAllowed(enodeId, ip, port, raftPort); err != nil {
   530  		return false
   531  	} else {
   532  		return allowed
   533  	}
   534  }
   535  
   536  // check if the account is network admin
   537  func (q *QuorumControlsAPI) isNetworkAdmin(account common.Address) bool {
   538  	ac, _ := core.AcctInfoMap.GetAccount(account)
   539  	return ac != nil && ac.RoleId == q.permCtrl.permConfig.NwAdminRole
   540  }
   541  
   542  func (q *QuorumControlsAPI) isOrgAdmin(account common.Address, orgId string) error {
   543  	org, err := core.OrgInfoMap.GetOrg(orgId)
   544  	if err != nil {
   545  		return err
   546  	}
   547  	if org == nil {
   548  		return ptype.ErrOrgDoesNotExists
   549  	}
   550  	ac, _ := core.AcctInfoMap.GetAccount(account)
   551  	if ac == nil {
   552  		return ptype.ErrNotOrgAdmin
   553  	}
   554  	// check if the account is network admin
   555  	if !(ac.IsOrgAdmin && (ac.OrgId == orgId || ac.OrgId == org.UltimateParent)) {
   556  		return ptype.ErrNotOrgAdmin
   557  	}
   558  	return nil
   559  }
   560  
   561  func (q *QuorumControlsAPI) validateOrg(orgId, pOrgId string) error {
   562  	// validate Parent org id
   563  	if pOrgId != "" {
   564  		if _, err := core.OrgInfoMap.GetOrg(pOrgId); err != nil {
   565  			return ptype.ErrInvalidParentOrg
   566  		}
   567  		locOrgId := pOrgId + "." + orgId
   568  		if lorgRec, _ := core.OrgInfoMap.GetOrg(locOrgId); lorgRec != nil {
   569  			return ptype.ErrOrgExists
   570  		}
   571  	} else if orgRec, _ := core.OrgInfoMap.GetOrg(orgId); orgRec != nil {
   572  		return ptype.ErrOrgExists
   573  	}
   574  	return nil
   575  }
   576  
   577  func (q *QuorumControlsAPI) validatePendingOp(authOrg, orgId, url string, account common.Address, pendingOp int64) bool {
   578  	auditService, err := q.permCtrl.NewPermissionAuditService()
   579  	if err != nil {
   580  		return false
   581  	}
   582  	return auditService.ValidatePendingOp(authOrg, orgId, url, account, pendingOp)
   583  }
   584  
   585  func (q *QuorumControlsAPI) checkPendingOp(orgId string) bool {
   586  	auditService, err := q.permCtrl.NewPermissionAuditService()
   587  	if err != nil {
   588  		return false
   589  	}
   590  	return auditService.CheckPendingOp(orgId)
   591  }
   592  
   593  func (q *QuorumControlsAPI) checkOrgStatus(orgId string, op uint8) error {
   594  	org, _ := core.OrgInfoMap.GetOrg(orgId)
   595  
   596  	if org == nil {
   597  		return ptype.ErrOrgDoesNotExists
   598  	}
   599  	// check if its a master org. operation is allowed only if its a master org
   600  	if org.Level.Cmp(big.NewInt(1)) != 0 {
   601  		return ptype.ErrNotMasterOrg
   602  	}
   603  
   604  	if !((op == 1 && org.Status == core.OrgApproved) || (op == 2 && org.Status == core.OrgSuspended)) {
   605  		return ptype.ErrOpNotAllowed
   606  	}
   607  	return nil
   608  }
   609  
   610  func (q *QuorumControlsAPI) valNodeStatusChange(orgId, url string, op NodeUpdateAction, permAction PermAction) error {
   611  	// validates if the enode is linked the passed organization
   612  	// validate node id and if the status change can happen
   613  	if len(url) == 0 {
   614  		return ptype.ErrInvalidNode
   615  	}
   616  	if err := q.valNodeDetails(url); err != nil && err.Error() != ptype.ErrNodePresent.Error() {
   617  		return err
   618  	}
   619  
   620  	node, err := core.NodeInfoMap.GetNodeByUrl(url)
   621  	if err != nil {
   622  		return err
   623  	}
   624  
   625  	if node.OrgId != orgId {
   626  		return ptype.ErrNodeOrgMismatch
   627  	}
   628  
   629  	if node.Status == core.NodeBlackListed && op != RecoverBlacklistedNode {
   630  		return ptype.ErrBlacklistedNode
   631  	}
   632  
   633  	// validate the op and node status and check if the op can be performed
   634  	if (permAction == UpdateNodeStatus && (op != SuspendNode && op != ActivateSuspendedNode && op != BlacklistNode)) ||
   635  		(permAction == InitiateNodeRecovery && op != RecoverBlacklistedNode) ||
   636  		(permAction == ApproveNodeRecovery && op != ApproveBlacklistedNodeRecovery) {
   637  		return ptype.ErrOpNotAllowed
   638  	}
   639  
   640  	if (op == SuspendNode && node.Status != core.NodeApproved) ||
   641  		(op == ActivateSuspendedNode && node.Status != core.NodeDeactivated) ||
   642  		(op == BlacklistNode && node.Status == core.NodeRecoveryInitiated) ||
   643  		(op == RecoverBlacklistedNode && node.Status != core.NodeBlackListed) ||
   644  		(op == ApproveBlacklistedNodeRecovery && node.Status != core.NodeRecoveryInitiated) {
   645  		return ptype.ErrOpNotAllowed
   646  	}
   647  
   648  	return nil
   649  }
   650  
   651  func (q *QuorumControlsAPI) validateRole(orgId, roleId string) bool {
   652  	var r *core.RoleInfo
   653  	r, err := core.RoleInfoMap.GetRole(orgId, roleId)
   654  	if err != nil {
   655  		return false
   656  	}
   657  
   658  	orgRec, err := core.OrgInfoMap.GetOrg(orgId)
   659  	if err != nil {
   660  		return false
   661  	}
   662  	r, err = core.RoleInfoMap.GetRole(orgRec.UltimateParent, roleId)
   663  	if err != nil {
   664  		return false
   665  	}
   666  
   667  	return r != nil && r.Active
   668  }
   669  
   670  func (q *QuorumControlsAPI) valAccountStatusChange(orgId string, account common.Address, permAction PermAction, op AccountUpdateAction) error {
   671  	// validates if the enode is linked the passed organization
   672  	ac, err := core.AcctInfoMap.GetAccount(account)
   673  	if err != nil {
   674  		return err
   675  	}
   676  
   677  	if ac.IsOrgAdmin && (ac.RoleId == q.permCtrl.permConfig.NwAdminRole || ac.RoleId == q.permCtrl.permConfig.OrgAdminRole) && (op == 1 || op == 3) {
   678  		return ptype.ErrOpNotAllowed
   679  	}
   680  
   681  	if ac.OrgId != orgId {
   682  		return ptype.ErrOrgNotOwner
   683  	}
   684  	if (permAction == UpdateAccountStatus && (op != SuspendAccount && op != ActivateSuspendedAccount && op != BlacklistAccount)) ||
   685  		(permAction == InitiateAccountRecovery && op != RecoverBlacklistedAccount) ||
   686  		(permAction == ApproveAccountRecovery && op != ApproveBlacklistedAccountRecovery) {
   687  		return ptype.ErrOpNotAllowed
   688  	}
   689  
   690  	if ac.Status == core.AcctBlacklisted && op != RecoverBlacklistedAccount {
   691  		return ptype.ErrBlacklistedAccount
   692  	}
   693  
   694  	if (op == SuspendAccount && ac.Status != core.AcctActive) ||
   695  		(op == ActivateSuspendedAccount && ac.Status != core.AcctSuspended) ||
   696  		(op == BlacklistAccount && ac.Status == core.AcctRecoveryInitiated) ||
   697  		(op == RecoverBlacklistedAccount && ac.Status != core.AcctBlacklisted) ||
   698  		(op == ApproveBlacklistedAccountRecovery && ac.Status != core.AcctRecoveryInitiated) {
   699  		return ptype.ErrOpNotAllowed
   700  	}
   701  	return nil
   702  }
   703  
   704  func (q *QuorumControlsAPI) checkOrgAdminExists(orgId, roleId string, account common.Address) error {
   705  	if ac, _ := core.AcctInfoMap.GetAccount(account); ac != nil {
   706  		if ac.OrgId != orgId {
   707  			return ptype.ErrAccountInUse
   708  		}
   709  		if roleId != "" && roleId == q.permCtrl.permConfig.OrgAdminRole && ac.IsOrgAdmin {
   710  			return ptype.ErrAccountOrgAdmin
   711  		}
   712  	}
   713  	return nil
   714  }
   715  
   716  func (q *QuorumControlsAPI) valSubOrgBreadthDepth(porgId string) error {
   717  	org, err := core.OrgInfoMap.GetOrg(porgId)
   718  	if err != nil {
   719  		return ptype.ErrOpNotAllowed
   720  	}
   721  
   722  	if q.permCtrl.permConfig.SubOrgDepth.Cmp(org.Level) == 0 {
   723  		return ptype.ErrMaxDepth
   724  	}
   725  
   726  	if q.permCtrl.permConfig.SubOrgBreadth.Cmp(big.NewInt(int64(len(org.SubOrgList)))) == 0 {
   727  		return ptype.ErrMaxBreadth
   728  	}
   729  
   730  	return nil
   731  }
   732  
   733  func (q *QuorumControlsAPI) checkNodeExists(url, enodeId string) bool {
   734  	node, _ := core.NodeInfoMap.GetNodeByUrl(url)
   735  	if node != nil {
   736  		return true
   737  	}
   738  	// check if the same nodeid is in use with different port numbers
   739  	nodeList := core.NodeInfoMap.GetNodeList()
   740  	for _, n := range nodeList {
   741  		if enodeDet, er := enode.ParseV4(n.Url); er == nil {
   742  			if enodeDet.EnodeID() == enodeId {
   743  				return true
   744  			}
   745  		}
   746  	}
   747  	return false
   748  }
   749  
   750  func (q *QuorumControlsAPI) valNodeDetails(url string) error {
   751  	// validate node id and
   752  	if len(url) != 0 {
   753  		enodeDet, err := enode.ParseV4(url)
   754  		if err != nil {
   755  			return ptype.ErrInvalidNode
   756  		}
   757  		if q.permCtrl.isRaft && !q.permCtrl.useDns && enodeDet.Host() != "" {
   758  			return ptype.ErrHostNameNotSupported
   759  		}
   760  		// check if node already there
   761  		if q.checkNodeExists(url, enodeDet.EnodeID()) {
   762  			return ptype.ErrNodePresent
   763  		}
   764  	}
   765  	return nil
   766  }
   767  
   768  // all validations for add org operation
   769  func (q *QuorumControlsAPI) valAddOrg(args ptype.TxArgs) error {
   770  	// check if the org id contains "."
   771  	if args.OrgId == "" || args.Url == "" || args.AcctId == (common.Address{0}) {
   772  		return ptype.ErrInvalidInput
   773  	}
   774  	if !isStringAlphaNumeric(args.OrgId) {
   775  		return ptype.ErrInvalidOrgName
   776  	}
   777  
   778  	// check if caller is network admin
   779  	if !q.isNetworkAdmin(args.Txa.From) {
   780  		return ptype.ErrNotNetworkAdmin
   781  	}
   782  
   783  	// check if any previous op is pending approval for network admin
   784  	if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg) {
   785  		return ptype.ErrPendingApprovals
   786  	}
   787  	// check if org already exists
   788  	if er := q.validateOrg(args.OrgId, ""); er != nil {
   789  		return er
   790  	}
   791  
   792  	// validate node id and
   793  	if er := q.valNodeDetails(args.Url); er != nil {
   794  		return er
   795  	}
   796  
   797  	// check if account is already part of another org
   798  	if er := q.checkOrgAdminExists(args.OrgId, "", args.AcctId); er != nil {
   799  		return er
   800  	}
   801  	return nil
   802  }
   803  
   804  func (q *QuorumControlsAPI) valApproveOrg(args ptype.TxArgs) error {
   805  	// check caller is network admin
   806  	if !q.isNetworkAdmin(args.Txa.From) {
   807  		return ptype.ErrNotNetworkAdmin
   808  	}
   809  	// check if anything pending approval
   810  	if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.OrgId, args.Url, args.AcctId, 1) {
   811  		return ptype.ErrNothingToApprove
   812  	}
   813  	return nil
   814  }
   815  
   816  func (q *QuorumControlsAPI) valAddSubOrg(args ptype.TxArgs) error {
   817  	// check if the org id contains "."
   818  	if args.OrgId == "" {
   819  		return ptype.ErrInvalidInput
   820  	}
   821  	if !isStringAlphaNumeric(args.OrgId) {
   822  		return ptype.ErrInvalidOrgName
   823  	}
   824  
   825  	// check if caller is network admin
   826  	if er := q.isOrgAdmin(args.Txa.From, args.POrgId); er != nil {
   827  		return er
   828  	}
   829  
   830  	// check if org already exists
   831  	if er := q.validateOrg(args.OrgId, args.POrgId); er != nil {
   832  		return er
   833  	}
   834  
   835  	if er := q.valSubOrgBreadthDepth(args.POrgId); er != nil {
   836  		return er
   837  	}
   838  
   839  	if er := q.valNodeDetails(args.Url); er != nil {
   840  		return er
   841  	}
   842  	return nil
   843  }
   844  
   845  func (q *QuorumControlsAPI) valUpdateOrgStatus(args ptype.TxArgs) error {
   846  	// check if called is network admin
   847  	if !q.isNetworkAdmin(args.Txa.From) {
   848  		return ptype.ErrNotNetworkAdmin
   849  	}
   850  	if OrgUpdateAction(args.Action) != SuspendOrg &&
   851  		OrgUpdateAction(args.Action) != ActivateSuspendedOrg {
   852  		return ptype.ErrOpNotAllowed
   853  	}
   854  
   855  	//check if passed org id is network admin org. update should not be allowed
   856  	if args.OrgId == q.permCtrl.permConfig.NwAdminOrg {
   857  		return ptype.ErrOpNotAllowed
   858  	}
   859  	// check if status update can be performed. Org should be approved for suspension
   860  	if er := q.checkOrgStatus(args.OrgId, args.Action); er != nil {
   861  		return er
   862  	}
   863  	return nil
   864  }
   865  
   866  func (q *QuorumControlsAPI) valApproveOrgStatus(args ptype.TxArgs) error {
   867  	// check if called is network admin
   868  	if !q.isNetworkAdmin(args.Txa.From) {
   869  		return ptype.ErrNotNetworkAdmin
   870  	}
   871  	// check if anything is pending approval
   872  	var pendingOp int64
   873  	if args.Action == 1 {
   874  		pendingOp = 2
   875  	} else if args.Action == 2 {
   876  		pendingOp = 3
   877  	} else {
   878  		return ptype.ErrOpNotAllowed
   879  	}
   880  	if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.OrgId, "", common.Address{}, pendingOp) {
   881  		return ptype.ErrNothingToApprove
   882  	}
   883  	return nil
   884  }
   885  
   886  func (q *QuorumControlsAPI) valAddNode(args ptype.TxArgs) error {
   887  	if args.Url == "" {
   888  		return ptype.ErrInvalidInput
   889  	}
   890  	// check if caller is network admin
   891  	if er := q.isOrgAdmin(args.Txa.From, args.OrgId); er != nil {
   892  		return er
   893  	}
   894  
   895  	if er := q.valNodeDetails(args.Url); er != nil {
   896  		return er
   897  	}
   898  	return nil
   899  }
   900  
   901  func (q *QuorumControlsAPI) valUpdateNodeStatus(args ptype.TxArgs, permAction PermAction) error {
   902  	// check if org admin
   903  	// check if caller is network admin
   904  	if er := q.isOrgAdmin(args.Txa.From, args.OrgId); er != nil {
   905  		return er
   906  	}
   907  
   908  	// validation status change is with in allowed set
   909  	if er := q.valNodeStatusChange(args.OrgId, args.Url, NodeUpdateAction(args.Action), permAction); er != nil {
   910  		return er
   911  	}
   912  	return nil
   913  }
   914  
   915  func (q *QuorumControlsAPI) valAssignAdminRole(args ptype.TxArgs) error {
   916  	if args.AcctId == (common.Address{0}) {
   917  		return ptype.ErrInvalidInput
   918  	}
   919  	// check if caller is network admin
   920  	if args.RoleId != q.permCtrl.permConfig.OrgAdminRole && args.RoleId != q.permCtrl.permConfig.NwAdminRole {
   921  		return ptype.ErrOpNotAllowed
   922  	}
   923  
   924  	if !q.isNetworkAdmin(args.Txa.From) {
   925  		return ptype.ErrNotNetworkAdmin
   926  	}
   927  
   928  	if err := q.validateOrg(args.OrgId, ""); err == nil {
   929  		return ptype.ErrOrgDoesNotExists
   930  	}
   931  
   932  	// check if account is already part of another org
   933  	if er := q.checkOrgAdminExists(args.OrgId, args.RoleId, args.AcctId); er != nil && er.Error() != ptype.ErrOrgAdminExists.Error() {
   934  		return er
   935  	}
   936  	return nil
   937  }
   938  
   939  func (q *QuorumControlsAPI) valApproveAdminRole(args ptype.TxArgs) error {
   940  	// check if caller is network admin
   941  	if !q.isNetworkAdmin(args.Txa.From) {
   942  		return ptype.ErrNotNetworkAdmin
   943  	}
   944  	// check if the org exists
   945  
   946  	// check if account is valid
   947  	ac, _ := core.AcctInfoMap.GetAccount(args.AcctId)
   948  	if ac == nil {
   949  		return ptype.ErrInvalidAccount
   950  	}
   951  	// validate pending op
   952  	if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, ac.OrgId, "", args.AcctId, 4) {
   953  		return ptype.ErrNothingToApprove
   954  	}
   955  	return nil
   956  }
   957  
   958  func (q *QuorumControlsAPI) valAddNewRole(args ptype.TxArgs) error {
   959  	if args.RoleId == "" {
   960  		return ptype.ErrInvalidInput
   961  	}
   962  	// check if caller is network admin
   963  	if er := q.isOrgAdmin(args.Txa.From, args.OrgId); er != nil {
   964  		return er
   965  	}
   966  	// validate if role is already present
   967  	if roleRec, _ := core.RoleInfoMap.GetRole(args.OrgId, args.RoleId); roleRec != nil {
   968  		return ptype.ErrRoleExists
   969  	}
   970  	return nil
   971  }
   972  
   973  func (q *QuorumControlsAPI) valRemoveRole(args ptype.TxArgs) error {
   974  	// check if caller is network admin
   975  	if er := q.isOrgAdmin(args.Txa.From, args.OrgId); er != nil {
   976  		return er
   977  	}
   978  
   979  	// admin roles cannot be removed
   980  	if args.RoleId == q.permCtrl.permConfig.OrgAdminRole || args.RoleId == q.permCtrl.permConfig.NwAdminRole {
   981  		return ptype.ErrAdminRoles
   982  	}
   983  
   984  	// check if role is alraedy inactive
   985  	r, _ := core.RoleInfoMap.GetRole(args.OrgId, args.RoleId)
   986  	if r == nil {
   987  		return ptype.ErrInvalidRole
   988  	} else if !r.Active {
   989  		return ptype.ErrInactiveRole
   990  	}
   991  
   992  	// check if the role has active accounts. if yes operations should not be allowed
   993  	if len(core.AcctInfoMap.GetAcctListRole(args.OrgId, args.RoleId)) != 0 {
   994  		return ptype.ErrRoleActive
   995  	}
   996  	return nil
   997  }
   998  
   999  func (q *QuorumControlsAPI) valAssignRole(args ptype.TxArgs) error {
  1000  	if args.AcctId == (common.Address{0}) {
  1001  		return ptype.ErrInvalidInput
  1002  	}
  1003  	if args.RoleId == q.permCtrl.permConfig.OrgAdminRole || args.RoleId == q.permCtrl.permConfig.NwAdminRole {
  1004  		return ptype.ErrInvalidRole
  1005  	}
  1006  	// check if caller is network admin
  1007  	if er := q.isOrgAdmin(args.Txa.From, args.OrgId); er != nil {
  1008  		return er
  1009  	}
  1010  
  1011  	// check if the role is valid
  1012  	if !q.validateRole(args.OrgId, args.RoleId) {
  1013  		return ptype.ErrInvalidRole
  1014  	}
  1015  
  1016  	// check if the account is part of another org
  1017  	if ac, _ := core.AcctInfoMap.GetAccount(args.AcctId); ac != nil {
  1018  		if ac != nil && ac.OrgId != args.OrgId {
  1019  			return ptype.ErrAccountInUse
  1020  		}
  1021  	}
  1022  	return nil
  1023  }
  1024  
  1025  func (q *QuorumControlsAPI) valUpdateAccountStatus(args ptype.TxArgs, permAction PermAction) error {
  1026  	// check if the caller is org admin
  1027  	if er := q.isOrgAdmin(args.Txa.From, args.OrgId); er != nil {
  1028  		return er
  1029  	}
  1030  	// validation status change is with in allowed set
  1031  	if er := q.valAccountStatusChange(args.OrgId, args.AcctId, permAction, AccountUpdateAction(args.Action)); er != nil {
  1032  		return er
  1033  	}
  1034  	return nil
  1035  }
  1036  
  1037  func (q *QuorumControlsAPI) valRecoverNode(args ptype.TxArgs, action PermAction) error {
  1038  	// check if the caller is org admin
  1039  	if !q.isNetworkAdmin(args.Txa.From) {
  1040  		return ptype.ErrNotNetworkAdmin
  1041  	}
  1042  	// validate inputs - org id is valid, node is valid and in blacklisted state
  1043  	if err := q.validateOrg(args.OrgId, ""); err.Error() != ptype.ErrOrgExists.Error() {
  1044  		return ptype.ErrInvalidOrgName
  1045  	}
  1046  
  1047  	if action == InitiateNodeRecovery {
  1048  		if err := q.valNodeStatusChange(args.OrgId, args.Url, 4, InitiateAccountRecovery); err != nil {
  1049  			return err
  1050  		}
  1051  		// check no pending approval items
  1052  		if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg) {
  1053  			return ptype.ErrPendingApprovals
  1054  		}
  1055  	} else {
  1056  		// validate inputs - org id is valid, Node is valid pending recovery state
  1057  		if err := q.valNodeStatusChange(args.OrgId, args.Url, 5, ApproveNodeRecovery); err != nil {
  1058  			return err
  1059  		}
  1060  		if !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.OrgId, args.Url, common.Address{}, 5) {
  1061  			return ptype.ErrNothingToApprove
  1062  		}
  1063  	}
  1064  
  1065  	// if it is approval ensure that
  1066  
  1067  	return nil
  1068  }
  1069  
  1070  func (q *QuorumControlsAPI) valRecoverAccount(args ptype.TxArgs, action PermAction) error {
  1071  	// check if the caller is org admin
  1072  	if !q.isNetworkAdmin(args.Txa.From) {
  1073  		return ptype.ErrNotNetworkAdmin
  1074  	}
  1075  
  1076  	var opAction AccountUpdateAction
  1077  	if action == InitiateAccountRecovery {
  1078  		opAction = RecoverBlacklistedAccount
  1079  	} else {
  1080  		opAction = ApproveBlacklistedAccountRecovery
  1081  	}
  1082  
  1083  	if err := q.valAccountStatusChange(args.OrgId, args.AcctId, action, opAction); err != nil {
  1084  		return err
  1085  	}
  1086  
  1087  	if action == InitiateAccountRecovery && q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg) {
  1088  		return ptype.ErrPendingApprovals
  1089  	}
  1090  
  1091  	if action == ApproveAccountRecovery && !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.OrgId, "", args.AcctId, 6) {
  1092  		return ptype.ErrNothingToApprove
  1093  	}
  1094  	return nil
  1095  }