mirror of https://github.com/poanetwork/quorum.git
permissions: added blacklisted account recovery and approval.
This commit is contained in:
parent
56c2717eb1
commit
b966118614
|
@ -56,6 +56,8 @@ const (
|
|||
AcctSuspended
|
||||
AcctBlacklisted
|
||||
AdminRevoked
|
||||
AcctRecoveryInitiated
|
||||
AcctRecoveryCompleted
|
||||
)
|
||||
|
||||
type NodeInfo struct {
|
||||
|
|
|
@ -525,16 +525,16 @@ func (q *QuorumControlsAPI) RecoverBlackListedAccount(orgId string, acctId commo
|
|||
}
|
||||
args := txArgs{orgId: orgId, acctId: acctId, txa: txa}
|
||||
|
||||
if execStatus := q.valRecoverAccount(args, pinterf); execStatus != ExecSuccess {
|
||||
if execStatus := q.valRecoverAccount(args, pinterf, InitiateAccountRecovery); execStatus != ExecSuccess {
|
||||
return execStatus.OpStatus()
|
||||
}
|
||||
//tx, err := pinterf.RecoverBlacklistedAccount(args.orgId, args.acctId)
|
||||
//if err != nil {
|
||||
// log.Error("Failed to execute permission action", "action", InitiateAccountRecovery, "err", err)
|
||||
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
||||
// return ExecStatus{false, msg}.OpStatus()
|
||||
//}
|
||||
//log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx)
|
||||
tx, err := pinterf.StartBlacklistedAccountRecovery(args.orgId, args.acctId)
|
||||
if err != nil {
|
||||
log.Error("Failed to execute permission action", "action", InitiateAccountRecovery, "err", err)
|
||||
msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
||||
return ExecStatus{false, msg}.OpStatus()
|
||||
}
|
||||
log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx)
|
||||
return ExecSuccess.OpStatus()
|
||||
}
|
||||
|
||||
|
@ -545,16 +545,16 @@ func (q *QuorumControlsAPI) ApproveBlackListedAccountRecovery(orgId string, acct
|
|||
}
|
||||
args := txArgs{orgId: orgId, acctId: acctId, txa: txa}
|
||||
|
||||
if execStatus := q.valRecoverAccount(args, pinterf); execStatus != ExecSuccess {
|
||||
if execStatus := q.valRecoverAccount(args, pinterf, ApproveAccountRecovery); execStatus != ExecSuccess {
|
||||
return execStatus.OpStatus()
|
||||
}
|
||||
//tx, err := pinterf.ApproveAccountRecovery(args.orgId, args.acctId)
|
||||
//if err != nil {
|
||||
// log.Error("Failed to execute permission action", "action", ApproveAccountRecovery, "err", err)
|
||||
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
||||
// return ExecStatus{false, msg}.OpStatus()
|
||||
//}
|
||||
//log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx)
|
||||
tx, err := pinterf.ApproveBlacklistedAccountRecovery(args.orgId, args.acctId)
|
||||
if err != nil {
|
||||
log.Error("Failed to execute permission action", "action", ApproveAccountRecovery, "err", err)
|
||||
msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
||||
return ExecStatus{false, msg}.OpStatus()
|
||||
}
|
||||
log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx)
|
||||
return ExecSuccess.OpStatus()
|
||||
}
|
||||
|
||||
|
@ -685,16 +685,19 @@ func (q *QuorumControlsAPI) valAccountStatusChange(orgId string, account common.
|
|||
return ErrOrgNotOwner, errors.New("account does not belong to the organization passed")
|
||||
}
|
||||
|
||||
if ac.Status == types.AcctBlacklisted {
|
||||
if ac.Status == types.AcctBlacklisted && op != 4 {
|
||||
return ErrBlacklistedAccount, errors.New("blacklisted account. operation not allowed")
|
||||
}
|
||||
|
||||
// validate the op and node status and check if the op can be performed
|
||||
if op != 1 && op != 2 && op != 3 {
|
||||
if op != 1 && op != 2 && op != 3 && op != 4 && op != 5 {
|
||||
log.Info("SMK - at 694", "op", op)
|
||||
return ErrOpNotAllowed, errors.New("invalid account status change operation")
|
||||
}
|
||||
|
||||
if (op == 1 && ac.Status != types.AcctActive) || (op == 2 && ac.Status != types.AcctSuspended) {
|
||||
if (op == 1 && ac.Status != types.AcctActive) || (op == 2 && ac.Status != types.AcctSuspended) ||
|
||||
(op == 4 && ac.Status != types.AcctBlacklisted) || (op == 5 && ac.Status != types.AcctRecoveryInitiated) {
|
||||
log.Info("SMK - at 700", "op", op, "acStatus", ac.Status)
|
||||
return ErrOpNotAllowed, errors.New("account status change cannot be performed")
|
||||
}
|
||||
return ExecSuccess, nil
|
||||
|
@ -1063,16 +1066,30 @@ func (q *QuorumControlsAPI) valRecoverNode(args txArgs, pinterf *pbind.PermInter
|
|||
return ExecSuccess
|
||||
}
|
||||
|
||||
func (q *QuorumControlsAPI) valRecoverAccount(args txArgs, pinterf *pbind.PermInterfaceSession) ExecStatus {
|
||||
func (q *QuorumControlsAPI) valRecoverAccount(args txArgs, pinterf *pbind.PermInterfaceSession, action PermAction) ExecStatus {
|
||||
// check if the caller is org admin
|
||||
if !q.isNetworkAdmin(args.txa.From) {
|
||||
return ErrNotNetworkAdmin
|
||||
}
|
||||
|
||||
if q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
|
||||
var opAction int64
|
||||
if action == InitiateAccountRecovery {
|
||||
opAction = 4
|
||||
} else {
|
||||
opAction = 5
|
||||
}
|
||||
|
||||
if execStatus, err := q.valAccountStatusChange(args.orgId, args.acctId, opAction); err != nil {
|
||||
return execStatus
|
||||
}
|
||||
|
||||
if action == InitiateAccountRecovery && q.checkPendingOp(q.permCtrl.permConfig.NwAdminOrg, pinterf) {
|
||||
return ErrPendingApprovals
|
||||
}
|
||||
|
||||
if action == ApproveAccountRecovery && !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, "", args.acctId, 6, pinterf) {
|
||||
return ErrNothingToApprove
|
||||
}
|
||||
return ExecSuccess
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -16,6 +16,8 @@ import "./PermissionsUpgradable.sol";
|
|||
4 - Suspended
|
||||
5 - Blacklisted
|
||||
6 - Revoked
|
||||
7 - Recovery Initiated for blacklisted accounts and pending approval
|
||||
from network admins
|
||||
Once the account is blacklisted no further activity on the account is
|
||||
possible.
|
||||
When adding a new org admin account to an existing org, the existing org
|
||||
|
@ -204,12 +206,18 @@ contract AccountManager {
|
|||
* @param _orgId - org id
|
||||
* @param _account - account id
|
||||
* @param _action - new status of the account
|
||||
* @dev the following actions are allowed
|
||||
1 - Suspend the account
|
||||
2 - Reactivate a suspended account
|
||||
3 - Blacklist an account
|
||||
4 - Initiate recovery for black listed account
|
||||
5 - Complete recovery of black listed account and update status to active
|
||||
*/
|
||||
function updateAccountStatus(string calldata _orgId, address _account, uint _action) external
|
||||
onlyImplementation
|
||||
accountExists(_orgId, _account) {
|
||||
// operations that can be done 1-Suspend account, 2-Unsuspend Account, 3-Blacklist account
|
||||
require((_action == 1 || _action == 2 || _action == 3), "invalid status change request");
|
||||
require((_action > 0 && _action < 6), "invalid status change request");
|
||||
|
||||
// check if the account is org admin. if yes then do not allow any status change
|
||||
require(checkOrgAdmin(_account, _orgId, "") != true, "status change not possible for org admin accounts");
|
||||
uint newStatus;
|
||||
|
@ -230,6 +238,16 @@ contract AccountManager {
|
|||
"account is already blacklisted. operation cannot be done");
|
||||
newStatus = 5;
|
||||
}
|
||||
else if (_action == 4) {
|
||||
require(accountAccessList[_getAccountIndex(_account)].status == 5,
|
||||
"account is not blacklisted. operation cannot be done");
|
||||
newStatus = 7;
|
||||
}
|
||||
else if (_action == 5) {
|
||||
require(accountAccessList[_getAccountIndex(_account)].status == 7, "account recovery not initiated. operation cannot be done");
|
||||
newStatus = 2;
|
||||
}
|
||||
|
||||
accountAccessList[_getAccountIndex(_account)].status = newStatus;
|
||||
emit AccountStatusChanged(_account, _orgId, newStatus);
|
||||
}
|
||||
|
|
|
@ -409,7 +409,7 @@ contract PermissionsImplementation {
|
|||
nodeManager.updateNodeStatus(_enodeId, _orgId, _action);
|
||||
}
|
||||
|
||||
/** @notice function to initaite blacklisted nodes recovery. this can be
|
||||
/** @notice function to initiate blacklisted nodes recovery. this can be
|
||||
invoked by an network admin account only
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _enodeId full enode id being dded to the org
|
||||
|
@ -426,7 +426,7 @@ contract PermissionsImplementation {
|
|||
voterManager.addVotingItem(adminOrg, _orgId, _enodeId, address(0), 5);
|
||||
}
|
||||
|
||||
/** @notice function to initaite blacklisted nodes recovery. this can be
|
||||
/** @notice function to initiate blacklisted nodes recovery. this can be
|
||||
invoked by an network admin account only
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _enodeId full enode id being dded to the org
|
||||
|
@ -443,6 +443,39 @@ contract PermissionsImplementation {
|
|||
}
|
||||
}
|
||||
|
||||
/** @notice function to initaite blacklisted nodes recovery. this can be
|
||||
invoked by an network admin account only
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _account account id being dded to the org
|
||||
* @dev this function creates a voting record for other network admins to
|
||||
approve the operation. The recovery is complete only after majority voting
|
||||
*/
|
||||
function startBlacklistedAccountRecovery(string calldata _orgId, address _account,
|
||||
address _caller) external onlyInterface networkAdmin(_caller) {
|
||||
// update the account status as recovery initiated. action for this is 4
|
||||
accountManager.updateAccountStatus(_orgId, _account, 4);
|
||||
// add a voting record with pending op of 5 which corresponds to blacklisted node
|
||||
// recovery
|
||||
voterManager.addVotingItem(adminOrg, _orgId, "", _account, 6);
|
||||
}
|
||||
|
||||
/** @notice function to initaite blacklisted nodes recovery. this can be
|
||||
invoked by an network admin account only
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _account account id being dded to the org
|
||||
* @dev this function creates a voting record for other network admins to
|
||||
approve the operation. The recovery is complete only after majority voting
|
||||
*/
|
||||
function approveBlacklistedAccountRecovery(string calldata _orgId, address _account,
|
||||
address _caller) external onlyInterface networkAdmin(_caller) {
|
||||
// check if majority votes are received. pending op type is passed as 6
|
||||
// which stands for black listed account recovery
|
||||
if ((processVote(adminOrg, _caller, 6))) {
|
||||
// update the node back to active
|
||||
accountManager.updateAccountStatus(_orgId, _account, 5);
|
||||
}
|
||||
}
|
||||
|
||||
/** @notice function to fetch network boot status
|
||||
* @return bool network boot status
|
||||
*/
|
||||
|
|
|
@ -201,7 +201,7 @@ contract PermissionsInterface {
|
|||
|
||||
/** @notice interface to initiate blacklisted node recovery
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _enodeId full enode id being dded to the org
|
||||
* @param _enodeId full enode id being recovered
|
||||
*/
|
||||
function startBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId)
|
||||
external {
|
||||
|
@ -210,13 +210,31 @@ contract PermissionsInterface {
|
|||
|
||||
/** @notice interface to approve blacklisted node recoevry
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _enodeId full enode id being dded to the org
|
||||
* @param _enodeId full enode id being recovered
|
||||
*/
|
||||
function approveBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId)
|
||||
external {
|
||||
permImplementation.approveBlacklistedNodeRecovery(_orgId, _enodeId, msg.sender);
|
||||
}
|
||||
|
||||
/** @notice interface to initiate blacklisted account recovery
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _account account id being recovered
|
||||
*/
|
||||
function startBlacklistedAccountRecovery(string calldata _orgId, address _account)
|
||||
external {
|
||||
permImplementation.startBlacklistedAccountRecovery(_orgId, _account, msg.sender);
|
||||
}
|
||||
|
||||
/** @notice interface to approve blacklisted node recovery
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
* @param _account account id being recovered
|
||||
*/
|
||||
function approveBlacklistedAccountRecovery(string calldata _orgId, address _account)
|
||||
external {
|
||||
permImplementation.approveBlacklistedAccountRecovery(_orgId, _account, msg.sender);
|
||||
}
|
||||
|
||||
/** @notice interface to fetch detail of any pending approval activities
|
||||
for network admin organization
|
||||
* @param _orgId unique id of the organization to which the account belongs
|
||||
|
|
|
@ -17,6 +17,7 @@ import "./PermissionsUpgradable.sol";
|
|||
3 - Revoke of org suspension
|
||||
4 - Assigning admin role for a new account
|
||||
5 - Blacklisted node recovery
|
||||
6 - Blacklisted account recovery
|
||||
*/
|
||||
contract VoterManager {
|
||||
PermissionsUpgradable private permUpgradable;
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue