permissions: added blacklisted account recovery and approval.

This commit is contained in:
vsmk98 2019-08-02 10:28:20 +08:00
parent 56c2717eb1
commit b966118614
10 changed files with 204 additions and 31 deletions

View File

@ -56,6 +56,8 @@ const (
AcctSuspended AcctSuspended
AcctBlacklisted AcctBlacklisted
AdminRevoked AdminRevoked
AcctRecoveryInitiated
AcctRecoveryCompleted
) )
type NodeInfo struct { type NodeInfo struct {

View File

@ -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

View File

@ -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);
} }

View File

@ -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
*/ */

View File

@ -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

View File

@ -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