Skip to content

Commit a54598e

Browse files
authored
Merge pull request #321 from MatrixAI/nodeidfixes
General Data Validation - Boundary IO locations should be doing data validation and marshalling (and the decommissioning of GenericIdTypes for all IDs)
2 parents e7f13eb + cf54df9 commit a54598e

File tree

151 files changed

+2094
-824
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

151 files changed

+2094
-824
lines changed

src/acl/ACL.ts

Lines changed: 37 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,23 @@
1-
import type { Permission, VaultActions, PermissionIdString } from './types';
1+
import type {
2+
PermissionId,
3+
PermissionIdString,
4+
Permission,
5+
VaultActions,
6+
} from './types';
27
import type { DB, DBLevel, DBOp } from '@matrixai/db';
38
import type { NodeId } from '../nodes/types';
49
import type { GestaltAction } from '../gestalts/types';
510
import type { VaultAction, VaultId } from '../vaults/types';
611
import type { Ref } from '../types';
7-
812
import { Mutex } from 'async-mutex';
913
import Logger from '@matrixai/logger';
10-
import { IdInternal, utils as idUtils } from '@matrixai/id';
14+
import { IdInternal } from '@matrixai/id';
1115
import {
1216
CreateDestroyStartStop,
1317
ready,
1418
} from '@matrixai/async-init/dist/CreateDestroyStartStop';
1519
import * as aclUtils from './utils';
1620
import * as aclErrors from './errors';
17-
import { makePermissionId } from './utils';
1821

