Skip to content

Commit

Permalink
feat(trusted claim issuers): require trusted claim types on claimissuers
Browse files Browse the repository at this point in the history
Methods that modify default trusted claim issuers for a token now require passing Claim Types for
which that issuer is trusted

BREAKING CHANGE: - `TrustedClaimIssuers.set` and `TrustedClaimIssuers.add` now require an array of
`TrustedClaimIssuer` objects (each with an identity and an array of ClaimTypes)
  • Loading branch information
monitz87 committed Dec 2, 2020
1 parent 7f75d2f commit 2ed32a2
Show file tree
Hide file tree
Showing 10 changed files with 315 additions and 73 deletions.
6 changes: 3 additions & 3 deletions src/api/entities/DefaultTrustedClaimIssuer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export interface UniqueIdentifiers {
}

export interface Params {
trustedFor?: ClaimType[];
trustedFor: ClaimType[] | null;
}

/**
Expand All @@ -36,7 +36,7 @@ export class DefaultTrustedClaimIssuer extends Entity<UniqueIdentifiers> {
public identity: Identity;

/**
* claim types for which this Claim Issuer is trusted. A null value means all claim types are trusted
* claim types for which this Claim Issuer is trusted. A null value means that the issuer is trusted for all claim types
*/
public trustedFor: ClaimType[] | null;

