Skip to content

Commit

Permalink
fix(permissions): order permissions alphabetically before setting them
Browse files Browse the repository at this point in the history
Also exempted some transactions from requiring permissions (most of balances, all of staking, sudo
and session)
  • Loading branch information
monitz87 committed Feb 4, 2021
1 parent 0c130e3 commit f5a2ed1
Show file tree
Hide file tree
Showing 5 changed files with 54 additions and 22 deletions.
18 changes: 15 additions & 3 deletions src/api/entities/CurrentAccount.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { difference, differenceBy, differenceWith, isEqual } from 'lodash';
import { difference, differenceBy, differenceWith, isEqual, union } from 'lodash';

import { Account, CurrentIdentity } from '~/internal';
import { Permissions } from '~/types';
import { Permissions, TxTags } from '~/types';
import { portfolioToPortfolioId, signerToString } from '~/utils/conversion';

/**
Expand Down Expand Up @@ -65,14 +65,26 @@ export class CurrentAccount extends Account {
hasTokens = tokens.length === 0 || !differenceBy(tokens, currentTokens, 'ticker').length;
}

// these transactions are allowed to any account, independent of permissions
const exemptedTransactions = [
...difference(Object.values(TxTags.balances), [
TxTags.balances.DepositBlockRewardReserveBalance,
TxTags.balances.BurnAccountBalance,
]),
...Object.values(TxTags.staking),
...Object.values(TxTags.sudo),
...Object.values(TxTags.session),
];

let hasTransactions;
if (currentTransactions === null) {
hasTransactions = true;
} else if (transactions === null) {
hasTransactions = false;
} else {
hasTransactions =
transactions.length === 0 || !difference(transactions, currentTransactions).length;
transactions.length === 0 ||
!difference(transactions, union(currentTransactions, exemptedTransactions)).length;
}

let hasPortfolios;
Expand Down
22 changes: 22 additions & 0 deletions src/api/entities/__tests__/CurrentAccount.ts
Original file line number Diff line number Diff line change
Expand Up @@ -136,5 +136,27 @@ describe('CurrentAccount class', () => {

expect(result).toEqual(false);
});

test('should exempt certain transactions from requiring permissions', async () => {
const address = 'someAddress';

context = dsMockUtils.getContextInstance({ primaryKey: address });

const account = new CurrentAccount({ address }, context);

const result = await account.hasPermissions({
tokens: [],
portfolios: [],
transactions: [
TxTags.balances.Transfer,
TxTags.balances.TransferWithMemo,
TxTags.staking.AddPermissionedValidator,
TxTags.sudo.SetKey,
TxTags.session.PurgeKeys,
],
});

expect(result).toEqual(true);
});
});
});
15 changes: 5 additions & 10 deletions src/api/procedures/modifySignerPermissions.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import P from 'bluebird';

import { assertSecondaryKeys } from '~/api/procedures/utils';
import { Procedure } from '~/internal';
import { PermissionsLike, Signer, TxTags } from '~/types';
Expand Down Expand Up @@ -47,16 +45,13 @@ export async function prepareModifySignerPermissions(
secondaryKeys
);

const signersList = await P.map(
signerValues,
async ({ signer, permissions: permissionsLike }) => {
const permissions = await permissionsLikeToPermissions(permissionsLike, context);
const signersList = signerValues.map(({ signer, permissions: permissionsLike }) => {
const permissions = permissionsLikeToPermissions(permissionsLike, context);

const rawPermissions = permissionsToMeshPermissions(permissions, context);
const rawPermissions = permissionsToMeshPermissions(permissions, context);

return tuple(signerValueToSignatory(signer, context), rawPermissions);
}
);
return tuple(signerValueToSignatory(signer, context), rawPermissions);
});

this.addBatchTransaction(tx.identity.setPermissionToSigner, {}, signersList);
}
Expand Down
12 changes: 8 additions & 4 deletions src/utils/__tests__/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1013,7 +1013,7 @@ describe('permissionsToMeshPermissions and meshPermissionsToPermissions', () =>
entityMockUtils.cleanup();
});

test('permissionsToMeshPermissions should convert a Permissions to a polkadot Permissions object', () => {
test('permissionsToMeshPermissions should convert a Permissions to a polkadot Permissions object (ordering tx alphabetically)', () => {
let value: Permissions = {
tokens: null,
transactions: null,
Expand All @@ -1039,7 +1039,7 @@ describe('permissionsToMeshPermissions and meshPermissionsToPermissions', () =>
const did = 'someDid';
value = {
tokens: [entityMockUtils.getSecurityTokenInstance({ ticker })],
transactions: [TxTags.identity.AddClaim],
transactions: [TxTags.sto.Invest, TxTags.identity.AddClaim, TxTags.sto.CreateFundraiser],
portfolios: [entityMockUtils.getDefaultPortfolioInstance({ did })],
};

Expand All @@ -1052,12 +1052,16 @@ describe('permissionsToMeshPermissions and meshPermissionsToPermissions', () =>
.withArgs('Permissions', {
asset: [rawTicker],
extrinsic: [
/* eslint-disable @typescript-eslint/camelcase */
{
/* eslint-disable @typescript-eslint/camelcase */
pallet_name: 'Identity',
dispatchable_names: ['add_claim'],
/* eslint-enable @typescript-eslint/camelcase */
},
{
pallet_name: 'Sto',
dispatchable_names: ['create_fundraiser', 'invest'],
},
/* eslint-enable @typescript-eslint/camelcase */
],
portfolio: [rawPortfolioId],
})
Expand Down
9 changes: 4 additions & 5 deletions src/utils/conversion.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@ import {
} from '@polkadot/util';
import { blake2AsHex, decodeAddress, encodeAddress } from '@polkadot/util-crypto';
import BigNumber from 'bignumber.js';
import P from 'bluebird';
import { computeWithoutCheck } from 'iso-7064';
import { camelCase, isEqual, map, padEnd, range, rangeRight, snakeCase, values } from 'lodash';
import {
Expand Down Expand Up @@ -514,7 +513,7 @@ export function permissionsToMeshPermissions(
let extrinsic: { pallet_name: string; dispatchable_names: string[] }[] | null = null;

if (transactions) {
transactions.forEach(tag => {
transactions.sort().forEach(tag => {
const [modName, txName] = tag.split('.');

const palletName = stringUpperFirst(modName);
Expand Down Expand Up @@ -2223,10 +2222,10 @@ export function stoTierToPriceTier(tier: StoTier, context: Context): PriceTier {
/**
* @hidden
*/
export async function permissionsLikeToPermissions(
export function permissionsLikeToPermissions(
permissionsLike: PermissionsLike,
context: Context
): Promise<Permissions> {
): Permissions {
let tokenPermissions: SecurityToken[] | null = [];
let transactionPermissions: TxTag[] | null = [];
let portfolioPermissions: (DefaultPortfolio | NumberedPortfolio)[] | null = [];
Expand All @@ -2248,7 +2247,7 @@ export async function permissionsLikeToPermissions(
if (portfolios === null) {
portfolioPermissions = null;
} else if (portfolios) {
portfolioPermissions = await P.map(portfolios, portfolio =>
portfolioPermissions = portfolios.map(portfolio =>
portfolioLikeToPortfolio(portfolio, context)
);
}
Expand Down

0 comments on commit f5a2ed1

Please sign in to comment.