You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

65 lines
2.2 KiB

use axum::{
extract::State,
http::HeaderValue,
response::{IntoResponse, Redirect, Response},
Extension, Form,
};
use cookie::Cookie;
use entity::user;
use sea_orm::{ColumnTrait, EntityTrait, QueryFilter};
use std::sync::Arc;
use tracing::warn;
use crate::data::{AppState, LoginForm, UserSession};
pub async fn login(
State(state): State<Arc<AppState>>,
Form(form): Form<LoginForm>,
) -> Result<Response, Redirect> {
if let Some(u) = user::Entity::find()
.filter(user::Column::Name.eq(form.username))
.one(&state.db)
.await
.map_err(|_| Redirect::to("/?redirect_reason=login_failed"))?
{
let session = UserSession::new(u.id, u.is_admin);
let cookie_dec = Cookie::new("_session", session.get_decrypted_cookie());
let cookie_enc = state.encrypt_cookie(cookie_dec);
state
.sessions
.insert(session.get_decrypted_cookie(), session)
.map(|old_session| {
warn!(
"sound the alarms! same session cookie for user id={} generated twice: '{}'",
old_session.get_decrypted_cookie(),
session.get_decrypted_cookie()
)
});
let mut resp = Redirect::to("/gay").into_response();
resp.headers_mut().insert(
"SetCookie",
HeaderValue::from_str(&cookie_enc.to_string())
.expect("there is tomfoolery afoot! this operation should never fail! alas..."),
);
Ok(resp)
} else {
Err(Redirect::to("/?redirect_reason=login_failed"))
}
}
pub async fn logout(
State(state): State<Arc<AppState>>,
Extension(user_session): Extension<Option<UserSession>>,
) -> Redirect {
if user_session.is_some() {
// if let Some(key) = session_cookie {
// let removed = state.sessions.remove(&key);
// if &removed.as_ref().map(|kv| kv.1) != &user_session {
// warn!("mismatched user sessions!\ncookie {:?}\nuser_session {:?}\nremoved user session {:?}", &key, user_session, removed.map(|kv| kv.1));
// }
// }
}
Redirect::to("/")
}