feat(backend): replace auth stub with real session, create users and sessions tables

This commit is contained in:
2026-05-26 02:34:23 +03:00
parent a54ec4ed34
commit e7eaa42064
11 changed files with 636 additions and 135 deletions

View File

@@ -1,14 +1,12 @@
use axum::{
extract::{FromRequestParts, Request},
extract::{FromRequestParts, Request, State},
middleware::Next,
response::Response,
};
use lazy_regex::regex_captures;
use tower_cookies::{Cookie, Cookies};
use tower_cookies::Cookies;
use crate::{ctx::Ctx, error::LoftError, web::AUTH_TOKEN};
use crate::{ctx::Ctx, error::LoftError, model::UserRepository, web::AUTH_TOKEN};
/// validates the cookie exists and is well-formed (3-part format)
pub async fn mw_require_auth(
ctx: Result<Ctx, LoftError>,
req: Request,
@@ -20,35 +18,27 @@ pub async fn mw_require_auth(
}
pub async fn mw_ctx_resolver(
State(user_repository): State<UserRepository>,
cookies: Cookies,
mut req: Request,
next: Next,
) -> Result<Response, LoftError> {
let auth_token = cookies.get(AUTH_TOKEN).map(|c| c.value().to_string());
let result_ctx = match auth_token
.ok_or(LoftError::AuthFailNoAuthTokenCookie)
.and_then(parse_auth_token)
{
Ok((user_id, _, _)) => {
//TODO: add validation
Ok(Ctx::new(user_id))
}
Err(e) => Err(e),
let result_ctx = match auth_token {
Some(token) => user_repository
.get_session(token)
.await
.map(|s| Ctx::new(s.user_id)),
None => Err(LoftError::AuthFailNoAuthTokenCookie),
};
if result_ctx.is_err() && !matches!(result_ctx, Err(LoftError::AuthFailNoAuthTokenCookie)) {
cookies.remove(Cookie::from(AUTH_TOKEN))
}
req.extensions_mut().insert(result_ctx);
Ok(next.run(req).await)
}
impl<S: Send + Sync> FromRequestParts<S> for Ctx {
type Rejection = LoftError;
// extracts user_id from the token and makes it available to handlers as an extractor
fn from_request_parts(
parts: &mut axum::http::request::Parts,
_: &S,
@@ -62,18 +52,3 @@ impl<S: Send + Sync> FromRequestParts<S> for Ctx {
}
}
}
fn parse_auth_token(auth_token: String) -> Result<(u64, u64, String), LoftError> {
let (_, user_id, expiration, signature) =
regex_captures!(r"^user-(\d+)\.(\d+)\.([a-f0-9]+)$", &auth_token)
.ok_or(LoftError::AuthFailTokenWrongFormat)?;
let user_id: u64 = user_id
.parse()
.map_err(|_| LoftError::AuthFailTokenWrongFormat)?;
let expiration: u64 = expiration
.parse()
.map_err(|_| LoftError::AuthFailTokenWrongFormat)?;
Ok((user_id, expiration, signature.to_string()))
}