From bd8d56efaf972d0a8dee20e23d0f8b55f08ef267 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Micha=C5=82=20=27rysiek=27=20Wo=C5=BAniak?= Date: Sat, 26 Nov 2022 18:40:21 +0000 Subject: [PATCH] started working on lrcli and on basic-integrity plugin cli (ref. %5) --- cli/README.md | 6 +++ cli/lrcli.js | 90 ++++++++++++++++++++++++++++++++++ plugins/basic-integrity/cli.js | 58 ++++++++++++++++++++++ 3 files changed, 154 insertions(+) create mode 100644 cli/README.md create mode 100644 cli/lrcli.js create mode 100644 plugins/basic-integrity/cli.js diff --git a/cli/README.md b/cli/README.md new file mode 100644 index 0000000..35fbc3d --- /dev/null +++ b/cli/README.md @@ -0,0 +1,6 @@ +# LibResilient CLI + +This is the command-line interface for LibResilient. It is supposed to understand the `config.json` configuration file, and simplify deployment of content so as to ensure that all configured transport plugins work as expected. It should also *test* if those channels work as expected. + +This is a work in progress and not production-ready yet. + diff --git a/cli/lrcli.js b/cli/lrcli.js new file mode 100644 index 0000000..4066e50 --- /dev/null +++ b/cli/lrcli.js @@ -0,0 +1,90 @@ +import { parse } from "https://deno.land/std/flags/mod.ts"; + +var parsed_args = parse( + Deno.args, + { + default: { + h: false, + }, + boolean: [ "h" ], + string: [], + alias: { + h: [ "help", "usage", "u" ] + }, + negatable: [], + // a function which is invoked with a command line parameter not defined + // in the options configuration object. If the function returns false, + // the unknown option is not added to parsedArgs. + unknown: null + } +); + +let printUsage = () => { + let usage = ` +Command-line interface for LibResilient. + +This script creates a common interface to CLI actions implemented by LibResilient plugins. + +Usage: + ${new URL('', import.meta.url).toString().split('/').at(-1)} [options] [plugin-name [plugin-options]] + +Options: + + -h, --help [plugin-name] + -u, --usage [plugin-name] + Print this message, if no plugin-name is given. + If plugin-name is provided, print usage information of that plugin. + +` + + console.log(usage) +} + +let printpluginUsage = (plugin) => { + let usage = ` +LibResilient CLI for plugin: ${plugin.name}. + +Plugin Description: + ${plugin.description} + +Usage: + ${new URL('', import.meta.url).toString().split('/').at(-1)} [general-options] ${plugin.name} [plugin-action [action-options]] + +General Options: + + -h, --help [plugin-name] + -u, --usage [plugin-name] + Print this message, if no plugin-name is given. + If plugin-name is provided, print usage information of that plugin. + +Actions and Action Options: +` + + console.log(usage) +} + +// assuming: +// - the first unknown argument is the name of the plugin +// - plugins live in ../plugins//cli.js, relative to lrcli.js location +// - only one plugin loaded per invocation, at least for now +let plugin +if (parsed_args._.length > 0) { + plugin = await import(`../plugins/${parsed_args._[0]}/cli.js`); + if (parsed_args._.length > 1) { + let action = parsed_args._[1] + if (action in plugin.actions) { + plugin.actions[action].run() + } else { + printpluginUsage(plugin) + } + } else { + printpluginUsage(plugin) + } +} else { + printUsage() +} + + + +console.log(parsed_args) +console.log(new URL('', import.meta.url).toString().split('/').at(-1)) diff --git a/plugins/basic-integrity/cli.js b/plugins/basic-integrity/cli.js new file mode 100644 index 0000000..de0356a --- /dev/null +++ b/plugins/basic-integrity/cli.js @@ -0,0 +1,58 @@ +/* ========================================================================= *\ +|* === basic-integrity: pre-configured subresource integrity for content === *| +\* ========================================================================= */ + +/** + * basic-integrity plugin's deploy/utility functions + * + * this code expects a Deno runtime: + * https://deno.land/ + */ + +/** + * get integrity data for specified urls, using specified algorithms + * + * naming of algorithms as accepted by SubtleCrypto.digest(): + * https://developer.mozilla.org/en-US/docs/Web/API/SubtleCrypto/digest + * + * paths - array of strings, paths to individual pieces of content + * algos - array of algorithms to use to calculate digests (default: "SHA-256") + */ +let getIntegrity = (paths, algos=["SHA-256"]) => { + + // we need non-emtpy arrays of string in the arguments + if (!Array.isArray(paths) || (paths.length == 0)) { + throw new Error("Expected non-empty array of strings in the 'paths' argument.") + } + if (!Array.isArray(algos) || (algos.length == 0)) { + throw new Error("Expected non-empty array of strings in the 'algos' argument.") + } + + console.log('weeee') + console.log(paths) + console.log(algos) + +} + + +// this never changes +const pluginName = "basic-integrity" +const pluginDescription = "verifying subresource integrity for resources fetched by other plugins" +const pluginVersion = 'COMMIT_UNKNOWN' +const pluginActions = { + "get-integrity": { + run: getIntegrity, + description: "calculate subresource integrity hashes for provided files", + arguments: { + paths: "array of strings, paths to individual pieces of content", + algos: "array of SubtleCrypto.digest-compatible algorithm names nto use to calculate digests (default: \"SHA-256\")" + } + } +} + +export { + pluginName as name, + pluginDescription as description, + pluginVersion as version, + pluginActions as actions +}