Skip to content

Commit 8872ffd

Browse files
tegefaulkesScott
authored and
Scott
committed
Vaults sharing, permissions and scanning
1 parent 2732d79 commit 8872ffd

Some content is hidden

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

66 files changed

+1570
-2475
lines changed

Diff for: src/PolykeyAgent.ts

+14-15
Original file line numberDiff line numberDiff line change
@@ -286,18 +286,29 @@ class Polykey {
286286
fs: fs_,
287287
logger: logger_.getChild('NodeManager'),
288288
}));
289+
const notifications_ =
290+
notificationsManager ??
291+
(await NotificationsManager.createNotificationsManager({
292+
acl: acl_,
293+
db: db_,
294+
nodeManager: nodes_,
295+
keyManager: keys_,
296+
logger: logger_.getChild('NotificationsManager'),
297+
fresh,
298+
}));
289299
const vaults_ =
290300
vaultManager ??
291301
(await VaultManager.createVaultManager({
292302
keyManager: keys_,
293303
vaultsPath: vaultsPath,
294-
vaultsKey: keys_.vaultKey,
295304
nodeManager: nodes_,
296305
gestaltGraph: gestalts_,
306+
notificationsManager: notifications_,
297307
acl: acl_,
298308
db: db_,
299309
fs: fs_,
300310
logger: logger_.getChild('VaultManager'),
311+
fresh,
301312
}));
302313
// Setting the workerManager for vaults.
303314
if (workers_ != null) {
@@ -319,16 +330,6 @@ class Polykey {
319330
nodeManager: nodes_,
320331
logger: logger_.getChild('Discovery'),
321332
}));
322-
const notifications_ =
323-
notificationsManager ??
324-
(await NotificationsManager.createNotificationsManager({
325-
acl: acl_,
326-
db: db_,
327-
nodeManager: nodes_,
328-
keyManager: keys_,
329-
logger: logger_.getChild('NotificationsManager'),
330-
fresh,
331-
}));
332333

