78 lines
2.4 KiB
Rust
78 lines
2.4 KiB
Rust
pub mod change_password;
|
|
pub mod dashboard;
|
|
pub mod newsletters;
|
|
|
|
use crate::{routes::error_chain_fmt, session_state::TypedSession, templates::ErrorTemplate};
|
|
use askama::Template;
|
|
use axum::{
|
|
Json,
|
|
response::{Html, IntoResponse, Redirect, Response},
|
|
};
|
|
pub use change_password::*;
|
|
pub use dashboard::*;
|
|
pub use newsletters::*;
|
|
use reqwest::StatusCode;
|
|
|
|
#[derive(thiserror::Error)]
|
|
pub enum AdminError {
|
|
#[error("Something went wrong.")]
|
|
UnexpectedError(#[from] anyhow::Error),
|
|
#[error("Trying to access admin dashboard without authentication.")]
|
|
NotAuthenticated,
|
|
#[error("Updating password failed.")]
|
|
ChangePassword(String),
|
|
#[error("Could not publish newsletter.")]
|
|
Publish(#[source] anyhow::Error),
|
|
#[error("The idempotency key was invalid.")]
|
|
Idempotency(String),
|
|
}
|
|
|
|
impl std::fmt::Debug for AdminError {
|
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
error_chain_fmt(self, f)
|
|
}
|
|
}
|
|
|
|
impl IntoResponse for AdminError {
|
|
fn into_response(self) -> Response {
|
|
#[derive(serde::Serialize)]
|
|
struct ErrorResponse<'a> {
|
|
message: &'a str,
|
|
}
|
|
|
|
tracing::error!("{:?}", self);
|
|
|
|
match &self {
|
|
AdminError::UnexpectedError(_) => (
|
|
StatusCode::INTERNAL_SERVER_ERROR,
|
|
Json(ErrorResponse {
|
|
message: "An internal server error occured.",
|
|
}),
|
|
)
|
|
.into_response(),
|
|
AdminError::NotAuthenticated => Redirect::to("/login").into_response(),
|
|
AdminError::ChangePassword(e) => {
|
|
let template = ErrorTemplate {
|
|
error_message: e.to_owned(),
|
|
};
|
|
Html(template.render().unwrap()).into_response()
|
|
}
|
|
AdminError::Publish(e) => {
|
|
let template = ErrorTemplate {
|
|
error_message: e.to_string(),
|
|
};
|
|
Html(template.render().unwrap()).into_response()
|
|
}
|
|
AdminError::Idempotency(e) => {
|
|
(StatusCode::BAD_REQUEST, Json(ErrorResponse { message: e })).into_response()
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
#[tracing::instrument(name = "Logging out", skip(session))]
|
|
pub async fn logout(session: TypedSession) -> Result<Response, AdminError> {
|
|
session.clear().await;
|
|
Ok(Redirect::to("/login").into_response())
|
|
}
|