Migrate server to new crate

This commit is contained in:
Jett Chen 2024-11-22 11:21:02 +08:00
parent b806b28a6e
commit 321d36b743
18 changed files with 167 additions and 63 deletions

67
Cargo.lock generated
View file

@ -122,9 +122,9 @@ dependencies = [
[[package]] [[package]]
name = "anyhow" name = "anyhow"
version = "1.0.87" version = "1.0.93"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10f00e1f6e58a40e807377c75c6a7f97bf9044fab57816f2414e6f5f4499d7b8" checksum = "4c95c10ba0b00a02636238b814946408b1322d5ac4760326e6fb8ec956d85775"
[[package]] [[package]]
name = "arraydeque" name = "arraydeque"
@ -539,11 +539,11 @@ dependencies = [
"nix 0.27.1", "nix 0.27.1",
"once_cell", "once_cell",
"parking_lot", "parking_lot",
"prost 0.13.2", "prost 0.13.3",
"prost-types 0.13.2", "prost-types 0.13.3",
"rand", "rand",
"rand_core", "rand_core",
"reqwest 0.12.7", "reqwest 0.12.9",
"ring", "ring",
"rusqlite", "rusqlite",
"rust-ini 0.21.1", "rust-ini 0.21.1",
@ -2644,12 +2644,12 @@ dependencies = [
[[package]] [[package]]
name = "prost" name = "prost"
version = "0.13.2" version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b2ecbe40f08db5c006b5764a2645f7f3f141ce756412ac9e1dd6087e6d32995" checksum = "7b0487d90e047de87f984913713b85c601c05609aad5b0df4b4573fbf69aa13f"
dependencies = [ dependencies = [
"bytes", "bytes",
"prost-derive 0.13.2", "prost-derive 0.13.3",
] ]
[[package]] [[package]]
@ -2666,8 +2666,8 @@ dependencies = [
"once_cell", "once_cell",
"petgraph", "petgraph",
"prettyplease", "prettyplease",
"prost 0.13.2", "prost 0.13.3",
"prost-types 0.13.2", "prost-types 0.13.3",
"regex", "regex",
"syn 2.0.89", "syn 2.0.89",
"tempfile", "tempfile",
@ -2688,9 +2688,9 @@ dependencies = [
[[package]] [[package]]
name = "prost-derive" name = "prost-derive"
version = "0.13.2" version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "acf0c195eebb4af52c752bec4f52f645da98b6e92077a04110c7f349477ae5ac" checksum = "e9552f850d5f0964a4e4d0bf306459ac29323ddfbae05e35a7c0d35cb0803cc5"
dependencies = [ dependencies = [
"anyhow", "anyhow",
"itertools 0.13.0", "itertools 0.13.0",
@ -2710,11 +2710,11 @@ dependencies = [
[[package]] [[package]]
name = "prost-types" name = "prost-types"
version = "0.13.2" version = "0.13.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "60caa6738c7369b940c3d49246a8d1749323674c65cb13010134f5c9bad5b519" checksum = "4759aa0d3a6232fb8dbdb97b61de2c20047c68aca932c7ed76da9d788508d670"
dependencies = [ dependencies = [
"prost 0.13.2", "prost 0.13.3",
] ]
[[package]] [[package]]
@ -2899,9 +2899,9 @@ dependencies = [
[[package]] [[package]]
name = "reqwest" name = "reqwest"
version = "0.12.7" version = "0.12.9"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f8f4955649ef5c38cc7f9e8aa41761d48fb9677197daea9984dc54f56aad5e63" checksum = "a77c62af46e79de0a562e1a9849205ffcb7fc1238876e9bd743357570e04046f"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"bytes", "bytes",
@ -3249,9 +3249,9 @@ dependencies = [
[[package]] [[package]]
name = "serde_json" name = "serde_json"
version = "1.0.128" version = "1.0.133"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6ff5456707a1de34e7e37f2a6fd3d3f808c318259cbd01ab6377795054b483d8" checksum = "c7fceb2473b9166b2294ef05efcb65a3db80803f0b03ef86a5fc88a2b85ee377"
dependencies = [ dependencies = [
"itoa", "itoa",
"memchr", "memchr",
@ -3290,6 +3290,27 @@ dependencies = [
"serde", "serde",
] ]
[[package]]
name = "server"
version = "0.1.0"
dependencies = [
"anyhow",
"clap",
"config",
"dotenvy",
"jwt-simple",
"log",
"prost 0.13.3",
"prost-types 0.13.3",
"reqwest 0.12.9",
"rusqlite",
"serde",
"serde_json",
"tokio",
"tonic 0.12.3",
"tonic-build",
]
[[package]] [[package]]
name = "sha-1" name = "sha-1"
version = "0.10.1" version = "0.10.1"
@ -3591,9 +3612,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
[[package]] [[package]]
name = "tokio" name = "tokio"
version = "1.40.0" version = "1.41.1"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e2b070231665d27ad9ec9b8df639893f46727666c6767db40317fbe920a5d998" checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33"
dependencies = [ dependencies = [
"backtrace", "backtrace",
"bytes", "bytes",
@ -3754,7 +3775,7 @@ dependencies = [
"hyper-util", "hyper-util",
"percent-encoding", "percent-encoding",
"pin-project", "pin-project",
"prost 0.13.2", "prost 0.13.3",
"socket2", "socket2",
"tokio", "tokio",
"tokio-stream", "tokio-stream",
@ -3773,7 +3794,7 @@ dependencies = [
"prettyplease", "prettyplease",
"proc-macro2", "proc-macro2",
"prost-build", "prost-build",
"prost-types 0.13.2", "prost-types 0.13.3",
"quote", "quote",
"syn 2.0.89", "syn 2.0.89",
] ]

View file

@ -1,5 +1,5 @@
[workspace] [workspace]
members = ["burrow", "tun"] members = ["burrow", "server", "tun"]
resolver = "2" resolver = "2"
exclude = ["burrow-gtk"] exclude = ["burrow-gtk"]

View file

@ -1,2 +0,0 @@
pub mod client;
pub mod server;

View file

@ -5,18 +5,13 @@ pub mod wireguard;
mod daemon; mod daemon;
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
pub mod database; pub mod database;
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
mod auth;
pub(crate) mod tracing; pub(crate) mod tracing;
#[cfg(target_vendor = "apple")] #[cfg(target_vendor = "apple")]
pub use daemon::apple::spawn_in_process; pub use daemon::apple::spawn_in_process;
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
pub use daemon::{ pub use daemon::{
rpc::DaemonResponse, rpc::DaemonResponse, rpc::ServerInfo, DaemonClient, DaemonCommand, DaemonResponseData,
rpc::ServerInfo,
DaemonClient,
DaemonCommand,
DaemonResponseData,
DaemonStartOptions, DaemonStartOptions,
}; };

View file

@ -7,9 +7,6 @@ pub(crate) mod tracing;
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
mod wireguard; mod wireguard;
#[cfg(any(target_os = "linux", target_vendor = "apple"))]
mod auth;
#[cfg(any(target_os = "linux", target_vendor = "apple"))] #[cfg(any(target_os = "linux", target_vendor = "apple"))]
use daemon::{DaemonClient, DaemonCommand}; use daemon::{DaemonClient, DaemonCommand};
@ -52,8 +49,6 @@ enum Commands {
ServerConfig, ServerConfig,
/// Reload Config /// Reload Config
ReloadConfig(ReloadConfigArgs), ReloadConfig(ReloadConfigArgs),
/// Authentication server
AuthServer,
/// Server Status /// Server Status
ServerStatus, ServerStatus,
/// Tunnel Config /// Tunnel Config
@ -276,7 +271,6 @@ async fn main() -> Result<()> {
Commands::ServerInfo => try_serverinfo().await?, Commands::ServerInfo => try_serverinfo().await?,
Commands::ServerConfig => try_serverconfig().await?, Commands::ServerConfig => try_serverconfig().await?,
Commands::ReloadConfig(args) => try_reloadconfig(args.interface_id.clone()).await?, Commands::ReloadConfig(args) => try_reloadconfig(args.interface_id.clone()).await?,
Commands::AuthServer => crate::auth::server::serve().await?,
Commands::ServerStatus => try_serverstatus().await?, Commands::ServerStatus => try_serverstatus().await?,
Commands::TunnelConfig => try_tun_config().await?, Commands::TunnelConfig => try_tun_config().await?,
Commands::NetworkAdd(args) => { Commands::NetworkAdd(args) => {

40
server/Cargo.toml Normal file
View file

@ -0,0 +1,40 @@
[package]
name = "server"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.93"
jwt-simple = "0.12.10"
log = "0.4.22"
reqwest = { version = "0.12.9", default-features = false, features = [
"json",
"rustls-tls",
] }
serde = "1.0.215"
serde_json = "1.0.133"
tokio = { version = "1.41.1", features = [
"rt",
"macros",
"sync",
"io-util",
"rt-multi-thread",
"signal",
"time",
"tracing",
"fs",
] }
tonic = "0.12.3"
clap = { version = "4.4", features = ["derive"] }
rusqlite = { version = "0.31.0", features = ["blob"] }
dotenvy = "0.15.7"
config = "0.14.1"
prost = "0.13.3"
prost-types = "0.13.3"
[features]
bundled = ["rusqlite/bundled"]
[build-dependencies]
tonic-build = "0.12.3"

4
server/build.rs Normal file
View file

@ -0,0 +1,4 @@
fn main() -> Result<(), Box<dyn std::error::Error>> {
tonic_build::configure().compile_protos(&["../proto/burrowweb.proto"], &["../proto"])?;
Ok(())
}

1
server/src/build.rs Normal file
View file

@ -0,0 +1 @@

6
server/src/main.rs Normal file
View file

@ -0,0 +1,6 @@
pub mod client;
pub mod server;
fn main() {
println!("Hello, world!");
}

View file

@ -1,7 +1,5 @@
use anyhow::Result; use anyhow::Result;
use crate::daemon::rpc::grpc_defs::{Network, NetworkType};
pub static PATH: &str = "./server.sqlite3"; pub static PATH: &str = "./server.sqlite3";
pub fn init_db() -> Result<()> { pub fn init_db() -> Result<()> {

View file

@ -2,13 +2,12 @@ use std::sync::Arc;
use tonic::{Request, Response, Status}; use tonic::{Request, Response, Status};
use crate::auth::server::providers::{KeypairT, OpenIdUser}; use super::providers::{KeypairT, OpenIdUser};
use super::{ use super::{
grpc_defs::{ grpc_defs::{
burrowwebrpc::burrow_web_server::{BurrowWeb, BurrowWebServer}, burrowwebrpc::burrow_web_server::BurrowWeb, CreateDeviceRequest, CreateDeviceResponse,
CreateDeviceRequest, CreateDeviceResponse, Empty, JwtInfo, ListDevicesResponse, Empty, JwtInfo, ListDevicesResponse, SlackAuthRequest,
SlackAuthRequest,
}, },
providers::slack::auth, providers::slack::auth,
settings::BurrowAuthServerConfig, settings::BurrowAuthServerConfig,

View file

@ -5,29 +5,16 @@ pub mod providers;
pub mod settings; pub mod settings;
use anyhow::Result; use anyhow::Result;
use axum::{http::StatusCode, routing::post, Router};
use providers::slack::auth; use providers::slack::auth;
use tokio::signal; use tokio::signal;
pub async fn serve() -> Result<()> { pub async fn serve() -> Result<()> {
db::init_db()?; db::init_db()?;
let app = Router::new().route("/device/new", post(device_new));
let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap(); let listener = tokio::net::TcpListener::bind("0.0.0.0:8080").await.unwrap();
log::info!("Starting auth server on port 8080"); log::info!("Starting auth server on port 8080");
axum::serve(listener, app)
.with_graceful_shutdown(shutdown_signal())
.await
.unwrap();
Ok(()) Ok(())
} }
async fn device_new() -> StatusCode {
StatusCode::OK
}
async fn shutdown_signal() { async fn shutdown_signal() {
let ctrl_c = async { let ctrl_c = async {
signal::ctrl_c() signal::ctrl_c()

View file

@ -0,0 +1,66 @@
pub mod slack;
use self::grpc_defs::JwtInfo;
pub use super::{db, grpc_defs, settings::BurrowAuthServerConfig};
use anyhow::{anyhow, Result};
use jwt_simple::{
claims::{Claims, NoCustomClaims},
prelude::{Duration, Ed25519KeyPair, EdDSAKeyPairLike, EdDSAPublicKeyLike},
};
use serde::{Deserialize, Serialize};
pub type KeypairT = Ed25519KeyPair;
#[derive(Serialize, Deserialize, Default, Debug, PartialEq, Eq, Clone)]
pub struct OpenIdUser {
pub sub: String,
pub name: String,
}
#[derive(Serialize, Deserialize, Debug)]
struct OpenIDCustomField {
pub name: String,
}
impl OpenIdUser {
pub fn try_from_jwt(jwt_info: &JwtInfo, keypair: &KeypairT) -> Result<Self> {
let claims = keypair
.public_key()
.verify_token::<OpenIDCustomField>(&jwt_info.jwt, None)?;
Ok(Self {
sub: claims.subject.ok_or(anyhow!("No Subject!"))?,
name: claims.custom.name,
})
}
}
impl JwtInfo {
fn try_from_oid(oid_user: OpenIdUser, keypair: &KeypairT) -> Result<Self> {
let claims = Claims::with_custom_claims(
OpenIDCustomField { name: oid_user.name },
Duration::from_days(10),
)
.with_subject(oid_user.sub);
let jwt = keypair.sign(claims)?;
Ok(Self { jwt })
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_jwt() -> Result<()> {
let key_pair = Ed25519KeyPair::generate();
let sample_usr = OpenIdUser {
sub: "Spanish".into(),
name: "Inquisition".into(),
};
let encoded = JwtInfo::try_from_oid(sample_usr.clone(), &key_pair)?;
println!("{}", encoded.jwt);
let decoded = OpenIdUser::try_from_jwt(&encoded, &key_pair)?;
assert_eq!(decoded, sample_usr);
Ok(())
}
}

View file

@ -1,9 +1,4 @@
use anyhow::Result; use anyhow::Result;
use axum::{
extract::Json,
http::StatusCode,
routing::{get, post},
};
use reqwest::header::AUTHORIZATION; use reqwest::header::AUTHORIZATION;
use serde::Deserialize; use serde::Deserialize;