use axum::http::StatusCode; use axum::response::Redirect; use axum::Form; use axum_login::AuthSession; use super::internal_error; use crate::prelude::*; use crate::session::Credentials; pub struct LoginTemplate { pub username: String, pub password: String, pub error: Option, } pub async fn login_page( State(provider): State, auth_session: AuthSession, ) -> Result { if let Some(_user) = auth_session.user { Ok(Redirect::to("/").into_response()) } else { render_login_page(&provider, "", "", None) } } fn render_login_page( provider: &Provider, username: &str, password: &str, error: Option<&'static str>, ) -> Result { provider.render_resp( "login.html", context! { username => username, password => password, error => error, }, ) } const LOGIN_ERROR_MSG: &str = "Invalid username or password"; pub async fn login_submit( State(provider): State, mut auth_session: AuthSession, Form(creds): Form, ) -> Result { if let Some(user) = auth_session.authenticate(creds).await.map_err(internal_error)? { auth_session.login(&user).await.map_err(internal_error)?; Ok(Redirect::to("/").into_response()) } else { render_login_page(&provider, "", "", Some(LOGIN_ERROR_MSG)) } } pub async fn logout(mut auth_session: AuthSession) -> Response { if let Err(err) = auth_session.logout().await { error!(?err, "error while logging out user"); } Redirect::to("/login").into_response() }