Skip to content

Commit 69747e1

Browse files
committed
Fixed identities search command to search connected identities
Unattended background discovery for Discovery domain Adding trusted nodes/identities to the Gestalt Graph
1 parent a54598e commit 69747e1

38 files changed

Lines changed: 3348 additions & 769 deletions

src/PolykeyAgent.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@ import type { FileSystem } from './types';
22
import type { PolykeyWorkerManagerInterface } from './workers/types';
33
import type { Host, Port } from './network/types';
44
import type { NodeMapping } from './nodes/types';
5-
65
import type { RootKeyPairChangeData } from './keys/types';
76
import path from 'path';
87
import process from 'process';
@@ -266,11 +265,10 @@ class PolykeyAgent {
266265
logger: logger.getChild(NodeManager.name),
267266
fresh,
268267
}));
269-
// Discovery uses in-memory CreateDestroy pattern
270-
// Therefore it should be destroyed during stop
271268
discovery =
272269
discovery ??
273270
(await Discovery.createDiscovery({
271+
db,
274272
gestaltGraph,
275273
identitiesManager,
276274
nodeManager,
@@ -323,7 +321,7 @@ class PolykeyAgent {
323321
await sessionManager?.stop();
324322
await notificationsManager?.stop();
325323
await vaultManager?.stop();
326-
await discovery?.destroy();
324+
await discovery?.stop();
327325
await nodeManager?.stop();
328326
await revProxy?.stop();
329327
await fwdProxy?.stop();
@@ -578,6 +576,7 @@ class PolykeyAgent {
578576
await this.nodeManager.start({ fresh });
579577
await this.nodeManager.getConnectionsToSeedNodes();
580578
await this.nodeManager.syncNodeGraph();
579+
await this.discovery.start({ fresh });
581580
await this.vaultManager.start({ fresh });
582581
await this.notificationsManager.start({ fresh });
583582
await this.sessionManager.start({ fresh });
@@ -596,7 +595,7 @@ class PolykeyAgent {
596595
await this.sessionManager?.stop();
597596
await this.notificationsManager?.stop();
598597
await this.vaultManager?.stop();
599-
await this.discovery?.destroy();
598+
await this.discovery?.stop();
600599
await this.nodeManager?.stop();
601600
await this.revProxy?.stop();
602601
await this.fwdProxy?.stop();
@@ -624,7 +623,7 @@ class PolykeyAgent {
624623
await this.sessionManager.stop();
625624
await this.notificationsManager.stop();
626625
await this.vaultManager.stop();
627-
await this.discovery.destroy();
626+
await this.discovery.stop();
628627
await this.nodeManager.stop();
629628
await this.revProxy.stop();
630629
await this.fwdProxy.stop();
@@ -649,6 +648,7 @@ class PolykeyAgent {
649648
await this.sessionManager.destroy();
650649
await this.notificationsManager.destroy();
651650
await this.vaultManager.destroy();
651+
await this.discovery.destroy();
652652
await this.nodeManager.destroy();
653653
await this.gestaltGraph.destroy();
654654
await this.acl.destroy();

src/bin/identities/CommandDiscover.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ class CommandDiscover extends CommandPolykey {
1010
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
1111
super(...args);
1212
this.name('discover');
13-
this.description(
14-
'Starts Discovery Process using Node or Identity as a Starting Point',
15-
);
13+
this.description('Adds a Node or Identity to the Discovery Queue');
1614
this.argument(
1715
'<gestaltId>',
1816
'Node ID or `Provider ID:Identity ID`',

src/bin/identities/CommandSearch.ts

Lines changed: 68 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
import type PolykeyClient from '../../PolykeyClient';
2+
import type { IdentityId, ProviderId } from '../../identities/types';
23
import CommandPolykey from '../CommandPolykey';
34
import * as binOptions from '../utils/options';
45
import * as binUtils from '../utils';
6+
import * as parsers from '../utils/parsers';
57
import * as binProcessors from '../utils/processors';
68

79
class CommandSearch extends CommandPolykey {
@@ -10,13 +12,32 @@ class CommandSearch extends CommandPolykey {
1012
this.name('search');
1113
this.description('Searches a Provider for any Connected Identities');
1214
this.argument(
13-
'<providerId>',
14-
'Name of the digital identity provider to search on',
15+
'[searchTerms...]',
16+
'Search parameters to apply to connected identities',
17+
);
18+
this.option(
19+
'-pi, --provider-id [providerId...]',
20+
'Digital identity provider(s) to search on',
21+
parsers.parseProviderIdList,
22+
);
23+
this.option(
24+
'-ii, --identity-id [identityId]',
25+
'Name of the digital identity to search for',
26+
parsers.parseIdentityId,
27+
);
28+
this.option(
29+
'-d, --disconnected',
30+
'Include disconnected identities in search',
31+
);
32+
this.option(
33+
'-l, --limit [number]',
34+
'Limit the number of search results to display to a specific number',
35+
parsers.parseInteger,
1536
);
1637
this.addOption(binOptions.nodeId);
1738
this.addOption(binOptions.clientHost);
1839
this.addOption(binOptions.clientPort);
19-
this.action(async (providerId, options) => {
40+
this.action(async (searchTerms, options) => {
2041
const { default: PolykeyClient } = await import('../../PolykeyClient');
2142
const identitiesPB = await import(
2243
'../../proto/js/polykey/v1/identities/identities_pb'
@@ -34,7 +55,11 @@ class CommandSearch extends CommandPolykey {
3455
this.fs,
3556
);
3657
let pkClient: PolykeyClient;
58+
let genReadable: ReturnType<
59+
typeof pkClient.grpcClient.identitiesInfoConnectedGet
60+
>;
3761
this.exitHandlers.handlers.push(async () => {
62+
if (genReadable != null) genReadable.stream.cancel();
3863
if (pkClient != null) await pkClient.stop();
3964
});
4065
try {
@@ -45,25 +70,48 @@ class CommandSearch extends CommandPolykey {
4570
port: clientOptions.clientPort,
4671
logger: this.logger.getChild(PolykeyClient.name),
4772
});
48-
const providerMessage = new identitiesPB.Provider();
49-
providerMessage.setProviderId(providerId);
50-
const res = await binUtils.retryAuthentication(
51-
(auth) =>
52-
pkClient.grpcClient.identitiesInfoGet(providerMessage, auth),
53-
meta,
54-
);
55-
let output = '';
56-
if (res.getIdentityId() && res.getProviderId()) {
57-
output = `${res.getProviderId()}:${res.getIdentityId()}`;
73+
const providerSearchMessage = new identitiesPB.ProviderSearch();
74+
providerSearchMessage.setSearchTermList(searchTerms);
75+
if (options.providerId) {
76+
providerSearchMessage.setProviderIdList(options.providerId);
77+
}
78+
if (options.disconnected) {
79+
providerSearchMessage.setDisconnected(true);
5880
} else {
59-
this.logger.info('No Connected Identities found for Provider');
81+
providerSearchMessage.setDisconnected(false);
82+
}
83+
if (options.limit) {
84+
providerSearchMessage.setLimit(options.limit);
6085
}
61-
process.stdout.write(
62-
binUtils.outputFormatter({
63-
type: options.format === 'json' ? 'json' : 'list',
64-
data: [output],
65-
}),
66-
);
86+
await binUtils.retryAuthentication(async (auth) => {
87+
if (options.identity) {
88+
providerSearchMessage.setIdentityId(options.identity);
89+
genReadable = pkClient.grpcClient.identitiesInfoGet(
90+
providerSearchMessage,
91+
auth,
92+
);
93+
} else {
94+
genReadable = pkClient.grpcClient.identitiesInfoConnectedGet(
95+
providerSearchMessage,
96+
auth,
97+
);
98+
}
99+
for await (const val of genReadable) {
100+
const output = {
101+
providerId: val.getProvider()!.getProviderId() as ProviderId,
102+
identityId: val.getProvider()!.getIdentityId() as IdentityId,
103+
name: val.getName(),
104+
email: val.getEmail(),
105+
url: val.getUrl(),
106+
};
107+
process.stdout.write(
108+
binUtils.outputFormatter({
109+
type: options.format === 'json' ? 'json' : 'dict',
110+
data: output,
111+
}),
112+
);
113+
}
114+
}, meta);
67115
} finally {
68116
if (pkClient! != null) await pkClient.stop();
69117
}

src/bin/identities/CommandTrust.ts

Lines changed: 6 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,6 @@ class CommandTrust extends CommandPolykey {
2424
const identitiesPB = await import(
2525
'../../proto/js/polykey/v1/identities/identities_pb'
2626
);
27-
const permissionsPB = await import(
28-
'../../proto/js/polykey/v1/permissions/permissions_pb'
29-
);
3027
const nodesPB = await import('../../proto/js/polykey/v1/nodes/nodes_pb');
3128
const clientOptions = await binProcessors.processClientOptions(
3229
options.nodePath,
@@ -52,32 +49,24 @@ class CommandTrust extends CommandPolykey {
5249
port: clientOptions.clientPort,
5350
logger: this.logger.getChild(PolykeyClient.name),
5451
});
55-
const action = 'notify';
56-
const setActionMessage = new permissionsPB.ActionSet();
57-
setActionMessage.setAction(action);
5852
if (gestaltId.type === 'node') {
59-
// Setting by Node
53+
// Setting by Node.
6054
const nodeMessage = new nodesPB.Node();
6155
nodeMessage.setNodeId(gestaltId.nodeId);
62-
setActionMessage.setNode(nodeMessage);
6356
await binUtils.retryAuthentication(
6457
(auth) =>
65-
pkClient.grpcClient.gestaltsActionsSetByNode(
66-
setActionMessage,
67-
auth,
68-
),
58+
pkClient.grpcClient.gestaltsGestaltTrustByNode(nodeMessage, auth),
6959
meta,
7060
);
7161
} else {
7262
// Setting by Identity
7363
const providerMessage = new identitiesPB.Provider();
74-
providerMessage.setProviderId(gestaltId.providerId!);
75-
providerMessage.setIdentityId(gestaltId.identityId!);
76-
setActionMessage.setIdentity(providerMessage);
64+
providerMessage.setProviderId(gestaltId.providerId);
65+
providerMessage.setIdentityId(gestaltId.identityId);
7766
await binUtils.retryAuthentication(
7867
(auth) =>
79-
pkClient.grpcClient.gestaltsActionsSetByIdentity(
80-
setActionMessage,
68+
pkClient.grpcClient.gestaltsGestaltTrustByIdentity(
69+
providerMessage,
8170
auth,
8271
),
8372
meta,

src/bin/utils/parsers.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,25 @@ function validateParserToArgParser<T>(
2828
};
2929
}
3030

31+
/**
32+
* Converts a validation parser to commander variadic argument parser
33+
*/
34+
function validateParserToArgListParser<T>(
35+
validate: (data: string) => T,
36+
): (data: string) => Array<T> {
37+
return (data: string) => {
38+
try {
39+
return data.split(' ').map(validate);
40+
} catch (e) {
41+
if (e instanceof validationErrors.ErrorParse) {
42+
throw new commander.InvalidArgumentError(e.message);
43+
} else {
44+
throw e;
45+
}
46+
}
47+
};
48+
}
49+
3150
const parseInteger = validateParserToArgParser(validationUtils.parseInteger);
3251
const parseNumber = validateParserToArgParser(validationUtils.parseNumber);
3352
const parseNodeId = validateParserToArgParser(validationUtils.parseNodeId);
@@ -40,6 +59,13 @@ const parseHostOrHostname = validateParserToArgParser(
4059
validationUtils.parseHostOrHostname,
4160
);
4261
const parsePort = validateParserToArgParser(validationUtils.parsePort);
62+
const parseIdentityId = validateParserToArgParser(
63+
validationUtils.parseIdentityId,
64+
);
65+
66+
const parseProviderIdList = validateParserToArgListParser(
67+
validationUtils.parseProviderId,
68+
);
4369

4470
function parseCoreCount(v: string): number | undefined {
4571
if (v === 'all') {
@@ -159,4 +185,6 @@ export {
159185
getDefaultSeedNodes,
160186
parseSeedNodes,
161187
parseNetwork,
188+
parseProviderIdList,
189+
parseIdentityId,
162190
};

src/client/GRPCClientClient.ts

Lines changed: 21 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,8 @@ import Logger from '@matrixai/logger';
1919
import * as clientErrors from './errors';
2020
import * as clientUtils from './utils';
2121
import { ClientServiceClient } from '../proto/js/polykey/v1/client_service_grpc_pb';
22-
import { GRPCClient, utils as grpcUtils } from '../grpc';
22+
import { GRPCClient } from '../grpc';
23+
import * as grpcUtils from '../grpc/utils';
2324

2425
interface GRPCClientClient extends CreateDestroy {}
2526
@CreateDestroy()
@@ -486,6 +487,22 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
486487
)(...args);
487488
}
488489

490+
@ready(new clientErrors.ErrorClientClientDestroyed())
491+
public gestaltsGestaltTrustByNode(...args) {
492+
return grpcUtils.promisifyUnaryCall<utilsPB.EmptyMessage>(
493+
this.client,
494+
this.client.gestaltsGestaltTrustByNode,
495+
)(...args);
496+
}
497+
498+
@ready(new clientErrors.ErrorClientClientDestroyed())
499+
public gestaltsGestaltTrustByIdentity(...args) {
500+
return grpcUtils.promisifyUnaryCall<utilsPB.EmptyMessage>(
501+
this.client,
502+
this.client.gestaltsGestaltTrustByIdentity,
503+
)(...args);
504+
}
505+
489506
@ready(new clientErrors.ErrorClientClientDestroyed())
490507
public identitiesTokenPut(...args) {
491508
return grpcUtils.promisifyUnaryCall<utilsPB.EmptyMessage>(
@@ -559,16 +576,16 @@ class GRPCClientClient extends GRPCClient<ClientServiceClient> {
559576
}
560577

561578
@ready(new clientErrors.ErrorClientClientDestroyed())
562-
public identitiesInfoGetConnected(...args) {
579+
public identitiesInfoConnectedGet(...args) {
563580
return grpcUtils.promisifyReadableStreamCall<identitiesPB.Info>(
564581
this.client,
565-
this.client.identitiesInfoGetConnected,
582+
this.client.identitiesInfoConnectedGet,
566583
)(...args);
567584
}
568585

569586
@ready(new clientErrors.ErrorClientClientDestroyed())
570587
public identitiesInfoGet(...args) {
571-
return grpcUtils.promisifyUnaryCall<identitiesPB.Provider>(
588+
return grpcUtils.promisifyReadableStreamCall<identitiesPB.Info>(
572589
this.client,
573590
this.client.identitiesInfoGet,
574591
)(...args);

src/client/service/gestaltsDiscoveryByIdentity.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import type { Authenticate } from '../types';
33
import type { Discovery } from '../../discovery';
44
import type { IdentityId, ProviderId } from '../../identities/types';
55
import type * as identitiesPB from '../../proto/js/polykey/v1/identities/identities_pb';
6-
import { utils as grpcUtils } from '../../grpc';
7-
import { validateSync, utils as validationUtils } from '../../validation';
6+
import { validateSync } from '../../validation';
87
import { matchSync } from '../../utils';
8+
import * as grpcUtils from '../../grpc/utils';
9+
import * as validationUtils from '../../validation/utils';
910
import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';
1011

1112
function gestaltsDiscoveryByIdentity({
@@ -42,10 +43,7 @@ function gestaltsDiscoveryByIdentity({
4243
identityId: call.request.getIdentityId(),
4344
},
4445
);
45-
const gen = discovery.discoverGestaltByIdentity(providerId, identityId);
46-
for await (const _ of gen) {
47-
// Empty
48-
}
46+
await discovery.queueDiscoveryByIdentity(providerId, identityId);
4947
callback(null, response);
5048
return;
5149
} catch (e) {

src/client/service/gestaltsDiscoveryByNode.ts

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ import type { Authenticate } from '../types';
33
import type { Discovery } from '../../discovery';
44
import type { NodeId } from '../../nodes/types';
55
import type * as nodesPB from '../../proto/js/polykey/v1/nodes/nodes_pb';
6-
import { utils as grpcUtils } from '../../grpc';
7-
import { validateSync, utils as validationUtils } from '../../validation';
6+
import { validateSync } from '../../validation';
87
import { matchSync } from '../../utils';
8+
import * as grpcUtils from '../../grpc/utils';
9+
import * as validationUtils from '../../validation/utils';
910
import * as utilsPB from '../../proto/js/polykey/v1/utils/utils_pb';
1011

1112
function gestaltsDiscoveryByNode({
@@ -38,10 +39,7 @@ function gestaltsDiscoveryByNode({
3839
nodeId: call.request.getNodeId(),
3940
},
4041
);
41-
const gen = discovery.discoverGestaltByNode(nodeId);
42-
for await (const _ of gen) {
43-
// Empty
44-
}
42+
await discovery.queueDiscoveryByNode(nodeId);
4543
callback(null, response);
4644
return;
4745
} catch (e) {

0 commit comments

Comments
 (0)