Skip to content

Commit

Permalink
Merge pull request #318 from MatrixAI/NodeId_changes
Browse files Browse the repository at this point in the history
Change `NodeId` from encoded string to an opaque alias of `Id` which is a typed array from js-id
  • Loading branch information
tegefaulkes authored Jan 28, 2022
2 parents e2e1cc8 + 733d540 commit e7f13eb
Show file tree
Hide file tree
Showing 103 changed files with 1,578 additions and 1,234 deletions.
6 changes: 3 additions & 3 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@
"@grpc/grpc-js": "1.3.7",
"@matrixai/async-init": "^1.6.0",
"@matrixai/db": "^1.1.2",
"@matrixai/id": "^2.1.0",
"@matrixai/id": "^3.3.0",
"@matrixai/logger": "^2.1.0",
"@matrixai/workers": "^1.2.5",
"ajv": "^7.0.4",
Expand Down
112 changes: 78 additions & 34 deletions src/acl/ACL.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import type { Ref } from '../types';

import { Mutex } from 'async-mutex';
import Logger from '@matrixai/logger';
import { utils as idUtils } from '@matrixai/id';
import { IdInternal, utils as idUtils } from '@matrixai/id';
import {
CreateDestroyStartStop,
ready,
Expand Down Expand Up @@ -130,8 +130,16 @@ class ACL {
nodeId2: NodeId,
): Promise<boolean> {
return await this._transaction(async () => {
const permId1 = await this.db.get(this.aclNodesDbDomain, nodeId1, true);
const permId2 = await this.db.get(this.aclNodesDbDomain, nodeId2, true);
const permId1 = await this.db.get(
this.aclNodesDbDomain,
nodeId1.toBuffer(),
true,
);
const permId2 = await this.db.get(
this.aclNodesDbDomain,
nodeId2.toBuffer(),
true,
);
if (permId1 != null && permId2 != null && permId1 === permId2) {
return true;
}
Expand All @@ -147,7 +155,7 @@ class ACL {
Record<NodeId, Permission>
> = {};
for await (const o of this.aclNodesDb.createReadStream()) {
const nodeId = (o as any).key as NodeId;
const nodeId = IdInternal.create<NodeId>((o as any).key);
const data = (o as any).value as Buffer;
const permId = makePermissionId(
await this.db.deserializeDecrypt(data, true),
Expand Down Expand Up @@ -196,15 +204,16 @@ class ACL {
);
const nodePerm: Record<NodeId, Permission> = {};
const nodeIdsGc: Set<NodeId> = new Set();
for (const nodeId in nodeIds) {
for (const nodeIdString in nodeIds) {
const nodeId: NodeId = IdInternal.fromString(nodeIdString);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId as NodeId,
nodeId.toBuffer(),
true,
);
if (permId == null) {
// Invalid node id
nodeIdsGc.add(nodeId as NodeId);
nodeIdsGc.add(nodeId);
continue;
}
const permRef = (await this.db.get(
Expand All @@ -213,7 +222,7 @@ class ACL {
)) as Ref<Permission>;
if (!(vaultId in permRef.object.vaults)) {
// Vault id is missing from the perm
nodeIdsGc.add(nodeId as NodeId);
nodeIdsGc.add(nodeId);
continue;
}
nodePerm[nodeId] = permRef.object;
Expand Down Expand Up @@ -244,7 +253,11 @@ class ACL {
@ready(new aclErrors.ErrorACLNotRunning())
public async getNodePerm(nodeId: NodeId): Promise<Permission | undefined> {
return await this._transaction(async () => {
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
if (permId == null) {
return;
}
Expand Down Expand Up @@ -275,15 +288,16 @@ class ACL {
}
const perms: Record<NodeId, Permission> = {};
const nodeIdsGc: Set<NodeId> = new Set();
for (const nodeId in nodeIds) {
for (const nodeIdString in nodeIds) {
const nodeId: NodeId = IdInternal.fromString(nodeIdString);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId as NodeId,
nodeId.toBuffer(),
true,
);
if (permId == null) {
// Invalid node id
nodeIdsGc.add(nodeId as NodeId);
nodeIdsGc.add(nodeId);
continue;
}
const permRef = (await this.db.get(
Expand All @@ -292,7 +306,7 @@ class ACL {
)) as Ref<Permission>;
if (!(vaultId in permRef.object.vaults)) {
// Vault id is missing from the perm
nodeIdsGc.add(nodeId as NodeId);
nodeIdsGc.add(nodeId);
continue;
}
perms[nodeId] = permRef.object;
Expand All @@ -318,7 +332,11 @@ class ACL {
action: GestaltAction,
): Promise<void> {
return await this._transaction(async () => {
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
const ops: Array<DBOp> = [];
if (permId == null) {
const permId = await aclUtils.generatePermId();
Expand All @@ -341,7 +359,7 @@ class ACL {
{
type: 'put',
domain: this.aclNodesDbDomain,
key: nodeId,
key: nodeId.toBuffer(),
value: idUtils.toBuffer(permId),
raw: true,
},
Expand Down Expand Up @@ -369,7 +387,11 @@ class ACL {
action: GestaltAction,
): Promise<void> {
return await this._transaction(async () => {
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
if (permId == null) {
return;
}
Expand All @@ -394,7 +416,11 @@ class ACL {
this.aclVaultsDbDomain,
idUtils.toBuffer(vaultId),
)) ?? {};
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
if (permId == null) {
throw new aclErrors.ErrorACLNodeIdMissing();
}
Expand All @@ -419,7 +445,7 @@ class ACL {
{
type: 'put',
domain: this.aclNodesDbDomain,
key: nodeId,
key: nodeId.toBuffer(),
value: permId,
raw: true,
},
Expand Down Expand Up @@ -448,7 +474,11 @@ class ACL {
if (nodeIds == null || !(nodeId in nodeIds)) {
return;
}
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
if (permId == null) {
return;
}
Expand Down Expand Up @@ -491,7 +521,7 @@ class ACL {
for (const nodeId of nodeIds) {
const permIdBuffer = await this.db.get(
this.aclNodesDbDomain,
nodeId,
nodeId.toBuffer(),
true,
);
if (permIdBuffer == null) {
Expand Down Expand Up @@ -537,7 +567,7 @@ class ACL {
ops.push({
domain: this.aclNodesDbDomain,
type: 'put',
key: nodeId,
key: nodeId.toBuffer(),
value: idUtils.toBuffer(permId),
raw: true,
});
Expand All @@ -558,7 +588,11 @@ class ACL {
nodeId: NodeId,
perm: Permission,
): Promise<Array<DBOp>> {
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
const ops: Array<DBOp> = [];
if (permId == null) {
const permId = await aclUtils.generatePermId();
Expand All @@ -576,7 +610,7 @@ class ACL {
{
type: 'put',
domain: this.aclNodesDbDomain,
key: nodeId,
key: nodeId.toBuffer(),
value: idUtils.toBuffer(permId),
raw: true,
},
Expand Down Expand Up @@ -608,7 +642,11 @@ class ACL {

@ready(new aclErrors.ErrorACLNotRunning())
public async unsetNodePermOps(nodeId: NodeId): Promise<Array<DBOp>> {
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
if (permId == null) {
return [];
}
Expand All @@ -635,7 +673,7 @@ class ACL {
ops.push({
type: 'del',
domain: this.aclNodesDbDomain,
key: nodeId,
key: nodeId.toBuffer(),
});
// We do not remove the node id from the vaults
// they can be removed later upon inspection
Expand All @@ -653,10 +691,11 @@ class ACL {
return;
}
const ops: Array<DBOp> = [];
for (const nodeId in nodeIds) {
for (const nodeIdString in nodeIds) {
const nodeId: NodeId = IdInternal.fromString(nodeIdString);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId as NodeId,
nodeId.toBuffer(),
true,
);
// Skip if the nodeId doesn't exist
Expand Down Expand Up @@ -703,7 +742,11 @@ class ACL {
nodeIdsJoin: Array<NodeId>,
perm?: Permission,
): Promise<Array<DBOp>> {
const permId = await this.db.get(this.aclNodesDbDomain, nodeId, true);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId.toBuffer(),
true,
);
if (permId == null) {
throw new aclErrors.ErrorACLNodeIdMissing();
}
Expand All @@ -719,7 +762,7 @@ class ACL {
for (const nodeIdJoin of nodeIdsJoin) {
const permIdJoin = await this.db.get(
this.aclNodesDbDomain,
nodeIdJoin,
nodeIdJoin.toBuffer(),
true,
);
if (permIdJoin === permId) {
Expand Down Expand Up @@ -750,7 +793,7 @@ class ACL {
ops.push({
type: 'put',
domain: this.aclNodesDbDomain,
key: nodeIdJoin,
key: nodeIdJoin.toBuffer(),
value: permId,
raw: true,
});
Expand Down Expand Up @@ -789,15 +832,16 @@ class ACL {
}
const ops: Array<DBOp> = [];
const nodeIdsGc: Set<NodeId> = new Set();
for (const nodeId in nodeIds) {
for (const nodeIdString in nodeIds) {
const nodeId: NodeId = IdInternal.fromString(nodeIdString);
const permId = await this.db.get(
this.aclNodesDbDomain,
nodeId as NodeId,
nodeId.toBuffer(),
true,
);
if (permId == null) {
// Invalid node id
nodeIdsGc.add(nodeId as NodeId);
nodeIdsGc.add(nodeId);
continue;
}
const permRef = (await this.db.get(
Expand All @@ -806,7 +850,7 @@ class ACL {
)) as Ref<Permission>;
if (!(vaultId in permRef.object.vaults)) {
// Vault id is missing from the perm
nodeIdsGc.add(nodeId as NodeId);
nodeIdsGc.add(nodeId);
continue;
}
const vaultActions: VaultActions | undefined =
Expand Down
3 changes: 2 additions & 1 deletion src/agent/GRPCClientAgent.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,8 @@ import type * as notificationsPB from '../proto/js/polykey/v1/notifications/noti
import Logger from '@matrixai/logger';
import { CreateDestroy, ready } from '@matrixai/async-init/dist/CreateDestroy';
import * as agentErrors from './errors';
import { GRPCClient, utils as grpcUtils } from '../grpc';
import * as grpcUtils from '../grpc/utils';
import GRPCClient from '../grpc/GRPCClient';
import { AgentServiceClient } from '../proto/js/polykey/v1/agent_service_grpc_pb';

interface GRPCClientAgent extends CreateDestroy {}
Expand Down
6 changes: 4 additions & 2 deletions src/agent/service/nodesClosestLocalNodesGet.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,15 +19,17 @@ function nodesClosestLocalNodesGet({
): Promise<void> => {
const response = new nodesPB.NodeTable();
try {
const targetNodeId = nodesUtils.makeNodeId(call.request.getNodeId());
const targetNodeId = nodesUtils.decodeNodeId(call.request.getNodeId());
// Get all local nodes that are closest to the target node from the request
const closestNodes = await nodeManager.getClosestLocalNodes(targetNodeId);
for (const node of closestNodes) {
const addressMessage = new nodesPB.Address();
addressMessage.setHost(node.address.host);
addressMessage.setPort(node.address.port);
// Add the node to the response's map (mapping of node ID -> node address)
response.getNodeTableMap().set(node.id, addressMessage);
response
.getNodeTableMap()
.set(nodesUtils.encodeNodeId(node.id), addressMessage);
}
} catch (err) {
callback(grpcUtils.fromError(err), response);
Expand Down
7 changes: 4 additions & 3 deletions src/agent/service/nodesCrossSignClaim.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import type { KeyManager } from '../../keys';
import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb';
import { utils as grpcUtils } from '../../grpc';
import { utils as claimsUtils, errors as claimsErrors } from '../../claims';
import { utils as nodesUtils } from '../../nodes';

function nodesCrossSignClaim({
keyManager,
Expand Down Expand Up @@ -66,7 +67,7 @@ function nodesCrossSignClaim({
}
// Verify the claim
const senderPublicKey = await nodeManager.getPublicKey(
payloadData.node1,
nodesUtils.decodeNodeId(payloadData.node1),
);
const verified = await claimsUtils.verifyClaimSignature(
constructedEncodedClaim,
Expand All @@ -79,12 +80,12 @@ function nodesCrossSignClaim({
const doublySignedClaim = await claimsUtils.signIntermediaryClaim({
claim: constructedIntermediaryClaim,
privateKey: keyManager.getRootKeyPairPem().privateKey,
signeeNodeId: nodeManager.getNodeId(),
signeeNodeId: nodesUtils.encodeNodeId(nodeManager.getNodeId()),
});
// Then create your own intermediary node claim (from X -> Y)
const singlySignedClaim = await sigchain.createIntermediaryClaim({
type: 'node',
node1: nodeManager.getNodeId(),
node1: nodesUtils.encodeNodeId(nodeManager.getNodeId()),
node2: payloadData.node1,
});
// Should never be reached, but just for type safety
Expand Down
Loading

0 comments on commit e7f13eb

Please sign in to comment.