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
|
AcctSuspended
|
||||||
AcctBlacklisted
|
AcctBlacklisted
|
||||||
AdminRevoked
|
AdminRevoked
|
||||||
|
AcctRecoveryInitiated
|
||||||
|
AcctRecoveryCompleted
|
||||||
)
|
)
|
||||||
|
|
||||||
type NodeInfo struct {
|
type NodeInfo struct {
|
||||||
|
|
|
@ -525,16 +525,16 @@ func (q *QuorumControlsAPI) RecoverBlackListedAccount(orgId string, acctId commo
|
||||||
}
|
}
|
||||||
args := txArgs{orgId: orgId, acctId: acctId, txa: txa}
|
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()
|
return execStatus.OpStatus()
|
||||||
}
|
}
|
||||||
//tx, err := pinterf.RecoverBlacklistedAccount(args.orgId, args.acctId)
|
tx, err := pinterf.StartBlacklistedAccountRecovery(args.orgId, args.acctId)
|
||||||
//if err != nil {
|
if err != nil {
|
||||||
// log.Error("Failed to execute permission action", "action", InitiateAccountRecovery, "err", err)
|
log.Error("Failed to execute permission action", "action", InitiateAccountRecovery, "err", err)
|
||||||
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
||||||
// return ExecStatus{false, msg}.OpStatus()
|
return ExecStatus{false, msg}.OpStatus()
|
||||||
//}
|
}
|
||||||
//log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx)
|
log.Debug("executed permission action", "action", InitiateAccountRecovery, "tx", tx)
|
||||||
return ExecSuccess.OpStatus()
|
return ExecSuccess.OpStatus()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -545,16 +545,16 @@ func (q *QuorumControlsAPI) ApproveBlackListedAccountRecovery(orgId string, acct
|
||||||
}
|
}
|
||||||
args := txArgs{orgId: orgId, acctId: acctId, txa: txa}
|
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()
|
return execStatus.OpStatus()
|
||||||
}
|
}
|
||||||
//tx, err := pinterf.ApproveAccountRecovery(args.orgId, args.acctId)
|
tx, err := pinterf.ApproveBlacklistedAccountRecovery(args.orgId, args.acctId)
|
||||||
//if err != nil {
|
if err != nil {
|
||||||
// log.Error("Failed to execute permission action", "action", ApproveAccountRecovery, "err", err)
|
log.Error("Failed to execute permission action", "action", ApproveAccountRecovery, "err", err)
|
||||||
// msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
msg := fmt.Sprintf("failed to execute permissions action: %v", err)
|
||||||
// return ExecStatus{false, msg}.OpStatus()
|
return ExecStatus{false, msg}.OpStatus()
|
||||||
//}
|
}
|
||||||
//log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx)
|
log.Debug("executed permission action", "action", ApproveAccountRecovery, "tx", tx)
|
||||||
return ExecSuccess.OpStatus()
|
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")
|
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")
|
return ErrBlacklistedAccount, errors.New("blacklisted account. operation not allowed")
|
||||||
}
|
}
|
||||||
|
|
||||||
// validate the op and node status and check if the op can be performed
|
// 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")
|
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 ErrOpNotAllowed, errors.New("account status change cannot be performed")
|
||||||
}
|
}
|
||||||
return ExecSuccess, nil
|
return ExecSuccess, nil
|
||||||
|
@ -1063,16 +1066,30 @@ func (q *QuorumControlsAPI) valRecoverNode(args txArgs, pinterf *pbind.PermInter
|
||||||
return ExecSuccess
|
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
|
// check if the caller is org admin
|
||||||
if !q.isNetworkAdmin(args.txa.From) {
|
if !q.isNetworkAdmin(args.txa.From) {
|
||||||
return ErrNotNetworkAdmin
|
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
|
return ErrPendingApprovals
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if action == ApproveAccountRecovery && !q.validatePendingOp(q.permCtrl.permConfig.NwAdminOrg, args.orgId, "", args.acctId, 6, pinterf) {
|
||||||
|
return ErrNothingToApprove
|
||||||
|
}
|
||||||
return ExecSuccess
|
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
|
4 - Suspended
|
||||||
5 - Blacklisted
|
5 - Blacklisted
|
||||||
6 - Revoked
|
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
|
Once the account is blacklisted no further activity on the account is
|
||||||
possible.
|
possible.
|
||||||
When adding a new org admin account to an existing org, the existing org
|
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 _orgId - org id
|
||||||
* @param _account - account id
|
* @param _account - account id
|
||||||
* @param _action - new status of the account
|
* @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
|
function updateAccountStatus(string calldata _orgId, address _account, uint _action) external
|
||||||
onlyImplementation
|
onlyImplementation
|
||||||
accountExists(_orgId, _account) {
|
accountExists(_orgId, _account) {
|
||||||
// operations that can be done 1-Suspend account, 2-Unsuspend Account, 3-Blacklist account
|
require((_action > 0 && _action < 6), "invalid status change request");
|
||||||
require((_action == 1 || _action == 2 || _action == 3), "invalid status change request");
|
|
||||||
// check if the account is org admin. if yes then do not allow any status change
|
// 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");
|
require(checkOrgAdmin(_account, _orgId, "") != true, "status change not possible for org admin accounts");
|
||||||
uint newStatus;
|
uint newStatus;
|
||||||
|
@ -230,6 +238,16 @@ contract AccountManager {
|
||||||
"account is already blacklisted. operation cannot be done");
|
"account is already blacklisted. operation cannot be done");
|
||||||
newStatus = 5;
|
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;
|
accountAccessList[_getAccountIndex(_account)].status = newStatus;
|
||||||
emit AccountStatusChanged(_account, _orgId, newStatus);
|
emit AccountStatusChanged(_account, _orgId, newStatus);
|
||||||
}
|
}
|
||||||
|
|
|
@ -409,7 +409,7 @@ contract PermissionsImplementation {
|
||||||
nodeManager.updateNodeStatus(_enodeId, _orgId, _action);
|
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
|
invoked by an network admin account only
|
||||||
* @param _orgId unique id of the organization to which the account belongs
|
* @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 dded to the org
|
||||||
|
@ -426,7 +426,7 @@ contract PermissionsImplementation {
|
||||||
voterManager.addVotingItem(adminOrg, _orgId, _enodeId, address(0), 5);
|
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
|
invoked by an network admin account only
|
||||||
* @param _orgId unique id of the organization to which the account belongs
|
* @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 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
|
/** @notice function to fetch network boot status
|
||||||
* @return bool network boot status
|
* @return bool network boot status
|
||||||
*/
|
*/
|
||||||
|
|
|
@ -201,7 +201,7 @@ contract PermissionsInterface {
|
||||||
|
|
||||||
/** @notice interface to initiate blacklisted node recovery
|
/** @notice interface to initiate blacklisted node recovery
|
||||||
* @param _orgId unique id of the organization to which the account belongs
|
* @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)
|
function startBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId)
|
||||||
external {
|
external {
|
||||||
|
@ -210,13 +210,31 @@ contract PermissionsInterface {
|
||||||
|
|
||||||
/** @notice interface to approve blacklisted node recoevry
|
/** @notice interface to approve blacklisted node recoevry
|
||||||
* @param _orgId unique id of the organization to which the account belongs
|
* @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)
|
function approveBlacklistedNodeRecovery(string calldata _orgId, string calldata _enodeId)
|
||||||
external {
|
external {
|
||||||
permImplementation.approveBlacklistedNodeRecovery(_orgId, _enodeId, msg.sender);
|
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
|
/** @notice interface to fetch detail of any pending approval activities
|
||||||
for network admin organization
|
for network admin organization
|
||||||
* @param _orgId unique id of the organization to which the account belongs
|
* @param _orgId unique id of the organization to which the account belongs
|
||||||
|
|
|
@ -17,6 +17,7 @@ import "./PermissionsUpgradable.sol";
|
||||||
3 - Revoke of org suspension
|
3 - Revoke of org suspension
|
||||||
4 - Assigning admin role for a new account
|
4 - Assigning admin role for a new account
|
||||||
5 - Blacklisted node recovery
|
5 - Blacklisted node recovery
|
||||||
|
6 - Blacklisted account recovery
|
||||||
*/
|
*/
|
||||||
contract VoterManager {
|
contract VoterManager {
|
||||||
PermissionsUpgradable private permUpgradable;
|
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