Expand All @@ -49,7 +49,7 @@ export class DefaultTrustedClaimIssuer extends Entity<UniqueIdentifiers> {
* @hidden
*/
public constructor(args: UniqueIdentifiers & Params, context: Context) {
const { trustedFor = null, ...identifiers } = args;
const { trustedFor, ...identifiers } = args;

super(identifiers, context);

Expand Down
22 changes: 15 additions & 7 deletions src/api/entities/SecurityToken/Compliance/TrustedClaimIssuers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,8 @@ import { TrustedIssuer } from 'polymesh-types/types';
import {
DefaultTrustedClaimIssuer,
modifyTokenTrustedClaimIssuers,
ModifyTokenTrustedClaimIssuersParams,
ModifyTokenTrustedClaimIssuersAddSetParams,
ModifyTokenTrustedClaimIssuersRemoveParams,
Namespace,
SecurityToken,
TransactionQueue,
Expand All @@ -23,7 +24,9 @@ export class TrustedClaimIssuers extends Namespace<SecurityToken> {
*
* @param args.claimIssuerDids - array of Identity IDs of the default Trusted Claim Issuers
*/
public set(args: ModifyTokenTrustedClaimIssuersParams): Promise<TransactionQueue<SecurityToken>> {
public set(
args: ModifyTokenTrustedClaimIssuersAddSetParams
): Promise<TransactionQueue<SecurityToken>> {
const {
parent: { ticker },
context,
Expand All @@ -37,9 +40,11 @@ export class TrustedClaimIssuers extends Namespace<SecurityToken> {
/**
* Add the supplied Identities to the Security Token's list of trusted claim issuers
*
* @param args.claimIssuerDids - array of Identity IDs of the default claim issuers
* @param args.claimIssuers - array of [[TrustedClaimIssuer | Trusted Claim Issuers]]
*/
public add(args: ModifyTokenTrustedClaimIssuersParams): Promise<TransactionQueue<SecurityToken>> {
public add(
args: ModifyTokenTrustedClaimIssuersAddSetParams
): Promise<TransactionQueue<SecurityToken>> {
const {
parent: { ticker },
context,
Expand All @@ -53,10 +58,10 @@ export class TrustedClaimIssuers extends Namespace<SecurityToken> {
/**
* Remove the supplied Identities from the Security Token's list of trusted claim issuers *
*
* @param args.claimIssuerDids - array of Identity IDs of the default claim issuers
* @param args.claimIssuers - array of Identities (or DIDs) of the default claim issuers
*/
public remove(
args: ModifyTokenTrustedClaimIssuersParams
args: ModifyTokenTrustedClaimIssuersRemoveParams
): Promise<TransactionQueue<SecurityToken>> {
const {
parent: { ticker },
Expand Down Expand Up @@ -95,7 +100,10 @@ export class TrustedClaimIssuers extends Namespace<SecurityToken> {
const assembleResult = (issuers: TrustedIssuer[]): DefaultTrustedClaimIssuer[] =>
issuers.map(
({ issuer }) =>
new DefaultTrustedClaimIssuer({ did: identityIdToString(issuer), ticker }, context)
new DefaultTrustedClaimIssuer(
{ did: identityIdToString(issuer), ticker, trustedFor: null },
context
)
);

if (callback) {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { Ticker, TrustedIssuer } from 'polymesh-types/types';
import sinon from 'sinon';

import { ModifyTokenTrustedClaimIssuersAddSetParams } from '~/api/procedures/modifyTokenTrustedClaimIssuers';
import {
Context,
DefaultTrustedClaimIssuer,
Expand Down Expand Up @@ -48,8 +49,11 @@ describe('TrustedClaimIssuers class', () => {
const token = entityMockUtils.getSecurityTokenInstance();
const trustedClaimIssuers = new TrustedClaimIssuers(token, context);

const args = {
claimIssuerIdentities: ['someDid', 'otherDid'],
const args: ModifyTokenTrustedClaimIssuersAddSetParams = {
claimIssuers: [
{ identity: entityMockUtils.getIdentityInstance({ did: 'someDid' }), trustedFor: null },
{ identity: entityMockUtils.getIdentityInstance({ did: 'otherDid' }), trustedFor: null },
],
};

const expectedQueue = ('someQueue' as unknown) as TransactionQueue<SecurityToken>;
Expand Down Expand Up @@ -80,8 +84,11 @@ describe('TrustedClaimIssuers class', () => {
const token = entityMockUtils.getSecurityTokenInstance();
const trustedClaimIssuers = new TrustedClaimIssuers(token, context);

const args = {
claimIssuerIdentities: ['someDid', 'otherDid'],
const args: ModifyTokenTrustedClaimIssuersAddSetParams = {
claimIssuers: [
{ identity: entityMockUtils.getIdentityInstance({ did: 'someDid' }), trustedFor: null },
{ identity: entityMockUtils.getIdentityInstance({ did: 'otherDid' }), trustedFor: null },
],
};

const expectedQueue = ('someQueue' as unknown) as TransactionQueue<SecurityToken>;
Expand Down Expand Up @@ -113,7 +120,7 @@ describe('TrustedClaimIssuers class', () => {
const trustedClaimIssuers = new TrustedClaimIssuers(token, context);

const args = {
claimIssuerIdentities: ['someDid', 'otherDid'],
claimIssuers: ['someDid', 'otherDid'],
};

const expectedQueue = ('someQueue' as unknown) as TransactionQueue<SecurityToken>;
Expand Down Expand Up @@ -161,7 +168,9 @@ describe('TrustedClaimIssuers class', () => {
claimIssuers = [];

expectedDids.forEach(did => {
expectedTrustedClaimIssuers.push(new DefaultTrustedClaimIssuer({ did, ticker }, context));
expectedTrustedClaimIssuers.push(
new DefaultTrustedClaimIssuer({ did, ticker, trustedFor: null }, context)
);
claimIssuers.push(
dsMockUtils.createMockTrustedIssuer({
issuer: dsMockUtils.createMockIdentityId(did),
Expand Down
15 changes: 12 additions & 3 deletions src/api/entities/__tests__/DefaultTrustedClaimIssuer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,10 @@ describe('DefaultTrustedClaimIssuer class', () => {
const did = 'someDid';
const ticker = 'SOMETICKER';
const identity = new Identity({ did }, context);
const trustedClaimIssuer = new DefaultTrustedClaimIssuer({ did, ticker }, context);
const trustedClaimIssuer = new DefaultTrustedClaimIssuer(
{ did, ticker, trustedFor: null },
context
);

expect(trustedClaimIssuer.ticker).toBe(ticker);
expect(trustedClaimIssuer.identity).toEqual(identity);
Expand Down Expand Up @@ -68,7 +71,10 @@ describe('DefaultTrustedClaimIssuer class', () => {
const blockDate = new Date('4/14/2020');
const eventIdx = 1;
const fakeResult = { blockNumber, blockDate, eventIndex: eventIdx };
const trustedClaimIssuer = new DefaultTrustedClaimIssuer({ did, ticker }, context);
const trustedClaimIssuer = new DefaultTrustedClaimIssuer(
{ did, ticker, trustedFor: null },
context
);

dsMockUtils.createApolloQueryStub(eventByIndexedArgs(variables), {
/* eslint-disable @typescript-eslint/camelcase */
Expand All @@ -86,7 +92,10 @@ describe('DefaultTrustedClaimIssuer class', () => {
});

test('should return null if the query result is empty', async () => {
const trustedClaimIssuer = new DefaultTrustedClaimIssuer({ did, ticker }, context);
const trustedClaimIssuer = new DefaultTrustedClaimIssuer(
{ did, ticker, trustedFor: null },
context
);

dsMockUtils.createApolloQueryStub(eventByIndexedArgs(variables), {});
const result = await trustedClaimIssuer.addedAt();
Expand Down
41 changes: 29 additions & 12 deletions src/api/procedures/__tests__/modifyTokenTrustedClaimIssuers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,11 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
let identityIdToStringStub: sinon.SinonStub<[IdentityId], string>;
let trustedClaimIssuerStub: sinon.SinonStub;
let ticker: string;
let claimIssuerIdentities: string[];
let claimIssuerDids: string[];
let claimIssuers: TrustedClaimIssuer[];
let rawTicker: Ticker;
let rawClaimIssuers: TrustedIssuer[];
let args: Omit<Params, 'operation'>;
let args: Omit<Omit<Params, 'operation'>, 'claimIssuers'>;

beforeAll(() => {
dsMockUtils.initMocks();
Expand All @@ -40,9 +41,13 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
);
identityIdToStringStub = sinon.stub(utilsConversionModule, 'identityIdToString');
ticker = 'someTicker';
claimIssuerIdentities = ['aDid', 'otherDid', 'differentDid'];
claimIssuerDids = ['aDid', 'otherDid', 'differentDid'];
claimIssuers = claimIssuerDids.map(did => ({
identity: new Identity({ did }, mockContext),
trustedFor: null,
}));
rawTicker = dsMockUtils.createMockTicker(ticker);
rawClaimIssuers = claimIssuerIdentities.map(did =>
rawClaimIssuers = claimIssuerDids.map(did =>
dsMockUtils.createMockTrustedIssuer({
issuer: dsMockUtils.createMockIdentityId(did),
// eslint-disable-next-line @typescript-eslint/camelcase
Expand All @@ -51,7 +56,6 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
);
args = {
ticker,
claimIssuerIdentities,
};
});

Expand Down Expand Up @@ -83,11 +87,11 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
mockContext = dsMockUtils.getContextInstance();

stringToTickerStub.withArgs(ticker, mockContext).returns(rawTicker);
claimIssuerIdentities.forEach((did, index) => {
claimIssuers.forEach((issuer, index) => {
trustedClaimIssuerToTrustedIssuerStub
.withArgs({ identity: new Identity({ did }, mockContext) }, mockContext)
.withArgs(issuer, mockContext)
.returns(rawClaimIssuers[index]);
identityIdToStringStub.withArgs(rawClaimIssuers[index].issuer).returns(did);
identityIdToStringStub.withArgs(rawClaimIssuers[index].issuer).returns(issuer.identity.did);
});
});

Expand All @@ -110,13 +114,14 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
return expect(
prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers,
operation: TrustedClaimIssuerOperation.Set,
})
).rejects.toThrow('The supplied claim issuer list is equal to the current one');
});

test("should throw an error if some of the supplied dids don't exist", async () => {
const nonExistentDid = claimIssuerIdentities[1];
const nonExistentDid = claimIssuerDids[1];
dsMockUtils.configureMocks({ contextOptions: { invalidDids: [nonExistentDid] } });
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(mockContext);

Expand All @@ -125,6 +130,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
try {
await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers,
operation: TrustedClaimIssuerOperation.Set,
});
} catch (err) {
Expand All @@ -142,6 +148,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {

const result = await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers,
operation: TrustedClaimIssuerOperation.Set,
});

Expand All @@ -165,6 +172,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {

const result = await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers,
operation: TrustedClaimIssuerOperation.Set,
});

Expand All @@ -185,8 +193,8 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {

const result = await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers: [],
operation: TrustedClaimIssuerOperation.Set,
claimIssuerIdentities: [],
});

sinon.assert.calledWith(
Expand All @@ -209,6 +217,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
try {
await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers: claimIssuerDids,
operation: TrustedClaimIssuerOperation.Remove,
});
} catch (err) {
Expand All @@ -218,16 +227,22 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
expect(error.message).toBe(
'One or more of the supplied Identities are not Trusted Claim Issuers'
);
expect(error.data).toMatchObject({ notPresent: args.claimIssuerIdentities });
expect(error.data).toMatchObject({ notPresent: claimIssuerDids });
});

test('should add a transaction to remove the supplied Trusted Claim Issuers (remove)', async () => {
const currentClaimIssuers = rawClaimIssuers;
trustedClaimIssuerStub.withArgs(rawTicker).returns(currentClaimIssuers);
const proc = procedureMockUtils.getInstance<Params, SecurityToken>(mockContext);
claimIssuerDids.forEach((did, index) => {
trustedClaimIssuerToTrustedIssuerStub
.withArgs(sinon.match({ identity: sinon.match({ did }) }), mockContext)
.returns(rawClaimIssuers[index]);
});

const result = await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers: claimIssuerDids,
operation: TrustedClaimIssuerOperation.Remove,
});

Expand All @@ -250,6 +265,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
try {
await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers,
operation: TrustedClaimIssuerOperation.Add,
});
} catch (err) {
Expand All @@ -259,7 +275,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {
expect(error.message).toBe(
'One or more of the supplied Identities already are Trusted Claim Issuers'
);
expect(error.data).toMatchObject({ present: args.claimIssuerIdentities });
expect(error.data).toMatchObject({ present: claimIssuerDids });
});

test('should add a transaction to add the supplied Trusted Claim Issuers (add)', async () => {
Expand All @@ -269,6 +285,7 @@ describe('modifyTokenTrustedClaimIssuers procedure', () => {

const result = await prepareModifyTokenTrustedClaimIssuers.call(proc, {
...args,
claimIssuers,
operation: TrustedClaimIssuerOperation.Add,
});

Expand Down

0 comments on commit 2ed32a2

Please sign in to comment.