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