diff --git a/Cargo.lock b/Cargo.lock index 4aaedf5..498787a 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -335,9 +335,9 @@ checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" [[package]] name = "cc" -version = "1.1.36" +version = "1.1.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baee610e9452a8f6f0a1b6194ec09ff9e2d85dea54432acdae41aa0761c95d70" +checksum = "40545c26d092346d8a8dab71ee48e7685a7a9cba76e634790c215b41a4a7b4cf" dependencies = [ "jobserver", "libc", @@ -439,9 +439,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpufeatures" -version = "0.2.14" +version = "0.2.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "608697df725056feaccfa42cffdaeeec3fccc4ffc38358ecd19b243e716a78e0" +checksum = "0ca741a962e1b0bff6d724a1a0958b686406e853bb14061f218562e1896f95e6" dependencies = [ "libc", ] @@ -652,9 +652,9 @@ dependencies = [ [[package]] name = "fastrand" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8c02a5121d4ea3eb16a80748c74f5549a5665e4c21333c6098f283870fbdea6" +checksum = "486f806e73c5707928240ddc295403b1b93c96a02038563881c4a2fd84b81ac4" [[package]] name = "fixedbitset" @@ -851,7 +851,7 @@ dependencies = [ "aho-corasick", "bstr", "log", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -1274,9 +1274,9 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.161" +version = "0.2.162" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9489c2807c139ffd9c1794f4af0ebe86a828db53ecdc7fea2111d0fed085d1" +checksum = "18d287de67fe55fd7e1581fe933d965a5a9477b38e949cfa9f8574ef01506398" [[package]] name = "libgit2-sys" @@ -1735,7 +1735,7 @@ checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", - "regex-automata 0.4.8", + "regex-automata 0.4.9", "regex-syntax 0.8.5", ] @@ -1750,9 +1750,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.8" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "368758f23274712b504848e9d5a6f010445cc8b87a7cdb4d7cbee666c1288da3" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -1829,9 +1829,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.39" +version = "0.38.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "375116bee2be9ed569afe2154ea6a99dfdffd257f533f187498c2a8f5feaf4ee" +checksum = "99e4ea3e1cdc4b559b8e5650f9c8e5998e3e5c1343b4eaf034565f32318d63c0" dependencies = [ "bitflags", "errno", @@ -1945,9 +1945,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.0" +version = "2.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea4a292869320c0272d7bc55a5a6aafaff59b4f63404a003887b679a2e05b4b6" +checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" dependencies = [ "core-foundation-sys", "libc", @@ -1955,18 +1955,18 @@ dependencies = [ [[package]] name = "serde" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f55c3193aca71c12ad7890f1785d2b73e1b9f63a0bbc353c08ef26fe03fc56b5" +checksum = "6513c1ad0b11a9376da888e3e0baa0077f1aed55c17f50e7b2397136129fb88f" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.214" +version = "1.0.215" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de523f781f095e28fa605cdce0f8307e451cc0fd14e2eb4cd2e98a355b147766" +checksum = "ad1e866f866923f252f05c889987993144fb74e722403468a4ebd70c3cd756c0" dependencies = [ "proc-macro2", "quote", @@ -2147,9 +2147,9 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.13.0" +version = "3.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0f2c9fc62d0beef6951ccffd757e241266a2c833136efbe35af6cd2567dca5b" +checksum = "28cce251fcbc87fac86a866eeb0d6c2d536fc16d06f184bb61aeae11aa4cee0c" dependencies = [ "cfg-if", "fastrand", @@ -2160,18 +2160,18 @@ dependencies = [ [[package]] name = "thiserror" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "02dd99dc800bbb97186339685293e1cc5d9df1f8fae2d0aecd9ff1c77efea892" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ "thiserror-impl", ] [[package]] name = "thiserror-impl" -version = "1.0.68" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7c61ec9a6f64d2793d8a45faba21efbe3ced62a886d44c36a009b2b519b4c7e" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", @@ -2233,9 +2233,9 @@ dependencies = [ [[package]] name = "tokio" -version = "1.41.0" +version = "1.41.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "145f3413504347a2be84393cc8a7d2fb4d863b375909ea59f2158261aa258bbb" +checksum = "22cfb5bee7a6a52939ca9224d6ac897bb669134078daa8735560897f69de4d33" dependencies = [ "backtrace", "bytes", @@ -2575,6 +2575,7 @@ dependencies = [ "form_urlencoded", "idna", "percent-encoding", + "serde", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index b0ca2ad..8edcfde 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,7 +38,7 @@ anyhow = "1.0" clap = { version = "4.5", features = ["derive", "env", "cargo"] } # other utils dotenvy = "0.15" -url = "2.5" +url = { version = "2.5", features = ["serde"] } tower_governor = "0.4" # UI embedding rust-embed = { version = "8.5", features = ["include-exclude"] } diff --git a/src/config.rs b/src/config.rs index 17f0190..b1dcd5e 100644 --- a/src/config.rs +++ b/src/config.rs @@ -3,6 +3,7 @@ use std::{fs::read_to_string, path::PathBuf}; use clap::Parser; use log::LevelFilter; use serde::Deserialize; +use url::Url; #[derive(Parser, Debug, Deserialize)] #[command(version)] @@ -38,9 +39,10 @@ pub struct Config { #[arg( long, env = "DEFGUARD_PROXY_URL", + value_parser = Url::parse, default_value = "http://localhost:8080" )] - pub url: String, + pub url: Url, /// Configuration file path #[arg(long = "config", short)] diff --git a/src/handlers/openid_login.rs b/src/handlers/openid_login.rs index 908cb8f..c000e02 100644 --- a/src/handlers/openid_login.rs +++ b/src/handlers/openid_login.rs @@ -47,9 +47,9 @@ async fn auth_info( ) -> Result<(PrivateCookieJar, Json), ApiError> { debug!("Getting auth info for OAuth2/OpenID login"); - let mut redirect_url = state.url.clone(); - redirect_url.push_str("/openid/callback"); - let request = AuthInfoRequest { redirect_url }; + let request = AuthInfoRequest { + redirect_url: state.callback_url().to_string(), + }; let rx = state .grpc_server @@ -115,12 +115,10 @@ async fn auth_callback( .remove(Cookie::from(NONCE_COOKIE_NAME)) .remove(Cookie::from(CSRF_COOKIE_NAME)); - let mut callback_url = state.url.clone(); - callback_url.push_str("/openid/callback"); let request = AuthCallbackRequest { id_token: payload.id_token, nonce, - callback_url, + callback_url: state.callback_url().to_string(), }; let rx = state diff --git a/src/http.rs b/src/http.rs index 8abd84d..7278221 100644 --- a/src/http.rs +++ b/src/http.rs @@ -23,6 +23,7 @@ use tower_governor::{ }; use tower_http::trace::{self, TraceLayer}; use tracing::{info_span, Level}; +use url::Url; use crate::{ assets::{index, svg, web_asset}, @@ -41,7 +42,20 @@ const RATE_LIMITER_CLEANUP_PERIOD: Duration = Duration::from_secs(60); pub(crate) struct AppState { pub(crate) grpc_server: ProxyServer, key: Key, - pub(crate) url: String, + url: Url, +} + +impl AppState { + /// Returns configured URL with "auth/callback" appended to the path. + #[must_use] + pub(crate) fn callback_url(&self) -> Url { + let mut url = self.url.clone(); + // Append "/api/v1/openid/callback" to the URL. + if let Ok(mut path_segments) = url.path_segments_mut() { + path_segments.extend(&["api", "v1", "openid", "callback"]); + } + url + } } impl FromRef for Key {