diff options
-rw-r--r-- | Cargo.lock | 48 | ||||
-rw-r--r-- | crates/auth/Cargo.toml | 1 | ||||
-rw-r--r-- | crates/auth/src/main.rs | 1 | ||||
-rw-r--r-- | crates/auth/src/server.rs | 11 | ||||
-rw-r--r-- | crates/auth/src/server/csrf_token_validation.rs | 11 | ||||
-rw-r--r-- | crates/auth/src/server/routes.rs | 2 | ||||
-rw-r--r-- | crates/auth/src/server/routes/authorised.rs | 11 | ||||
-rw-r--r-- | crates/auth/src/server/routes/discord/discord_auth.rs | 3 |
8 files changed, 64 insertions, 24 deletions
@@ -195,6 +195,7 @@ dependencies = [ "clap", "config", "futures-util", + "jsonwebtoken", "nanoid", "oauth2", "reqwest", @@ -1419,6 +1420,21 @@ dependencies = [ ] [[package]] +name = "jsonwebtoken" +version = "9.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5a87cc7a48537badeae96744432de36f4be2b4a34a05a5ef32e9dd8a1c169dde" +dependencies = [ + "base64", + "js-sys", + "pem", + "ring", + "serde", + "serde_json", + "simple_asn1", +] + +[[package]] name = "lazy_static" version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1590,6 +1606,16 @@ dependencies = [ ] [[package]] +name = "num-bigint" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a5e44f723f1133c9deac646763579fdb3ac745e418f2a7af9cd0c431da1f20b9" +dependencies = [ + "num-integer", + "num-traits", +] + +[[package]] name = "num-bigint-dig" version = "0.8.4" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -1769,6 +1795,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df94ce210e5bc13cb6651479fa48d14f601d9858cfe0467f43ae157023b938d3" [[package]] +name = "pem" +version = "3.0.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38af38e8470ac9dee3ce1bae1af9c1671fffc44ddfd8bd1d0a3445bf349a8ef3" +dependencies = [ + "base64", + "serde", +] + +[[package]] name = "pem-rfc7468" version = "0.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" @@ -2411,6 +2447,18 @@ dependencies = [ ] [[package]] +name = "simple_asn1" +version = "0.6.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "297f631f50729c8c99b84667867963997ec0b50f32b2a7dbcab828ef0541e8bb" +dependencies = [ + "num-bigint", + "num-traits", + "thiserror 2.0.12", + "time", +] + +[[package]] name = "slab" version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" diff --git a/crates/auth/Cargo.toml b/crates/auth/Cargo.toml index b6ad707..ccd18f3 100644 --- a/crates/auth/Cargo.toml +++ b/crates/auth/Cargo.toml @@ -15,6 +15,7 @@ base64.workspace = true clap = { workspace = true, features = ["derive"] } config = { workspace = true, features = ["convert-case", "toml"] } futures-util.workspace = true +jsonwebtoken = "9.3.1" nanoid.workspace = true oauth2 = "5.0.0" reqwest = { workspace = true, features = ["json", "rustls-tls"] } diff --git a/crates/auth/src/main.rs b/crates/auth/src/main.rs index ef8a358..a1883ad 100644 --- a/crates/auth/src/main.rs +++ b/crates/auth/src/main.rs @@ -40,7 +40,6 @@ async fn main() -> Result<(), AppError> { }; let mut config: Configuration = config.build()?.try_deserialize()?; - dbg!(&config); config.application.name = env!("CARGO_CRATE_NAME").into(); config.application.version = env!("CARGO_PKG_VERSION").into(); diff --git a/crates/auth/src/server.rs b/crates/auth/src/server.rs index d724d68..2892412 100644 --- a/crates/auth/src/server.rs +++ b/crates/auth/src/server.rs @@ -1,20 +1,23 @@ use axum::{Router, routing::get}; use tower_http::trace::TraceLayer; -use crate::{server::routes::health_check, state::AppHandle}; +use crate::{ + server::routes::{authorised::login_authorised, health_check}, + state::AppHandle, +}; pub mod csrf_token_validation; pub mod routes; const CSRF_TOKEN: &str = "csrf_token"; -const COOKIE_NAME: &str = "SESSION"; const OAUTH_CSRF_COOKIE: &str = "SESSION"; pub fn router(state: AppHandle) -> Router { Router::new() - .merge(routes::discord::discord_router(state.clone())) + .route("/auth/authorised", get(login_authorised)) .route("/", get(health_check)) - .route("/auth/authorised", get(health_check)) + .with_state(state.clone()) + .merge(routes::discord::discord_router(state)) .layer(TraceLayer::new_for_http()) } diff --git a/crates/auth/src/server/csrf_token_validation.rs b/crates/auth/src/server/csrf_token_validation.rs index c9a627c..94424c8 100644 --- a/crates/auth/src/server/csrf_token_validation.rs +++ b/crates/auth/src/server/csrf_token_validation.rs @@ -1,23 +1,14 @@ use anyhow::{Context, anyhow}; -use axum_extra::headers; use oauth2::CsrfToken; -use time::OffsetDateTime; use tower_sessions::{CachingSessionStore, SessionStore, session::Id}; use tower_sessions_moka_store::MokaStore; use tower_sessions_sqlx_store::PostgresStore; use crate::{ error::AppError, - server::{COOKIE_NAME, CSRF_TOKEN, routes::authorised::AuthRequest}, - state::AppHandle, + server::{CSRF_TOKEN, routes::authorised::AuthRequest}, }; -pub struct Session { - id: String, - expires_at: OffsetDateTime, - user_id: String, -} - pub async fn csrf_token_validation_workflow( auth_request: &AuthRequest, store: &CachingSessionStore<MokaStore, PostgresStore>, diff --git a/crates/auth/src/server/routes.rs b/crates/auth/src/server/routes.rs index 7a25e70..1ab012c 100644 --- a/crates/auth/src/server/routes.rs +++ b/crates/auth/src/server/routes.rs @@ -34,7 +34,7 @@ mod tests { #[sqlx::test] async fn health_check(pool: PgPool) { let services = Services { postgres: pool }; - let state = AppState::create(services, &test_config()).await.unwrap(); + let (state, _) = AppState::create(services, &test_config()).await.unwrap(); let app = server::router(state); let response = app diff --git a/crates/auth/src/server/routes/authorised.rs b/crates/auth/src/server/routes/authorised.rs index 42bbde2..d493db5 100644 --- a/crates/auth/src/server/routes/authorised.rs +++ b/crates/auth/src/server/routes/authorised.rs @@ -43,7 +43,7 @@ struct User { const SESSION_COOKIE: &str = "info"; const SESSION_DATA_KEY: &str = "data"; -async fn login_authorized( +pub async fn login_authorised( Query(query): Query<AuthRequest>, State(state): State<AppHandle>, TypedHeader(cookies): TypedHeader<headers::Cookie>, @@ -52,8 +52,7 @@ async fn login_authorized( cookies .get(OAUTH_CSRF_COOKIE) .context("missing session cookie")?, - ) - .unwrap(); + )?; csrf_token_validation_workflow(&query, &state.session_store, oauth_session_id).await?; let client = state.http_client.clone(); @@ -65,7 +64,7 @@ async fn login_authorized( .exchange_code(AuthorizationCode::new(query.code.clone())) .request_async(&client) .await - .context("failed in sending request request to authorization server")?; + .context("failed in sending request request to authorisation server")?; let user_data: User = client // https://discord.com/developers/docs/resources/user#get-current-user @@ -76,7 +75,7 @@ async fn login_authorized( .context("failed in sending request to target Url")? .json::<User>() .await - .context("failed to deserialize response as JSON")?; + .context("failed to deserialise response as JSON")?; // Create a new session filled with user data let session_id = Id(i128::from_le_bytes(uuid::Uuid::new_v4().to_bytes_le())); @@ -92,7 +91,7 @@ async fn login_authorized( + Duration::from_secs(state.local_config.oauth.session_lifespan), }) .await - .context("failed in inserting serialized value into session")?; + .context("failed in inserting serialised value into session")?; // Store session and get corresponding cookie. let cookie = format!("{SESSION_COOKIE}={session_id}; SameSite=Lax; HttpOnly; Secure; Path=/"); diff --git a/crates/auth/src/server/routes/discord/discord_auth.rs b/crates/auth/src/server/routes/discord/discord_auth.rs index 5257a33..a45de86 100644 --- a/crates/auth/src/server/routes/discord/discord_auth.rs +++ b/crates/auth/src/server/routes/discord/discord_auth.rs @@ -43,8 +43,7 @@ pub async fn discord_auth(State(state): State<AppHandle>) -> Result<impl IntoRes + Duration::from_secs(state.local_config.oauth.session_lifespan), }) .await - .unwrap(); - // .context("failed in inserting CSRF token into session")?; + .context("failed in inserting CSRF token into session")?; // Attach the session cookie to the response header let cookie = |