Start to serve config

This commit is contained in:
Pierre HUBERT 2022-08-30 10:17:38 +02:00
parent 2441552165
commit 4afc1fad37
7 changed files with 84 additions and 28 deletions

18
Cargo.lock generated
View File

@ -181,6 +181,21 @@ dependencies = [
"syn", "syn",
] ]
[[package]]
name = "actix-web-httpauth"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6dda62cf04bc3a9ad2ea8f314f721951cfdb4cdacec4e984d20e77c7bb170991"
dependencies = [
"actix-utils",
"actix-web",
"base64",
"futures-core",
"futures-util",
"log",
"pin-project-lite",
]
[[package]] [[package]]
name = "adler" name = "adler"
version = "1.0.2" version = "1.0.2"
@ -507,6 +522,7 @@ dependencies = [
"futures-task", "futures-task",
"pin-project-lite", "pin-project-lite",
"pin-utils", "pin-utils",
"slab",
] ]
[[package]] [[package]]
@ -1046,6 +1062,8 @@ name = "tcp_relay_server"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"actix-web", "actix-web",
"actix-web-httpauth",
"base",
"clap", "clap",
"env_logger", "env_logger",
"log", "log",

View File

@ -1,5 +1,7 @@
#[derive(serde::Serialize, serde::Deserialize)] #[derive(serde::Serialize, serde::Deserialize)]
pub struct RelayedPort { pub struct RelayedPort {
pub id: u64, pub id: usize,
pub port: u16, pub port: u16,
} }
pub type RemoteConfig = Vec<RelayedPort>;

View File

@ -4,7 +4,9 @@ version = "0.1.0"
edition = "2021" edition = "2021"
[dependencies] [dependencies]
base = { path = "../base" }
clap = { version = "3.2.18", features = ["derive", "env"] } clap = { version = "3.2.18", features = ["derive", "env"] }
log = "0.4.17" log = "0.4.17"
env_logger = "0.9.0" env_logger = "0.9.0"
actix-web = "4" actix-web = "4"
actix-web-httpauth = "0.8.0"

View File

@ -0,0 +1,23 @@
use clap::Parser;
/// TCP relay server
#[derive(Parser, Debug, Clone)]
#[clap(author, version, about, long_about = None)]
pub struct Args {
/// Access tokens
#[clap(short, long)]
pub tokens: Vec<String>,
/// Forwarded ports
#[clap(short, long)]
pub ports: Vec<u16>,
/// HTTP server listen address
#[clap(short, long, default_value = "0.0.0.0:8000")]
pub listen_address: String,
/// Increment ports on client. Useful for debugging and running both client and server
/// on the same machine
#[clap(short, long, default_value_t = 0)]
pub increment_ports: u16,
}

View File

@ -1 +1 @@
pub mod server; pub mod args;

View File

@ -1,30 +1,39 @@
use std::sync::Arc; use std::sync::Arc;
use actix_web::{App, HttpServer, web}; use actix_web::{App, Error, HttpResponse, HttpServer, middleware, Responder, web};
use actix_web::dev::ServiceRequest;
use actix_web::error::ErrorUnauthorized;
use actix_web::web::Data;
use actix_web_httpauth::extractors::bearer::BearerAuth;
use actix_web_httpauth::middleware::HttpAuthentication;
use clap::Parser; use clap::Parser;
use tcp_relay_server::server::*; use base::RelayedPort;
use tcp_relay_server::args::Args;
/// TCP relay server async fn auth_validator(
#[derive(Parser, Debug, Clone)] req: ServiceRequest,
#[clap(author, version, about, long_about = None)] creds: BearerAuth,
struct Args { ) -> Result<ServiceRequest, (Error, ServiceRequest)> {
/// Access tokens let args: &Data<Arc<Args>> = req.app_data().unwrap();
#[clap(short, long)] if args.tokens.iter().any(|t| t == creds.token()) {
tokens: Vec<String>, Ok(req)
} else {
Err((ErrorUnauthorized("invalid token"), req))
}
}
/// Forwarded ports pub async fn hello_route() -> &'static str {
#[clap(short, long)] "TCP relay. Hello world!"
ports: Vec<usize>, }
/// HTTP server listen address pub async fn config_route(data: Data<Arc<Args>>) -> impl Responder {
#[clap(short, long, default_value = "0.0.0.0:8000")] HttpResponse::Ok().json(
listen_address: String, data.ports.iter()
.enumerate()
/// Increment ports on client. Useful for debugging and running both client and server .map(|(id, port)| RelayedPort { id, port: port + data.increment_ports })
/// on the same machine .collect::<Vec<_>>()
#[clap(short, long, default_value_t = 0)] )
increment_ports: usize,
} }
#[actix_web::main] #[actix_web::main]
@ -46,9 +55,14 @@ async fn main() -> std::io::Result<()> {
log::info!("Starting relay on http://{}", args.listen_address); log::info!("Starting relay on http://{}", args.listen_address);
HttpServer::new(|| { let args_clone = args.clone();
HttpServer::new(move || {
App::new() App::new()
.wrap(middleware::Logger::default())
.wrap(HttpAuthentication::bearer(auth_validator))
.app_data(Data::new(args_clone.clone()))
.route("/", web::get().to(hello_route)) .route("/", web::get().to(hello_route))
.route("/config", web::get().to(config_route))
}) })
.bind(&args.listen_address)? .bind(&args.listen_address)?
.run() .run()

View File

@ -1,3 +0,0 @@
pub async fn hello_route() -> &'static str {
"TCP relay. Hello world!"
}