45 lines
1.7 KiB
Rust
45 lines
1.7 KiB
Rust
//! Deliberately small anonymous surface. Operational templates/assets are private.
|
|
use crate::{auth::Session, runtime::{ApiError, App}, settings::PanelCompression};
|
|
use axum::{extract::{rejection::JsonRejection, State}, response::{Html, IntoResponse, Response}, Extension};
|
|
use http::{HeaderMap, StatusCode};
|
|
use std::sync::{Arc, OnceLock};
|
|
|
|
use super::panel_content::PanelContent;
|
|
|
|
static ADMIN_INDEX: OnceLock<PanelContent> = OnceLock::new();
|
|
|
|
fn panel_response(headers: &HeaderMap, compression: &PanelCompression) -> Response {
|
|
let content = ADMIN_INDEX.get_or_init(|| {
|
|
let html = include_str!("web/index.html")
|
|
.replace("__RUSTPROXY_VERSION__", env!("CARGO_PKG_VERSION"));
|
|
// Exactly one static panel document shared between all administrator accounts.
|
|
PanelContent::new(Box::leak(html.into_boxed_str()))
|
|
});
|
|
content.response(headers, compression, "text/html; charset=utf-8")
|
|
}
|
|
|
|
pub(super) async fn index(
|
|
State(state): State<Arc<App>>,
|
|
session: Option<Extension<Session>>,
|
|
headers: HeaderMap,
|
|
) -> Response {
|
|
if session.is_none() {
|
|
return Html(include_str!("web/login.html")).into_response();
|
|
}
|
|
let snapshot = state.config.load();
|
|
panel_response(&headers, &snapshot.envelope.config.administration.panel_compression)
|
|
}
|
|
|
|
pub(super) fn invalid_json(error: JsonRejection) -> ApiError {
|
|
// Keep useful protocol statuses without returning serde's input excerpts.
|
|
let status = match error.status() {
|
|
StatusCode::PAYLOAD_TOO_LARGE => StatusCode::PAYLOAD_TOO_LARGE,
|
|
StatusCode::UNSUPPORTED_MEDIA_TYPE => StatusCode::UNSUPPORTED_MEDIA_TYPE,
|
|
_ => StatusCode::BAD_REQUEST,
|
|
};
|
|
ApiError(status, "auth.invalid_request".into())
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests;
|