Skip to content

Commit 2d89fd4

Browse files
committed
WIP - #305
1 parent 3b72275 commit 2d89fd4

26 files changed

+2784
-1508
lines changed

src/PolykeyAgent.ts

-1
Original file line numberDiff line numberDiff line change
@@ -327,7 +327,6 @@ class PolykeyAgent {
327327
vaultsPath,
328328
keyManager,
329329
nodeConnectionManager,
330-
nodeManager,
331330
notificationsManager,
332331
gestaltGraph,
333332
acl,

src/acl/types.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ type PermissionIdString = Opaque<'PermissionIdString', string>;
88

99
type Permission = {
1010
gestalt: GestaltActions;
11-
vaults: Record<VaultId | string, VaultActions>; // FIXME: the string union on VaultId is to prevent some false errors.
11+
vaults: Record<VaultId, VaultActions>;
1212
};
1313

1414
type GestaltActions = Partial<Record<GestaltAction, null>>;

src/agent/service/vaultsGitInfoGet.ts

+31-23
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
import type { VaultName } from '../../vaults/types';
22
import type { VaultManager } from '../../vaults';
33
import type { ACL } from '../../acl';
4+
import type { ConnectionInfoGetter } from '../../agent/types';
45
import * as grpc from '@grpc/grpc-js';
5-
import { utils as idUtils } from '@matrixai/id';
66
import { utils as grpcUtils } from '../../grpc';
77
import { utils as vaultsUtils, errors as vaultsErrors } from '../../vaults';
88
import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
99
import * as validationUtils from '../../validation/utils';
10+
import * as nodesUtils from '../../nodes/utils';
11+
import { never } from '../../utils/utils';
1012

1113
function vaultsGitInfoGet({
1214
vaultManager,
1315
acl,
16+
connectionInfoGetter,
1417
}: {
1518
vaultManager: VaultManager;
1619
acl: ACL;
20+
connectionInfoGetter: ConnectionInfoGetter;
1721
}) {
1822
return async (
1923
call: grpc.ServerWritableStream<vaultsPB.InfoRequest, vaultsPB.PackChunk>,
@@ -25,42 +29,46 @@ function vaultsGitInfoGet({
2529
await genWritable.throw({ code: grpc.status.NOT_FOUND });
2630
return;
2731
}
28-
const nodeMessage = request.getNode();
29-
if (nodeMessage == null) {
30-
await genWritable.throw({ code: grpc.status.NOT_FOUND });
31-
return;
32-
}
3332
let vaultName;
3433
const vaultNameOrId = vaultMessage.getNameOrId();
3534
let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName);
3635
vaultName = vaultNameOrId;
3736
if (!vaultId) {
3837
try {
3938
vaultId = validationUtils.parseVaultId(vaultNameOrId);
40-
vaultName = (await vaultManager.getVaultMeta(vaultId)).name;
39+
vaultName = (await vaultManager.getVaultMeta(vaultId))?.vaultName;
4140
} catch (err) {
4241
await genWritable.throw(new vaultsErrors.ErrorVaultsVaultUndefined());
4342
return;
4443
}
4544
}
46-
const nodeId = validationUtils.parseNodeId(nodeMessage.getNodeId());
47-
const actionType = request.getAction();
48-
const perms = await acl.getNodePerm(nodeId);
49-
if (!perms) {
50-
await genWritable.throw(new vaultsErrors.ErrorVaultsPermissionDenied());
45+
// Getting the NodeId from the ReverseProxy connection info
46+
const connectionInfo = connectionInfoGetter(call.getPeer());
47+
// If this is getting run the connection exists
48+
// It SHOULD exist here
49+
if (connectionInfo == null) never();
50+
const nodeId = connectionInfo.nodeId;
51+
const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId);
52+
const actionType = validationUtils.parseVaultAction(request.getAction());
53+
const permissions = await acl.getNodePerm(nodeId);
54+
if (permissions == null) {
55+
await genWritable.throw(
56+
new vaultsErrors.ErrorVaultsPermissionDenied(
57+
`No permissions found for ${nodeIdEncoded}`,
58+
),
59+
);
5160
return;
5261
}
53-
const vaultPerms = perms.vaults[idUtils.toString(vaultId)];
54-
try {
55-
if (vaultPerms[actionType] !== null) {
56-
await genWritable.throw(new vaultsErrors.ErrorVaultsPermissionDenied());
57-
return;
58-
}
59-
} catch (err) {
60-
if (err instanceof TypeError) {
61-
await genWritable.throw(new vaultsErrors.ErrorVaultsPermissionDenied());
62-
return;
63-
}
62+
const vaultPerms = permissions.vaults[vaultId];
63+
if (vaultPerms[actionType] !== null) {
64+
await genWritable.throw(
65+
new vaultsErrors.ErrorVaultsPermissionDenied(
66+
`${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId(
67+
vaultId,
68+
)}`,
69+
),
70+
);
71+
return;
6472
}
6573
const meta = new grpc.Metadata();
6674
meta.set('vaultName', vaultName);

src/agent/service/vaultsGitPackGet.ts

+44-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,24 @@
11
import type * as grpc from '@grpc/grpc-js';
22
import type { VaultName } from '../../vaults/types';
33
import type { VaultManager } from '../../vaults';
4+
import type { ConnectionInfoGetter } from '../../agent/types';
5+
import type ACL from '../../acl/ACL';
6+
import { never } from '../../utils/utils';
7+
import * as nodesUtils from '../../nodes/utils';
48
import { errors as grpcErrors, utils as grpcUtils } from '../../grpc';
59
import { utils as vaultsUtils, errors as vaultsErrors } from '../../vaults';
610
import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
11+
import * as validationUtils from '../../validation/utils';
712

8-
function vaultsGitPackGet({ vaultManager }: { vaultManager: VaultManager }) {
13+
function vaultsGitPackGet({
14+
vaultManager,
15+
acl,
16+
connectionInfoGetter,
17+
}: {
18+
vaultManager: VaultManager;
19+
acl: ACL;
20+
connectionInfoGetter: ConnectionInfoGetter;
21+
}) {
922
return async (
1023
call: grpc.ServerDuplexStream<vaultsPB.PackChunk, vaultsPB.PackChunk>,
1124
) => {
@@ -15,14 +28,43 @@ function vaultsGitPackGet({ vaultManager }: { vaultManager: VaultManager }) {
1528
clientBodyBuffers.push(clientRequest!.getChunk_asU8());
1629
const body = Buffer.concat(clientBodyBuffers);
1730
const meta = call.metadata;
31+
// Getting the NodeId from the ReverseProxy connection info
32+
const connectionInfo = connectionInfoGetter(call.getPeer());
33+
// If this is getting run the connection exists
34+
// It SHOULD exist here
35+
if (connectionInfo == null) never();
36+
const nodeId = connectionInfo.nodeId;
37+
const nodeIdEncoded = nodesUtils.encodeNodeId(nodeId);
38+
// Getting vaultId
1839
const vaultNameOrId = meta.get('vaultNameOrId').pop()!.toString();
1940
if (vaultNameOrId == null) {
2041
throw new grpcErrors.ErrorGRPC('vault-name not in metadata');
2142
}
2243
let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName);
2344
vaultId = vaultId ?? vaultsUtils.decodeVaultId(vaultNameOrId);
2445
if (vaultId == null) {
25-
await genDuplex.throw(new vaultsErrors.ErrorVaultsVaultUndefined());
46+
await genDuplex.throw(
47+
// Throwing permission error to hide information about vaults existence
48+
new vaultsErrors.ErrorVaultsPermissionDenied(
49+
`No permissions found for ${nodeIdEncoded}`,
50+
),
51+
);
52+
return;
53+
}
54+
// Checking permissions
55+
const permissions = await acl.getNodePerm(nodeId);
56+
const vaultPerms = permissions?.vaults[vaultId];
57+
const actionType = validationUtils.parseVaultAction(
58+
meta.get('vaultAction').pop(),
59+
);
60+
if (vaultPerms?.[actionType] !== null) {
61+
await genDuplex.throw(
62+
new vaultsErrors.ErrorVaultsPermissionDenied(
63+
`${nodeIdEncoded} does not have permission to ${actionType} from vault ${vaultsUtils.encodeVaultId(
64+
vaultId,
65+
)}`,
66+
),
67+
);
2668
return;
2769
}
2870
const response = new vaultsPB.PackChunk();

src/agent/service/vaultsScan.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ import type * as grpc from '@grpc/grpc-js';
22
import type { GestaltGraph } from '../../gestalts';
33
import type { VaultManager } from '../../vaults';
44
import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb';
5-
import * as validationUtils from '@/validation/utils';
5+
import * as validationUtils from '../../validation/utils';
66
import * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
77
import { utils as vaultsUtils, errors as vaultsErrors } from '../../vaults';
88
import { utils as grpcUtils } from '../../grpc';

src/bootstrap/utils.ts

-1
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,6 @@ async function bootstrapState({
177177
keyManager,
178178
nodeConnectionManager,
179179
vaultsPath,
180-
nodeManager,
181180
notificationsManager,
182181
logger: logger.getChild(VaultManager.name),
183182
fresh,

src/client/service/vaultsClone.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ function vaultsClone({
3737
// Vault id
3838
let vaultId;
3939
const vaultNameOrId = vaultMessage.getNameOrId();
40-
vaultId = vaultManager.getVaultId(vaultNameOrId)
40+
vaultId = vaultManager.getVaultId(vaultNameOrId);
4141
vaultId = vaultId ?? vaultsUtils.decodeVaultId(vaultNameOrId);
4242
if (vaultId == null) throw new vaultsErrors.ErrorVaultsVaultUndefined();
4343
// Node id

src/client/service/vaultsShare.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ import type { VaultId, VaultName } from '../../vaults/types';
44
import type * as vaultsPB from '../../proto/js/polykey/v1/vaults/vaults_pb';
55
import * as grpc from '@grpc/grpc-js';
66
import { utils as idUtils } from '@matrixai/id';
7-
import * as validationUtils from '@/validation/utils';
7+
import * as validationUtils from '../../validation/utils';
88
import { errors as vaultsErrors } from '../../vaults';
99
import { utils as grpcUtils } from '../../grpc';
1010
import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';

src/proto/js/polykey/v1/vaults/vaults_pb.d.ts

-6
Original file line numberDiff line numberDiff line change
@@ -409,11 +409,6 @@ export class InfoRequest extends jspb.Message {
409409
clearVault(): void;
410410
getVault(): Vault | undefined;
411411
setVault(value?: Vault): InfoRequest;
412-
413-
hasNode(): boolean;
414-
clearNode(): void;
415-
getNode(): polykey_v1_nodes_nodes_pb.Node | undefined;
416-
setNode(value?: polykey_v1_nodes_nodes_pb.Node): InfoRequest;
417412
getAction(): string;
418413
setAction(value: string): InfoRequest;
419414

@@ -430,7 +425,6 @@ export class InfoRequest extends jspb.Message {
430425
export namespace InfoRequest {
431426
export type AsObject = {
432427
vault?: Vault.AsObject,
433-
node?: polykey_v1_nodes_nodes_pb.Node.AsObject,
434428
action: string,
435429
}
436430
}

src/proto/js/polykey/v1/vaults/vaults_pb.js

-51
Original file line numberDiff line numberDiff line change
@@ -3264,7 +3264,6 @@ proto.polykey.v1.vaults.InfoRequest.prototype.toObject = function(opt_includeIns
32643264
proto.polykey.v1.vaults.InfoRequest.toObject = function(includeInstance, msg) {
32653265
var f, obj = {
32663266
vault: (f = msg.getVault()) && proto.polykey.v1.vaults.Vault.toObject(includeInstance, f),
3267-
node: (f = msg.getNode()) && polykey_v1_nodes_nodes_pb.Node.toObject(includeInstance, f),
32683267
action: jspb.Message.getFieldWithDefault(msg, 3, "")
32693268
};
32703269

@@ -3307,11 +3306,6 @@ proto.polykey.v1.vaults.InfoRequest.deserializeBinaryFromReader = function(msg,
33073306
reader.readMessage(value,proto.polykey.v1.vaults.Vault.deserializeBinaryFromReader);
33083307
msg.setVault(value);
33093308
break;
3310-
case 2:
3311-
var value = new polykey_v1_nodes_nodes_pb.Node;
3312-
reader.readMessage(value,polykey_v1_nodes_nodes_pb.Node.deserializeBinaryFromReader);
3313-
msg.setNode(value);
3314-
break;
33153309
case 3:
33163310
var value = /** @type {string} */ (reader.readString());
33173311
msg.setAction(value);
@@ -3353,14 +3347,6 @@ proto.polykey.v1.vaults.InfoRequest.serializeBinaryToWriter = function(message,
33533347
proto.polykey.v1.vaults.Vault.serializeBinaryToWriter
33543348
);
33553349
}
3356-
f = message.getNode();
3357-
if (f != null) {
3358-
writer.writeMessage(
3359-
2,
3360-
f,
3361-
polykey_v1_nodes_nodes_pb.Node.serializeBinaryToWriter
3362-
);
3363-
}
33643350
f = message.getAction();
33653351
if (f.length > 0) {
33663352
writer.writeString(
@@ -3408,43 +3394,6 @@ proto.polykey.v1.vaults.InfoRequest.prototype.hasVault = function() {
34083394
};
34093395

34103396

3411-
/**
3412-
* optional polykey.v1.nodes.Node node = 2;
3413-
* @return {?proto.polykey.v1.nodes.Node}
3414-
*/
3415-
proto.polykey.v1.vaults.InfoRequest.prototype.getNode = function() {
3416-
return /** @type{?proto.polykey.v1.nodes.Node} */ (
3417-
jspb.Message.getWrapperField(this, polykey_v1_nodes_nodes_pb.Node, 2));
3418-
};
3419-
3420-
3421-
/**
3422-
* @param {?proto.polykey.v1.nodes.Node|undefined} value
3423-
* @return {!proto.polykey.v1.vaults.InfoRequest} returns this
3424-
*/
3425-
proto.polykey.v1.vaults.InfoRequest.prototype.setNode = function(value) {
3426-
return jspb.Message.setWrapperField(this, 2, value);
3427-
};
3428-
3429-
3430-
/**
3431-
* Clears the message field making it undefined.
3432-
* @return {!proto.polykey.v1.vaults.InfoRequest} returns this
3433-
*/
3434-
proto.polykey.v1.vaults.InfoRequest.prototype.clearNode = function() {
3435-
return this.setNode(undefined);
3436-
};
3437-
3438-
3439-
/**
3440-
* Returns whether this field is set.
3441-
* @return {boolean}
3442-
*/
3443-
proto.polykey.v1.vaults.InfoRequest.prototype.hasNode = function() {
3444-
return jspb.Message.getField(this, 2) != null;
3445-
};
3446-
3447-
34483397
/**
34493398
* optional string action = 3;
34503399
* @return {string}

src/proto/schemas/polykey/v1/vaults/vaults.proto

-1
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,6 @@ message LogEntry {
8989
// Agent specific.
9090
message InfoRequest {
9191
Vault vault = 1;
92-
polykey.v1.nodes.Node node = 2;
9392
string action = 3;
9493
}
9594

src/sigchain/Sigchain.ts

+1-1
Original file line numberDiff line numberDiff line change
@@ -440,7 +440,7 @@ class Sigchain {
440440

441441
@ready(new sigchainErrors.ErrorSigchainNotRunning())
442442
public async clearDB() {
443-
this.sigchainDb.clear();
443+
await this.sigchainDb.clear();
444444

445445
await this._transaction(async () => {
446446
await this.db.put(

0 commit comments

Comments
 (0)