added ppc server and mize run external subcommands

This commit is contained in:
Sebastian Moser
2026-09-30 09:37:21 +02:00
parent e96e93a5a0
commit c19de1ed84
9 changed files with 497 additions and 55 deletions

237
Cargo.lock generated
View File

@@ -242,6 +242,12 @@ version = "1.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a" checksum = "9dbc3a507a82b17ba0d98f6ce8fd6954ea0c8152e98009d36a40d8dcc8ce078a"
[[package]]
name = "askama_escape"
version = "0.13.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3df27b8d5ddb458c5fb1bbc1ce172d4a38c614a97d550b0ac89003897fb01de4"
[[package]] [[package]]
name = "assign" name = "assign"
version = "1.1.1" version = "1.1.1"
@@ -419,7 +425,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf" checksum = "3b829e4e32b91e643de6eafe82b1d90675f5874230191a4ffbc1b336dec4d6bf"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum-core", "axum-core 0.3.4",
"base64 0.21.7", "base64 0.21.7",
"bitflags 1.3.2", "bitflags 1.3.2",
"bytes", "bytes",
@@ -429,7 +435,7 @@ dependencies = [
"http-body 0.4.6", "http-body 0.4.6",
"hyper 0.14.32", "hyper 0.14.32",
"itoa", "itoa",
"matchit", "matchit 0.7.3",
"memchr", "memchr",
"mime", "mime",
"percent-encoding", "percent-encoding",
@@ -448,6 +454,39 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "axum"
version = "0.8.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "31b698c5f9a010f6573133b09e0de5408834d0c82f8d7475a89fc1867a71cd90"
dependencies = [
"axum-core 0.5.6",
"bytes",
"form_urlencoded",
"futures-util",
"http 1.5.0",
"http-body 1.1.0",
"http-body-util",
"hyper 1.11.1",
"hyper-util",
"itoa",
"matchit 0.8.4",
"memchr",
"mime",
"percent-encoding",
"pin-project-lite",
"serde_core",
"serde_json",
"serde_path_to_error",
"serde_urlencoded",
"sync_wrapper 1.0.2",
"tokio",
"tower 0.5.3",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "axum-core" name = "axum-core"
version = "0.3.4" version = "0.3.4"
@@ -465,13 +504,32 @@ dependencies = [
"tower-service", "tower-service",
] ]
[[package]]
name = "axum-core"
version = "0.5.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1"
dependencies = [
"bytes",
"futures-core",
"http 1.5.0",
"http-body 1.1.0",
"http-body-util",
"mime",
"pin-project-lite",
"sync_wrapper 1.0.2",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "axum-extra" name = "axum-extra"
version = "0.4.2" version = "0.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f9a320103719de37b7b4da4c8eb629d4573f6bcfd3dfe80d3208806895ccf81d" checksum = "f9a320103719de37b7b4da4c8eb629d4573f6bcfd3dfe80d3208806895ccf81d"
dependencies = [ dependencies = [
"axum", "axum 0.6.20",
"bytes", "bytes",
"futures-util", "futures-util",
"http 0.2.12", "http 0.2.12",
@@ -496,6 +554,27 @@ dependencies = [
"syn 2.0.119", "syn 2.0.119",
] ]
[[package]]
name = "axum-oidc"
version = "1.0.0-dev-1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4e035204cbe5a2275fbb47dd0c36e5111963da82a62ab7da05a515f7688951b3"
dependencies = [
"axum 0.8.9",
"axum-core 0.5.6",
"futures-util",
"http 1.5.0",
"openidconnect",
"reqwest 0.12.28",
"serde",
"thiserror 2.0.20",
"tower-layer",
"tower-service",
"tower-sessions 0.14.0",
"tracing",
"urlencoding",
]
[[package]] [[package]]
name = "backon" name = "backon"
version = "1.6.0" version = "1.6.0"
@@ -1187,6 +1266,7 @@ version = "0.18.2"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87" checksum = "1a373e3602691c3cdea496d2f0ee5935151e6168fe87739483c463db1b2f2f87"
dependencies = [ dependencies = [
"percent-encoding",
"time", "time",
"version_check", "version_check",
] ]
@@ -2049,6 +2129,18 @@ dependencies = [
"warnings", "warnings",
] ]
[[package]]
name = "dioxus-ssr"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4544ecf908962909de403bfdf94f771b036e9e1857e371cd3279841a15a892e6"
dependencies = [
"askama_escape",
"dioxus-core",
"dioxus-core-types",
"rustc-hash 2.1.3",
]
[[package]] [[package]]
name = "dioxus-stores" name = "dioxus-stores"
version = "0.7.10" version = "0.7.10"
@@ -3494,6 +3586,7 @@ dependencies = [
"http 1.5.0", "http 1.5.0",
"http-body 1.1.0", "http-body 1.1.0",
"httparse", "httparse",
"httpdate",
"itoa", "itoa",
"pin-project-lite", "pin-project-lite",
"smallvec", "smallvec",
@@ -4287,6 +4380,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965" checksum = "224399e74b87b5f3557511d98dff8b14089b3dadafcab6bb93eab67d3aace965"
dependencies = [ dependencies = [
"scopeguard", "scopeguard",
"serde",
] ]
[[package]] [[package]]
@@ -4517,10 +4611,13 @@ dependencies = [
name = "marts" name = "marts"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"axum 0.8.9",
"axum-oidc",
"chrono", "chrono",
"chrono-tz", "chrono-tz",
"clap", "clap",
"dioxus", "dioxus",
"dioxus-ssr",
"flume 0.12.0", "flume 0.12.0",
"futures", "futures",
"generated", "generated",
@@ -4537,6 +4634,9 @@ dependencies = [
"spacetimedb", "spacetimedb",
"spacetimedb-sdk", "spacetimedb-sdk",
"tokio", "tokio",
"tower 0.5.3",
"tower-http 0.7.1",
"tower-sessions 0.15.0",
"tracing", "tracing",
"url", "url",
"wasm-bindgen", "wasm-bindgen",
@@ -4577,6 +4677,12 @@ version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94" checksum = "0e7465ac9959cc2b1404e8e2367b43684a6d13790fe23056cc8c6c5a6b7bcb94"
[[package]]
name = "matchit"
version = "0.8.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3"
[[package]] [[package]]
name = "matrix-pickle" name = "matrix-pickle"
version = "0.2.3" version = "0.2.3"
@@ -5005,7 +5111,7 @@ name = "mize"
version = "0.0.1" version = "0.0.1"
dependencies = [ dependencies = [
"async-trait", "async-trait",
"axum", "axum 0.6.20",
"axum-extra", "axum-extra",
"axum-macros", "axum-macros",
"ciborium", "ciborium",
@@ -8758,6 +8864,23 @@ dependencies = [
"tokio", "tokio",
"tower-layer", "tower-layer",
"tower-service", "tower-service",
"tracing",
]
[[package]]
name = "tower-cookies"
version = "0.11.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "151b5a3e3c45df17466454bb74e9ecedecc955269bdedbf4d150dfa393b55a36"
dependencies = [
"axum-core 0.5.6",
"cookie",
"futures-util",
"http 1.5.0",
"parking_lot",
"pin-project-lite",
"tower-layer",
"tower-service",
] ]
[[package]] [[package]]
@@ -8807,6 +8930,23 @@ dependencies = [
"url", "url",
] ]
[[package]]
name = "tower-http"
version = "0.7.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "08a05a66a4fdd61cbbe0a1d755ffe0ca6aba159dd4820936a0ff8a8278245b9c"
dependencies = [
"bitflags 2.13.1",
"bytes",
"http 1.5.0",
"http-body 1.1.0",
"percent-encoding",
"pin-project-lite",
"tower-layer",
"tower-service",
"tracing",
]
[[package]] [[package]]
name = "tower-layer" name = "tower-layer"
version = "0.3.3" version = "0.3.3"
@@ -8819,6 +8959,95 @@ version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3" checksum = "8df9b6e13f2d32c91b9bd719c00d1958837bc7dec474d94952798cc8e69eeec3"
[[package]]
name = "tower-sessions"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43a05911f23e8fae446005fe9b7b97e66d95b6db589dc1c4d59f6a2d4d4927d3"
dependencies = [
"async-trait",
"http 1.5.0",
"time",
"tokio",
"tower-cookies",
"tower-layer",
"tower-service",
"tower-sessions-core 0.14.0",
"tracing",
]
[[package]]
name = "tower-sessions"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "518dca34b74a17cadfcee06e616a09d2bd0c3984eff1769e1e76d58df978fc78"
dependencies = [
"async-trait",
"http 1.5.0",
"time",
"tokio",
"tower-cookies",
"tower-layer",
"tower-service",
"tower-sessions-core 0.15.0",
"tower-sessions-memory-store",
"tracing",
]
[[package]]
name = "tower-sessions-core"
version = "0.14.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce8cce604865576b7751b7a6bc3058f754569a60d689328bb74c52b1d87e355b"
dependencies = [
"async-trait",
"axum-core 0.5.6",
"base64 0.22.1",
"futures",
"http 1.5.0",
"parking_lot",
"rand 0.8.8",
"serde",
"serde_json",
"thiserror 2.0.20",
"time",
"tokio",
"tracing",
]
[[package]]
name = "tower-sessions-core"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "568531ec3dfcf3ffe493de1958ae5662a0284ac5d767476ecdb6a34ff8c6b06c"
dependencies = [
"async-trait",
"axum-core 0.5.6",
"base64 0.22.1",
"futures",
"http 1.5.0",
"parking_lot",
"rand 0.9.5",
"serde",
"serde_json",
"thiserror 2.0.20",
"time",
"tokio",
"tracing",
]
[[package]]
name = "tower-sessions-memory-store"
version = "0.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "713fabf882b6560a831e2bbed6204048b35bdd60e50bbb722902c74f8df33460"
dependencies = [
"async-trait",
"time",
"tokio",
"tower-sessions-core 0.15.0",
]
[[package]] [[package]]
name = "tracing" name = "tracing"
version = "0.1.44" version = "0.1.44"

View File

@@ -2,7 +2,7 @@ use clap::ArgMatches;
use core::result::Result::Err; use core::result::Result::Err;
use core::unimplemented; use core::unimplemented;
use mize::flume::bounded; use mize::flume::bounded;
use mize::mize_err; use mize::{instance, mize_err};
use std::ffi::OsString; use std::ffi::OsString;
use std::io::Read; use std::io::Read;
use std::path::PathBuf; use std::path::PathBuf;
@@ -18,8 +18,7 @@ use mize::item::{IntoItemData, ItemData};
use mize::platform::os::config_from_cli_args; use mize::platform::os::config_from_cli_args;
use mize::platform::os::fsstore::FileStore; use mize::platform::os::fsstore::FileStore;
pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn get(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
let id = sub_matches let id = sub_matches
.get_one::<String>("id") .get_one::<String>("id")
@@ -42,13 +41,12 @@ pub fn get(sub_matches: &ArgMatches) -> MizeResult<()> {
return Ok(()); return Ok(());
} }
pub fn call(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn call(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
println!("call cmd not implemented"); println!("call cmd not implemented");
Ok(()) Ok(())
} }
pub fn create(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn create(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
let mut instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
let item = instance.new_item()?; let item = instance.new_item()?;
@@ -58,27 +56,37 @@ pub fn create(sub_matches: &ArgMatches) -> MizeResult<()> {
return Ok(()); return Ok(());
} }
pub fn status(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn status(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
println!("not implemented"); println!("not implemented");
Err(mize_err!("not implemented")) Err(mize_err!("not implemented"))
} }
pub fn info(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn info(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
println!("not implemented"); println!("not implemented");
Err(mize_err!("not implemented")) Err(mize_err!("not implemented"))
} }
pub fn run(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn run(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?; match sub_matches.subcommand() {
None => {
instance.wait(); instance.wait();
}
Some((runnable, sub_matches)) => {
let ext_args: Vec<String> = sub_matches
.get_many::<OsString>("")
.unwrap_or_default()
.map(|v| v.to_string_lossy().to_string())
.collect();
return Ok(()); println!("runnable: {}", runnable);
println!("args: {:?}", ext_args);
}
}
Ok(())
} }
pub fn set(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn set(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
let id = sub_matches let id = sub_matches
.get_one::<String>("id") .get_one::<String>("id")
.ok_or(MizeError::new().msg("No id Argument specified"))?; .ok_or(MizeError::new().msg("No id Argument specified"))?;
@@ -92,7 +100,7 @@ pub fn set(sub_matches: &ArgMatches) -> MizeResult<()> {
Ok(()) Ok(())
} }
pub fn show(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn show(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
println!("not implemented"); println!("not implemented");
// let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?; // let instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
@@ -116,7 +124,7 @@ pub fn show(sub_matches: &ArgMatches) -> MizeResult<()> {
Ok(()) Ok(())
} }
pub fn format_cbor(sub_matches: &ArgMatches) -> MizeResult<()> { pub fn format_cbor(sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
let mut input: Vec<u8> = Vec::new(); let mut input: Vec<u8> = Vec::new();
let stdin = std::io::stdin(); let stdin = std::io::stdin();
let mut handle = stdin.lock(); let mut handle = stdin.lock();
@@ -130,7 +138,7 @@ pub fn format_cbor(sub_matches: &ArgMatches) -> MizeResult<()> {
Ok(()) Ok(())
} }
pub fn run_from_part(cmd: &str, sub_matches: &ArgMatches) -> MizeResult<()> { pub fn run_from_part(cmd: &str, sub_matches: &ArgMatches, instance: &mut Mize) -> MizeResult<()> {
let default = OsString::default(); let default = OsString::default();
let mut sub_cmd_line: Vec<OsString> = sub_matches let mut sub_cmd_line: Vec<OsString> = sub_matches
.get_many::<OsString>("") .get_many::<OsString>("")
@@ -139,8 +147,6 @@ pub fn run_from_part(cmd: &str, sub_matches: &ArgMatches) -> MizeResult<()> {
.collect(); .collect();
sub_cmd_line.insert(0, OsString::from_str(cmd)?); sub_cmd_line.insert(0, OsString::from_str(cmd)?);
let mut instance = Mize::with_config(config_from_cli_args(sub_matches)?)?;
debug!("loading module '{}'", cmd); debug!("loading module '{}'", cmd);
instance.load_part(cmd)?; instance.load_part(cmd)?;

View File

@@ -9,8 +9,9 @@ use std::process::exit;
use mize::error::{MizeError, MizeResult}; use mize::error::{MizeError, MizeResult};
use mize::item::ItemData; use mize::item::ItemData;
use mize::platform::os::config_from_cli_args;
use mize::platform::os::logging::init_logger; use mize::platform::os::logging::init_logger;
use mize::{instance, Mize}; use mize::{Mize, instance, mize_err};
use std::env; use std::env;
use std::io::Write; use std::io::Write;
use std::sync::Arc; use std::sync::Arc;
@@ -21,37 +22,72 @@ mod cli;
static APPNAME: &str = "mize"; static APPNAME: &str = "mize";
macro_rules! compile_in_parts {
(
$mize:ident,
$(
$name:literal : $part:path
),+ $(,)?
) => {
let enable = $mize.get_config("enable")?;
let mut enable_str = Vec::new();
for name in enable.cbor().as_array().ok_or(mize_err!("config(enable) not a list"))? {
enable_str.push(name.as_text().ok_or("part name not a str")?);
}
$(
if enable_str.contains(&$name) {
tracing::info!("enabling compiled_in_part: {}", $name);
$part(&mut $mize);
}
)+
};
}
fn main() { fn main() {
// welcome to the mize source code if let Err(e) = tried_main() {
// this is the main entry point for platforms with an os (eg: Linux, MacOS, Windows, BSD, ...) e.log();
// Also let's try to make the most best documented code ever. (eventually) so it's fun to work on }
}
fn tried_main() -> MizeResult<()> {
let cli_matches = cli_matches(); let cli_matches = cli_matches();
// logging
init_logger(&cli_matches); init_logger(&cli_matches);
// match command // init mize
let result = match cli_matches.subcommand() { let mut mize = Mize::with_config(config_from_cli_args(&cli_matches)?)?;
Some(("run", sub_matches)) => cli::run(sub_matches),
Some(("status", sub_matches)) => cli::status(sub_matches),
Some(("info", sub_matches)) => cli::info(sub_matches),
Some(("get", sub_matches)) => cli::get(sub_matches), // compiled in parts (which for now is all)
Some(("set", sub_matches)) => cli::set(sub_matches), compile_in_parts! {
Some(("show", sub_matches)) => cli::show(sub_matches), mize,
Some(("call", sub_matches)) => cli::call(sub_matches), "cli": marts::cli,
Some(("create", sub_matches)) => cli::create(sub_matches), "auth": marts::part_client_auth,
Some(("format-cbor", sub_matches)) => cli::format_cbor(sub_matches), "spacetime": marts::spacetime,
//"matrix": marts::part_matrix,
Some((cmd, sub_matches)) => cli::run_from_part(cmd, sub_matches), "ppc.server": marts::ppc::server::part_ppc_server,
None => Err(MizeError::new() "c2vi": marts::part_c2vi,
.msg("No subcommand was passed. use --help to list availavle comamnds.")),
}; };
if let Err(err) = result {
err.log(); // match subcommand
exit(1); match cli_matches.subcommand() {
} Some(("run", sub_matches)) => cli::run(sub_matches, &mut mize),
Some(("status", sub_matches)) => cli::status(sub_matches, &mut mize),
Some(("info", sub_matches)) => cli::info(sub_matches, &mut mize),
Some(("get", sub_matches)) => cli::get(sub_matches, &mut mize),
Some(("set", sub_matches)) => cli::set(sub_matches, &mut mize),
Some(("show", sub_matches)) => cli::show(sub_matches, &mut mize),
Some(("call", sub_matches)) => cli::call(sub_matches, &mut mize),
Some(("create", sub_matches)) => cli::create(sub_matches, &mut mize),
Some(("format-cbor", sub_matches)) => cli::format_cbor(sub_matches, &mut mize),
Some((cmd, sub_matches)) => cli::run_from_part(cmd, sub_matches, &mut mize),
None => Err(MizeError::new()
.msg("No subcommand was passed. use --help to list availavle comamnds.")),
}?;
Ok(())
} }
fn cli_matches() -> clap::ArgMatches { fn cli_matches() -> clap::ArgMatches {
@@ -119,7 +155,7 @@ fn cli_matches() -> clap::ArgMatches {
.subcommand(Command::new("call").aliases(["c"])) .subcommand(Command::new("call").aliases(["c"]))
.subcommand(Command::new("create").aliases(["cr"])) .subcommand(Command::new("create").aliases(["cr"]))
.subcommand(Command::new("status").aliases(["st"])) .subcommand(Command::new("status").aliases(["st"]))
.subcommand(Command::new("run")) .subcommand(Command::new("run").allow_external_subcommands(true))
.subcommand(Command::new("format-cbor").aliases(["fc"])) .subcommand(Command::new("format-cbor").aliases(["fc"]))
.arg_required_else_help(true); .arg_required_else_help(true);

View File

@@ -41,6 +41,13 @@ chrono-tz = { version = "0.10.4", default-features = false }
url = "2.5.8" url = "2.5.8"
serenity = { version = "0.12.5", optional = true } serenity = { version = "0.12.5", optional = true }
matrix-sdk = "0.18.0" matrix-sdk = "0.18.0"
axum = { version = "0.8.9", optional = true }
dioxus-ssr = { version = "0.7.10", optional = true }
axum-oidc = { version = "=1.0.0-dev-1", optional = true }
tower = { version = "0.5.3", optional = true }
tower-sessions = { version = "0.15.0", optional = true }
tower-http = { version = "0.7.1", optional = true, features = [ "cors", "trace" ] }
[features] [features]
@@ -52,6 +59,6 @@ target-js = [ "mize/target-js", "spacetimedb-sdk/browser", "wasm-bindgen", "wasm
target-obsidian = [ "target-js" ] target-obsidian = [ "target-js" ]
desktop = ["dioxus/desktop"] desktop = ["dioxus/desktop"]
client = [] client = []
server = [] server = [ "axum", "dioxus-ssr", "axum-oidc", "tower", "tower-sessions", "tower-http" ]
clap = ["dep:clap"] clap = ["dep:clap"]
serenity = ["dep:serenity"] serenity = ["dep:serenity"]

View File

@@ -1,8 +1,19 @@
use dioxus::prelude::*; use dioxus::prelude::*;
use axum::response::Html;
pub fn main_page() -> Html<String> {
let html_output = dioxus_ssr::render_element(rsx! {
div {
h1 { "Hello from Dioxus SSR!" }
p { "This was rendered on the server and sent via Axum." }
}
});
pub fn main_page() -> Element { Html(html_output)
}
pub fn main_page_element() -> Element {
rsx! { rsx! {
"hello world" "hello world"
div { div {

View File

@@ -1,4 +1,9 @@
use std::str::FromStr;
use clap::Command;
use dioxus::prelude::*;
use mize::Mize;
use mize::MizeResult;
pub mod server;
pub mod main_page; pub mod main_page;
pub use main_page::main_page;

145
marts/src/ppc/server.rs Normal file
View File

@@ -0,0 +1,145 @@
use std::str::FromStr;
use mize::{Mize, MizeError, MizeResult, mize_err};
use axum::response::Html;
use serde_json::json;
use serde_json::Value;
use axum::{
Json,
Router,
error_handling::HandleErrorLayer,
http::Uri,
response::IntoResponse,
routing::{any, get},
};
use axum_oidc::handle_oidc_redirect;
use axum_oidc::{
EmptyAdditionalClaims, OidcAuthLayer, OidcClaims, OidcClient, OidcLoginLayer,
OidcRpInitiatedLogout, error::MiddlewareError,
};
use openidconnect::Scope;
use openidconnect::{ClientId, ClientSecret, IssuerUrl};
use tower::ServiceBuilder;
use tower_sessions::{
Expiry, MemoryStore, SessionManagerLayer,
cookie::{SameSite, time::Duration},
};
pub fn part_ppc_server(mize: &mut Mize) -> MizeResult<()> {
mize.add_name_only_part("ppc.server");
let mut mize_clone = mize.clone();
mize.spawn_async("ppc.server_runner", start_server(mize_clone));
Ok(())
}
pub async fn start_server(mut mize: Mize) -> MizeResult<()> {
dioxus::logger::initialize_default();
let issuer = mize.get_config("auth.issuer")?.value_string()?;
let client_id = mize.get_config("auth.client_id")?.value_string()?;
let client_secret = mize.get_config("auth.client_secret")?.value_string()?;
let url = mize.get_config("web.url")?.value_string()?;
let redirect_url = format!("{url}/oidc");
let session_store = MemoryStore::default();
let session_layer = SessionManagerLayer::new(session_store)
.with_secure(false)
.with_same_site(SameSite::Lax)
.with_expiry(Expiry::OnInactivity(Duration::seconds(120)));
let oidc_login_service = ServiceBuilder::new()
.layer(HandleErrorLayer::new(|e: MiddlewareError| async {
dbg!(&e);
e.into_response()
}))
.layer(OidcLoginLayer::<EmptyAdditionalClaims>::new());
let oidc_client = OidcClient::<EmptyAdditionalClaims>::builder()
.with_default_http_client()
.with_redirect_url(Uri::from_str(redirect_url.as_str())?)
.with_client_id(ClientId::new(client_id))
.add_scope(Scope::new("profile".into()))
.add_scope(Scope::new("email".into()))
// Optional: add untrusted audiences. If the `aud` claim contains any of these audiences, the token is rejected.
//.add_untrusted_audience(Audience::new("123456789".to_string()))
.with_client_secret(ClientSecret::new(client_secret))
.discover(IssuerUrl::new(issuer.into()).expect("Invalid IssuerUrl"))
.await
.unwrap()
.build();
let oidc_auth_service = ServiceBuilder::new()
.layer(HandleErrorLayer::new(|e: MiddlewareError| async {
dbg!(&e);
e.into_response()
}))
.layer(OidcAuthLayer::new(oidc_client));
let app = Router::new()
.route("/foo", get(authenticated))
.route("/logout", get(logout))
.layer(oidc_login_service)
.route("/bar", get(maybe_authenticated))
.route("/oidc", any(handle_oidc_redirect::<EmptyAdditionalClaims>))
.layer(oidc_auth_service)
.layer(session_layer)
.layer(tower_http::trace::TraceLayer::new_for_http())
// not authenticated routes
.route("/", get(crate::ppc::main_page::main_page()))
// matrix .well-known
.route(
"/.well-known/matrix/client",
get(handle_matrix_client).layer(tower_http::cors::CorsLayer::permissive()),
)
.route(
"/.well-known/matrix/server",
get(handle_matrix_server),
);
tracing::info!("Running on http://localhost:3000");
let listener = tokio::net::TcpListener::bind("0.0.0.0:3000").await.unwrap();
axum::serve(listener, app.into_make_service())
.await
.unwrap();
Ok(())
}
async fn authenticated(claims: OidcClaims<EmptyAdditionalClaims>) -> impl IntoResponse {
format!("Hello {}", claims.subject().as_str())
}
async fn maybe_authenticated(
claims: Result<OidcClaims<EmptyAdditionalClaims>, axum_oidc::error::ExtractorError>,
) -> impl IntoResponse {
if let Ok(claims) = claims {
format!(
"Hello {}! You are already logged in from another Handler.",
claims.subject().as_str()
)
} else {
"Hello anon!".to_string()
}
}
async fn logout(logout: OidcRpInitiatedLogout) -> impl IntoResponse {
logout.with_post_logout_redirect(Uri::from_static("https://localhost:3000"))
}
async fn handle_matrix_client() -> Json<Value> {
Json(json!({
"m.homeserver": {
"base_url": "https://matrix.ppc.social"
}
}))
}
async fn handle_matrix_server() -> Json<Value> {
Json(json!({
"m.server": "://ppc.social"
}))
}

View File

@@ -1028,6 +1028,9 @@ impl Mize {
}; };
self.add_part(Box::new(part)); self.add_part(Box::new(part));
} }
pub fn id_path(&self, id: &MizeId) -> MizeResult<String> {
Ok(id.path().join("/"))
}
} }
#[derive(Default)] #[derive(Default)]

View File

@@ -387,14 +387,14 @@ pub fn load_part(mize: &mut Mize, part_name: &str, path: Option<String>) -> Mize
pub fn config_from_cli_args(matches: &ArgMatches) -> MizeResult<ItemData> { pub fn config_from_cli_args(matches: &ArgMatches) -> MizeResult<ItemData> {
let mut config = ItemData::new(); let mut config = ItemData::new();
if let Some(config_file_path) = matches.get_one::<String>("config-file") { if let Some(config_file_path) = matches.get_one::<String>("config") {
config.merge(config_from_file(config_file_path.to_string())?); config.merge(config_from_file(config_file_path.to_string())?);
trace!("config after --config-file arg: {}", config); trace!("config after --config arg: {}", config);
} }
if let Some(config_string) = matches.get_one::<String>("config") { if let Some(config_string) = matches.get_one::<String>("opt") {
config.merge(data_from_string(config_string.to_string())?); config.merge(data_from_string(config_string.to_string())?);
trace!("config after --config arg: {}", config); trace!("config after --opt arg: {}", config);
} }
return Ok(config); return Ok(config);