From 041531e88a19e426eb9007199052212c040a3db4 Mon Sep 17 00:00:00 2001 From: sam Date: Thu, 18 Jan 2024 21:44:53 +0100 Subject: [PATCH] more work on identity->chat hello/handshake --- chat/src/http/hello.rs | 21 +++++++++++++++++++++ chat/src/http/mod.rs | 18 ++++++++++++++++++ chat/src/main.rs | 12 +++++++++++- foxchat/src/fed/request.rs | 20 ++++++++++---------- foxchat/src/fed/signature.rs | 4 ++-- foxchat/src/s2s/http/hello.rs | 18 ++++++++++++++++++ foxchat/src/s2s/http/mod.rs | 3 +++ foxchat/src/s2s/mod.rs | 1 + identity/src/http/mod.rs | 2 +- identity/src/http/node.rs | 11 ++--------- identity/src/main.rs | 3 +-- identity/src/model/chat_instance.rs | 23 ++++++++--------------- 12 files changed, 96 insertions(+), 40 deletions(-) create mode 100644 chat/src/http/hello.rs create mode 100644 chat/src/http/mod.rs create mode 100644 foxchat/src/s2s/http/hello.rs create mode 100644 foxchat/src/s2s/http/mod.rs diff --git a/chat/src/http/hello.rs b/chat/src/http/hello.rs new file mode 100644 index 0000000..45d7414 --- /dev/null +++ b/chat/src/http/hello.rs @@ -0,0 +1,21 @@ +use std::sync::Arc; + +use axum::{Extension, Json}; +use foxchat::{ + http::ApiError, + s2s::http::{HelloRequest, HelloResponse, NodeResponse}, fed, +}; + +use crate::{app_state::AppState, model::instance::Instance}; + +pub async fn post_hello( + Extension(state): Extension>, + Json(data): Json, +) -> Result, ApiError> { + let instance = Instance::get(&state.pool).await?; + + let node = fed::get::(&instance.private_key, &state.config.domain, &data.host, "/_fox/ident/node", None).await?; + + // TODO: validate identity server's signature, probably adapt FoxRequestData.from_request_parts() (or extract it into a separate function? not sure if that's possible though) + todo!() +} diff --git a/chat/src/http/mod.rs b/chat/src/http/mod.rs new file mode 100644 index 0000000..5d7c812 --- /dev/null +++ b/chat/src/http/mod.rs @@ -0,0 +1,18 @@ +mod hello; + +use crate::{app_state::AppState, config::Config}; +use axum::{routing::post, Extension, Router}; +use sqlx::{Pool, Postgres}; +use std::sync::Arc; +use tower_http::trace::TraceLayer; + +pub fn new(pool: Pool, config: Config) -> Router { + let app_state = Arc::new(AppState { pool, config }); + + let app = Router::new() + .route("/_fox/chat/hello", post(hello::post_hello)) + .layer(TraceLayer::new_for_http()) + .layer(Extension(app_state)); + + return app; +} diff --git a/chat/src/main.rs b/chat/src/main.rs index 5d310f0..2b11e53 100644 --- a/chat/src/main.rs +++ b/chat/src/main.rs @@ -1,12 +1,15 @@ +mod app_state; mod config; mod db; mod fed; -mod app_state; +mod http; mod model; use crate::config::Config; use clap::{Parser, Subcommand}; use eyre::Result; +use std::net::{Ipv4Addr, SocketAddrV4}; +use tokio::net::TcpListener; use tracing::info; #[derive(Debug, Parser)] @@ -61,5 +64,12 @@ async fn main_web(config: Config) -> Result<()> { db::init_instance(&pool).await?; info!("Initialized instance data!"); + let port = config.port; + let app = http::new(pool, config); + + let listener = TcpListener::bind(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port)).await?; + + axum::serve(listener, app).await?; + Ok(()) } diff --git a/foxchat/src/fed/request.rs b/foxchat/src/fed/request.rs index 36a1f46..537aa8d 100644 --- a/foxchat/src/fed/request.rs +++ b/foxchat/src/fed/request.rs @@ -27,15 +27,15 @@ pub fn is_valid_domain(domain: &str) -> bool { pub async fn get( private_key: &RsaPrivateKey, - self_domain: String, - host: String, - path: String, + self_domain: &str, + host: &str, + path: &str, user_id: Option<&str>, ) -> Result { let (signature, date) = build_signature( private_key, - host.clone(), - path.clone(), + host, + path, None, user_id.clone(), ); @@ -58,9 +58,9 @@ pub async fn get( pub async fn post( private_key: &RsaPrivateKey, - self_domain: String, - host: String, - path: String, + self_domain: &str, + host: &str, + path: &str, user_id: Option<&str>, body: &T, ) -> Result { @@ -68,8 +68,8 @@ pub async fn post( let (signature, date) = build_signature( private_key, - host.clone(), - path.clone(), + host, + path, Some(body.len()), user_id.clone(), ); diff --git a/foxchat/src/fed/signature.rs b/foxchat/src/fed/signature.rs index df2590a..0aa106a 100644 --- a/foxchat/src/fed/signature.rs +++ b/foxchat/src/fed/signature.rs @@ -10,8 +10,8 @@ use crate::FoxError; pub fn build_signature( private_key: &RsaPrivateKey, - host: String, - request_path: String, + host: &str, + request_path: &str, content_length: Option, user_id: Option<&str>, ) -> (String, DateTime) { diff --git a/foxchat/src/s2s/http/hello.rs b/foxchat/src/s2s/http/hello.rs new file mode 100644 index 0000000..fb89293 --- /dev/null +++ b/foxchat/src/s2s/http/hello.rs @@ -0,0 +1,18 @@ +use serde::{Serialize, Deserialize}; + +#[derive(Serialize, Deserialize, Debug)] +pub struct HelloRequest { + pub host: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct HelloResponse { + pub public_key: String, + pub host: String, +} + +#[derive(Serialize, Deserialize, Debug)] +pub struct NodeResponse { + pub software: String, + pub public_key: String, +} diff --git a/foxchat/src/s2s/http/mod.rs b/foxchat/src/s2s/http/mod.rs new file mode 100644 index 0000000..d9da359 --- /dev/null +++ b/foxchat/src/s2s/http/mod.rs @@ -0,0 +1,3 @@ +mod hello; + +pub use hello::{HelloRequest, HelloResponse, NodeResponse}; diff --git a/foxchat/src/s2s/mod.rs b/foxchat/src/s2s/mod.rs index 1a46ca7..a5a2d8e 100644 --- a/foxchat/src/s2s/mod.rs +++ b/foxchat/src/s2s/mod.rs @@ -1,3 +1,4 @@ mod event; +pub mod http; pub use event::{DispatchEvent, Payload}; diff --git a/identity/src/http/mod.rs b/identity/src/http/mod.rs index 1d04da4..bd1715b 100644 --- a/identity/src/http/mod.rs +++ b/identity/src/http/mod.rs @@ -1,5 +1,5 @@ -mod node; mod account; +mod node; use std::sync::Arc; diff --git a/identity/src/http/node.rs b/identity/src/http/node.rs index 6b880b4..14b8f73 100644 --- a/identity/src/http/node.rs +++ b/identity/src/http/node.rs @@ -2,9 +2,8 @@ use std::sync::Arc; use axum::{Extension, Json, extract::Path}; use eyre::{Context, Result}; -use foxchat::http::ApiError; +use foxchat::{http::ApiError, s2s::http::NodeResponse}; use rsa::pkcs1::EncodeRsaPublicKey; -use serde::Serialize; use crate::{app_state::AppState, model::{instance::Instance, chat_instance::ChatInstance}}; @@ -19,19 +18,13 @@ pub async fn get_node( .wrap_err("serializing public key")?; Ok(Json(NodeResponse { - software: NODE_SOFTWARE, + software: NODE_SOFTWARE.into(), public_key, })) } const NODE_SOFTWARE: &str = "foxchat_ident"; -#[derive(Serialize)] -pub struct NodeResponse { - pub software: &'static str, - pub public_key: String, -} - pub async fn get_chat_node( Extension(state): Extension>, Path(domain): Path, diff --git a/identity/src/main.rs b/identity/src/main.rs index 36a1122..c7441ee 100644 --- a/identity/src/main.rs +++ b/identity/src/main.rs @@ -4,11 +4,10 @@ mod db; mod http; mod model; -use std::net::{Ipv4Addr, SocketAddrV4}; - use crate::config::Config; use clap::{Parser, Subcommand}; use color_eyre::eyre::Result; +use std::net::{Ipv4Addr, SocketAddrV4}; use tokio::net::TcpListener; use tracing::info; diff --git a/identity/src/model/chat_instance.rs b/identity/src/model/chat_instance.rs index 360adda..75d24a3 100644 --- a/identity/src/model/chat_instance.rs +++ b/identity/src/model/chat_instance.rs @@ -1,7 +1,11 @@ use std::sync::Arc; use eyre::Result; -use foxchat::{fed::{self, request::is_valid_domain}, FoxError}; +use foxchat::{ + fed::{self, request::is_valid_domain}, + s2s::http::{HelloRequest, HelloResponse}, + FoxError, +}; use serde::{Deserialize, Serialize}; use ulid::Ulid; @@ -47,9 +51,9 @@ impl ChatInstance { let resp: HelloResponse = fed::post( ¤t_instance.private_key, - state.config.domain.clone(), - domain.clone(), - "/_fox/chat/hello".into(), + &state.config.domain, + &domain, + "/_fox/chat/hello", None, &HelloRequest { host: state.config.domain.clone(), @@ -78,14 +82,3 @@ impl ChatInstance { Ok(instance) } } - -#[derive(Serialize, Debug)] -struct HelloRequest { - pub host: String, -} - -#[derive(Deserialize, Debug)] -struct HelloResponse { - pub public_key: String, - pub host: String, -}