Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change NodeId from encoded string to an opaque alias of Id which is a typed array from js-id #318

Merged
merged 1 commit into from
Jan 28, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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(),
CMCDragonkai marked this conversation as resolved.
Show resolved Hide resolved
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