64 lines
1.7 KiB
Rust
64 lines
1.7 KiB
Rust
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<String>,
|
|
}
|
|
|
|
pub async fn login_page(
|
|
State(provider): State<Provider>,
|
|
auth_session: AuthSession<Provider>,
|
|
) -> Result<Response, (StatusCode, String)> {
|
|
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<Response, (StatusCode, String)> {
|
|
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<Provider>,
|
|
mut auth_session: AuthSession<Provider>,
|
|
Form(creds): Form<Credentials>,
|
|
) -> Result<Response, (StatusCode, String)> {
|
|
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<Provider>) -> Response {
|
|
if let Err(err) = auth_session.logout().await {
|
|
error!(?err, "error while logging out user");
|
|
}
|
|
|
|
Redirect::to("/login").into_response()
|
|
}
|