Skip to content

Commit

Permalink
feat(procedures): add checkAuthorization to every method
Browse files Browse the repository at this point in the history
Methods that run transactions can be checked for authorization before being run. For example,
instead of calling `SecurityToken.freeze()` you can first call
`SecurityToken.freeze.checkAuthorization()` to see if you have sufficient permissions
  • Loading branch information
monitz87 committed Dec 17, 2020
1 parent 38678cd commit d861221
Show file tree
Hide file tree
Showing 39 changed files with 808 additions and 463 deletions.
66 changes: 52 additions & 14 deletions src/Claims.ts
@@ -1,4 +1,4 @@
import { Context, Identity, modifyClaims, ModifyClaimsParams, TransactionQueue } from '~/internal';
import { Context, Identity, modifyClaims, ModifyClaimsParams } from '~/internal';
import {
didsWithClaims,
issuerDidsWithClaimsByTarget,
Expand All @@ -14,14 +14,14 @@ import {
ResultSet,
Scope,
} from '~/types';
import { ClaimOperation } from '~/types/internal';
import { ClaimOperation, ProcedureMethod } from '~/types/internal';
import {
middlewareScopeToScope,
scopeToMiddlewareScope,
signerToString,
toIdentityWithClaimsArray,
} from '~/utils/conversion';
import { calculateNextKey, getDid, removePadding } from '~/utils/internal';
import { calculateNextKey, createProcedureMethod, getDid, removePadding } from '~/utils/internal';

/**
* Handles all Claims related functionality
Expand All @@ -34,36 +34,74 @@ export class Claims {
*/
constructor(context: Context) {
this.context = context;

this.addClaims = createProcedureMethod<
Omit<ModifyClaimsParams, 'operation'>,
ModifyClaimsParams,
void
>(
args => [
modifyClaims,
{
...args,
operation: ClaimOperation.Add,
} as ModifyClaimsParams,
],
context
);

this.editClaims = createProcedureMethod<
Omit<ModifyClaimsParams, 'operation'>,
ModifyClaimsParams,
void
>(
args => [
modifyClaims,
{
...args,
operation: ClaimOperation.Edit,
} as ModifyClaimsParams,
],
context
);

this.revokeClaims = createProcedureMethod<
Omit<ModifyClaimsParams, 'operation'>,
ModifyClaimsParams,
void
>(
args => [
modifyClaims,
{
...args,
operation: ClaimOperation.Revoke,
} as ModifyClaimsParams,
],
context
);
}

/**
* Add claims to Identities
*
* @param args.claims - array of claims to be added
*/
public addClaims(args: Omit<ModifyClaimsParams, 'operation'>): Promise<TransactionQueue<void>> {
return modifyClaims.prepare({ ...args, operation: ClaimOperation.Add }, this.context);
}
public addClaims: ProcedureMethod<Pick<ModifyClaimsParams, 'claims'>, void>;

/**
* Edit claims associated to Identities (only the expiry date can be modified)
*
* * @param args.claims - array of claims to be edited
*/
public editClaims(args: Omit<ModifyClaimsParams, 'operation'>): Promise<TransactionQueue<void>> {
return modifyClaims.prepare({ ...args, operation: ClaimOperation.Edit }, this.context);
}

public editClaims: ProcedureMethod<Pick<ModifyClaimsParams, 'claims'>, void>;

/**
* Revoke claims from Identities
*
* @param args.claims - array of claims to be revoked
*/
public revokeClaims(
args: Omit<ModifyClaimsParams, 'operation'>
): Promise<TransactionQueue<void>> {
return modifyClaims.prepare({ ...args, operation: ClaimOperation.Revoke }, this.context);
}
public revokeClaims: ProcedureMethod<Pick<ModifyClaimsParams, 'claims'>, void>;

/**
* Retrieve all claims issued by an Identity
Expand Down
23 changes: 12 additions & 11 deletions src/Polymesh.ts
Expand Up @@ -21,7 +21,6 @@ import {
ReserveTickerParams,
SecurityToken,
TickerReservation,
TransactionQueue,
transferPolyX,
TransferPolyXParams,
} from '~/internal';
Expand All @@ -39,6 +38,7 @@ import {
UiKeyring,
UnsubCallback,
} from '~/types';
import { ProcedureMethod } from '~/types/internal';
import {
moduleAddressToString,
signerToString,
Expand All @@ -48,7 +48,7 @@ import {
tickerToString,
u32ToBigNumber,
} from '~/utils/conversion';
import { getDid, stringIsClean } from '~/utils/internal';
import { createProcedureMethod, getDid, stringIsClean } from '~/utils/internal';

import { Claims } from './Claims';
// import { Governance } from './Governance';
Expand Down Expand Up @@ -93,6 +93,12 @@ export class Polymesh {
// this.governance = new Governance(context);
this.claims = new Claims(context);
this.middleware = new Middleware(context);

this.transferPolyX = createProcedureMethod(args => [transferPolyX, args], context);

this.reserveTicker = createProcedureMethod(args => [reserveTicker, args], context);

this.registerIdentity = createProcedureMethod(args => [registerIdentity, args], context);
}

/**
Expand Down Expand Up @@ -262,9 +268,8 @@ export class Polymesh {
* @param args.amount - amount of POLYX to be transferred
* @param args.memo - identifier string to help differentiate transfers
*/
public transferPolyX(args: TransferPolyXParams): Promise<TransactionQueue<void>> {
return transferPolyX.prepare(args, this.context);
}

public transferPolyX: ProcedureMethod<TransferPolyXParams, void>;

/**
* Get the free/locked POLYX balance of an Account
Expand Down Expand Up @@ -322,9 +327,7 @@ export class Polymesh {
*
* @param args.ticker - ticker symbol to reserve
*/
public reserveTicker(args: ReserveTickerParams): Promise<TransactionQueue<TickerReservation>> {
return reserveTicker.prepare(args, this.context);
}
public reserveTicker: ProcedureMethod<ReserveTickerParams, TickerReservation>;

/**
* Check if a ticker hasn't been reserved
Expand Down Expand Up @@ -636,9 +639,7 @@ export class Polymesh {
* the corresponding [[Account | Accounts]] and/or [[Identity | Identities]]. An Account or Identity can
* fetch its pending Authorization Requests by calling `authorizations.getReceived`
*/
public registerIdentity(args: RegisterIdentityParams): Promise<TransactionQueue<Identity>> {
return registerIdentity.prepare(args, this.context);
}
public registerIdentity: ProcedureMethod<RegisterIdentityParams, Identity>;

/**
* Retrieve the number of the latest block in the chain
Expand Down
64 changes: 36 additions & 28 deletions src/__tests__/Claims.ts
@@ -1,7 +1,7 @@
import sinon from 'sinon';

import { Claims } from '~/Claims';
import { Context, Identity, modifyClaims, TransactionQueue } from '~/internal';
import { Context, modifyClaims, TransactionQueue } from '~/internal';
import {
didsWithClaims,
issuerDidsWithClaimsByTarget,
Expand All @@ -22,6 +22,11 @@ import {
import { ClaimOperation } from '~/types/internal';
import * as utilsConversionModule from '~/utils/conversion';

jest.mock(
'~/api/entities/Identity',
require('~/testUtils/mocks/entities').mockIdentityModule('~/api/entities/Identity')
);

describe('Claims Class', () => {
let context: Mocked<Context>;
let claims: Claims;
Expand Down Expand Up @@ -52,8 +57,8 @@ describe('Claims Class', () => {
const issuedClaims: ResultSet<ClaimData> = {
data: [
{
target: new Identity({ did: target }, context),
issuer: new Identity({ did: 'otherDid' }, context),
target: entityMockUtils.getIdentityInstance({ did: target }),
issuer: entityMockUtils.getIdentityInstance({ did: 'otherDid' }),
issuedAt: new Date(),
expiry: null,
claim: { type: ClaimType.NoData },
Expand Down Expand Up @@ -83,29 +88,30 @@ describe('Claims Class', () => {
const issuerDid = 'someIssuerDid';
const date = 1589816265000;
const customerDueDiligenceType = ClaimTypeEnum.CustomerDueDiligence;
const cddId = 'someCddId';
const claimData = {
type: ClaimTypeEnum.CustomerDueDiligence,
id: cddId,
};
const claim = {
target: new Identity({ did: targetDid }, context),
issuer: new Identity({ did: issuerDid }, context),
target: entityMockUtils.getIdentityInstance({ did: targetDid }),
issuer: entityMockUtils.getIdentityInstance({ did: issuerDid }),
issuedAt: new Date(date),
};

const fakeClaims = [
{
identity: new Identity({ did: targetDid }, context),
identity: entityMockUtils.getIdentityInstance({ did: targetDid }),
claims: [
{
...claim,
expiry: new Date(date),
claim: {
type: customerDueDiligenceType,
},
claim: claimData,
},
{
...claim,
expiry: null,
claim: {
type: customerDueDiligenceType,
},
claim: claimData,
},
],
},
Expand All @@ -127,11 +133,13 @@ describe('Claims Class', () => {
...commonClaimData,
expiry: date,
type: customerDueDiligenceType,
cdd_id: cddId,
},
{
...commonClaimData,
expiry: null,
type: customerDueDiligenceType,
cdd_id: cddId,
},
],
},
Expand Down Expand Up @@ -164,7 +172,7 @@ describe('Claims Class', () => {
size: 1,
});

expect(result.data).toEqual(fakeClaims);
expect(JSON.stringify(result.data)).toBe(JSON.stringify(fakeClaims));
expect(result.count).toEqual(25);
expect(result.next).toEqual(1);

Expand All @@ -185,7 +193,7 @@ describe('Claims Class', () => {

result = await claims.getIdentitiesWithClaims();

expect(result.data).toEqual(fakeClaims);
expect(JSON.stringify(result.data)).toBe(JSON.stringify(fakeClaims));
expect(result.count).toEqual(25);
expect(result.next).toEqual(null);
});
Expand All @@ -197,14 +205,14 @@ describe('Claims Class', () => {
const date = 1589816265000;
const accreditedType = ClaimTypeEnum.Accredited;
const claim = {
target: new Identity({ did: targetDid }, context),
issuer: new Identity({ did: issuerDid }, context),
target: entityMockUtils.getIdentityInstance({ did: targetDid }),
issuer: entityMockUtils.getIdentityInstance({ did: issuerDid }),
issuedAt: new Date(date),
};

const fakeClaims = [
{
identity: new Identity({ did: targetDid }, context),
identity: entityMockUtils.getIdentityInstance({ did: targetDid }),
claims: [
{
...claim,
Expand Down Expand Up @@ -288,9 +296,9 @@ describe('Claims Class', () => {
size: 1,
});

expect(result.data).toEqual(fakeClaims);
expect(result.count).toEqual(25);
expect(result.next).toEqual(1);
expect(JSON.stringify(result.data)).toBe(JSON.stringify(fakeClaims));
expect(result.count).toBe(25);
expect(result.next).toBe(1);
});
});

Expand Down Expand Up @@ -394,8 +402,8 @@ describe('Claims Class', () => {
const issuedClaims: ResultSet<ClaimData> = {
data: [
{
target: new Identity({ did: target }, context),
issuer: new Identity({ did: 'otherDid' }, context),
target: entityMockUtils.getIdentityInstance({ did: target }),
issuer: entityMockUtils.getIdentityInstance({ did: 'otherDid' }),
issuedAt: new Date(),
expiry: null,
claim: { type: ClaimType.CustomerDueDiligence, id: 'someCddId' },
Expand Down Expand Up @@ -470,13 +478,13 @@ describe('Claims Class', () => {
const issuerDid = 'someIssuerDid';
const date = 1589816265000;
const claim = {
target: new Identity({ did }, context),
issuer: new Identity({ did: issuerDid }, context),
target: entityMockUtils.getIdentityInstance({ did }),
issuer: entityMockUtils.getIdentityInstance({ did: issuerDid }),
issuedAt: new Date(date),
};
const fakeClaims: IdentityWithClaims[] = [
{
identity: new Identity({ did }, context),
identity: entityMockUtils.getIdentityInstance({ did }),
claims: [
{
...claim,
Expand Down Expand Up @@ -573,13 +581,13 @@ describe('Claims Class', () => {
const scope: Scope = { type: ScopeType.Ticker, value: 'someValue' };
const date = 1589816265000;
const claim = {
target: new Identity({ did }, context),
issuer: new Identity({ did: issuerDid }, context),
target: entityMockUtils.getIdentityInstance({ did }),
issuer: entityMockUtils.getIdentityInstance({ did: issuerDid }),
issuedAt: new Date(date),
};
const fakeClaims: IdentityWithClaims[] = [
{
identity: new Identity({ did }, context),
identity: entityMockUtils.getIdentityInstance({ did }),
claims: [
{
...claim,
Expand Down

0 comments on commit d861221

Please sign in to comment.