mirror of
https://seed.radicle.dev/rad:z4V1sjrXqjvFdnCUbxPFqd5p4DtH5.git
synced 2026-10-30 16:50:47 +08:00
Move rad-web binary to radicle-httpd package
Signed-off-by: Thomas Scholtes <geigerzaehler@axiom.fm>
This commit is contained in:
committed by
cloudhead
parent
d707f0978e
commit
cd071f031c
@@ -37,6 +37,7 @@ tower-http = { version = "0.3.4", default-features = false, features = ["trace",
|
||||
tracing = { version = "0.1.37", default-features = false, features = ["std", "log"] }
|
||||
tracing-logfmt = { version = "0.2", optional = true }
|
||||
tracing-subscriber = { version = "0.3", default-features = false, features = ["std", "ansi", "fmt"] }
|
||||
ureq = { version = "2.9", default-features = false, features = ["json"] }
|
||||
|
||||
[dependencies.radicle]
|
||||
path = "../radicle"
|
||||
@@ -45,6 +46,9 @@ version = "0.2.0"
|
||||
[dependencies.radicle-term]
|
||||
path = "../radicle-term"
|
||||
|
||||
[dependencies.radicle-cli]
|
||||
path = "../radicle-cli"
|
||||
|
||||
[dev-dependencies]
|
||||
hyper = { version = "0.14.17", default-features = false, features = ["client"] }
|
||||
pretty_assertions = { version = "1.3.0" }
|
||||
|
||||
@@ -122,9 +122,9 @@ async fn session_delete_handler(
|
||||
|
||||
#[cfg(test)]
|
||||
mod routes {
|
||||
use crate::commands::web::{sign, SessionInfo};
|
||||
use axum::body::Body;
|
||||
use axum::http::StatusCode;
|
||||
use radicle_cli::commands::rad_web::{self, SessionInfo};
|
||||
|
||||
use crate::api::auth::{AuthState, Session};
|
||||
use crate::test::{self, get, post, put};
|
||||
@@ -154,7 +154,7 @@ mod routes {
|
||||
|
||||
// Create request body
|
||||
let signer = ctx.profile.signer().unwrap();
|
||||
let signature = rad_web::sign(signer, &session_info).unwrap();
|
||||
let signature = sign(signer, &session_info).unwrap();
|
||||
let body = serde_json::to_vec(&super::AuthChallenge {
|
||||
sig: signature,
|
||||
pk: session_info.public_key,
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
use radicle_cli::terminal as term;
|
||||
use radicle_httpd::commands::web as rad_web;
|
||||
|
||||
fn main() {
|
||||
term::run_command_args::<rad_web::Options, _>(
|
||||
rad_web::HELP,
|
||||
rad_web::run,
|
||||
std::env::args_os().skip(1).collect(),
|
||||
)
|
||||
}
|
||||
@@ -0,0 +1,2 @@
|
||||
//! Extra CLI commands relating to HTTPd.
|
||||
pub mod web;
|
||||
@@ -0,0 +1,123 @@
|
||||
use std::ffi::OsString;
|
||||
|
||||
use anyhow::anyhow;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use radicle::crypto::{PublicKey, Signature, Signer};
|
||||
|
||||
use radicle_cli::terminal as term;
|
||||
use radicle_cli::terminal::args::{Args, Error, Help};
|
||||
|
||||
pub const HELP: Help = Help {
|
||||
name: "web",
|
||||
description: "Connect web with node",
|
||||
version: env!("CARGO_PKG_VERSION"),
|
||||
usage: r#"
|
||||
Usage
|
||||
|
||||
rad web [<option>...]
|
||||
|
||||
Options
|
||||
|
||||
--backend, -b httpd to bind to
|
||||
--frontend, -f Web interface to bind to
|
||||
--verbose, -v Verbose output
|
||||
--json Output as json
|
||||
--help Print help
|
||||
"#,
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Deserialize, Serialize)]
|
||||
#[serde(rename_all = "camelCase")]
|
||||
pub struct SessionInfo {
|
||||
pub session_id: String,
|
||||
pub public_key: PublicKey,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Options {
|
||||
pub backend: String,
|
||||
pub frontend: String,
|
||||
pub json: bool,
|
||||
pub verbose: bool,
|
||||
}
|
||||
|
||||
impl Args for Options {
|
||||
fn from_args(args: Vec<OsString>) -> anyhow::Result<(Self, Vec<OsString>)> {
|
||||
use lexopt::prelude::*;
|
||||
|
||||
let mut parser = lexopt::Parser::from_args(args);
|
||||
let mut backend = None;
|
||||
let mut frontend = None;
|
||||
let mut json = false;
|
||||
let mut verbose = false;
|
||||
|
||||
while let Some(arg) = parser.next()? {
|
||||
match arg {
|
||||
Long("verbose") | Short('v') => verbose = true,
|
||||
Long("backend") | Short('b') => {
|
||||
backend = Some(parser.value()?.to_string_lossy().to_string())
|
||||
}
|
||||
Long("frontend") | Short('f') => {
|
||||
frontend = Some(parser.value()?.to_string_lossy().to_string())
|
||||
}
|
||||
Long("json") => json = true,
|
||||
Long("help") | Short('h') => {
|
||||
return Err(Error::Help.into());
|
||||
}
|
||||
_ => {
|
||||
return Err(anyhow!(arg.unexpected()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Ok((
|
||||
Options {
|
||||
json,
|
||||
verbose,
|
||||
backend: backend.unwrap_or(String::from("http://0.0.0.0:8080")),
|
||||
frontend: frontend.unwrap_or(String::from("https://app.radicle.xyz")),
|
||||
},
|
||||
vec![],
|
||||
))
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sign(signer: Box<dyn Signer>, session: &SessionInfo) -> Result<Signature, anyhow::Error> {
|
||||
signer
|
||||
.try_sign(format!("{}:{}", session.session_id, session.public_key).as_bytes())
|
||||
.map_err(anyhow::Error::from)
|
||||
}
|
||||
|
||||
pub fn run(options: Options, ctx: impl term::Context) -> anyhow::Result<()> {
|
||||
let session: SessionInfo = ureq::post(&format!("{}/api/v1/sessions", options.backend))
|
||||
.call()?
|
||||
.into_json()?;
|
||||
let profile = ctx.profile()?;
|
||||
let signer = profile.signer()?;
|
||||
let signature = sign(signer, &session)?;
|
||||
|
||||
if options.json {
|
||||
println!(
|
||||
"{}",
|
||||
serde_json::json!({
|
||||
"sessionId": session.session_id,
|
||||
"publicKey": session.public_key,
|
||||
"signature": signature,
|
||||
})
|
||||
)
|
||||
} else {
|
||||
term::blank();
|
||||
term::info!("Open the following link to authenticate:");
|
||||
term::info!(
|
||||
" 👉 {}/session/{}?pk={}&sig={}",
|
||||
options.frontend,
|
||||
session.session_id,
|
||||
session.public_key,
|
||||
signature,
|
||||
);
|
||||
term::blank();
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
#![allow(clippy::type_complexity)]
|
||||
#![allow(clippy::too_many_arguments)]
|
||||
#![recursion_limit = "256"]
|
||||
pub mod commands;
|
||||
pub mod error;
|
||||
|
||||
use std::collections::HashMap;
|
||||
|
||||
Reference in New Issue
Block a user