Skip to content

Commit

Permalink
Merge pull request #321 from MatrixAI/nodeidfixes
Browse files Browse the repository at this point in the history
General Data Validation - Boundary IO locations should be doing data validation and marshalling (and the decommissioning of GenericIdTypes for all IDs)
  • Loading branch information
CMCDragonkai committed Feb 7, 2022
2 parents e7f13eb + cf54df9 commit a54598e
Show file tree
Hide file tree
Showing 151 changed files with 2,094 additions and 824 deletions.
73 changes: 37 additions & 36 deletions src/acl/ACL.ts
Original file line number Diff line number Diff line change
@@ -1,20 +1,23 @@
import type { Permission, VaultActions, PermissionIdString } from './types';
import type {
PermissionId,
PermissionIdString,
Permission,
VaultActions,
} from './types';
import type { DB, DBLevel, DBOp } from '@matrixai/db';
import type { NodeId } from '../nodes/types';
import type { GestaltAction } from '../gestalts/types';
import type { VaultAction, VaultId } from '../vaults/types';
import type { Ref } from '../types';

import { Mutex } from 'async-mutex';
import Logger from '@matrixai/logger';
import { IdInternal, utils as idUtils } from '@matrixai/id';
import { IdInternal } from '@matrixai/id';
import {
CreateDestroyStartStop,
ready,
} from '@matrixai/async-init/dist/CreateDestroyStartStop';
import * as aclUtils from './utils';
import * as aclErrors from './errors';
import { makePermissionId } from './utils';