333334
const sessionManager = await SessionManager.createSessionManager({
334335
db: db_,
@@ -476,6 +477,8 @@ class Polykey {
476477
nodeManager: this.nodes,
477478
sigchain: this.sigchain,
478479
notificationsManager: this.notifications,
480+
acl: this.acl,
481+
gestaltGraph: this.gestalts,
479482
});
480483

481484
// Registering providers.
@@ -492,7 +495,6 @@ class Polykey {
492495
*/
493496
public async start({ fresh = false }: { fresh?: boolean }) {
494497
this.logger.info('Starting Polykey');
495-
496498
if (
497499
(await Lockfile.checkLock(
498500
this.fs,
@@ -525,7 +527,6 @@ class Polykey {
525527

526528
const keyPrivatePem = this.keys.getRootKeyPairPem().privateKey;
527529
const certChainPem = await this.keys.getRootCertChainPem();
528-
529530
// GRPC Server
530531
// Client server
531532
await this.clientGrpcServer.start({
@@ -543,7 +544,6 @@ class Polykey {
543544
host: this.agentGrpcHost as Host,
544545
port: this.agentGrpcPort as Port,
545546
});
546-
547547
await this.fwdProxy.start({
548548
tlsConfig: {
549549
keyPrivatePem: keyPrivatePem,
@@ -571,7 +571,6 @@ class Polykey {
571571
'fwdProxyPort',
572572
this.fwdProxy.getProxyPort(),
573573
);
574-
575574
this.logger.info('Started Polykey');
576575
}
577576

Diff for: src/agent/GRPCClientAgent.ts

+3-11
Original file line numberDiff line numberDiff line change
@@ -85,10 +85,10 @@ class GRPCClientAgent extends GRPCClient<AgentServiceClient> {
8585
}
8686

8787
@ready(new grpcErrors.ErrorGRPCClientNotStarted())
88-
public vaultsScan(...args) {
89-
return grpcUtils.promisifyReadableStreamCall<vaultsPB.Vault>(
88+
public nodesScan(...args) {
89+
return grpcUtils.promisifyReadableStreamCall<vaultsPB.List>(
9090
this.client,
91-
this.client.vaultsScan,
91+
this.client.nodesScan,
9292
)(...args);
9393
}
9494

@@ -132,14 +132,6 @@ class GRPCClientAgent extends GRPCClient<AgentServiceClient> {
132132
)(...args);
133133
}
134134

135-
@ready(new grpcErrors.ErrorGRPCClientNotStarted())
136-
public vaultsPermisssionsCheck(...args) {
137-
return grpcUtils.promisifyUnaryCall<vaultsPB.NodePermissionAllowed>(
138-
this.client,
139-
this.client.vaultsPermisssionsCheck,
140-
)(...args);
141-
}
142-
143135
@ready(new grpcErrors.ErrorGRPCClientNotStarted())
144136
public nodesCrossSignClaim(...args) {
145137
return grpcUtils.promisifyDuplexStreamCall<

Diff for: src/agent/agentService.ts

+77-62
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ import type {
44
ClaimIdString,
55
} from '../claims/types';
66
import type { VaultName } from '../vaults/types';
7+
import type { ACL } from '../acl';
8+
import type { GestaltGraph } from '../gestalts';
9+
import type { NodeId } from '../nodes/types';
710

811
import * as grpc from '@grpc/grpc-js';
912
import { promisify } from '../utils';
@@ -44,12 +47,16 @@ function createAgentService({
4447
nodeManager,
4548
notificationsManager,
4649
sigchain,
50+
acl,
51+
gestaltGraph,
4752
}: {
4853
keyManager: KeyManager;
4954
vaultManager: VaultManager;
5055
nodeManager: NodeManager;
5156
sigchain: Sigchain;
5257
notificationsManager: NotificationsManager;
58+
acl: ACL;
59+
gestaltGraph: GestaltGraph;
5360
}): IAgentServiceServer {
5461
const agentService: IAgentServiceServer = {
5562
echo: async (
@@ -66,21 +73,44 @@ function createAgentService({
6673
const genWritable = grpcUtils.generatorWritable(call);
6774
const request = call.request;
6875
const vaultNameOrId = request.getNameOrId();
69-
let vaultId, vaultName;
76+
let vaultName;
77+
let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName);
78+
if (!vaultId) {
79+
try {
80+
vaultId = makeVaultId(idUtils.fromString(vaultNameOrId));
81+
vaultName = await vaultManager.getVaultName(vaultId);
82+
} catch (err) {
83+
await genWritable.throw(new vaultsErrors.ErrorVaultUndefined());
84+
return;
85+
}
86+
} else {
87+
vaultName = vaultNameOrId;
88+
}
89+
await vaultManager.openVault(vaultId);
90+
const metaIn = call.metadata;
91+
const nodeId = metaIn.get('nodeId').pop()!.toString() as NodeId;
92+
const actionType = metaIn.get('action').pop()!.toString();
93+
const perms = await acl.getNodePerm(nodeId);
94+
if (!perms) {
95+
await genWritable.throw(new vaultsErrors.ErrorVaultPermissionDenied());
96+
return;
97+
}
98+
const vaultPerms = perms.vaults[idUtils.toString(vaultId)];
7099
try {
71-
vaultId = makeVaultId(idUtils.fromString(vaultNameOrId));
72-
await vaultManager.openVault(vaultId);
73-
vaultName = await vaultManager.getVaultName(vaultId);
100+
if (vaultPerms[actionType] !== null) {
101+
await genWritable.throw(
102+
new vaultsErrors.ErrorVaultPermissionDenied(),
103+
);
104+
return;
105+
}
74106
} catch (err) {
75-
if (err instanceof vaultsErrors.ErrorVaultUndefined) {
76-
vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName);
77-
await vaultManager.openVault(vaultId);
78-
vaultName = vaultNameOrId;
79-
} else {
80-
throw err;
107+
if (err instanceof TypeError) {
108+
await genWritable.throw(
109+
new vaultsErrors.ErrorVaultPermissionDenied(),
110+
);
111+
return;
81112
}
82113
}
83-
// TODO: Check the permissions here
84114
const meta = new grpc.Metadata();
85115
meta.set('vaultName', vaultName);
86116
meta.set('vaultId', makeVaultIdPretty(vaultId));
@@ -112,22 +142,15 @@ function createAgentService({
112142
const vaultNameOrId = meta.get('vaultNameOrId').pop()!.toString();
113143
if (vaultNameOrId == null)
114144
throw new ErrorGRPC('vault-name not in metadata.');
115-
let vaultId;
116-
try {
117-
vaultId = makeVaultId(vaultNameOrId);
118-
await vaultManager.openVault(vaultId);
119-
} catch (err) {
120-
if (
121-
err instanceof vaultsErrors.ErrorVaultUndefined ||
122-
err instanceof SyntaxError
123-
) {
124-
vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName);
125-
await vaultManager.openVault(vaultId);
126-
} else {
127-
throw err;
145+
let vaultId = await vaultManager.getVaultId(vaultNameOrId as VaultName);
146+
if (!vaultId) {
147+
try {
148+
vaultId = makeVaultId(vaultNameOrId);
149+
} catch (err) {
150+
return;
128151
}
129152
}
130-
// TODO: Check the permissions here
153+
await vaultManager.openVault(vaultId);
131154
const response = new vaultsPB.PackChunk();
132155
const [sideBand, progressStream] = await vaultManager.handlePackRequest(
133156
vaultId,
@@ -154,20 +177,39 @@ function createAgentService({
154177
call.end();
155178
});
156179
},
157-
vaultsScan: async (
158-
call: grpc.ServerWritableStream<nodesPB.Node, vaultsPB.Vault>,
180+
nodesScan: async (
181+
call: grpc.ServerWritableStream<nodesPB.Node, vaultsPB.List>,
159182
): Promise<void> => {
160183
const genWritable = grpcUtils.generatorWritable(call);
161-
const response = new vaultsPB.Vault();
162-
const id = makeNodeId(call.request.getNodeId());
184+
const response = new vaultsPB.List();
185+
const nodeId = makeNodeId(call.request.getNodeId());
186+
const perms = await gestaltGraph.getGestaltActionsByNode(nodeId);
187+
if (!perms) {
188+
await genWritable.throw(new vaultsErrors.ErrorVaultPermissionDenied());
189+
return;
190+
}
163191
try {
164-
throw Error('Not implemented');
165-
// FIXME: handleVaultNamesRequest doesn't exist.
166-
// const listResponse = vaultManager.handleVaultNamesRequest(id);
167-
let listResponse;
168-
for await (const vault of listResponse) {
192+
if (perms['scan'] !== null) {
193+
await genWritable.throw(
194+
new vaultsErrors.ErrorVaultPermissionDenied(),
195+
);
196+
return;
197+
}
198+
} catch (err) {
199+
if (err instanceof TypeError) {
200+
await genWritable.throw(
201+
new vaultsErrors.ErrorVaultPermissionDenied(),
202+
);
203+
return;
204+
}
205+
throw err;
206+
}
207+
try {
208+
const listResponse = await vaultManager.listVaults();
209+
for (const vault of listResponse) {
169210
if (vault !== null) {
170-
response.setNameOrId(vault);
211+
response.setVaultName(vault[0]);
212+
response.setVaultId(makeVaultIdPretty(vault[1]));
171213
await genWritable.next(response);
172214
} else {
173215
await genWritable.next(null);
@@ -304,33 +346,6 @@ function createAgentService({
304346
}
305347
callback(null, response);
306348
},
307-
vaultsPermisssionsCheck: async (
308-
call: grpc.ServerUnaryCall<
309-
vaultsPB.NodePermission,
310-
vaultsPB.NodePermissionAllowed
311-
>,
312-
callback: grpc.sendUnaryData<vaultsPB.NodePermissionAllowed>,
313-
): Promise<void> => {
314-
const response = new vaultsPB.NodePermissionAllowed();
315-
try {
316-
const nodeId = makeNodeId(call.request.getNodeId());
317-
const vaultId = makeVaultId(call.request.getVaultId());
318-
throw Error('Not Implemented');
319-
// FIXME: getVaultPermissions not implemented.
320-
// const result = await vaultManager.getVaultPermissions(vaultId, nodeId);
321-
let result;
322-
if (result[nodeId] === undefined) {
323-
response.setPermission(false);
324-
} else if (result[nodeId]['pull'] === undefined) {
325-
response.setPermission(false);
326-
} else {
327-
response.setPermission(true);
328-
}
329-
callback(null, response);
330-
} catch (err) {
331-
callback(grpcUtils.fromError(err), null);
332-
}
333-
},
334349
nodesCrossSignClaim: async (
335350
call: grpc.ServerDuplexStream<nodesPB.CrossSign, nodesPB.CrossSign>,
336351
) => {

Diff for: src/agent/backgroundAgent.ts

+1
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ process.on('message', async (startOptions: string) => {
2222
polykeyAgent = await PolykeyAgent.createPolykey({
2323
password: ops.password,
2424
nodePath: ops.nodePath,
25+
fresh: ops.fresh,
2526
});
2627
await polykeyAgent.start({});
2728
//Catching kill signals.

Diff for: src/agent/utils.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -26,9 +26,10 @@ async function checkAgentRunning(nodePath: string): Promise<boolean> {
2626
return false;
2727
}
2828

29-
async function spawnBackgroundAgent( // FIXME, this is broken.
29+
async function spawnBackgroundAgent(
3030
nodePath: string,
3131
password: string,
32+
fresh = false,
3233
): Promise<number> {
3334
//Checking agent running.
3435
if (await checkAgentRunning(nodePath)) {
@@ -85,6 +86,7 @@ async function spawnBackgroundAgent( // FIXME, this is broken.
8586
const startOptions = {
8687
nodePath: nodePath,
8788
password: password,
89+
fresh: fresh,
8890
};
8991

9092
let pid;

Diff for: src/bin/agent/start.ts

+10-2
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ const start = binUtils.createCommand('start', {
1414
format: true,
1515
passwordFile: true,
1616
});
17+
start.option('-fr, --fresh', 'Starts a fresh agent');
1718
start.option('-b, --background', 'Starts the agent as a background process');
1819
start.action(async (options) => {
1920
const agentConfig = {};
@@ -28,20 +29,27 @@ start.action(async (options) => {
2829
: utils.getDefaultNodePath();
2930
agentConfig['nodePath'] = nodePath;
3031
const background = options.background;
32+
if (options.fresh) {
33+
agentConfig['fresh'] = true;
34+
}
3135

3236
const password = await fs.promises.readFile(options.passwordFile, {
3337
encoding: 'utf-8',
3438
});
3539

3640
try {
3741
if (background) {
38-
await agentUtils.spawnBackgroundAgent(nodePath, password);
42+
await agentUtils.spawnBackgroundAgent(
43+
nodePath,
44+
password,
45+
agentConfig['fresh'],
46+
);
3947
} else {
4048
const agent = await PolykeyAgent.createPolykey({
4149
password,
4250
...agentConfig,
4351
});
44-
await agent.start({});
52+
await agent.start({ fresh: agentConfig['fresh'] });
4553

4654
// If started add handlers for terminating.
4755
const termHandler = async () => {

Diff for: src/bin/nodes/index.ts

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import claim from './claim';
44
// Import commandUnclaimNode from "./commandUnclaimNode";
55
import add from './add';
66
import find from './find';
7+
import scan from './scan';
78

89
const commandNodes = createCommand('node');
910
commandNodes.description('nodes commands');
@@ -13,5 +14,6 @@ commandNodes.addCommand(ping);
1314
commandNodes.addCommand(add);
1415
commandNodes.addCommand(find);
1516
commandNodes.addCommand(claim);
17+
commandNodes.addCommand(scan);
1618

1719
export default commandNodes;

0 commit comments

Comments
 (0)