From 549d98f3b457ddfc6dffbe2fad406da4ac50ebc7 Mon Sep 17 00:00:00 2001 From: rtkay123 Date: Mon, 2 Feb 2026 13:30:25 +0200 Subject: refactor: collapse auth --- Cargo.lock | 57 +++++---------------------------------- Cargo.toml | 4 +-- lib/auth/Cargo.toml | 13 --------- lib/auth/src/lib.rs | 41 ---------------------------- src/config/mod.rs | 6 +++++ src/server/driver/auth.rs | 34 +++++++++++++++++++++++ src/server/driver/mod.rs | 3 +++ src/server/mod.rs | 15 ++++++----- src/server/routes/auth/discord.rs | 20 +++++++++----- src/server/state/mod.rs | 10 ++++--- 10 files changed, 79 insertions(+), 124 deletions(-) delete mode 100644 lib/auth/Cargo.toml delete mode 100644 lib/auth/src/lib.rs create mode 100644 src/server/driver/auth.rs diff --git a/Cargo.lock b/Cargo.lock index 468bd41..165861d 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -297,7 +297,7 @@ version = "3.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89ec27229c38ed0eb3c0feee3d2c1d6a4379ae44f418a29a658890e062d8f365" dependencies = [ - "darling 0.23.0", + "darling", "ident_case", "prettyplease", "proc-macro2", @@ -509,18 +509,8 @@ version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc7f46116c46ff9ab3eb1597a45688b6715c6e628b5c133e288e709a29bcb4ee" dependencies = [ - "darling_core 0.20.11", - "darling_macro 0.20.11", -] - -[[package]] -name = "darling" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25ae13da2f202d56bd7f91c25fba009e7717a1e4a1cc98a76d844b65ae912e9d" -dependencies = [ - "darling_core 0.23.0", - "darling_macro 0.23.0", + "darling_core", + "darling_macro", ] [[package]] @@ -537,37 +527,13 @@ dependencies = [ "syn 2.0.114", ] -[[package]] -name = "darling_core" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9865a50f7c335f53564bb694ef660825eb8610e0a53d3e11bf1b0d3df31e03b0" -dependencies = [ - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.114", -] - [[package]] name = "darling_macro" version = "0.20.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc34b93ccb385b40dc71c6fceac4b2ad23662c7eeb248cf10d529b7e055b6ead" dependencies = [ - "darling_core 0.20.11", - "quote", - "syn 2.0.114", -] - -[[package]] -name = "darling_macro" -version = "0.23.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ac3984ec7bd6cfa798e62b4a642426a5be0e68f9401cfc2a01e3fa9ea2fcdb8d" -dependencies = [ - "darling_core 0.23.0", + "darling_core", "quote", "syn 2.0.114", ] @@ -609,7 +575,7 @@ version = "0.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "2d5bcf7b024d6835cfb3d473887cd966994907effbe9227e8c8219824d06c4e8" dependencies = [ - "darling 0.20.11", + "darling", "proc-macro2", "quote", "syn 2.0.114", @@ -2052,11 +2018,11 @@ dependencies = [ "anyhow", "async-trait", "axum", + "bon", "clap", "oauth2", "rand 0.9.2", "secrecy", - "sellershut-auth", "serde", "sqlx", "tokio", @@ -2075,17 +2041,6 @@ dependencies = [ "uuid", ] -[[package]] -name = "sellershut-auth" -version = "0.1.0" -dependencies = [ - "bon", - "oauth2", - "secrecy", - "thiserror 2.0.18", - "url", -] - [[package]] name = "serde" version = "1.0.228" diff --git a/Cargo.toml b/Cargo.toml index f9cca9b..31d5fbb 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,6 +1,6 @@ [workspace] resolver = "3" -members = [ ".", "lib/*" ] +members = [ "." ] [workspace.package] description = "A federated marketplace platform" @@ -35,10 +35,10 @@ activitypub_federation = { version = "0.7.0-beta.8", default-features = false, f anyhow.workspace = true async-trait.workspace = true axum = { version = "0.8.8", features = ["macros"] } +bon.workspace = true clap = { version = "4.5.56", features = ["derive", "env"] } oauth2.workspace = true secrecy = { workspace = true, features = ["serde"] } -sellershut-auth = { path = "lib/auth" } serde = { workspace = true, features = ["derive"] } tokio = { version = "1.49.0", features = ["rt-multi-thread", "macros", "signal"] } toml = "0.9.11" diff --git a/lib/auth/Cargo.toml b/lib/auth/Cargo.toml deleted file mode 100644 index 0852935..0000000 --- a/lib/auth/Cargo.toml +++ /dev/null @@ -1,13 +0,0 @@ -[package] -name = "sellershut-auth" -version = "0.1.0" -edition = "2024" -license.workspace = true -documentation.workspace = true - -[dependencies] -bon.workspace = true -oauth2.workspace = true -secrecy.workspace = true -thiserror.workspace = true -url.workspace = true diff --git a/lib/auth/src/lib.rs b/lib/auth/src/lib.rs deleted file mode 100644 index 2a1390e..0000000 --- a/lib/auth/src/lib.rs +++ /dev/null @@ -1,41 +0,0 @@ -use bon::Builder; -use oauth2::{AuthUrl, ClientId, ClientSecret, EndpointNotSet, EndpointSet, RedirectUrl, TokenUrl}; -use secrecy::{ExposeSecret, SecretString}; -use thiserror::Error; - -#[derive(Builder)] -pub struct ClientOptions { - client_id: String, - client_secret: SecretString, - token_url: String, - auth_url: String, - redirect_url: String, -} - -#[derive(Error, Debug)] -pub enum OauthError { - #[error("invalid url")] - InvalidUrl(#[from] url::ParseError), -} - -pub type OauthClient = oauth2::basic::BasicClient< - EndpointSet, - EndpointNotSet, - EndpointNotSet, - EndpointNotSet, - EndpointSet, ->; - -pub fn oauth_client(opts: &ClientOptions) -> Result { - let redirect_url = RedirectUrl::new(opts.redirect_url.to_owned())?; - let client_id = ClientId::new(opts.client_id.to_owned()); - let auth_url = AuthUrl::new(opts.auth_url.to_owned())?; - let token_url = TokenUrl::new(opts.token_url.to_owned())?; - let client_secret = ClientSecret::new(opts.client_secret.expose_secret().to_string()); - - Ok(oauth2::basic::BasicClient::new(client_id) - .set_client_secret(client_secret) - .set_auth_uri(auth_url) - .set_token_uri(token_url) - .set_redirect_uri(redirect_url)) -} diff --git a/src/config/mod.rs b/src/config/mod.rs index 01af6d8..aa6f770 100644 --- a/src/config/mod.rs +++ b/src/config/mod.rs @@ -52,6 +52,7 @@ pub struct Api { } #[derive(Debug, Clone, Deserialize)] +#[cfg(feature = "oauth")] pub struct OAuth { #[cfg(feature = "oauth-discord")] pub discord: DiscordOauth, @@ -71,21 +72,26 @@ pub struct DiscordOauth { pub auth_url: Url, } +#[cfg(feature = "oauth-discord")] fn discord_token_url() -> Url { Url::parse("https://discord.com/api/oauth2/authorize?response_type=code").expect("valid url") } +#[cfg(feature = "oauth-discord")] fn discord_auth_url() -> Url { Url::parse("https://discord.com/api/oauth2/authorize?response_type=code").expect("valid url") } +#[cfg(feature = "oauth")] fn redirect_url() -> Url { Url::parse("http://127.0.0.1:2210/auth/authorised").expect("valid url") } +#[cfg(feature = "oauth")] impl Default for OAuth { fn default() -> Self { Self { + #[cfg(feature = "oauth-discord")] discord: DiscordOauth { client_id: String::default(), client_secret: SecretString::default(), diff --git a/src/server/driver/auth.rs b/src/server/driver/auth.rs new file mode 100644 index 0000000..9215372 --- /dev/null +++ b/src/server/driver/auth.rs @@ -0,0 +1,34 @@ +use bon::Builder; +use oauth2::{AuthUrl, ClientId, ClientSecret, EndpointNotSet, EndpointSet, RedirectUrl, TokenUrl}; +use secrecy::{ExposeSecret, SecretString}; + +#[derive(Builder)] +pub struct ClientOptions { + client_id: String, + client_secret: SecretString, + token_url: String, + auth_url: String, + redirect_url: String, +} + +pub type OauthClient = oauth2::basic::BasicClient< + EndpointSet, + EndpointNotSet, + EndpointNotSet, + EndpointNotSet, + EndpointSet, +>; + +pub fn oauth_client(opts: &ClientOptions) -> anyhow::Result { + let redirect_url = RedirectUrl::new(opts.redirect_url.to_owned())?; + let client_id = ClientId::new(opts.client_id.to_owned()); + let auth_url = AuthUrl::new(opts.auth_url.to_owned())?; + let token_url = TokenUrl::new(opts.token_url.to_owned())?; + let client_secret = ClientSecret::new(opts.client_secret.expose_secret().to_string()); + + Ok(oauth2::basic::BasicClient::new(client_id) + .set_client_secret(client_secret) + .set_auth_uri(auth_url) + .set_token_uri(token_url) + .set_redirect_uri(redirect_url)) +} diff --git a/src/server/driver/mod.rs b/src/server/driver/mod.rs index 4c540cb..c006cb0 100644 --- a/src/server/driver/mod.rs +++ b/src/server/driver/mod.rs @@ -1,3 +1,6 @@ +#[cfg(feature = "oauth")] +pub mod auth; + use async_trait::async_trait; use sqlx::PgPool; diff --git a/src/server/mod.rs b/src/server/mod.rs index 3301035..2050758 100644 --- a/src/server/mod.rs +++ b/src/server/mod.rs @@ -26,7 +26,6 @@ use crate::{ config::Config, server::{ middleware::request_id::{REQUEST_ID_HEADER, add_request_id}, - routes::auth::OAuthDoc, state::{AppState, federation}, }, }; @@ -43,12 +42,16 @@ pub async fn router(config: &Config, state: AppState) -> anyhow::Result) -> Result { + let data = data.app_data(); -async fn auth( - State(client): State>, -) -> Result { - Ok(()) + let (auth_url, csrf_token) = data + .oauth_discord + .authorize_url(CsrfToken::new_random) + .add_scope(Scope::new("identify".to_string())) + .url(); + + Ok(String::default()) } diff --git a/src/server/state/mod.rs b/src/server/state/mod.rs index f5f731e..03e8c70 100644 --- a/src/server/state/mod.rs +++ b/src/server/state/mod.rs @@ -3,25 +3,25 @@ pub mod federation; use std::sync::Arc; -use sellershut_auth::{ClientOptions, OauthClient}; #[cfg(feature = "oauth-discord")] use url::Url; #[cfg(feature = "oauth-discord")] -use crate::config::DiscordOauth; +use crate::{config::DiscordOauth, server::driver::auth::OauthClient}; use crate::{config::Config, server::driver::SellershutDriver}; #[derive(Clone)] pub struct AppState { driver: Arc, #[cfg(feature = "oauth-discord")] - oauth_discord: OauthClient, + pub oauth_discord: OauthClient, } impl AppState { pub async fn new(config: &Config, driver: impl SellershutDriver) -> anyhow::Result { Ok(Self { driver: Arc::new(driver), + #[cfg(feature = "oauth-discord")] oauth_discord: discord_client(&config.oauth.discord, &config.oauth.oauth_redirect_url)?, }) } @@ -29,6 +29,8 @@ impl AppState { #[cfg(feature = "oauth-discord")] fn discord_client(disc: &DiscordOauth, redirect: &Url) -> anyhow::Result { + use crate::server::driver::{self, auth::ClientOptions}; + let discord_opts = ClientOptions::builder() .client_id(disc.client_id.to_owned()) .redirect_url(redirect.to_string()) @@ -37,5 +39,5 @@ fn discord_client(disc: &DiscordOauth, redirect: &Url) -> anyhow::Result