interface ACL extends CreateDestroyStartStop {}
@CreateDestroyStartStop(
Expand Down Expand Up @@ -49,6 +52,7 @@ class ACL {
protected aclNodesDb: DBLevel;
protected aclVaultsDb: DBLevel;
protected lock: Mutex = new Mutex();
protected generatePermId: () => PermissionId;

constructor({ db, logger }: { db: DB; logger: Logger }) {
this.logger = logger;
Expand Down Expand Up @@ -81,6 +85,7 @@ class ACL {
this.aclPermsDb = aclPermsDb;
this.aclNodesDb = aclNodesDb;
this.aclVaultsDb = aclVaultsDb;
this.generatePermId = aclUtils.createPermIdGenerator();
this.logger.info(`Started ${this.constructor.name}`);
}

Expand Down Expand Up @@ -155,9 +160,9 @@ class ACL {
Record<NodeId, Permission>
> = {};
for await (const o of this.aclNodesDb.createReadStream()) {
const nodeId = IdInternal.create<NodeId>((o as any).key);
const nodeId = IdInternal.fromBuffer<NodeId>((o as any).key);
const data = (o as any).value as Buffer;
const permId = makePermissionId(
const permId = IdInternal.fromBuffer<PermissionId>(
await this.db.deserializeDecrypt(data, true),
);
let nodePerm: Record<NodeId, Permission>;
Expand All @@ -174,7 +179,7 @@ class ACL {
} else {
const permRef = (await this.db.get(
this.aclPermsDbDomain,
idUtils.toBuffer(permId),
permId.toBuffer(),
)) as Ref<Permission>;
nodePerm = { [nodeId]: permRef.object };
permIds[permId] = nodePerm;
Expand Down Expand Up @@ -235,7 +240,7 @@ class ACL {
ops.push({
type: 'put',
domain: this.aclVaultsDbDomain,
key: idUtils.toBuffer(vaultId),
key: vaultId.toBuffer(),
value: nodeIds,
});
}
Expand Down Expand Up @@ -281,7 +286,7 @@ class ACL {
return await this._transaction(async () => {
const nodeIds = await this.db.get<Record<NodeId, null>>(
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
vaultId.toBuffer(),
);
if (nodeIds == null) {
return {};
Expand Down Expand Up @@ -316,11 +321,7 @@ class ACL {
for (const nodeId of nodeIdsGc) {
delete nodeIds[nodeId];
}
await this.db.put(
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
nodeIds,
);
await this.db.put(this.aclVaultsDbDomain, vaultId.toBuffer(), nodeIds);
}
return perms;
});
Expand All @@ -339,7 +340,7 @@ class ACL {
);
const ops: Array<DBOp> = [];
if (permId == null) {
const permId = await aclUtils.generatePermId();
const permId = await this.generatePermId();
const permRef = {
count: 1,
object: {
Expand All @@ -353,14 +354,14 @@ class ACL {
{
type: 'put',
domain: this.aclPermsDbDomain,
key: idUtils.toBuffer(permId),
key: permId.toBuffer(),
value: permRef,
},
{
type: 'put',
domain: this.aclNodesDbDomain,
key: nodeId.toBuffer(),
value: idUtils.toBuffer(permId),
value: permId.toBuffer(),
raw: true,
},
);
Expand Down Expand Up @@ -414,7 +415,7 @@ class ACL {
const nodeIds =
(await this.db.get<Record<NodeId, null>>(
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
vaultId.toBuffer(),
)) ?? {};
const permId = await this.db.get(
this.aclNodesDbDomain,
Expand Down Expand Up @@ -452,7 +453,7 @@ class ACL {
{
type: 'put',
domain: this.aclVaultsDbDomain,
key: idUtils.toBuffer(vaultId),
key: vaultId.toBuffer(),
value: nodeIds,
},
];
Expand All @@ -469,7 +470,7 @@ class ACL {
await this._transaction(async () => {
const nodeIds = await this.db.get<Record<NodeId, null>>(
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
vaultId.toBuffer(),
);
if (nodeIds == null || !(nodeId in nodeIds)) {
return;
Expand Down Expand Up @@ -527,48 +528,48 @@ class ACL {
if (permIdBuffer == null) {
continue;
}
const permId = makePermissionId(permIdBuffer);
const permId = IdInternal.fromBuffer<PermissionId>(permIdBuffer);
permIdCounts[permId] = (permIdCounts[permId] ?? 0) + 1;
}
for (const permIdString in permIdCounts) {
const permId = makePermissionId(idUtils.fromString(permIdString));
const permId = IdInternal.fromString<PermissionId>(permIdString);
const permRef = (await this.db.get(
this.aclPermsDbDomain,
idUtils.toBuffer(permId),
permId.toBuffer(),
)) as Ref<Permission>;
permRef.count = permRef.count - permIdCounts[permId];
if (permRef.count === 0) {
ops.push({
type: 'del',
domain: this.aclPermsDbDomain,
key: idUtils.toBuffer(permId),
key: permId.toBuffer(),
});
} else {
ops.push({
type: 'put',
domain: this.aclPermsDbDomain,
key: idUtils.toBuffer(permId),
key: permId.toBuffer(),
value: permRef,
});
}
}
const permId = await aclUtils.generatePermId();
const permId = await this.generatePermId();
const permRef = {
count: nodeIds.length,
object: perm,
};
ops.push({
domain: this.aclPermsDbDomain,
type: 'put',
key: idUtils.toBuffer(permId),
key: permId.toBuffer(),
value: permRef,
});
for (const nodeId of nodeIds) {
ops.push({
domain: this.aclNodesDbDomain,
type: 'put',
key: nodeId.toBuffer(),
value: idUtils.toBuffer(permId),
value: permId.toBuffer(),
raw: true,
});
}
Expand All @@ -595,7 +596,7 @@ class ACL {
);
const ops: Array<DBOp> = [];
if (permId == null) {
const permId = await aclUtils.generatePermId();
const permId = await this.generatePermId();
const permRef = {
count: 1,
object: perm,
Expand All @@ -604,14 +605,14 @@ class ACL {
{
type: 'put',
domain: this.aclPermsDbDomain,
key: idUtils.toBuffer(permId),
key: permId.toBuffer(),
value: permRef,
},
{
type: 'put',
domain: this.aclNodesDbDomain,
key: nodeId.toBuffer(),
value: idUtils.toBuffer(permId),
value: permId.toBuffer(),
raw: true,
},
);
Expand Down Expand Up @@ -685,7 +686,7 @@ class ACL {
await this._transaction(async () => {
const nodeIds = await this.db.get<Record<NodeId, null>>(
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
vaultId.toBuffer(),
);
if (nodeIds == null) {
return;
Expand Down Expand Up @@ -718,7 +719,7 @@ class ACL {
ops.push({
type: 'del',
domain: this.aclVaultsDbDomain,
key: idUtils.toBuffer(vaultId),
key: vaultId.toBuffer(),
});
await this.db.batch(ops);
});
Expand Down Expand Up @@ -825,7 +826,7 @@ class ACL {
): Promise<Array<DBOp>> {
const nodeIds = await this.db.get<Record<NodeId, null>>(
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
vaultId.toBuffer(),
);
if (nodeIds == null) {
throw new aclErrors.ErrorACLVaultIdMissing();
Expand Down Expand Up @@ -869,7 +870,7 @@ class ACL {
ops.push({
type: 'put',
domain: this.aclVaultsDbDomain,
key: idUtils.toBuffer(vaultIdJoin),
key: vaultIdJoin.toBuffer(),
value: nodeIds,
});
}
Expand All @@ -881,7 +882,7 @@ class ACL {
ops.push({
type: 'put',
domain: this.aclVaultsDbDomain,
key: idUtils.toBuffer(vaultId),
key: vaultId.toBuffer(),
value: nodeIds,
});
}
Expand Down
5 changes: 2 additions & 3 deletions src/acl/types.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,10 @@
import type { Opaque } from '../types';
import type { GestaltAction } from '../gestalts/types';
import type { VaultActions, VaultId } from '../vaults/types';
import type { Id, IdString } from '../GenericIdTypes';
import type { Id } from '@matrixai/id';

type PermissionId = Opaque<'PermissionId', Id>;

type PermissionIdString = Opaque<'PermissionIdString', IdString>;
type PermissionIdString = Opaque<'PermissionIdString', string>;

type Permission = {
gestalt: GestaltActions;
Expand Down
35 changes: 5 additions & 30 deletions src/acl/utils.ts
Original file line number Diff line number Diff line change
@@ -1,27 +1,9 @@
import type { Permission, PermissionId, PermissionIdString } from './types';

import type { Permission, PermissionId } from './types';
import { IdRandom } from '@matrixai/id';
import { isIdString, isId, makeIdString, makeId } from '../GenericIdTypes';

function isPermissionId(arg: any): arg is PermissionId {
return isId<PermissionId>(arg);
}

function makePermissionId(arg: any) {
return makeId<PermissionId>(arg);
}

function isPermissionIdString(arg: any): arg is PermissionIdString {
return isIdString<PermissionIdString>(arg);
}

function makePermissionIdString(arg: any) {
return makeIdString<PermissionIdString>(arg);
}

const randomIdGenerator = new IdRandom();
async function generatePermId(): Promise<PermissionId> {
return makePermissionId(randomIdGenerator.get());
function createPermIdGenerator() {
const generator = new IdRandom<PermissionId>();
return () => generator.get();
}

function permUnion(perm1: Permission, perm2: Permission): Permission {
Expand All @@ -44,11 +26,4 @@ function permUnion(perm1: Permission, perm2: Permission): Permission {
return perm;
}

export {
generatePermId,
permUnion,
isPermissionId,
makePermissionId,
isPermissionIdString,
makePermissionIdString,
};
export { createPermIdGenerator, permUnion };
14 changes: 8 additions & 6 deletions src/agent/service/nodesChainDataGet.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import type * as grpc from '@grpc/grpc-js';
import type { ClaimIdString } from '../../claims/types';
import type { ClaimIdEncoded } from '../../claims/types';
import type { NodeManager } from '../../nodes';
import type * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';
import { utils as grpcUtils } from '../../grpc';
Expand All @@ -13,12 +13,12 @@ function nodesChainDataGet({ nodeManager }: { nodeManager: NodeManager }) {
call: grpc.ServerUnaryCall<utilsPB.EmptyMessage, nodesPB.ChainData>,
callback: grpc.sendUnaryData<nodesPB.ChainData>,
): Promise<void> => {
const response = new nodesPB.ChainData();
try {
const response = new nodesPB.ChainData();
const chainData = await nodeManager.getChainData();
// Iterate through each claim in the chain, and serialize for transport
for (const c in chainData) {
const claimId = c as ClaimIdString;
const claimId = c as ClaimIdEncoded;
const claim = chainData[claimId];
const claimMessage = new nodesPB.AgentClaim();
// Will always have a payload (never undefined) so cast as string
Expand All @@ -34,10 +34,12 @@ function nodesChainDataGet({ nodeManager }: { nodeManager: NodeManager }) {
// Add the serialized claim
response.getChainDataMap().set(claimId, claimMessage);
}
} catch (err) {
callback(grpcUtils.fromError(err), response);
callback(null, response);
return;
} catch (e) {
callback(grpcUtils.fromError(e));
return;
}
callback(null, response);
};
}

Expand Down
Loading

0 comments on commit a54598e

Please sign in to comment.