diff --git a/Cargo.lock b/Cargo.lock index 45bb96d..545982a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -125,6 +125,12 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "bitflags" +version = "2.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b588b76d00fde79687d7646a9b5bdf3cc0f655e0bbd080335a95d7e96f3587da" + [[package]] name = "block-buffer" version = "0.12.1" @@ -369,6 +375,12 @@ dependencies = [ "pin-project-lite", ] +[[package]] +name = "http-range-header" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9171a2ea8a68358193d15dd5d70c1c10a2afc3e7e4c5bc92bc9f025cebd7359c" + [[package]] name = "httparse" version = "1.10.1" @@ -504,11 +516,13 @@ dependencies = [ "http", "ldap3_proto", "minijinja", + "minijinja-embed", "serde", "static-serve", "tokio", "tokio-util", "tower", + "tower-http", "tracing", "tracing-subscriber", "uuid", @@ -564,6 +578,12 @@ dependencies = [ "serde", ] +[[package]] +name = "minijinja-embed" +version = "2.24.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c2795289c499a1331f73166ff8b8e0e68fdc81ef0b385eecb0e4de96f1638b66" + [[package]] name = "minimal-lexical" version = "0.2.1" @@ -964,6 +984,7 @@ version = "1.53.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "202caea871b69668250d242070849eb495be178ed697a3e98aebce5bc81a0bed" dependencies = [ + "bytes", "libc", "mio", "pin-project-lite", @@ -1013,6 +1034,31 @@ dependencies = [ "tracing", ] +[[package]] +name = "tower-http" +version = "0.7.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "08a05a66a4fdd61cbbe0a1d755ffe0ca6aba159dd4820936a0ff8a8278245b9c" +dependencies = [ + "bitflags", + "bytes", + "futures-core", + "futures-util", + "http", + "http-body", + "http-body-util", + "http-range-header", + "httpdate", + "mime", + "mime_guess", + "percent-encoding", + "pin-project-lite", + "tokio", + "tokio-util", + "tower-layer", + "tower-service", +] + [[package]] name = "tower-layer" version = "0.3.3" diff --git a/Cargo.toml b/Cargo.toml index 9ce4c55..903b294 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -13,11 +13,13 @@ futures-util = { version = "0.3.34", features = ["sink"] } http = { version = "1.5.0", optional = true } ldap3_proto = "0.8.1" minijinja = { version = "2.24.0", optional = true } +minijinja-embed = { version = "2.24.0", optional = true } serde = { version = "1.0.229", features = ["derive"] } static-serve = { version = "0.6.3", optional = true } tokio = { version = "1.53.1", features = ["macros", "net", "rt", "time", "sync"] } tokio-util = { version = "0.7.19", features = ["codec"] } tower = "0.5.3" +tower-http = { version = "0.7.1", features = ["fs"], optional = true } tracing = "0.1.44" tracing-subscriber = "0.3.23" uuid = { version = "1.26.0", features = ["v4"] } @@ -30,5 +32,12 @@ perf = "deny" style = "deny" [features] -default = [ "http" ] -http = ["dep:axum", "dep:axum-extra", "dep:http", "dep:minijinja", "dep:static-serve"] +default = [ "http", "noembed" ] +# Embed assets and templates in binary +embed = [ "dep:minijinja-embed", "dep:static-serve" ] +# Don't embed assets and templates in binary +noembed = [ "dep:tower-http" ] +http = ["dep:axum", "dep:axum-extra", "dep:http", "dep:minijinja"] + +[build-dependencies] +minijinja-embed = { version = "2.24.0", optional = true } diff --git a/build.rs b/build.rs new file mode 100644 index 0000000..19fb9dc --- /dev/null +++ b/build.rs @@ -0,0 +1,4 @@ +fn main() { + #[cfg(feature = "embed")] + minijinja_embed::embed_templates!("templates"); +} diff --git a/src/db/memory.rs b/src/db/memory.rs index 56c5934..62b98a3 100644 --- a/src/db/memory.rs +++ b/src/db/memory.rs @@ -65,10 +65,12 @@ impl DatabaseInterface for MemoryDatabase { self.create_user(new_user).await } - fn list_users(&self, domain: Option) -> impl Future, BoxedError>> { + fn list_users( + &self, + domain: Option, + ) -> impl Future, BoxedError>> { let users = if let Some(domain) = domain { - self - .users + self.users .iter() .filter(|user| user.domain.as_ref() == Some(&domain)) .cloned() diff --git a/src/http/mod.rs b/src/http/mod.rs index 89187c2..98a20ed 100644 --- a/src/http/mod.rs +++ b/src/http/mod.rs @@ -5,8 +5,13 @@ use axum::routing::{get, post}; use axum::serve::Listener as AxumListener; use axum_extra::extract::cookie::CookieJar; use http::StatusCode; -use minijinja::{Environment, context, path_loader}; +#[cfg(not(feature = "embed"))] +use minijinja::path_loader; +use minijinja::{Environment, context}; +#[cfg(feature = "embed")] use static_serve::embed_assets; +#[cfg(not(feature = "embed"))] +use tower_http::services::ServeDir; use crate::db::{Database, DatabaseInterface, Operation}; use crate::listener::{Listener, ListenerKind}; @@ -67,6 +72,9 @@ pub struct HttpState { impl HttpState { pub fn new(db: Database) -> Self { let mut templates = Environment::new(); + #[cfg(feature = "embed")] + minijinja_embed::load_templates!(&mut templates); + #[cfg(not(feature = "embed"))] templates.set_loader(path_loader("templates")); Self { db, @@ -77,9 +85,19 @@ impl HttpState { } pub async fn http_listen(listener: Listener, db: Database) { - embed_assets!("assets"); - let app = Router::new() - .nest("/assets", static_router()) + #[cfg(all(feature = "embed", feature = "noembed"))] + compile_error!("You cannot have `embed` and `noembed` features enabled at the same time."); + #[cfg(not(any(feature = "embed", feature = "noembed")))] + compile_error!("You must have `embed` or `noembed` feature enabled."); + + #[cfg(feature = "embed")] + let app = { + embed_assets!("assets"); + Router::new().nest("/assets", static_router()) + }; + #[cfg(not(feature = "embed"))] + let app = { Router::new().nest_service("/assets", ServeDir::new("assets")) }; + let app = app .route("/", get(home)) .route("/login", get(home)) .route("/login", post(login::post_login))