1922
interface ACL extends CreateDestroyStartStop {}
2023
@CreateDestroyStartStop(
@@ -49,6 +52,7 @@ class ACL {
4952
protected aclNodesDb: DBLevel;
5053
protected aclVaultsDb: DBLevel;
5154
protected lock: Mutex = new Mutex();
55+
protected generatePermId: () => PermissionId;
5256

5357
constructor({ db, logger }: { db: DB; logger: Logger }) {
5458
this.logger = logger;
@@ -81,6 +85,7 @@ class ACL {
8185
this.aclPermsDb = aclPermsDb;
8286
this.aclNodesDb = aclNodesDb;
8387
this.aclVaultsDb = aclVaultsDb;
88+
this.generatePermId = aclUtils.createPermIdGenerator();
8489
this.logger.info(`Started ${this.constructor.name}`);
8590
}
8691

@@ -155,9 +160,9 @@ class ACL {
155160
Record<NodeId, Permission>
156161
> = {};
157162
for await (const o of this.aclNodesDb.createReadStream()) {
158-
const nodeId = IdInternal.create<NodeId>((o as any).key);
163+
const nodeId = IdInternal.fromBuffer<NodeId>((o as any).key);
159164
const data = (o as any).value as Buffer;
160-
const permId = makePermissionId(
165+
const permId = IdInternal.fromBuffer<PermissionId>(
161166
await this.db.deserializeDecrypt(data, true),
162167
);
163168
let nodePerm: Record<NodeId, Permission>;
@@ -174,7 +179,7 @@ class ACL {
174179
} else {
175180
const permRef = (await this.db.get(
176181
this.aclPermsDbDomain,
177-
idUtils.toBuffer(permId),
182+
permId.toBuffer(),
178183
)) as Ref<Permission>;
179184
nodePerm = { [nodeId]: permRef.object };
180185
permIds[permId] = nodePerm;
@@ -235,7 +240,7 @@ class ACL {
235240
ops.push({
236241
type: 'put',
237242
domain: this.aclVaultsDbDomain,
238-
key: idUtils.toBuffer(vaultId),
243+
key: vaultId.toBuffer(),
239244
value: nodeIds,
240245
});
241246
}
@@ -281,7 +286,7 @@ class ACL {
281286
return await this._transaction(async () => {
282287
const nodeIds = await this.db.get<Record<NodeId, null>>(
283288
this.aclVaultsDbDomain,
284-
idUtils.toBuffer(vaultId),
289+
vaultId.toBuffer(),
285290
);
286291
if (nodeIds == null) {
287292
return {};
@@ -316,11 +321,7 @@ class ACL {
316321
for (const nodeId of nodeIdsGc) {
317322
delete nodeIds[nodeId];
318323
}
319-
await this.db.put(
320-
this.aclVaultsDbDomain,
321-
idUtils.toBuffer(vaultId),
322-
nodeIds,
323-
);
324+
await this.db.put(this.aclVaultsDbDomain, vaultId.toBuffer(), nodeIds);
324325
}
325326
return perms;
326327
});
@@ -339,7 +340,7 @@ class ACL {
339340
);
340341
const ops: Array<DBOp> = [];
341342
if (permId == null) {
342-
const permId = await aclUtils.generatePermId();
343+
const permId = await this.generatePermId();
343344
const permRef = {
344345
count: 1,
345346
object: {
@@ -353,14 +354,14 @@ class ACL {
353354
{
354355
type: 'put',
355356
domain: this.aclPermsDbDomain,
356-
key: idUtils.toBuffer(permId),
357+
key: permId.toBuffer(),
357358
value: permRef,
358359
},
359360
{
360361
type: 'put',
361362
domain: this.aclNodesDbDomain,
362363
key: nodeId.toBuffer(),
363-
value: idUtils.toBuffer(permId),
364+
value: permId.toBuffer(),
364365
raw: true,
365366
},
366367
);
@@ -414,7 +415,7 @@ class ACL {
414415
const nodeIds =
415416
(await this.db.get<Record<NodeId, null>>(
416417
this.aclVaultsDbDomain,
417-
idUtils.toBuffer(vaultId),
418+
vaultId.toBuffer(),
418419
)) ?? {};
419420
const permId = await this.db.get(
420421
this.aclNodesDbDomain,
@@ -452,7 +453,7 @@ class ACL {
452453
{
453454
type: 'put',
454455
domain: this.aclVaultsDbDomain,
455-
key: idUtils.toBuffer(vaultId),
456+
key: vaultId.toBuffer(),
456457
value: nodeIds,
457458
},
458459
];
@@ -469,7 +470,7 @@ class ACL {
469470
await this._transaction(async () => {
470471
const nodeIds = await this.db.get<Record<NodeId, null>>(
471472
this.aclVaultsDbDomain,
472-
idUtils.toBuffer(vaultId),
473+
vaultId.toBuffer(),
473474
);
474475
if (nodeIds == null || !(nodeId in nodeIds)) {
475476
return;
@@ -527,48 +528,48 @@ class ACL {
527528
if (permIdBuffer == null) {
528529
continue;
529530
}
530-
const permId = makePermissionId(permIdBuffer);
531+
const permId = IdInternal.fromBuffer<PermissionId>(permIdBuffer);
531532
permIdCounts[permId] = (permIdCounts[permId] ?? 0) + 1;
532533
}
533534
for (const permIdString in permIdCounts) {
534-
const permId = makePermissionId(idUtils.fromString(permIdString));
535+
const permId = IdInternal.fromString<PermissionId>(permIdString);
535536
const permRef = (await this.db.get(
536537
this.aclPermsDbDomain,
537-
idUtils.toBuffer(permId),
538+
permId.toBuffer(),
538539
)) as Ref<Permission>;
539540
permRef.count = permRef.count - permIdCounts[permId];
540541
if (permRef.count === 0) {
541542
ops.push({
542543
type: 'del',
543544
domain: this.aclPermsDbDomain,
544-
key: idUtils.toBuffer(permId),
545+
key: permId.toBuffer(),
545546
});
546547
} else {
547548
ops.push({
548549
type: 'put',
549550
domain: this.aclPermsDbDomain,
550-
key: idUtils.toBuffer(permId),
551+
key: permId.toBuffer(),
551552
value: permRef,
552553
});
553554
}
554555
}
555-
const permId = await aclUtils.generatePermId();
556+
const permId = await this.generatePermId();
556557
const permRef = {
557558
count: nodeIds.length,
558559
object: perm,
559560
};
560561
ops.push({
561562
domain: this.aclPermsDbDomain,
562563
type: 'put',
563-
key: idUtils.toBuffer(permId),
564+
key: permId.toBuffer(),
564565
value: permRef,
565566
});
566567
for (const nodeId of nodeIds) {
567568
ops.push({
568569
domain: this.aclNodesDbDomain,
569570
type: 'put',
570571
key: nodeId.toBuffer(),
571-
value: idUtils.toBuffer(permId),
572+
value: permId.toBuffer(),
572573
raw: true,
573574
});
574575
}
@@ -595,7 +596,7 @@ class ACL {
595596
);
596597
const ops: Array<DBOp> = [];
597598
if (permId == null) {
598-
const permId = await aclUtils.generatePermId();
599+
const permId = await this.generatePermId();
599600
const permRef = {
600601
count: 1,
601602
object: perm,
@@ -604,14 +605,14 @@ class ACL {
604605
{
605606
type: 'put',
606607
domain: this.aclPermsDbDomain,
607-
key: idUtils.toBuffer(permId),
608+
key: permId.toBuffer(),
608609
value: permRef,
609610
},
610611
{
611612
type: 'put',
612613
domain: this.aclNodesDbDomain,
613614
key: nodeId.toBuffer(),
614-
value: idUtils.toBuffer(permId),
615+
value: permId.toBuffer(),
615616
raw: true,
616617
},
617618
);
@@ -685,7 +686,7 @@ class ACL {
685686
await this._transaction(async () => {
686687
const nodeIds = await this.db.get<Record<NodeId, null>>(
687688
this.aclVaultsDbDomain,
688-
idUtils.toBuffer(vaultId),
689+
vaultId.toBuffer(),
689690
);
690691
if (nodeIds == null) {
691692
return;
@@ -718,7 +719,7 @@ class ACL {
718719
ops.push({
719720
type: 'del',
720721
domain: this.aclVaultsDbDomain,
721-
key: idUtils.toBuffer(vaultId),
722+
key: vaultId.toBuffer(),
722723
});
723724
await this.db.batch(ops);
724725
});
@@ -825,7 +826,7 @@ class ACL {
825826
): Promise<Array<DBOp>> {
826827
const nodeIds = await this.db.get<Record<NodeId, null>>(
827828
this.aclVaultsDbDomain,
828-
idUtils.toBuffer(vaultId),
829+
vaultId.toBuffer(),
829830
);
830831
if (nodeIds == null) {
831832
throw new aclErrors.ErrorACLVaultIdMissing();
@@ -869,7 +870,7 @@ class ACL {
869870
ops.push({
870871
type: 'put',
871872
domain: this.aclVaultsDbDomain,
872-
key: idUtils.toBuffer(vaultIdJoin),
873+
key: vaultIdJoin.toBuffer(),
873874
value: nodeIds,
874875
});
875876
}
@@ -881,7 +882,7 @@ class ACL {
881882
ops.push({
882883
type: 'put',
883884
domain: this.aclVaultsDbDomain,
884-
key: idUtils.toBuffer(vaultId),
885+
key: vaultId.toBuffer(),
885886
value: nodeIds,
886887
});
887888
}

src/acl/types.ts

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,10 @@
11
import type { Opaque } from '../types';
22
import type { GestaltAction } from '../gestalts/types';
33
import type { VaultActions, VaultId } from '../vaults/types';
4-
import type { Id, IdString } from '../GenericIdTypes';
4+
import type { Id } from '@matrixai/id';
55

66
type PermissionId = Opaque<'PermissionId', Id>;
7-
8-
type PermissionIdString = Opaque<'PermissionIdString', IdString>;
7+
type PermissionIdString = Opaque<'PermissionIdString', string>;
98

109
type Permission = {
1110
gestalt: GestaltActions;

src/acl/utils.ts

Lines changed: 5 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,9 @@
1-
import type { Permission, PermissionId, PermissionIdString } from './types';
2-
1+
import type { Permission, PermissionId } from './types';
32
import { IdRandom } from '@matrixai/id';
4-
import { isIdString, isId, makeIdString, makeId } from '../GenericIdTypes';
5-
6-
function isPermissionId(arg: any): arg is PermissionId {
7-
return isId<PermissionId>(arg);
8-
}
9-
10-
function makePermissionId(arg: any) {
11-
return makeId<PermissionId>(arg);
12-
}
13-
14-
function isPermissionIdString(arg: any): arg is PermissionIdString {
15-
return isIdString<PermissionIdString>(arg);
16-
}
17-
18-
function makePermissionIdString(arg: any) {
19-
return makeIdString<PermissionIdString>(arg);
20-
}
213

22-
const randomIdGenerator = new IdRandom();
23-
async function generatePermId(): Promise<PermissionId> {
24-
return makePermissionId(randomIdGenerator.get());
4+
function createPermIdGenerator() {
5+
const generator = new IdRandom<PermissionId>();
6+
return () => generator.get();
257
}
268

279
function permUnion(perm1: Permission, perm2: Permission): Permission {
@@ -44,11 +26,4 @@ function permUnion(perm1: Permission, perm2: Permission): Permission {
4426
return perm;
4527
}
4628

47-
export {
48-
generatePermId,
49-
permUnion,
50-
isPermissionId,
51-
makePermissionId,
52-
isPermissionIdString,
53-
makePermissionIdString,
54-
};
29+
export { createPermIdGenerator, permUnion };

src/agent/service/nodesChainDataGet.ts

Lines changed: 8 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import type * as grpc from '@grpc/grpc-js';
2-
import type { ClaimIdString } from '../../claims/types';
2+
import type { ClaimIdEncoded } from '../../claims/types';
33
import type { NodeManager } from '../../nodes';
44
import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';
55
import { utils as grpcUtils } from '../../grpc';
@@ -13,12 +13,12 @@ function nodesChainDataGet({ nodeManager }: { nodeManager: NodeManager }) {
1313
call: grpc.ServerUnaryCall<utilsPB.EmptyMessage, nodesPB.ChainData>,
1414
callback: grpc.sendUnaryData<nodesPB.ChainData>,
1515
): Promise<void> => {
16-
const response = new nodesPB.ChainData();
1716
try {
17+
const response = new nodesPB.ChainData();
1818
const chainData = await nodeManager.getChainData();
1919
// Iterate through each claim in the chain, and serialize for transport
2020
for (const c in chainData) {
21-
const claimId = c as ClaimIdString;
21+
const claimId = c as ClaimIdEncoded;
2222
const claim = chainData[claimId];
2323
const claimMessage = new nodesPB.AgentClaim();
2424
// Will always have a payload (never undefined) so cast as string
@@ -34,10 +34,12 @@ function nodesChainDataGet({ nodeManager }: { nodeManager: NodeManager }) {
3434
// Add the serialized claim
3535
response.getChainDataMap().set(claimId, claimMessage);
3636
}
37-
} catch (err) {
38-
callback(grpcUtils.fromError(err), response);
37+
callback(null, response);
38+
return;
39+
} catch (e) {
40+
callback(grpcUtils.fromError(e));
41+
return;
3942
}
40-
callback(null, response);
4143
};
4244
}
4345

0 commit comments

Comments
 (0)