manta_server/server/handlers/
template.rs

1//! BOS session-template handlers.
2//!
3//! - `GET  /api/v1/templates`                       → [`get_templates`] —
4//!   wraps `service::template::get_templates`.
5//! - `POST /api/v1/templates/{name}/sessions`       → [`post_template_session`] —
6//!   wraps `service::template::create_template_session`; starts a
7//!   BOS session from the named template.
8
9use axum::{
10  Json,
11  extract::{Path, Query},
12  http::StatusCode,
13  response::IntoResponse,
14};
15
16use super::{
17  ErrorResponse, RequestCtx, SiteHeader, serialize_or_500, to_handler_error,
18};
19use crate::service;
20
21// ---------------------------------------------------------------------------
22// GET /api/v1/templates
23// ---------------------------------------------------------------------------
24
25pub use manta_shared::types::api::queries::TemplateQuery;
26
27/// GET /templates — list BOS session templates with optional filters.
28#[utoipa::path(get, path = "/templates", tag = "templates",
29  params(TemplateQuery, SiteHeader),
30  security(("bearerAuth" = [])),
31  responses(
32    // BosSessionTemplate lives in manta-backend-dispatcher (third-party,
33    // no ToSchema) — kept as Value until upstream derives it.
34    (status = 200, description = "List of session templates", body = serde_json::Value),
35    (status = 401, description = "Unauthorized",              body = ErrorResponse),
36    (status = 500, description = "Internal error",            body = ErrorResponse),
37  )
38)]
39#[tracing::instrument(skip_all)]
40pub async fn get_templates(
41  ctx: RequestCtx,
42  Query(q): Query<TemplateQuery>,
43) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
44  let infra = ctx.infra();
45
46  let params = service::template::GetTemplateParams {
47    name: q.name,
48    group_name: q.hsm_group,
49    settings_group_name: None,
50    limit: q.limit,
51  };
52
53  let templates = service::template::get_templates(&infra, &ctx.token, &params)
54    .await
55    .map_err(to_handler_error)?;
56
57  Ok(Json(templates))
58}
59
60// ---------------------------------------------------------------------------
61// POST /api/v1/templates/{name}/sessions — Create BOS session from template
62// ---------------------------------------------------------------------------
63
64pub use manta_shared::types::api::template::{
65  BosOperation, PostTemplateSessionRequest,
66};
67
68/// `POST /api/v1/templates/{name}/sessions` — create a BOS session from a session template.
69#[utoipa::path(post, path = "/templates/{name}/sessions", tag = "templates",
70  params(("name" = String, Path, description = "Template name"), SiteHeader),
71  request_body = PostTemplateSessionRequest,
72  security(("bearerAuth" = [])),
73  responses(
74    // dry_run/real result union — kept as Value until the union shape is formalised
75    (status = 200, description = "Dry run preview",  body = serde_json::Value),
76    // BosSession lives in manta-backend-dispatcher (third-party, no
77    // ToSchema) — kept as Value until upstream derives it.
78    (status = 201, description = "Session created",  body = serde_json::Value),
79    (status = 400, description = "Bad request",      body = ErrorResponse),
80    (status = 401, description = "Unauthorized",     body = ErrorResponse),
81    (status = 500, description = "Internal error",   body = ErrorResponse),
82  )
83)]
84#[tracing::instrument(skip_all)]
85pub async fn post_template_session(
86  ctx: RequestCtx,
87  Path(name): Path<String>,
88  Json(body): Json<PostTemplateSessionRequest>,
89) -> Result<impl IntoResponse, (StatusCode, Json<ErrorResponse>)> {
90  tracing::info!(
91    "post_template_session template={} op={:?} dry_run={}",
92    name,
93    body.operation,
94    body.dry_run
95  );
96  let infra = ctx.infra();
97
98  let params = service::template::ApplyTemplateParams {
99    bos_session_name: body.session_name,
100    bos_sessiontemplate_name: name,
101    bos_session_operation: body.operation.as_str().to_string(),
102    limit: body.limit,
103    include_disabled: body.include_disabled,
104  };
105
106  let (bos_session, _) =
107    service::template::validate_and_prepare_template_session(
108      &infra, &ctx.token, &params,
109    )
110    .await
111    .map_err(to_handler_error)?;
112
113  if body.dry_run {
114    return Ok((StatusCode::OK, Json(serialize_or_500(&bos_session)?)));
115  }
116
117  let created =
118    service::template::create_bos_session(&infra, &ctx.token, bos_session)
119      .await
120      .map_err(to_handler_error)?;
121
122  Ok((StatusCode::CREATED, Json(serialize_or_500(&created)?)))
123}