Refactor admin routes to use new AppError struct in responses

This commit is contained in:
Alphonse Paix
2025-09-20 01:08:05 +02:00
parent 2b9cf979e8
commit 7971095227
7 changed files with 86 additions and 75 deletions

View File

@@ -1,6 +1,6 @@
use crate::{
authentication::{self, AuthenticatedUser, Credentials, validate_credentials},
routes::AdminError,
routes::{AdminError, AppError},
startup::AppState,
templates::MessageTemplate,
};
@@ -25,7 +25,7 @@ pub async fn change_password(
connection_pool, ..
}): State<AppState>,
Form(form): Form<PasswordFormData>,
) -> Result<Response, AdminError> {
) -> Result<Response, AppError> {
let credentials = Credentials {
username,
password: form.current_password,
@@ -33,16 +33,15 @@ pub async fn change_password(
if form.new_password.expose_secret() != form.new_password_check.expose_secret() {
Err(AdminError::ChangePassword(
"You entered two different passwords - the field values must match.".to_string(),
))
)
.into())
} else if validate_credentials(credentials, &connection_pool)
.await
.is_err()
{
Err(AdminError::ChangePassword(
"The current password is incorrect.".to_string(),
))
Err(AdminError::ChangePassword("The current password is incorrect.".to_string()).into())
} else if let Err(e) = verify_password(form.new_password.expose_secret()) {
Err(AdminError::ChangePassword(e))
Err(AdminError::ChangePassword(e).into())
} else {
authentication::change_password(user_id, form.new_password, &connection_pool)
.await

View File

@@ -1,13 +1,13 @@
use crate::{routes::AdminError, session_state::TypedSession};
use crate::session_state::TypedSession;
use axum::{
http::{HeaderMap, StatusCode},
response::{IntoResponse, Response},
};
#[tracing::instrument(name = "Logging out", skip(session))]
pub async fn logout(session: TypedSession) -> Result<Response, AdminError> {
pub async fn logout(session: TypedSession) -> Response {
session.clear().await;
let mut headers = HeaderMap::new();
headers.insert("HX-Redirect", "/login".parse().unwrap());
Ok((StatusCode::OK, headers).into_response())
}
(StatusCode::OK, headers).into_response()
}

View File

@@ -1,7 +1,7 @@
use crate::{
authentication::AuthenticatedUser,
idempotency::{IdempotencyKey, save_response, try_processing},
routes::AdminError,
routes::{AdminError, AppError},
startup::AppState,
templates::MessageTemplate,
};
@@ -75,7 +75,7 @@ pub async fn publish_newsletter(
}): State<AppState>,
Extension(AuthenticatedUser { user_id, .. }): Extension<AuthenticatedUser>,
Form(form): Form<BodyData>,
) -> Result<Response, AdminError> {
) -> Result<Response, AppError> {
validate_form(&form).map_err(|e| AdminError::Publish(anyhow::anyhow!(e)))?;
let idempotency_key: IdempotencyKey = form
@@ -104,9 +104,10 @@ pub async fn publish_newsletter(
);
let template = MessageTemplate::Success { message };
let response = Html(template.render().unwrap()).into_response();
save_response(transaction, &idempotency_key, user_id, response)
let response = save_response(transaction, &idempotency_key, user_id, response)
.await
.map_err(AdminError::UnexpectedError)
.map_err(AdminError::UnexpectedError)?;
Ok(response)
}
fn validate_form(form: &BodyData) -> Result<(), &'static str> {

View File

@@ -1,7 +1,7 @@
use crate::{
authentication::AuthenticatedUser,
idempotency::{IdempotencyKey, save_response, try_processing},
routes::{AdminError, enqueue_delivery_tasks, insert_newsletter_issue},
routes::{AdminError, AppError, enqueue_delivery_tasks, insert_newsletter_issue},
startup::AppState,
templates::MessageTemplate,
};
@@ -38,7 +38,7 @@ pub async fn create_post(
}): State<AppState>,
Extension(AuthenticatedUser { user_id, .. }): Extension<AuthenticatedUser>,
Form(form): Form<CreatePostForm>,
) -> Result<Response, AdminError> {
) -> Result<Response, AppError> {
validate_form(&form).map_err(AdminError::Publish)?;
let idempotency_key: IdempotencyKey = form
@@ -65,16 +65,14 @@ pub async fn create_post(
.await
.context("Failed to enqueue delivery tasks.")?;
// Send emails with unique identifiers that contains link to blog post with special param
// Get handpoint that returns the post and mark the email as opened
let template = MessageTemplate::Success {
message: "Your new post has been saved. Subscribers will be notified.".into(),
};
let response = Html(template.render().unwrap()).into_response();
save_response(transaction, &idempotency_key, user_id, response)
let response = save_response(transaction, &idempotency_key, user_id, response)
.await
.map_err(AdminError::UnexpectedError)
.map_err(AdminError::UnexpectedError)?;
Ok(response)
}
#[tracing::instrument(
@@ -116,5 +114,6 @@ pub async fn create_newsletter(
content: &str,
_post_id: &Uuid,
) -> Result<Uuid, sqlx::Error> {
// We need to send a special link with a unique ID to determine if the user clicked it or not.
insert_newsletter_issue(transaction, title, content, content).await
}