diff options
| author | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-11 18:02:55 +0200 |
|---|---|---|
| committer | Benedikt Peetz <benedikt.peetz@b-peetz.de> | 2026-06-11 18:02:55 +0200 |
| commit | 0b6ca5cb8ca4c46265e08e13053260d9b5cff568 (patch) | |
| tree | 9dc656095f806e6dd1177e40b9a87cf6d6f10f1b /crates/turtle/src/atuin_server/router.rs | |
| parent | chore(server): Remove the last remnants of the "hub" sync-server thingy (diff) | |
| download | atuin-0b6ca5cb8ca4c46265e08e13053260d9b5cff568.zip | |
feat(server): Make user stuff stateless
Diffstat (limited to 'crates/turtle/src/atuin_server/router.rs')
| -rw-r--r-- | crates/turtle/src/atuin_server/router.rs | 74 |
1 files changed, 21 insertions, 53 deletions
diff --git a/crates/turtle/src/atuin_server/router.rs b/crates/turtle/src/atuin_server/router.rs index 778e699a..dfc2cac4 100644 --- a/crates/turtle/src/atuin_server/router.rs +++ b/crates/turtle/src/atuin_server/router.rs @@ -1,18 +1,19 @@ use crate::{ atuin_common::api::{ATUIN_CARGO_VERSION, ATUIN_HEADER_VERSION, ErrorResponse}, - atuin_server::database::{DbError, db::Database, models::User}, + atuin_server::database::{db::Database, models::User}, }; use axum::{ Router, - extract::{FromRequestParts, Request}, + extract::{FromRequestParts, Path, Request}, http::{self, request::Parts}, middleware::Next, response::{IntoResponse, Response}, - routing::{delete, get, patch, post}, + routing::{get, post}, }; use eyre::Result; use tower::ServiceBuilder; use tower_http::trace::TraceLayer; +use uuid::Uuid; use super::handlers; use crate::atuin_server::{ @@ -30,42 +31,19 @@ impl FromRequestParts<AppState> for UserAuth { req: &mut Parts, state: &AppState, ) -> Result<Self, Self::Rejection> { - let auth_header = req - .headers - .get(http::header::AUTHORIZATION) - .ok_or_else(|| { - ErrorResponse::reply("missing authorization header") - .with_status(http::StatusCode::BAD_REQUEST) - })?; - let auth_header = auth_header.to_str().map_err(|_| { - ErrorResponse::reply("invalid authorization header encoding") - .with_status(http::StatusCode::BAD_REQUEST) - })?; - let (typ, token) = auth_header.split_once(' ').ok_or_else(|| { - ErrorResponse::reply("invalid authorization header encoding") - .with_status(http::StatusCode::BAD_REQUEST) - })?; + let user_id = { + let Path(user_id) = + <Path<Uuid> as FromRequestParts<AppState>>::from_request_parts(req, state) + .await + .map_err(|_| { + ErrorResponse::reply("invalid user_id path param") + .with_status(http::StatusCode::BAD_REQUEST) + })?; - if typ != "Token" { - return Err( - ErrorResponse::reply("invalid authorization header encoding") - .with_status(http::StatusCode::BAD_REQUEST), - ); - } + user_id + }; - let user = state - .database - .get_session_user(token) - .await - .map_err(|e| match e { - DbError::NotFound => ErrorResponse::reply("session not found") - .with_status(http::StatusCode::FORBIDDEN), - DbError::Other(e) => { - tracing::error!(error = ?e, "could not query user session"); - ErrorResponse::reply("could not query user session") - .with_status(http::StatusCode::INTERNAL_SERVER_ERROR) - } - })?; + let user = User { id: user_id }; Ok(UserAuth(user)) } @@ -96,22 +74,12 @@ pub(crate) struct AppState { pub(crate) fn router(database: Database, settings: Settings) -> Router { let routes = Router::new() .route("/", get(handlers::index)) - .route("/healthz", get(handlers::health::health_check)); - - let routes = routes - .route("/user/{username}", get(handlers::user::get)) - .route("/account", delete(handlers::user::delete)) - .route("/account/password", patch(handlers::user::change_password)) - .route("/register", post(handlers::user::register)) - .route("/login", post(handlers::user::login)) - .route("/record", post(handlers::record::post)) - .route("/record", get(handlers::record::index)) - .route("/record/next", get(handlers::record::next)) - .route("/api/v0/me", get(handlers::v0::me::get)) - .route("/api/v0/record", post(handlers::v0::record::post)) - .route("/api/v0/record", get(handlers::v0::record::index)) - .route("/api/v0/record/next", get(handlers::v0::record::next)) - .route("/api/v0/store", delete(handlers::v0::store::delete)); + .route("/api/v0/{user_id}/record", post(handlers::v0::record::post)) + .route("/api/v0/{user_id}/record", get(handlers::v0::record::index)) + .route( + "/api/v0/{user_id}/record/next", + get(handlers::v0::record::next), + ); let path = settings.path.as_str(); if path.is_empty() { |
