Skip to content

Commit

Permalink
wip: audit prototyping
Browse files Browse the repository at this point in the history
[ci skip]
  • Loading branch information
tegefaulkes committed Apr 29, 2024
1 parent 670884c commit 857d979
Show file tree
Hide file tree
Showing 6 changed files with 493 additions and 0 deletions.
13 changes: 13 additions & 0 deletions src/audit/CommandAudit.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import CommandDiscovery from './CommandDiscovery';
import CommandPolykey from '../CommandPolykey';

class CommandIdentities extends CommandPolykey {
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
super(...args);
this.name('audit');
this.description('Auditing');
this.addCommand(new CommandDiscovery(...args));
}
}

export default CommandIdentities;
117 changes: 117 additions & 0 deletions src/audit/CommandDiscovery.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
import type PolykeyClient from 'polykey/dist/PolykeyClient';
import CommandPolykey from '../CommandPolykey';
import * as binOptions from '../utils/options';
import * as binUtils from '../utils';
import * as binProcessors from '../utils/processors';

class CommandDiscover extends CommandPolykey {
constructor(...args: ConstructorParameters<typeof CommandPolykey>) {
super(...args);
this.name('discovery');
this.description('Displays discovery event history');
this.addOption(binOptions.nodeId);
this.addOption(binOptions.clientHost);
this.addOption(binOptions.clientPort);
this.addOption(binOptions.seekStart);
this.addOption(binOptions.seekEnd);
this.addOption(binOptions.futureEvents);
this.addOption(binOptions.discoveryEvents);
this.addOption(binOptions.limit);
this.addOption(binOptions.order);
this.action(async (options) => {
const { default: PolykeyClient } = await import(
'polykey/dist/PolykeyClient'
);
const clientOptions = await binProcessors.processClientOptions(
options.nodePath,
options.nodeId,
options.clientHost,
options.clientPort,
this.fs,
this.logger.getChild(binProcessors.processClientOptions.name),
);
const auth = await binProcessors.processAuthentication(
options.passwordFile,
this.fs,
);
let pkClient: PolykeyClient;
this.exitHandlers.handlers.push(async () => {
if (pkClient != null) await pkClient.stop();
});
try {
pkClient = await PolykeyClient.createPolykeyClient({
nodeId: clientOptions.nodeId,
host: clientOptions.clientHost,
port: clientOptions.clientPort,
options: {
nodePath: options.nodePath,
},
logger: this.logger.getChild(PolykeyClient.name),
});
// Creating an infinite timer to hold the process open
const holdOpenTimer = setTimeout(() => {}, 2 ** 30);
// We set up the readable stream watching the discovery events here
await binUtils
.retryAuthentication(async (auth) => {
const seek: number = options.seekStart;
const seekEnd: number | undefined = options.seekEnd;
const order: 'asc' | 'desc' = options.order;
const limit: number | undefined = options.limit;
const events: Array<
'queued' | 'processed' | 'cancelled' | 'failed'
> = options.discoveryEvents;
const awaitFutureEvents = options.futureEvents;
const readableStream =
await pkClient.rpcClient.methods.auditEventsGet({
awaitFutureEvents,
path: ['discovery', 'vertex'],
seek,
seekEnd,
order,
limit,
metadata: auth,
});
// Tracks vertices that are relevant to our current search
for await (const result of readableStream) {
const event = result.path[2];
const { vertex } = result.data;
// Don't emit events we're not filtering for
if (events != null && !(<Array<string>>events).includes(event)) {
continue;
}
const data = {
event,
vertex,
};
if (options.format === 'json') {
process.stdout.write(
binUtils.outputFormatter({
type: 'json',
data,
}),
);
} else {
process.stdout.write(
binUtils.outputFormatter({
type: 'list',
data: [
`${data.event}${' '.repeat(15 - data.event.length)}${
data.vertex
}`,
],
}),
);
}
}
}, auth)
.finally(() => {
clearTimeout(holdOpenTimer);
});
} finally {
if (pkClient! != null) await pkClient.stop();
}
});
}
}

export default CommandDiscover;
1 change: 1 addition & 0 deletions src/audit/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export { default } from './CommandAudit';
2 changes: 2 additions & 0 deletions src/polykey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -143,6 +143,7 @@ async function polykeyMain(argv: Array<string>): Promise<number> {
const { default: config } = await import('polykey/dist/config');
const { default: CommandBootstrap } = await import('./bootstrap');
const { default: CommandAgent } = await import('./agent');
const { default: CommandAudit } = await import('./audit');
const { default: CommandVaults } = await import('./vaults');
const { default: CommandSecrets } = await import('./secrets');
const { default: CommandKeys } = await import('./keys');
Expand All @@ -164,6 +165,7 @@ async function polykeyMain(argv: Array<string>): Promise<number> {
rootCommand.description('Polykey CLI');
rootCommand.addCommand(new CommandBootstrap({ exitHandlers, fs }));
rootCommand.addCommand(new CommandAgent({ exitHandlers, fs }));
rootCommand.addCommand(new CommandAudit({ exitHandlers, fs }));
rootCommand.addCommand(new CommandNodes({ exitHandlers, fs }));
rootCommand.addCommand(new CommandSecrets({ exitHandlers, fs }));
rootCommand.addCommand(new CommandKeys({ exitHandlers, fs }));
Expand Down
53 changes: 53 additions & 0 deletions src/utils/options.ts
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,53 @@ const discoveryMonitor = new commander.Option(
'Enabling monitoring will cause discover to output discovery events as they happen and will exit once all children are processed',
).default(false);

const parseDate = (value: string): number => {
if (value.toLowerCase() === 'now') return Date.now();
const date = Date.parse(value);
if (isNaN(date)) throw Error('Invalid data');
return date;
};

const seekStart = new commander.Option(
'--seek-start [seekStart]',
`time to start seeking from`,
)
.argParser(parseDate)
.default(0);

const seekEnd = new commander.Option(
'--seek-end [seekEnd]',
`time to seek until`,
)
.argParser(parseDate)
.default(undefined);

const futureEvents = new commander.Option(
'--future-events',
'If enabled, future events will be outputted as they happen',
).default(false);

const discoveryEvents = new commander.Option(
'--discovery-events [discoveryEvents...]',
'Filter for specified events',
)
.choices(['queued', 'processed', 'cancelled', 'failed'])
.default(undefined);

const limit = new commander.Option(
'--limit [limit]',
'Limit the number of emitted events',
)
.argParser(parseInt)
.default(undefined);

const order = new commander.Option(
'--order [order]',
'Filter for specified events',
)
.choices(['asc', 'desc'])
.default('asc');

export {
nodePath,
format,
Expand Down Expand Up @@ -272,4 +319,10 @@ export {
envInvalid,
envDuplicate,
discoveryMonitor,
seekStart,
seekEnd,
futureEvents,
discoveryEvents,
limit,
order,
};
Loading

0 comments on commit 857d979

Please sign in to comment.