This commit is contained in:
gru committed 2026-10-03 00:27:09 +01:00
commit 5e23e9af02
240 files changed
+99957

No files matched your search

+89
View File
@@ -0,0 +1,89 @@
//! Authenticated OpenAPI/Swagger UI, exclusively on the admin listener.
//! Only these allowlisted vendor assets can be read; no filesystem or wildcard route.
use axum::{
response::{Html, IntoResponse, Response},
Json,
};
use http::StatusCode;
use serde_json::Value;
use std::sync::OnceLock;
pub(super) async fn index() -> Html<&'static str> {
Html(include_str!("web/docs.html"))
}
pub(super) async fn script() -> impl IntoResponse {
(
[("content-type", "text/javascript; charset=utf-8")],
include_str!("web/docs.js"),
)
}
pub(super) async fn style() -> impl IntoResponse {
(
[("content-type", "text/css; charset=utf-8")],
include_str!("web/docs.css"),
)
}
pub(super) async fn schema() -> Json<Value> {
static DOCUMENT: OnceLock<Value> = OnceLock::new();
Json(
DOCUMENT
.get_or_init(|| {
let mut value: Value = serde_json::from_str(include_str!("openapi.json"))
.expect("validated embedded OpenAPI");
value["info"]["version"] = Value::String(env!("CARGO_PKG_VERSION").into());
value
})
.clone(),
)
}
pub(super) fn asset(name: &'static str) -> Response {
// Bytes are embedded for debug AND release, and always served through the
// authenticated router. Never read a file or fetch a CDN on an HTTP request.
let (content_type, bytes): (&'static str, &'static [u8]) = match name {
"swagger-ui-bundle.js" => (
"text/javascript; charset=utf-8",
include_bytes!(concat!(env!("OUT_DIR"), "/swagger-ui/swagger-ui-bundle.js")),
),
"swagger-ui.css" => (
"text/css; charset=utf-8",
include_bytes!(concat!(env!("OUT_DIR"), "/swagger-ui/swagger-ui.css")),
),
"licenses.txt" => (
"text/plain; charset=utf-8",
include_bytes!(concat!(env!("OUT_DIR"), "/swagger-ui/licenses.txt")),
),
_ => return StatusCode::NOT_FOUND.into_response(),
};
([("content-type", content_type)], bytes).into_response()
}
#[cfg(test)]
mod tests {
use super::*;
#[tokio::test]
async fn fixed_vendor_names_return_embedded_assets_with_expected_types() {
for (name, expected_type) in [
("swagger-ui-bundle.js", "text/javascript; charset=utf-8"),
("swagger-ui.css", "text/css; charset=utf-8"),
("licenses.txt", "text/plain; charset=utf-8"),
] {
let response = asset(name);
assert_eq!(response.status(), StatusCode::OK);
assert_eq!(response.headers()["content-type"], expected_type);
let bytes = axum::body::to_bytes(response.into_body(), 16 * 1024 * 1024)
.await
.unwrap();
assert!(!bytes.is_empty(), "{name}");
}
for name in [
"../Cargo.toml",
"index.html",
"openapi.json",
"source.json",
"unknown.js",
] {
assert_eq!(asset(name).status(), StatusCode::NOT_FOUND);
}
}
}