acme_proxy_admin/webadmin/handlers/
upstream_orders.rs1use axum::Json;
13use axum::extract::{Path, Query, State};
14use serde::Deserialize;
15use serde_json::Value;
16
17use crate::admin;
18use crate::webadmin::AdminState;
19use crate::webadmin::error::AdminError;
20use crate::webadmin::handlers::paging::{PageParams, page_envelope};
21use crate::webadmin::handlers::params::{bad_status, empty_is_absent};
22use crate::webadmin::session::Authenticated;
23use acme_proxy_store::status::UnknownStatus;
24use acme_proxy_store::status::UpstreamOrderStatus;
25use acme_proxy_store::upstream_order::UpstreamOrder;
26use acme_proxy_store::upstream_order::UpstreamOrderQuery;
27
28#[derive(Debug, Deserialize, Default)]
31pub struct UpstreamOrderListParams {
32 #[serde(default, deserialize_with = "empty_is_absent")]
33 pub profile: Option<String>,
34 #[serde(default, deserialize_with = "empty_is_absent")]
35 pub status: Option<String>,
36 pub limit: Option<i64>,
37 pub offset: Option<i64>,
38}
39
40impl UpstreamOrderListParams {
41 pub fn parsed_status(&self) -> Result<Option<UpstreamOrderStatus>, UnknownStatus> {
43 self.status.as_deref().map(str::parse).transpose()
44 }
45}
46
47pub(crate) fn upstream_order_query(
50 params: &UpstreamOrderListParams,
51 page: crate::webadmin::handlers::paging::Page,
52) -> Result<UpstreamOrderQuery, AdminError> {
53 Ok(UpstreamOrderQuery {
54 profile: params.profile.clone(),
55 status: params.parsed_status().map_err(bad_status)?,
56 limit: page.limit,
57 offset: page.offset,
58 })
59}
60
61pub async fn list_upstream_orders(
63 State(state): State<AdminState>,
64 Query(params): Query<UpstreamOrderListParams>,
65 _auth: Authenticated,
66) -> Result<Json<Value>, AdminError> {
67 let page = PageParams::from(params.limit, params.offset).resolve(&state.config);
68 let query = upstream_order_query(¶ms, page)?;
69 let (rows, total) = UpstreamOrder::search(&query, &state.database).await?;
70 let items = rows.iter().map(admin::render_upstream_order_json).collect();
71 Ok(Json(page_envelope(items, total, page)))
72}
73
74pub async fn get_upstream_order(
77 State(state): State<AdminState>,
78 Path(id): Path<String>,
79 _auth: Authenticated,
80) -> Result<Json<Value>, AdminError> {
81 let detail = admin::load_upstream_order_detail(&id, state.database.clone())
82 .await?
83 .ok_or_else(|| AdminError::not_found(format!("no upstream order for local order {id}")))?;
84 Ok(Json(admin::render_upstream_order_detail_json(&detail)))
85}