feat: with return url

Signed-off-by: kjuulh <contact@kjuulh.io>
This commit is contained in:
Kasper Juul Hermansen 2023-11-21 21:53:39 +01:00
parent 6bf847a24a
commit 9510b8fc42
Signed by: kjuulh
GPG Key ID: 57B6E1465221F912
13 changed files with 312 additions and 96 deletions

190
Cargo.lock generated
View File

@ -184,16 +184,29 @@ dependencies = [
]
[[package]]
name = "async-executor"
version = "1.6.0"
name = "async-channel"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4b0c4a4f319e45986f347ee47fef8bf5e81c9abc3f6f58dc2391439f30df65f0"
checksum = "d37875bd9915b7d67c2f117ea2c30a0989874d0b2cb694fe25403c85763c0c9e"
dependencies = [
"async-lock 2.8.0",
"concurrent-queue",
"event-listener 3.1.0",
"event-listener-strategy",
"futures-core",
"pin-project-lite",
]
[[package]]
name = "async-executor"
version = "1.7.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc5ea910c42e5ab19012bab31f53cb4d63d54c3a27730f9a833a88efcf4bb52d"
dependencies = [
"async-lock 3.1.1",
"async-task",
"concurrent-queue",
"fastrand 2.0.1",
"futures-lite 1.13.0",
"futures-lite 2.0.1",
"slab",
]
@ -203,7 +216,7 @@ version = "2.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f1b6f5d7df27bd294849f8eec66ecfc63d11814df7a4f5d74168a2394467b776"
dependencies = [
"async-channel",
"async-channel 1.9.0",
"async-executor",
"async-io 1.13.0",
"async-lock 2.8.0",
@ -238,14 +251,14 @@ version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "41ed9d5715c2d329bf1b4da8d60455b99b187f27ba726df2883799af9af60997"
dependencies = [
"async-lock 3.0.0",
"async-lock 3.1.1",
"cfg-if 1.0.0",
"concurrent-queue",
"futures-io",
"futures-lite 2.0.1",
"parking",
"polling 3.3.0",
"rustix 0.38.21",
"rustix 0.38.25",
"slab",
"tracing",
"waker-fn",
@ -263,11 +276,11 @@ dependencies = [
[[package]]
name = "async-lock"
version = "3.0.0"
version = "3.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "45e900cdcd39bb94a14487d3f7ef92ca222162e6c7c3fe7cb3550ea75fb486ed"
checksum = "655b9c7fe787d3b25cc0f804a1a8401790f0c5bc395beb5a64dc77d8de079105"
dependencies = [
"event-listener 3.0.1",
"event-listener 3.1.0",
"event-listener-strategy",
"pin-project-lite",
]
@ -295,9 +308,9 @@ dependencies = [
"async-signal",
"blocking",
"cfg-if 1.0.0",
"event-listener 3.0.1",
"event-listener 3.1.0",
"futures-lite 1.13.0",
"rustix 0.38.21",
"rustix 0.38.25",
"windows-sys",
]
@ -334,7 +347,7 @@ dependencies = [
"cfg-if 1.0.0",
"futures-core",
"futures-io",
"rustix 0.38.21",
"rustix 0.38.25",
"signal-hook-registry",
"slab",
"windows-sys",
@ -356,7 +369,7 @@ version = "1.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "62565bb4402e926b29953c785397c6dc0391b7b446e45008b0049eb43cec6f5d"
dependencies = [
"async-channel",
"async-channel 1.9.0",
"async-global-executor",
"async-io 1.13.0",
"async-lock 2.8.0",
@ -427,7 +440,7 @@ checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa"
[[package]]
name = "axum"
version = "0.6.16"
source = "git+https://github.com/tokio-rs/axum?branch=main#3ff45d9c96b5192af6b6ec26eb2a2bfcddd00d7d"
source = "git+https://github.com/tokio-rs/axum?branch=main#30afe97e99303fffc4bf2f411a93022b5bc1ba35"
dependencies = [
"async-trait",
"axum-core 0.3.4 (git+https://github.com/tokio-rs/axum?branch=main)",
@ -512,7 +525,7 @@ dependencies = [
[[package]]
name = "axum-core"
version = "0.3.4"
source = "git+https://github.com/tokio-rs/axum?branch=main#3ff45d9c96b5192af6b6ec26eb2a2bfcddd00d7d"
source = "git+https://github.com/tokio-rs/axum?branch=main#30afe97e99303fffc4bf2f411a93022b5bc1ba35"
dependencies = [
"async-trait",
"bytes",
@ -530,7 +543,7 @@ dependencies = [
[[package]]
name = "axum-extra"
version = "0.7.4"
source = "git+https://github.com/tokio-rs/axum?branch=main#3ff45d9c96b5192af6b6ec26eb2a2bfcddd00d7d"
source = "git+https://github.com/tokio-rs/axum?branch=main#30afe97e99303fffc4bf2f411a93022b5bc1ba35"
dependencies = [
"axum 0.6.16",
"axum-core 0.3.4 (git+https://github.com/tokio-rs/axum?branch=main)",
@ -594,7 +607,7 @@ dependencies = [
[[package]]
name = "axum-macros"
version = "0.3.7"
source = "git+https://github.com/tokio-rs/axum?branch=main#3ff45d9c96b5192af6b6ec26eb2a2bfcddd00d7d"
source = "git+https://github.com/tokio-rs/axum?branch=main#30afe97e99303fffc4bf2f411a93022b5bc1ba35"
dependencies = [
"heck",
"proc-macro2",
@ -684,7 +697,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"axum 0.6.16",
"clap 4.4.7",
"clap 4.4.8",
"nefarious-login",
"tokio",
"tracing-subscriber",
@ -749,16 +762,16 @@ dependencies = [
[[package]]
name = "blocking"
version = "1.4.1"
version = "1.5.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8c36a4d0d48574b3dd360b4b7d95cc651d2b6557b6402848a27d4b228a473e2a"
checksum = "6a37913e8dc4ddcc604f0c6d3bf2887c995153af3611de9e23c352b44c1b9118"
dependencies = [
"async-channel",
"async-lock 2.8.0",
"async-channel 2.1.0",
"async-lock 3.1.1",
"async-task",
"fastrand 2.0.1",
"futures-io",
"futures-lite 1.13.0",
"futures-lite 2.0.1",
"piper",
"tracing",
]
@ -833,7 +846,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"axum 0.6.16",
"clap 4.4.7",
"clap 4.4.8",
"nefarious-login",
"tokio",
"tracing-subscriber",
@ -841,9 +854,9 @@ dependencies = [
[[package]]
name = "clap"
version = "4.4.7"
version = "4.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac495e00dcec98c83465d5ad66c5c4fabd652fd6686e7c6269b117e729a6f17b"
checksum = "2275f18819641850fa26c89acc84d465c1bf91ce57bc2748b28c420473352f64"
dependencies = [
"clap_builder",
"clap_derive",
@ -851,9 +864,9 @@ dependencies = [
[[package]]
name = "clap_builder"
version = "4.4.7"
version = "4.4.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c77ed9a32a62e6ca27175d00d29d05ca32e396ea1eb5fb01d8256b669cec7663"
checksum = "07cdf1b148b25c1e1f7a42225e30a0d99a615cd4637eae7365548dd4529b95bc"
dependencies = [
"anstream",
"anstyle",
@ -999,9 +1012,9 @@ dependencies = [
[[package]]
name = "crypto-bigint"
version = "0.5.3"
version = "0.5.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "740fe28e594155f10cfc383984cbefd529d7396050557148f79cb0f621204124"
checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76"
dependencies = [
"generic-array",
"rand_core",
@ -1083,6 +1096,18 @@ version = "1.9.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4f8a51dd197fa6ba5b4dc98a990a43cc13693c23eb0089ebb0fcc1f04152bca6"
[[package]]
name = "custom_redirect"
version = "0.1.0"
dependencies = [
"anyhow",
"axum 0.6.16",
"clap 4.4.8",
"nefarious-login",
"tokio",
"tracing-subscriber",
]
[[package]]
name = "darling"
version = "0.20.3"
@ -1206,9 +1231,9 @@ checksum = "545b22097d44f8a9581187cdf93de7a71e4722bf51200cfaba810865b49a495d"
[[package]]
name = "ecdsa"
version = "0.16.8"
version = "0.16.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a4b1e0c257a9e9f25f90ff76d7a68360ed497ee519c8e428d1825ef0000799d4"
checksum = "ee27f32b5c5292967d2d4a9d7f1e0b0aed2c15daded5a60300e4abb9d8020bca"
dependencies = [
"der",
"digest 0.10.7",
@ -1230,14 +1255,15 @@ dependencies = [
[[package]]
name = "ed25519-dalek"
version = "2.0.0"
version = "2.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7277392b266383ef8396db7fdeb1e77b6c52fed775f5df15bb24f35b72156980"
checksum = "1f628eaec48bfd21b865dc2950cfa014450c01d2fa2b69a86c2fd5844ec523c0"
dependencies = [
"curve25519-dalek",
"ed25519",
"serde",
"sha2 0.10.8",
"subtle",
"zeroize",
]
@ -1252,9 +1278,9 @@ dependencies = [
[[package]]
name = "elliptic-curve"
version = "0.13.6"
version = "0.13.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d97ca172ae9dc9f9b779a6e3a65d308f2af74e5b8c921299075bdb4a0370e914"
checksum = "b5e6043086bf7973472e0c7dff2142ea0b680d30e18d9cc40f267efbf222bd47"
dependencies = [
"base16ct",
"crypto-bigint",
@ -1288,9 +1314,9 @@ checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5"
[[package]]
name = "errno"
version = "0.3.6"
version = "0.3.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7c18ee0ed65a5f1f81cac6b1d213b69c35fa47d4252ad41f1486dbd8226fe36e"
checksum = "f258a7194e7f7c2a7837a8913aeab7fd8c383457034fa20ce4dd3dcb813e8eb8"
dependencies = [
"libc",
"windows-sys",
@ -1315,9 +1341,9 @@ checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0"
[[package]]
name = "event-listener"
version = "3.0.1"
version = "3.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "01cec0252c2afff729ee6f00e903d479fba81784c8e2bd77447673471fdfaea1"
checksum = "d93877bcde0eb80ca09131a08d23f0a5c18a620b01db137dba666d18cd9b30c2"
dependencies = [
"concurrent-queue",
"parking",
@ -1330,7 +1356,7 @@ version = "0.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d96b852f1345da36d551b9473fa1e2b1eb5c5195585c6c018118bc92a8d91160"
dependencies = [
"event-listener 3.0.1",
"event-listener 3.1.0",
"pin-project-lite",
]
@ -1361,9 +1387,9 @@ dependencies = [
[[package]]
name = "fiat-crypto"
version = "0.2.3"
version = "0.2.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f69037fe1b785e84986b4f2cbcf647381876a00671d25ceef715d7812dd7e1dd"
checksum = "27573eac26f4dd11e2b1916c3fe1baa56407c83c71a773a8ba17ec0bca03b6b7"
[[package]]
name = "finl_unicode"
@ -1509,7 +1535,11 @@ version = "2.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d3831c2651acb5177cbd83943f3d9c8912c5ad03c76afcc0e9511ba568ec5ebb"
dependencies = [
"fastrand 2.0.1",
"futures-core",
"futures-io",
"memchr",
"parking",
"pin-project-lite",
]
@ -1619,9 +1649,9 @@ dependencies = [
[[package]]
name = "h2"
version = "0.3.21"
version = "0.3.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "91fc23aa11be92976ef4729127f1a74adf36d8436f7816b185d18df956790833"
checksum = "4d6250322ef6e60f93f9a2162799302cd6f68f79f6e5d85c8c16f14d1d958178"
dependencies = [
"bytes",
"fnv",
@ -1629,7 +1659,7 @@ dependencies = [
"futures-sink",
"futures-util",
"http",
"indexmap 1.9.3",
"indexmap 2.1.0",
"slab",
"tokio",
"tokio-util",
@ -1763,9 +1793,9 @@ dependencies = [
[[package]]
name = "http"
version = "0.2.10"
version = "0.2.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f95b9abcae896730d42b78e09c155ed4ddf82c07b4de772c64aee5b2d8b7c150"
checksum = "8947b1a6fad4393052c7ba1f4cd97bed3e953a95c79c92ad9b051a04611d9fbb"
dependencies = [
"bytes",
"fnv",
@ -2207,7 +2237,7 @@ dependencies = [
"axum 0.6.16",
"axum-extra 0.7.4",
"axum-sessions",
"clap 4.4.7",
"clap 4.4.8",
"oauth2",
"openidconnect",
"pretty_assertions",
@ -2239,7 +2269,7 @@ version = "0.1.0"
dependencies = [
"anyhow",
"axum 0.6.16",
"clap 4.4.7",
"clap 4.4.8",
"nefarious-login",
"tokio",
"tracing-subscriber",
@ -2666,7 +2696,7 @@ dependencies = [
"cfg-if 1.0.0",
"concurrent-queue",
"pin-project-lite",
"rustix 0.38.21",
"rustix 0.38.25",
"tracing",
"windows-sys",
]
@ -2707,9 +2737,9 @@ dependencies = [
[[package]]
name = "primeorder"
version = "0.13.3"
version = "0.13.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7dbe9ed3b56368bd99483eb32fe9c17fdd3730aebadc906918ce78d54c7eeb4"
checksum = "353e1ca18966c16d9deb1c69278edbc5f194139612772bd9537af60ac231e1e6"
dependencies = [
"elliptic-curve",
]
@ -2907,9 +2937,9 @@ dependencies = [
[[package]]
name = "rsa"
version = "0.9.3"
version = "0.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "86ef35bf3e7fe15a53c4ab08a998e42271eab13eb0db224126bc7bc4c4bad96d"
checksum = "6a3211b01eea83d80687da9eef70e39d65144a3894866a5153a2723e425a157f"
dependencies = [
"const-oid",
"digest 0.10.7",
@ -2956,9 +2986,9 @@ dependencies = [
[[package]]
name = "rustix"
version = "0.38.21"
version = "0.38.25"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2b426b0506e5d50a7d8dafcf2e81471400deb602392c7dd110815afb4eaf02a3"
checksum = "dc99bc2d4f1fed22595588a013687477aedf3cdcfb26558c559edb67b4d9b22e"
dependencies = [
"bitflags 2.4.1",
"errno",
@ -2969,9 +2999,9 @@ dependencies = [
[[package]]
name = "rustls"
version = "0.21.8"
version = "0.21.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "446e14c5cda4f3f30fe71863c34ec70f5ac79d6087097ad0bb433e1be5edf04c"
checksum = "629648aced5775d558af50b2b4c7b02983a04b312126d45eeead26e7caa498b9"
dependencies = [
"log",
"ring",
@ -3114,9 +3144,9 @@ checksum = "836fa6a3e1e547f9a2c4040802ec865b5d85f4014efe00555d7090a3dcaa1090"
[[package]]
name = "serde"
version = "1.0.192"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bca2a08484b285dcb282d0f67b26cadc0df8b19f8c12502c13d966bf9482f001"
checksum = "25dd9975e68d0cb5aa1120c288333fc98731bd1dd12f561e468ea4728c042b89"
dependencies = [
"serde_derive",
]
@ -3133,9 +3163,9 @@ dependencies = [
[[package]]
name = "serde_derive"
version = "1.0.192"
version = "1.0.193"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d6c7207fbec9faa48073f3e3074cbe553af6ea512d7c21ba46e434e70ea9fbc1"
checksum = "43576ca501357b9b071ac53cdc7da8ef0cbd9493d8df094cd821777ea6e894d3"
dependencies = [
"proc-macro2",
"quote",
@ -3279,9 +3309,9 @@ dependencies = [
[[package]]
name = "signature"
version = "2.1.0"
version = "2.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e1788eed21689f9cf370582dfc467ef36ed9c707f073528ddafa8d83e3b8500"
checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de"
dependencies = [
"digest 0.10.7",
"rand_core",
@ -3747,7 +3777,7 @@ dependencies = [
"cfg-if 1.0.0",
"fastrand 2.0.1",
"redox_syscall 0.4.1",
"rustix 0.38.21",
"rustix 0.38.25",
"windows-sys",
]
@ -3987,9 +4017,9 @@ dependencies = [
[[package]]
name = "tracing-log"
version = "0.1.4"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f751112709b4e791d8ce53e32c4ed2d353565a795ce84da2285393f41557bdf2"
checksum = "ee855f1f400bd0e5c02d150ae5de3840039a3f54b025156404e34c23c03f47c3"
dependencies = [
"log",
"once_cell",
@ -3998,9 +4028,9 @@ dependencies = [
[[package]]
name = "tracing-subscriber"
version = "0.3.17"
version = "0.3.18"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "30a651bc37f915e81f087d86e62a18eec5f79550c7faff886f7090b4ea757c77"
checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b"
dependencies = [
"matchers",
"nu-ansi-term",
@ -4095,9 +4125,9 @@ checksum = "711b9620af191e0cdc7468a8d14e709c3dcdb115b36f838e601583af800a370a"
[[package]]
name = "uuid"
version = "1.5.0"
version = "1.6.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "88ad59a7560b41a70d191093a945f0b87bc1deeda46fb237479708a1d6b6cdfc"
checksum = "5e395fcf16a7a3d8127ec99782007af141946b4795001f876d54fb0d55978560"
dependencies = [
"getrandom",
]
@ -4363,18 +4393,18 @@ checksum = "09041cd90cf85f7f8b2df60c646f853b7f535ce68f85244eb6731cf89fa498ec"
[[package]]
name = "zerocopy"
version = "0.7.25"
version = "0.7.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8cd369a67c0edfef15010f980c3cbe45d7f651deac2cd67ce097cd801de16557"
checksum = "e97e415490559a91254a2979b4829267a57d2fcd741a98eee8b722fb57289aa0"
dependencies = [
"zerocopy-derive",
]
[[package]]
name = "zerocopy-derive"
version = "0.7.25"
version = "0.7.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c2f140bda219a26ccc0cdb03dba58af72590c53b22642577d88a927bc5c87d6b"
checksum = "dd7e48ccf166952882ca8bd778a43502c64f33bf94c12ebe2a7f08e5a0f6689f"
dependencies = [
"proc-macro2",
"quote",
@ -4383,9 +4413,9 @@ dependencies = [
[[package]]
name = "zeroize"
version = "1.6.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2a0956f1ba7c7909bfb66c2e9e4124ab6f6482560f6628b5aaeba39207c9aad9"
checksum = "525b4ec142c6b68a2d10f01f7bbf6755599ca3f81ea53b8431b7dd348f5fdb2d"
[[package]]
name = "zitadel"

View File

@ -14,9 +14,14 @@ use crate::{
#[async_trait]
pub trait Auth {
async fn login(&self) -> anyhow::Result<Url>;
async fn login(&self, return_url: Option<String>) -> anyhow::Result<Url>;
async fn login_token(&self, user: &str, password: &str) -> anyhow::Result<IdToken>;
async fn login_authorized(&self, code: &str, state: &str) -> anyhow::Result<(HeaderMap, Url)>;
async fn login_authorized(
&self,
code: &str,
state: &str,
return_url: Option<String>,
) -> anyhow::Result<(HeaderMap, Url)>;
async fn get_user_from_session(&self, cookie: &str) -> anyhow::Result<User>;
}
@ -87,12 +92,17 @@ pub static COOKIE_NAME: &str = "SESSION";
#[async_trait]
impl Auth for ZitadelAuthService {
async fn login(&self) -> anyhow::Result<Url> {
let authorize_url = self.oauth.authorize_url().await?;
async fn login(&self, return_url: Option<String>) -> anyhow::Result<Url> {
let authorize_url = self.oauth.authorize_url(return_url).await?;
Ok(authorize_url)
}
async fn login_authorized(&self, code: &str, _state: &str) -> anyhow::Result<(HeaderMap, Url)> {
async fn login_authorized(
&self,
code: &str,
_state: &str,
return_path: Option<String>,
) -> anyhow::Result<(HeaderMap, Url)> {
let token = self.oauth.exchange(code).await?;
let id_token = self.introspection.get_id_token(token.as_str()).await?;
let cookie_value = self.session.insert_user("user", id_token).await?;
@ -102,9 +112,14 @@ impl Auth for ZitadelAuthService {
let mut headers = HeaderMap::new();
headers.insert(SET_COOKIE, cookie.parse().unwrap());
let mut return_url = self.config.return_url.clone();
if let Some(return_path) = return_path {
return_url.push_str(&format!("?returnPath={return_path}"));
}
Ok((
headers,
Url::parse(&self.config.return_url)
Url::parse(&return_url)
.context("failed to parse login_authorized zitadel return url")?,
))
}
@ -126,7 +141,7 @@ pub struct NoopAuthService {
#[async_trait]
impl Auth for NoopAuthService {
async fn login(&self) -> anyhow::Result<Url> {
async fn login(&self, return_url: Option<String>) -> anyhow::Result<Url> {
let url = Url::parse(&format!(
"{}/auth/authorized?code=noop&state=noop",
self.config
@ -142,6 +157,7 @@ impl Auth for NoopAuthService {
&self,
_code: &str,
_state: &str,
_return_url: Option<String>,
) -> anyhow::Result<(HeaderMap, Url)> {
let cookie_value = self
.session

View File

@ -18,7 +18,6 @@ use crate::session::User;
#[derive(Debug, Deserialize)]
pub struct ZitadelAuthParams {
#[allow(dead_code)]
return_url: Option<String>,
}
@ -51,7 +50,7 @@ where
pub async fn zitadel_auth(
State(auth_service): State<AuthService>,
) -> Result<impl IntoResponse, ErrorResponse> {
let url = auth_service.login().await.into_response()?;
let url = auth_service.login(None).await.into_response()?;
Ok(Redirect::to(url.as_ref()))
}
@ -61,6 +60,8 @@ pub async fn zitadel_auth(
pub struct AuthRequest {
code: String,
state: String,
#[serde(alias = "returnUrl")]
return_url: Option<String>,
}
pub async fn login_authorized(
@ -68,7 +69,7 @@ pub async fn login_authorized(
State(auth_service): State<AuthService>,
) -> Result<impl IntoResponse, ErrorResponse> {
let (headers, url) = auth_service
.login_authorized(&query.code, &query.state)
.login_authorized(&query.code, &query.state, query.return_url)
.await
.into_response()?;

View File

@ -31,7 +31,7 @@ impl Deref for OAuth {
#[async_trait]
pub trait OAuthClient {
async fn get_token(&self) -> anyhow::Result<()>;
async fn authorize_url(&self) -> anyhow::Result<Url>;
async fn authorize_url(&self, return_url: Option<String>) -> anyhow::Result<Url>;
async fn exchange(&self, code: &str) -> anyhow::Result<String>;
}

View File

@ -10,7 +10,7 @@ impl OAuthClient for NoopOAuthClient {
async fn get_token(&self) -> anyhow::Result<()> {
Ok(())
}
async fn authorize_url(&self) -> anyhow::Result<Url> {
async fn authorize_url(&self, return_url: Option<String>) -> anyhow::Result<Url> {
Ok(Url::parse("http://localhost:3000/auth/zitadel").unwrap())
}

View File

@ -104,15 +104,28 @@ impl OAuthClient for ZitadelOAuthClient {
async fn get_token(&self) -> anyhow::Result<()> {
Ok(())
}
async fn authorize_url(&self) -> anyhow::Result<Url> {
let (auth_url, _csrf_token) = self
async fn authorize_url(&self, return_url: Option<String>) -> anyhow::Result<Url> {
let req = self
.client
.authorize_url(CsrfToken::new_random)
.add_scope(Scope::new("identify".to_string()))
.add_scope(Scope::new("openid".to_string()))
.add_scope(Scope::new("email".to_string()))
.add_scope(Scope::new("profile".to_string()))
.url();
.add_scope(Scope::new("profile".to_string()));
let req = {
if let Some(return_url) = return_url {
let mut redirect_url = self.client.redirect_url().unwrap().as_str().to_string();
redirect_url.push_str(&format!("?returnUrl={}", return_url));
req.set_redirect_uri(std::borrow::Cow::Owned(RedirectUrl::new(redirect_url)?))
} else {
req
}
};
let (auth_url, _csrf_token) = req.url();
Ok(auth_url)
}

View File

@ -5,3 +5,9 @@ base: "git@git.front.kjuulh.io:kjuulh/cuddle-base.git"
vars:
service: "nefarious-login"
registry: kasperhermansen
scripts:
local_up:
type: shell
local_down:
type: shell

View File

@ -0,0 +1,16 @@
[package]
name = "custom_redirect"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
nefarious-login.workspace = true
tokio.workspace = true
anyhow.workspace = true
axum.workspace = true
clap.workspace = true
tracing-subscriber.workspace = true

View File

@ -0,0 +1,94 @@
use std::{net::SocketAddr, str::FromStr};
use axum::{
extract::{FromRef, State},
response::{IntoResponse, Redirect},
routing::get,
Router,
};
use nefarious_login::{
auth::AuthService,
axum::{AuthController, UserFromSession},
login::{
auth_clap::{AuthEngine, ZitadelClap},
config::ConfigClap,
AuthClap,
},
session::{PostgresqlSessionClap, SessionBackend},
};
use tracing_subscriber::EnvFilter;
#[derive(Clone)]
struct AppState {
auth: AuthService,
}
#[tokio::main]
async fn main() -> anyhow::Result<()> {
tracing_subscriber::fmt()
.with_env_filter(EnvFilter::from_default_env())
.init();
let auth = AuthClap {
engine: AuthEngine::Zitadel,
session_backend: SessionBackend::Postgresql,
zitadel: ZitadelClap {
authority_url: Some("https://personal-wxuujs.zitadel.cloud".into()),
client_id: Some("237412977047895154@nefarious-test".into()),
client_secret: Some(
"rWwDi8gjNOyuMFKoOjNSlhjcVZ1B25wDh6HsDL27f0g2Hb0xGbvEf0WXFY2akOlL".into(),
),
redirect_url: Some("http://localhost:3001/auth/authorized".into()),
},
session: nefarious_login::session::SessionClap {
postgresql: PostgresqlSessionClap {
conn: Some("postgres://nefarious-test:somenotverysecurepassword@localhost:5432/nefarious-test".into()),
},
},
config: ConfigClap { return_url: "http://localhost:3001".into() } // this normally has /authed
};
let auth_service = AuthService::new(&auth).await?;
let state = AppState {
auth: auth_service.clone(),
};
let app = Router::new()
.route("/unauthed", get(unauthed))
.route("/authed", get(authed))
.route("/login", get(login))
.with_state(state)
.nest("/auth", AuthController::new_router(auth_service).await?);
let addr = SocketAddr::from_str(&format!("{}:{}", "127.0.0.1", "3000"))?;
let listener = tokio::net::TcpListener::bind(&addr).await?;
axum::serve(listener, app).await?;
Ok(())
}
impl FromRef<AppState> for AuthService {
fn from_ref(input: &AppState) -> Self {
input.auth.clone()
}
}
async fn login(State(auth_service): State<AuthService>) -> impl IntoResponse {
let url = auth_service.login(Some("/authed".into())).await.unwrap();
Redirect::to(url.as_ref())
}
async fn unauthed() -> String {
"Hello Unauthorized User".into()
}
#[axum::debug_handler()]
async fn authed(
user: UserFromSession,
State(_auth_service): State<AuthService>,
) -> impl IntoResponse {
format!("Hello authorized user: {:?}", user.user.id)
}

7
scripts/local_down.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
set -e
cuddle render_template --template-file $TMP/docker-compose.local_up.yml.tmpl --dest $TMP/docker-compose.local_up.yml
docker compose -f $TMP/docker-compose.local_up.yml down -v

9
scripts/local_up.sh Executable file
View File

@ -0,0 +1,9 @@
#!/bin/bash
set -e
cuddle render_template --template-file $TMP/docker-compose.local_up.yml.tmpl --dest $TMP/docker-compose.local_up.yml
docker compose -f $TMP/docker-compose.local_up.yml up -d --remove-orphans --build
sleep 3

View File

@ -0,0 +1,7 @@
target/
.git/
.cuddle/
scripts/
cuddle.yaml
local.sh
README.md

View File

@ -0,0 +1,17 @@
version: '3.7'
services:
db:
image: bitnami/postgresql:16
restart: always
environment:
- POSTGRESQL_USERNAME=nefarious-test
- POSTGRESQL_DATABASE=nefarious-test
- POSTGRESQL_PASSWORD=somenotverysecurepassword
ports:
- 5432:5432
volumes:
- pgdata:/var/lib/postgresql/data
volumes:
pgdata: