diff options
| author | rtkay123 <dev@kanjala.com> | 2026-04-04 12:24:59 +0200 |
|---|---|---|
| committer | rtkay123 <dev@kanjala.com> | 2026-04-04 12:24:59 +0200 |
| commit | e86366c6d68b9d3d2af4ac4afb5cf7d5a8400dde (patch) | |
| tree | 6632795c61426f26ae3b5cdd1d2da7d2212b7d0c | |
| parent | 19c25138f88acf19c9a959a58de4f58e54026ebc (diff) | |
| download | sellershut-e86366c6d68b9d3d2af4ac4afb5cf7d5a8400dde.tar.bz2 sellershut-e86366c6d68b9d3d2af4ac4afb5cf7d5a8400dde.zip | |
feat(auth): create session
| -rw-r--r-- | Cargo.lock | 232 | ||||
| -rw-r--r-- | crates/api-auth/Cargo.toml | 1 | ||||
| -rw-r--r-- | crates/api-auth/src/discord/mod.rs | 18 | ||||
| -rw-r--r-- | crates/api-auth/src/lib.rs | 11 | ||||
| -rw-r--r-- | crates/sellershut/src/main.rs | 2 | ||||
| -rw-r--r-- | crates/sellershut/src/server/api/error.rs | 27 | ||||
| -rw-r--r-- | crates/sellershut/src/server/api/mod.rs | 10 | ||||
| -rw-r--r-- | crates/sellershut/src/server/api/routes/auth/discord.rs | 64 | ||||
| -rw-r--r-- | crates/sellershut/src/server/api/routes/auth/mod.rs | 22 | ||||
| -rw-r--r-- | crates/sellershut/src/server/api/routes/mod.rs | 1 | ||||
| -rw-r--r-- | crates/sellershut/src/server/mod.rs | 5 |
11 files changed, 343 insertions, 50 deletions
@@ -93,6 +93,7 @@ name = "api-auth" version = "0.0.0" dependencies = [ "api-core", + "async-session", "async-trait", "oauth2", "secrecy", @@ -124,6 +125,48 @@ dependencies = [ ] [[package]] +name = "arrayref" +version = "0.3.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76a2e8124351fda1ef8aaaa3bbd7ebbcb486bbcd4225aca0aa0d84bb2db8fecb" + +[[package]] +name = "arrayvec" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "23b62fc65de8e4e7f52534fb52b0f3ed04746ae267519eef2a83941e8085068b" + +[[package]] +name = "async-lock" +version = "2.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "287272293e9d8c41773cec55e365490fe034813a2f172f502d6ddcf75b2f582b" +dependencies = [ + "event-listener 2.5.3", +] + +[[package]] +name = "async-session" +version = "3.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "07da4ce523b4e2ebaaf330746761df23a465b951a83d84bbce4233dabedae630" +dependencies = [ + "anyhow", + "async-lock", + "async-trait", + "base64 0.13.1", + "bincode", + "blake3", + "chrono", + "hmac 0.11.0", + "log", + "rand 0.8.5", + "serde", + "serde_json", + "sha2 0.9.9", +] + +[[package]] name = "async-trait" version = "0.1.89" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -221,6 +264,12 @@ dependencies = [ [[package]] name = "base64" +version = "0.13.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9e1b586273c5702936fe7b7d6896644d8be71e6314cfe09d3167c95f712589e8" + +[[package]] +name = "base64" version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" @@ -232,6 +281,15 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2af50177e190e07a26ab74f8b1efbfe2ef87da2116221318cb1c2e82baf7de06" [[package]] +name = "bincode" +version = "1.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b1f45e9417d87227c7a56d22e471c6206462cba514c7590c09aff4cf6d1ddcad" +dependencies = [ + "serde", +] + +[[package]] name = "bitflags" version = "2.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -241,6 +299,30 @@ dependencies = [ ] [[package]] +name = "blake3" +version = "0.3.8" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b64485778c4f16a6a5a9d335e80d449ac6c70cdd6a06d2af18a6f6f775a125b3" +dependencies = [ + "arrayref", + "arrayvec", + "cc", + "cfg-if 0.1.10", + "constant_time_eq", + "crypto-mac 0.8.0", + "digest 0.9.0", +] + +[[package]] +name = "block-buffer" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4152116fd6e9dadb291ae18fc1ec3575ed6d84c29642d97890f4b4a3417297e4" +dependencies = [ + "generic-array", +] + +[[package]] name = "block-buffer" version = "0.10.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -304,6 +386,12 @@ dependencies = [ [[package]] name = "cfg-if" +version = "0.1.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4785bdd1c96b2a846b2bd7cc02e86b6b3dbf14e7e53446c4f54c92a361040822" + +[[package]] +name = "cfg-if" version = "1.0.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801" @@ -390,6 +478,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] +name = "constant_time_eq" +version = "0.1.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "245097e9a4535ee1e3e3931fcfcd55a796a44c643e8596ff6566d68f09b87bbc" + +[[package]] name = "core-foundation-sys" version = "0.8.7" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -425,7 +519,7 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", ] [[package]] @@ -463,6 +557,26 @@ dependencies = [ ] [[package]] +name = "crypto-mac" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b584a330336237c1eecd3e94266efb216c56ed91225d634cb2991c5f3fd1aeab" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] +name = "crypto-mac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "25fab6889090c8133f3deb8f73ba3c65a7f456f66436fc012a1b1e272b1e103e" +dependencies = [ + "generic-array", + "subtle", +] + +[[package]] name = "darling" version = "0.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -529,11 +643,20 @@ dependencies = [ [[package]] name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + +[[package]] +name = "digest" version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", + "block-buffer 0.10.4", "const-oid", "crypto-common", "subtle", @@ -577,13 +700,19 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "136d1b5283a1ab77bd9257427ffd09d8667ced0570b6f938942bc7568ed5b943" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "home", "windows-sys 0.48.0", ] [[package]] name = "event-listener" +version = "2.5.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0206175f82b8d6bf6652ff7d71a1e27fd2e4efde587fd368662814d6ec1d9ce0" + +[[package]] +name = "event-listener" version = "5.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e13b66accf52311f30a0db42147dadea9850cb48cd070028831ae5f5d4b856ab" @@ -722,7 +851,7 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ff2abc00be7fca6ebc474524697ae276ad847ad0a6b3faa4bcb027e9a4614ad0" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "js-sys", "libc", "wasi", @@ -735,7 +864,7 @@ version = "0.3.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "899def5c37c4fd7b2664648c28120ecec138e4d395b459e5ca34f9cce2dd77fd" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "js-sys", "libc", "r-efi", @@ -787,7 +916,17 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", +] + +[[package]] +name = "hmac" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2a2a2320eb7ec0ebe8da8f744d7812d9fc4cb4d09344ac01898dbcb6a20ae69b" +dependencies = [ + "crypto-mac 0.11.0", + "digest 0.9.0", ] [[package]] @@ -796,7 +935,7 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", ] [[package]] @@ -897,7 +1036,7 @@ version = "0.1.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "96547c2556ec9d12fb1578c4eaf448b04993e7fb79cbaad930a656880a6bdfa0" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-channel", "futures-util", @@ -1093,7 +1232,7 @@ version = "0.3.94" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2e04e2ef80ce82e13552136fabeef8a5ed1f985a96805761cbb9a2c34e7664d9" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "futures-util", "once_cell", "wasm-bindgen", @@ -1190,8 +1329,8 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ - "cfg-if", - "digest", + "cfg-if 1.0.4", + "digest 0.10.7", ] [[package]] @@ -1304,7 +1443,7 @@ version = "5.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51e219e79014df21a225b1860a479e2dcd7cbd9130f4defd4bd0e191ea31d67d" dependencies = [ - "base64", + "base64 0.22.1", "chrono", "getrandom 0.2.17", "http", @@ -1313,7 +1452,7 @@ dependencies = [ "serde", "serde_json", "serde_path_to_error", - "sha2", + "sha2 0.10.9", "thiserror 1.0.69", "url", ] @@ -1331,6 +1470,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" [[package]] +name = "opaque-debug" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c08d65885ee38876c4f86fa503fb49d7b507c2b62552df7c70b2fce627e06381" + +[[package]] name = "parking" version = "2.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1352,7 +1497,7 @@ version = "0.9.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2621685985a2ebf1c516881c026032ac7deafcda1a2c9b7850dc81e3dfcb64c1" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "libc", "redox_syscall 0.5.18", "smallvec", @@ -1644,7 +1789,7 @@ version = "0.12.28" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eddd3ca559203180a307f12d114c268abf583f59b03cb906fd0b3ff8646c1147" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "futures-core", "http", @@ -1683,7 +1828,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", - "cfg-if", + "cfg-if 1.0.4", "getrandom 0.2.17", "libc", "untrusted", @@ -1697,7 +1842,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b8573f03f5883dcaebdfcf4725caa1ecb9c15b2ef50c43a07b816e06799bb12d" dependencies = [ "const-oid", - "digest", + "digest 0.10.7", "num-bigint-dig", "num-integer", "num-traits", @@ -1740,7 +1885,7 @@ version = "8.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ - "sha2", + "sha2 0.10.9", "walkdir", ] @@ -1932,9 +2077,22 @@ version = "0.10.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", + "cpufeatures", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.9.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4d58a1e1bf39749807d89cf2d98ac2dfa0ff1cb3faa38fbb64dd88ac8013d800" +dependencies = [ + "block-buffer 0.9.0", + "cfg-if 1.0.4", "cpufeatures", - "digest", + "digest 0.9.0", + "opaque-debug", ] [[package]] @@ -1943,9 +2101,9 @@ version = "0.10.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "cpufeatures", - "digest", + "digest 0.10.7", ] [[package]] @@ -1969,7 +2127,7 @@ version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ - "digest", + "digest 0.10.7", "rand_core 0.6.4", ] @@ -2042,12 +2200,12 @@ version = "0.8.6" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ee6798b1838b6a0f69c007c133b8df5866302197e404e8b6ee8ed3e3a5e68dc6" dependencies = [ - "base64", + "base64 0.22.1", "bytes", "crc", "crossbeam-queue", "either", - "event-listener", + "event-listener 5.4.1", "futures-core", "futures-intrusive", "futures-io", @@ -2061,7 +2219,7 @@ dependencies = [ "percent-encoding", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "thiserror 2.0.18", "tracing", @@ -2096,7 +2254,7 @@ dependencies = [ "quote", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "sqlx-core", "sqlx-postgres", "syn", @@ -2110,12 +2268,12 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "aa003f0038df784eb8fecbbac13affe3da23b45194bd57dba231c8f48199c526" dependencies = [ "atoi", - "base64", + "base64 0.22.1", "bitflags", "byteorder", "bytes", "crc", - "digest", + "digest 0.10.7", "dotenvy", "either", "futures-channel", @@ -2125,7 +2283,7 @@ dependencies = [ "generic-array", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "itoa", "log", "md-5", @@ -2135,7 +2293,7 @@ dependencies = [ "rand 0.8.5", "rsa", "sha1", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -2151,7 +2309,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "db58fcd5a53cf07c184b154801ff91347e4c30d17a3562a635ff028ad5deda46" dependencies = [ "atoi", - "base64", + "base64 0.22.1", "bitflags", "byteorder", "crc", @@ -2162,7 +2320,7 @@ dependencies = [ "futures-util", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "home", "itoa", "log", @@ -2172,7 +2330,7 @@ dependencies = [ "rand 0.8.5", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "smallvec", "sqlx-core", "stringprep", @@ -2310,7 +2468,7 @@ version = "1.1.9" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f60246a4944f24f6e018aa17cdeffb7818b76356965d03b07d6a9886e8962185" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", ] [[package]] @@ -2720,7 +2878,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d047458f1b5b65237c2f6dc6db136945667f40a7668627b3490b9513a3d43a55" dependencies = [ "axum", - "base64", + "base64 0.22.1", "mime_guess", "regex", "rust-embed", @@ -2795,7 +2953,7 @@ version = "0.2.117" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0551fc1bb415591e3372d0bc4780db7e587d84e2a7e79da121051c5c4b89d0b0" dependencies = [ - "cfg-if", + "cfg-if 1.0.4", "once_cell", "rustversion", "wasm-bindgen-macro", diff --git a/crates/api-auth/Cargo.toml b/crates/api-auth/Cargo.toml index 7df9411..053bbb9 100644 --- a/crates/api-auth/Cargo.toml +++ b/crates/api-auth/Cargo.toml @@ -17,6 +17,7 @@ sqlx.workspace = true thiserror.workspace = true utoipa = { workspace = true, optional = true } url.workspace = true +async-session = "3.0.0" [features] discord = [] diff --git a/crates/api-auth/src/discord/mod.rs b/crates/api-auth/src/discord/mod.rs index a39722d..29b9bc2 100644 --- a/crates/api-auth/src/discord/mod.rs +++ b/crates/api-auth/src/discord/mod.rs @@ -1,8 +1,10 @@ use api_core::models::user::User; +use async_session::Session; use async_trait::async_trait; +use oauth2::{CsrfToken, Scope}; use sqlx::PgPool; -use crate::{BasicClient, OauthDriver, error::AuthError}; +use crate::{BasicClient, CSRF_TOKEN, OauthDriver, error::AuthError}; #[derive(Clone, Debug)] pub struct AuthServiceDiscord { @@ -24,7 +26,19 @@ impl OauthDriver for AuthServiceDiscord { async fn get_user(&self) -> Result<User, AuthError> { todo!() } - async fn create_session(&self, _user: &User) { + async fn create_oauth_session(&self)->Result<String,AuthError> { + let (auth_url, csrf_token) = self + .client + .authorize_url(CsrfToken::new_random) + .add_scope(Scope::new("identify".to_string())) + .url(); + + let mut session = Session::new(); + session.insert(CSRF_TOKEN, &csrf_token).unwrap(); + + Ok(String::default()) + } + async fn save_session(&self, user: &User)->Result<(), AuthError>{ todo!() } } diff --git a/crates/api-auth/src/lib.rs b/crates/api-auth/src/lib.rs index 284b772..95a04c4 100644 --- a/crates/api-auth/src/lib.rs +++ b/crates/api-auth/src/lib.rs @@ -3,7 +3,6 @@ pub mod discord; mod error; use api_core::auth::AuthClientConfig; -use api_core::auth::provider::OauthProvider; use api_core::models::user::User; pub use error::AuthClientError; @@ -24,20 +23,16 @@ pub struct BasicClient(C); pub trait OauthDriver: Send + Sync + std::fmt::Debug { async fn get_auth_token(&self) -> Result<String, AuthError>; async fn get_user(&self) -> Result<User, AuthError>; - async fn create_session(&self, user: &User); + async fn create_oauth_session(&self)->Result<String, AuthError>; + async fn save_session(&self, user: &User)->Result<(), AuthError>; } use oauth2::{AuthUrl, ClientId, ClientSecret, RedirectUrl, TokenUrl}; -use sqlx::PgPool; -use std::collections::HashMap; -use std::sync::Arc; use std::{convert::TryFrom, ops::Deref}; use crate::error::AuthError; -pub struct OauthService { - clients: HashMap<OauthProvider, Arc<dyn OauthDriver>>, -} +static CSRF_TOKEN: &str = "csrf_token"; impl Deref for BasicClient { type Target = C; diff --git a/crates/sellershut/src/main.rs b/crates/sellershut/src/main.rs index fca10e1..ebae4ed 100644 --- a/crates/sellershut/src/main.rs +++ b/crates/sellershut/src/main.rs @@ -16,7 +16,7 @@ use api_core::{ }; use clap::Parser; use sqlx::PgPool; -use tokio::{net::TcpListener}; +use tokio::net::TcpListener; use tracing::info; use crate::{ diff --git a/crates/sellershut/src/server/api/error.rs b/crates/sellershut/src/server/api/error.rs new file mode 100644 index 0000000..6d07f9f --- /dev/null +++ b/crates/sellershut/src/server/api/error.rs @@ -0,0 +1,27 @@ +use axum::{ + http::StatusCode, + response::{IntoResponse, Response}, +}; + +#[derive(Debug)] +pub struct AppError(anyhow::Error); + +// Tell axum how to convert `AppError` into a response. +impl IntoResponse for AppError { + fn into_response(self) -> Response { + tracing::error!("Application error: {:#}", self.0); + + (StatusCode::INTERNAL_SERVER_ERROR, "Something went wrong").into_response() + } +} + +// This enables using `?` on functions that return `Result<_, anyhow::Error>` to turn them into +// `Result<_, AppError>`. That way you don't need to do that manually. +impl<E> From<E> for AppError +where + E: Into<anyhow::Error>, +{ + fn from(err: E) -> Self { + Self(err.into()) + } +} diff --git a/crates/sellershut/src/server/api/mod.rs b/crates/sellershut/src/server/api/mod.rs index c227f59..ebe29f8 100644 --- a/crates/sellershut/src/server/api/mod.rs +++ b/crates/sellershut/src/server/api/mod.rs @@ -1,9 +1,15 @@ +pub mod error; + use api_core::health::ApiDocBase; use axum::Router; use utoipa::OpenApi; use utoipa_axum::router::OpenApiRouter; -use crate::{config::Config, server::api::routes::ServerConfigDoc, state::AppState}; +use crate::{ + config::Config, + server::api::routes::{ServerConfigDoc, auth::AuthDoc}, + state::AppState, +}; pub mod routes; @@ -20,10 +26,12 @@ pub async fn router(state: AppState, config: Config) -> Router<()> { doc.merge(ApiDocBase::openapi()); doc.merge(ServerConfigDoc::openapi()); + doc.merge(AuthDoc::openapi()); let stubs = OpenApiRouter::with_openapi(doc) .routes(utoipa_axum::routes!(routes::health)) .nest("/api", routes::router(state.clone())) + .nest("/api", routes::auth::router(state.clone())) .with_state(state); let (router, _api) = stubs.split_for_parts(); diff --git a/crates/sellershut/src/server/api/routes/auth/discord.rs b/crates/sellershut/src/server/api/routes/auth/discord.rs new file mode 100644 index 0000000..163619b --- /dev/null +++ b/crates/sellershut/src/server/api/routes/auth/discord.rs @@ -0,0 +1,64 @@ +use crate::server::api::error::AppError; +use anyhow::Context; +use api_core::auth::provider::OauthProvider; +use axum::{ + extract::State, + http::HeaderMap, + response::{IntoResponse, Redirect}, +}; + +use crate::state::AppState; + +/// Update log level +#[utoipa::path( + patch, + responses( + ( + status = 200, + description = "A redirect to discord", + headers( + ("x-request-id", description = "Request identifier") + ) + ), + ), + operation_id = "auth_discord", // https://github.com/juhaku/utoipa/issues/1170 + path = "/auth", + tag = super::AUTH, +)] +pub async fn discord_auth(State(state): State<AppState>) -> Result<impl IntoResponse, AppError> { + let client = state + .auth_clients + .get(&OauthProvider::Discord) + .context("missing discord driver")?; + + let headers = HeaderMap::new(); + Ok((headers, Redirect::to(redirect_url))) + + // let (auth_url, csrf_token) = client + // .authorize_url(CsrfToken::new_random) + // .add_scope(Scope::new("identify".to_string())) + // .url(); + // + // // Create session to store csrf_token + // let mut session = Session::new(); + // session + // .insert(CSRF_TOKEN, &csrf_token) + // .context("failed in inserting CSRF token into session")?; + // + // // Store the session in MemoryStore and retrieve the session cookie + // let cookie = store + // .store_session(session) + // .await + // .context("failed to store CSRF token session")? + // .context("unexpected error retrieving CSRF cookie value")?; + // + // // Attach the session cookie to the response header + // let cookie = format!("{COOKIE_NAME}={cookie}; SameSite=Lax; HttpOnly; Secure; Path=/"); + // let mut headers = HeaderMap::new(); + // headers.insert( + // SET_COOKIE, + // cookie.parse().context("failed to parse cookie")?, + // ); + // + // Ok((headers, Redirect::to(auth_url.as_ref()))) +} diff --git a/crates/sellershut/src/server/api/routes/auth/mod.rs b/crates/sellershut/src/server/api/routes/auth/mod.rs new file mode 100644 index 0000000..3e36eaa --- /dev/null +++ b/crates/sellershut/src/server/api/routes/auth/mod.rs @@ -0,0 +1,22 @@ +#[cfg(feature = "auth-discord")] +mod discord; + +use utoipa::OpenApi; +use utoipa_axum::router::OpenApiRouter; + +use crate::state::AppState; + +const AUTH: &str = "Authentication"; + +#[derive(OpenApi)] +#[openapi(tags((name = AUTH, description = "Transaction monitoring endpoints")))] +pub struct AuthDoc; + +pub fn router(store: AppState) -> OpenApiRouter<AppState> { + let router = OpenApiRouter::new(); + + #[cfg(feature = "auth-discord")] + let router = router.routes(utoipa_axum::routes!(discord::discord_auth)); + + router.with_state(store) +} diff --git a/crates/sellershut/src/server/api/routes/mod.rs b/crates/sellershut/src/server/api/routes/mod.rs index 1de8e80..822bfe7 100644 --- a/crates/sellershut/src/server/api/routes/mod.rs +++ b/crates/sellershut/src/server/api/routes/mod.rs @@ -1,3 +1,4 @@ +pub mod auth; mod logs; use axum::{extract::State, response::IntoResponse}; diff --git a/crates/sellershut/src/server/mod.rs b/crates/sellershut/src/server/mod.rs index a66eed5..f8ea2c5 100644 --- a/crates/sellershut/src/server/mod.rs +++ b/crates/sellershut/src/server/mod.rs @@ -3,7 +3,10 @@ pub mod logs; #[cfg(test)] mod boostrap { - use std::{collections::HashMap, sync::{Arc, OnceLock}}; + use std::{ + collections::HashMap, + sync::{Arc, OnceLock}, + }; use api_core::health::BaseService; use tracing_subscriber::{EnvFilter, Registry, layer::SubscriberExt, reload}; |
