Create a basic API client
This commit is contained in:
		
							
								
								
									
										66
									
								
								virtweb_backend/examples/api_curl.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								virtweb_backend/examples/api_curl.rs
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,66 @@
 | 
			
		||||
use clap::Parser;
 | 
			
		||||
use std::os::unix::prelude::CommandExt;
 | 
			
		||||
use std::process::Command;
 | 
			
		||||
use std::str::FromStr;
 | 
			
		||||
use virtweb_backend::api_tokens::TokenVerb;
 | 
			
		||||
use virtweb_backend::extractors::api_auth_extractor::TokenClaims;
 | 
			
		||||
use virtweb_backend::utils::jwt_utils::{sign_jwt, TokenPrivKey};
 | 
			
		||||
use virtweb_backend::utils::time_utils::time;
 | 
			
		||||
 | 
			
		||||
/// curl wrapper to query Virtweb backend API
 | 
			
		||||
#[derive(Parser, Debug)]
 | 
			
		||||
#[command(version, about, long_about = None)]
 | 
			
		||||
struct Args {
 | 
			
		||||
    /// URL of VirtWeb
 | 
			
		||||
    #[arg(short('u'), long, env, default_value = "http://localhost:8000")]
 | 
			
		||||
    virtweb_url: String,
 | 
			
		||||
 | 
			
		||||
    /// Token ID
 | 
			
		||||
    #[arg(short('i'), long, env)]
 | 
			
		||||
    token_id: String,
 | 
			
		||||
 | 
			
		||||
    /// Token private key
 | 
			
		||||
    #[arg(short('t'), long, env)]
 | 
			
		||||
    token_key: String,
 | 
			
		||||
 | 
			
		||||
    /// Request verb
 | 
			
		||||
    #[arg(short('X'), long, default_value = "GET")]
 | 
			
		||||
    verb: String,
 | 
			
		||||
 | 
			
		||||
    /// Request URI
 | 
			
		||||
    uri: String,
 | 
			
		||||
 | 
			
		||||
    /// Command line arguments to pass to cURL
 | 
			
		||||
    #[clap(trailing_var_arg = true, allow_hyphen_values = true)]
 | 
			
		||||
    run: Vec<String>,
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
fn main() {
 | 
			
		||||
    let args = Args::parse();
 | 
			
		||||
 | 
			
		||||
    let full_url = format!("{}{}", args.virtweb_url, args.uri);
 | 
			
		||||
    log::debug!("Full URL: {full_url}");
 | 
			
		||||
 | 
			
		||||
    let key = TokenPrivKey::ES384 {
 | 
			
		||||
        r#priv: args.token_key,
 | 
			
		||||
    };
 | 
			
		||||
    let claims = TokenClaims {
 | 
			
		||||
        sub: args.token_id.to_string(),
 | 
			
		||||
        iat: time() as usize,
 | 
			
		||||
        exp: time() as usize + 50,
 | 
			
		||||
        verb: TokenVerb::from_str(&args.verb).expect("Invalid request verb!"),
 | 
			
		||||
        path: args.uri,
 | 
			
		||||
        nonce: uuid::Uuid::new_v4().to_string(),
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    let jwt = sign_jwt(&key, &claims).expect("Failed to sign JWT!");
 | 
			
		||||
 | 
			
		||||
    Command::new("curl")
 | 
			
		||||
        .args(["-X", &args.verb])
 | 
			
		||||
        .args(["-H", &format!("x-token-id: {}", args.token_id)])
 | 
			
		||||
        .args(["-H", &format!("x-token-content: {jwt}")])
 | 
			
		||||
        .args(args.run)
 | 
			
		||||
        .arg(full_url)
 | 
			
		||||
        .exec();
 | 
			
		||||
    panic!("Failed to run curl!")
 | 
			
		||||
}
 | 
			
		||||
@@ -7,6 +7,7 @@ use crate::utils::jwt_utils::{TokenPrivKey, TokenPubKey};
 | 
			
		||||
use crate::utils::time_utils::time;
 | 
			
		||||
use actix_http::Method;
 | 
			
		||||
use std::path::Path;
 | 
			
		||||
use std::str::FromStr;
 | 
			
		||||
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Clone, Copy, Debug)]
 | 
			
		||||
pub struct TokenID(pub uuid::Uuid);
 | 
			
		||||
@@ -95,6 +96,21 @@ impl TokenVerb {
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
impl FromStr for TokenVerb {
 | 
			
		||||
    type Err = ();
 | 
			
		||||
 | 
			
		||||
    fn from_str(s: &str) -> Result<Self, Self::Err> {
 | 
			
		||||
        match s {
 | 
			
		||||
            "GET" => Ok(TokenVerb::GET),
 | 
			
		||||
            "POST" => Ok(TokenVerb::POST),
 | 
			
		||||
            "PUT" => Ok(TokenVerb::PUT),
 | 
			
		||||
            "PATCH" => Ok(TokenVerb::PATCH),
 | 
			
		||||
            "DELETE" => Ok(TokenVerb::DELETE),
 | 
			
		||||
            _ => Err(()),
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/// Structure used to create a token
 | 
			
		||||
#[derive(serde::Serialize, serde::Deserialize, Debug, Clone)]
 | 
			
		||||
pub struct NewToken {
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user