Files
zero2prod/src/routes/login.rs
Alphonse Paix 3e81c27ab3
Some checks failed
Rust / Test (push) Has been cancelled
Rust / Rustfmt (push) Has been cancelled
Rust / Clippy (push) Has been cancelled
Rust / Code coverage (push) Has been cancelled
Administrator privileges to get and delete subscribers
2025-09-30 18:28:04 +02:00

72 lines
2.1 KiB
Rust

use crate::{
authentication::{Credentials, validate_credentials},
routes::AppError,
session_state::TypedSession,
startup::AppState,
templates::LoginTemplate,
};
use anyhow::Context;
use askama::Template;
use axum::{
Form,
extract::State,
http::HeaderMap,
response::{Html, IntoResponse, Response},
};
use axum::{http::StatusCode, response::Redirect};
use secrecy::SecretString;
#[derive(serde::Deserialize)]
pub struct LoginFormData {
username: String,
password: SecretString,
}
pub async fn get_login(session: TypedSession) -> Result<Response, AppError> {
if session
.get_user_id()
.await
.context("Failed to retrieve user id from data store.")?
.is_some()
{
Ok(Redirect::to("/admin/dashboard").into_response())
} else {
Ok(Html(LoginTemplate.render().unwrap()).into_response())
}
}
#[tracing::instrument(name = "Authenticating user", skip_all, fields(name = %form.username))]
pub async fn post_login(
session: TypedSession,
State(AppState {
connection_pool, ..
}): State<AppState>,
Form(form): Form<LoginFormData>,
) -> Result<Response, AppError> {
let credentials = Credentials {
username: form.username.clone(),
password: form.password,
};
tracing::Span::current().record("username", tracing::field::display(&credentials.username));
let (user_id, role) = validate_credentials(credentials, &connection_pool).await?;
tracing::Span::current().record("user_id", tracing::field::display(&user_id));
session.renew().await.context("Failed to renew session.")?;
session
.insert_user_id(user_id)
.await
.context("Failed to insert user id in session data store.")?;
session
.insert_username(form.username)
.await
.context("Failed to insert username in session data store.")?;
session
.insert_role(role)
.await
.context("Failed to insert role in session data store.")?;
let mut headers = HeaderMap::new();
headers.insert("HX-Redirect", "/admin/dashboard".parse().unwrap());
Ok((StatusCode::OK, headers).into_response())
}