-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #22 from constata-eu/add_client
Add client
- Loading branch information
Showing
114 changed files
with
3,748 additions
and
648 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -10,5 +10,6 @@ members = [ | |
"integration_tests", | ||
"admin_cli", | ||
"i18n", | ||
"constata_cli", | ||
] | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
[package] | ||
name = "constata-cli" | ||
version = "0.1.0" | ||
authors = ["Constata <hola@constata.eu>"] | ||
description = "Command line client utility for Constata.eu graphql API" | ||
edition = "2018" | ||
|
||
[dependencies] | ||
dialoguer = "0.8.0" | ||
simplestcrypt = "*" | ||
serde = "1.0" | ||
base64 = "0.13.0" | ||
base64-serde = "0.6.1" | ||
serde_derive = "1.0" | ||
serde_json = "1.0" | ||
serde_with = { version = "1.6.4", features = ["hex"]} | ||
clap = { version = "4.2.1", features = ["derive"] } | ||
chrono = { version = "0.4", features = ["serde"] } | ||
bitcoin-wallet = { git = "https://github.com/rust-bitcoin/rust-wallet" } | ||
thiserror = "1.0.30" | ||
sha2 = "0.9.2" | ||
ureq = { version = "*", features = ["json"] } | ||
constata_lib = { path = "../constata_lib" } | ||
public_api = { path = "../public_api" } | ||
ex = "0.1.3" | ||
const_format = "*" | ||
hex = "*" | ||
|
||
# Add openssl-sys as a direct dependency so it can be cross compiled to | ||
# x86_64-unknown-linux-musl using the "vendored" feature below | ||
openssl-sys = "*" | ||
|
||
[features] | ||
# Force openssl-sys to staticly link in the openssl library. Necessary when | ||
# cross compiling to x86_64-unknown-linux-musl. | ||
vendored = ["openssl-sys/vendored"] | ||
|
||
[dependencies.bitcoin] | ||
version = "0.26.0" | ||
features = ["base64", "use-serde"] | ||
|
||
[dev-dependencies] | ||
fantoccini = "0.17.4" | ||
futures = "0.3.15" | ||
tokio = "*" | ||
assert_cmd = "*" | ||
|
||
[lib] | ||
name = "constata_client_lib" | ||
|
||
[[bin]] | ||
name = "constata-cli" | ||
path = "src/bin.rs" |
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# constata-cli | ||
Constata tool for generating, signing and timestamping diplomas, certificates of attendance and invitations. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,191 @@ | ||
mod runner; | ||
use runner::*; | ||
|
||
use clap::{Parser, Subcommand}; | ||
use std::path::PathBuf; | ||
use constata_client_lib::*; | ||
use dialoguer::{theme::ColorfulTheme, Password}; | ||
|
||
#[derive(Parser)] | ||
#[command(author, version, about, long_about = None)] | ||
struct Cli { | ||
/// Sets a custom config file | ||
#[arg(short, long, value_name = "FILE")] | ||
config: Option<PathBuf>, | ||
|
||
/// Use this daily password. Will prompt for a password if missing. | ||
#[arg(short, long, value_name = "FILE")] | ||
password: Option<String>, | ||
|
||
/// Extract a specific attribute from a successful JSON response. | ||
/// | ||
/// The id of your first issuance when calling all-issuances should be --json-pointer=/entries/0/id | ||
/// | ||
/// Exits with an error if the pointer is invalid or not found. | ||
/// | ||
/// See https://www.rfc-editor.org/rfc/rfc6901 for pointer syntax. | ||
#[arg(short, long)] | ||
json_pointer: Option<String>, | ||
|
||
#[command(subcommand)] | ||
command: Commands, | ||
} | ||
|
||
commands! { | ||
/// Start an issuance using a json array of objects as initial entries | ||
/// | ||
/// Each entry should be a flat object with strings as values, like: | ||
/// { | ||
/// "motive":"Big Data Analyst", | ||
/// "place":"Madrid, Spain", | ||
/// "date":"March 3, 2023", | ||
/// "recipient_identification":"Johnny777", | ||
/// "name":"John Doe", | ||
/// "shared_text":"Thank you for participating", | ||
/// "email":"john@example.com", | ||
/// "custom_text":"Large custom text" | ||
/// } | ||
CreateIssuanceFromJson => print_json, | ||
|
||
/// Start an issuance using a CSV file as initial entries. | ||
CreateIssuanceFromCsv => print_json, | ||
|
||
/// Append entries to a previously created issuance before signing it. | ||
AppendEntriesToIssuance => print_json, | ||
|
||
/// Lists your issuances | ||
AllIssuances => print_json, | ||
|
||
/// Queries an issuance's state, optionally waiting until the expected state is reached. | ||
IssuanceState => |runner, query| { | ||
runner.exit_with_boolean(query.run(&runner.client)?)?; | ||
}, | ||
|
||
/// Lists entries across all Issuances | ||
AllEntries => print_json, | ||
|
||
/// Gets an HTML preview of a specific entry so you can have a look before signing | ||
PreviewEntry => print_json_or_save("Preview for entry #{} saved to file"), | ||
|
||
/// Exports the verifiable HTML for an entry. | ||
/// | ||
/// Only available for entries in the 'done' state. | ||
/// See the entry-state to check for the entry status before calling. | ||
EntryHtmlExport => print_json_or_save("Verifiable HTML for Entry {} saved to file"), | ||
|
||
/// Exports all verifiable HTMLs from entries matching the given criteria | ||
/// | ||
/// Use all-entries to review your query before downloading. | ||
AllEntriesHtmlExport => |runner, query| { | ||
use std::io::Write; | ||
let result = query.run(&runner.client, |current, total, entry| { | ||
print!("\rProcessing entry {:>5}, its {:>5}/{:<5}", entry.id, current, total); | ||
let _ = std::io::stdout().flush(); | ||
})?; | ||
println!("\nSaved {} verifiable HTMLs", result); | ||
}, | ||
|
||
/// Exports the unsigned ZIP file with the entry contents, useful for signing. | ||
/// | ||
/// If you want an approximation of how an entry will look look at the preview-entry command. | ||
UnsignedEntryPayload => print_json_or_save("ZIP file with raw contents for entry {} was saved"), | ||
|
||
/// Gets an HTML preview of some entry in the given issue. Use when you don't care about a specific entry. | ||
PreviewSampleFromIssuance => print_json_or_save("Preview for entry {} saved to file"), | ||
|
||
/// Sign all entries in an issuance. | ||
/// | ||
/// This will download all entries and digitally sign them locally with your secure digital signature. | ||
SignIssuance => |runner, query| { | ||
use std::io::Write; | ||
query.run(&runner.client, |i| { | ||
print!("\rSigning entry {:>5} of {:>5}", i.current, i.total); | ||
let _ = std::io::stdout().flush(); | ||
})?; | ||
}, | ||
|
||
/// Export an issuance as a CSV file at any point. | ||
/// | ||
/// The exported issuance maintains the row ordering, and adds useful columns for each entry. | ||
/// You can use this export file to load up on another system, like mailchimp for campaigns. | ||
IssuanceExport => print_json_or_save("Export for Issuance #{} saved to file"), | ||
|
||
/// Lists all the templates you can use for your Issuances | ||
AllTemplates => print_json, | ||
|
||
/// Creates a new attestation of some files. | ||
CreateAttestation => print_json, | ||
|
||
/// Lists all your attestations | ||
AllAttestations => print_json, | ||
|
||
/// Downloads a verifiable HTML document from an attestation. | ||
AttestationHtmlExport => print_json_or_save("Verifiable HTML for Attestation {} saved to file"), | ||
|
||
/// Exports all verifiable HTMLs from attestations matching the given criteria | ||
/// | ||
/// Use all-attestations to review your query before downloading. | ||
AllAttestationsHtmlExport => |runner, query| { | ||
use std::io::Write; | ||
let result = query.run(&runner.client, |current, total, attestation| { | ||
print!("\rProcessing attestation {:>5}, its {:>5}/{:<5}", attestation.id, current, total); | ||
let _ = std::io::stdout().flush(); | ||
})?; | ||
println!("\nSaved {} verifiable HTMLs", result); | ||
}, | ||
|
||
/// Checks the state of an attestation, optionally waiting until it reaches that state. | ||
AttestationState => |runner, query| { | ||
runner.exit_with_boolean(query.run(&runner.client)?)?; | ||
}, | ||
|
||
/// Gets your organization's account state | ||
AccountState => print_json, | ||
|
||
/// Sets your web callbacks URL | ||
/// | ||
/// We will send a web callback to that URL when your attestations change state. | ||
/// Call with an empty URL to reset it. | ||
UpdateWebCallbacksUrl => print_json, | ||
|
||
/// Lists your web callbacks, for debugging and recovery. | ||
/// | ||
/// If you think you've missed any web callback, you can check here. | ||
/// The whole web callback body is included so you can reprocess it manually. | ||
AllWebCallbacks => print_json, | ||
|
||
/// Validate Web Callback, and outputs its contents if valid. | ||
ValidateWebCallback => print_json, | ||
|
||
/// Run a custom graphql query authenticated with your credentials. | ||
/// | ||
/// Gain access to new API features without a new client. | ||
/// Improve data transfer size by sending custom optimized queries. | ||
CustomGraphql => print_json, | ||
} | ||
|
||
impl Cli { | ||
fn run(self) -> ClientResult<()> { | ||
let daily_pass = self.password | ||
.map(|i| i.to_string()) | ||
.unwrap_or_else(|| { | ||
Password::with_theme(&ColorfulTheme::default()) | ||
.with_prompt("Enter your password") | ||
.interact() | ||
.unwrap() | ||
}); | ||
|
||
Runner::run( | ||
Client::from_config_file(self.config, &daily_pass)?, | ||
self.json_pointer, | ||
self.command | ||
) | ||
} | ||
} | ||
|
||
fn main() { | ||
if let Err(e) = Cli::parse().run() { | ||
println!("An error ocurred: {}", e); | ||
std::process::exit(1); | ||
} | ||
} |
Oops, something went wrong.