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
AcctBlacklisted
AdminRevoked
AcctRecoveryInitiated
AcctRecoveryCompleted
)
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}
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

View File

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

View File

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

View File

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

View File

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