qol(http): replaced all explicit header setting with axum cookie jar
This commit is contained in:
@@ -37,3 +37,4 @@ rubato = "3.0.0"
|
||||
chrono = "0.4.45"
|
||||
regex = "1"
|
||||
thiserror = "2.0.18"
|
||||
axum-extra = { version = "0.12.6", features = ["cookie"] }
|
||||
|
||||
+11
-38
@@ -6,6 +6,7 @@ use std::{
|
||||
},
|
||||
};
|
||||
|
||||
use axum_extra::extract::{CookieJar, cookie::Cookie};
|
||||
use regex::Regex;
|
||||
|
||||
// The Rust `regex` crate is guaranteed linear-time and therefore does NOT
|
||||
@@ -206,22 +207,6 @@ struct CreateStreamKeyBody {
|
||||
label: String,
|
||||
}
|
||||
|
||||
fn extract_session_token(headers: &HeaderMap) -> Option<String> {
|
||||
// Check bare `session` header first (curl / API clients)
|
||||
if let Some(v) = headers.get("session") {
|
||||
return Some(v.to_str().ok()?.to_string());
|
||||
}
|
||||
// Fall back to Cookie header (browsers)
|
||||
let cookie_header = headers.get("cookie")?.to_str().ok()?;
|
||||
cookie_header
|
||||
.split(';')
|
||||
.find_map(|pair| {
|
||||
let pair = pair.trim();
|
||||
pair.strip_prefix("session=")
|
||||
})
|
||||
.map(|v| v.to_string())
|
||||
}
|
||||
|
||||
struct AuthUser(entity::users::Model);
|
||||
|
||||
impl FromRequestParts<Arc<HttpServer>> for AuthUser {
|
||||
@@ -231,9 +216,10 @@ impl FromRequestParts<Arc<HttpServer>> for AuthUser {
|
||||
parts: &mut Parts,
|
||||
state: &Arc<HttpServer>,
|
||||
) -> Result<Self, HttpError> {
|
||||
let token = extract_session_token(&parts.headers).ok_or(HttpError::Unauthorized)?;
|
||||
let jar = CookieJar::from_request_parts(parts, state).await.unwrap();
|
||||
let session = jar.get("session").ok_or(HttpError::Unauthorized)?;
|
||||
|
||||
let user = users::Entity::find_by_auth_session(&state.db, token)
|
||||
let user = users::Entity::find_by_auth_session(&state.db, session.to_string())
|
||||
.await?
|
||||
.ok_or(HttpError::Unauthorized)?;
|
||||
|
||||
@@ -306,6 +292,7 @@ struct LoginResponse {
|
||||
async fn login_handler(
|
||||
State(state): State<Arc<HttpServer>>,
|
||||
Json(payload): Json<LoginForm>,
|
||||
jar: CookieJar,
|
||||
) -> Result<impl IntoResponse, HttpError> {
|
||||
let user = users::Entity::find_by_username(&state.db, payload.username.clone())
|
||||
.await?
|
||||
@@ -323,16 +310,8 @@ async fn login_handler(
|
||||
let auth = auth_session::Entity::create(&state.db, user.id).await?;
|
||||
let token = auth.value;
|
||||
|
||||
let mut meow = Response::new("".to_string());
|
||||
// TODO: Replace with axum cookie jar https://docs.rs/axum-extra/latest/axum_extra/extract/cookie/struct.CookieJar.html
|
||||
meow.headers_mut().insert(
|
||||
SET_COOKIE,
|
||||
format!("session={token}; SameSite=Strict; Path=/; Max-Age=2592000")
|
||||
.parse()
|
||||
.unwrap(),
|
||||
);
|
||||
*meow.status_mut() = StatusCode::OK;
|
||||
Ok(meow)
|
||||
let jar = jar.add(Cookie::new("session", token));
|
||||
Ok((StatusCode::OK, jar))
|
||||
}
|
||||
|
||||
#[derive(Deserialize)]
|
||||
@@ -345,7 +324,8 @@ struct CreateUserForm {
|
||||
async fn create_user_handler(
|
||||
State(state): State<Arc<HttpServer>>,
|
||||
Json(payload): Json<CreateUserForm>,
|
||||
) -> Result<(HeaderMap, StatusCode), HttpError> {
|
||||
jar: CookieJar,
|
||||
) -> Result<impl IntoResponse, HttpError> {
|
||||
if state.config.signup_code.is_empty() || payload.ref_token != state.config.signup_code {
|
||||
warn!(username = %payload.username, "signup rejected: invalid signup code");
|
||||
return Err(HttpError::Unauthorized);
|
||||
@@ -372,15 +352,8 @@ async fn create_user_handler(
|
||||
let session = auth_session::Entity::create(&state.db, user.id).await?;
|
||||
let token = session.value;
|
||||
|
||||
let mut headers = HeaderMap::new();
|
||||
// TODO: Replace with axum cookie jar https://docs.rs/axum-extra/latest/axum_extra/extract/cookie/struct.CookieJar.html
|
||||
headers.insert(
|
||||
SET_COOKIE,
|
||||
format!("session={token}; HttpOnly; SameSite=Strict; Path=/")
|
||||
.parse()
|
||||
.unwrap(),
|
||||
);
|
||||
Ok((headers, StatusCode::OK))
|
||||
let jar = jar.add(Cookie::new("session", token));
|
||||
Ok((jar, StatusCode::OK))
|
||||
}
|
||||
|
||||
async fn stream_handler(
|
||||
|
||||
Reference in New Issue
Block a user