tuwunel_api/client/admin/rooms/
delete_status.rs1use axum::extract::State;
2use ruma::RoomId;
3use synapse_admin_api::rooms::delete_status::{
4 by_delete_id::{
5 DeleteStatus, DeleteStatusKind, Request as ByDeleteIdRequest,
6 Response as ByDeleteIdResponse,
7 },
8 by_room_id::{Request as ByRoomIdRequest, Response as ByRoomIdResponse},
9};
10use tuwunel_core::{Err, Result, err};
11use tuwunel_service::tasks::{Status, TaskInfo};
12
13use crate::{Ruma, client::admin::require_admin};
14
15pub(crate) async fn admin_delete_status_by_id_route(
20 State(services): State<crate::State>,
21 body: Ruma<ByDeleteIdRequest>,
22) -> Result<ByDeleteIdResponse> {
23 require_admin(&services, body.sender_user()).await?;
24
25 let task = services
26 .tasks
27 .get(&body.delete_id)
28 .filter(|task| task.action == super::DELETE_ROOM_ACTION)
29 .ok_or_else(|| err!(Request(NotFound("Unknown delete task"))))?;
30
31 Ok(ByDeleteIdResponse { status: delete_status(task)? })
32}
33
34pub(crate) async fn admin_delete_status_by_room_route(
39 State(services): State<crate::State>,
40 body: Ruma<ByRoomIdRequest>,
41) -> Result<ByRoomIdResponse> {
42 require_admin(&services, body.sender_user()).await?;
43
44 let results = services
45 .tasks
46 .by_resource(body.room_id.as_str())
47 .into_iter()
48 .filter(|task| {
49 task.action == super::DELETE_ROOM_ACTION && task.status != Status::Scheduled
50 })
51 .map(delete_status)
52 .collect::<Result<Vec<_>>>()?;
53
54 if results.is_empty() {
55 return Err!(Request(NotFound("No delete task for this room found")));
56 }
57
58 Ok(ByRoomIdResponse { results })
59}
60
61fn delete_status(task: TaskInfo) -> Result<DeleteStatus> {
62 let room_id = RoomId::parse(&task.resource_id)
63 .map_err(|_| err!(Request(NotFound("Delete task has an invalid room id"))))?;
64
65 let shutdown_room = task
66 .result
67 .and_then(|result| serde_json::from_value(result).ok());
68
69 Ok(DeleteStatus {
70 delete_id: task.id.to_string(),
71 room_id,
72 status: delete_status_kind(task.status),
73 shutdown_room,
74 })
75}
76
77fn delete_status_kind(status: Status) -> DeleteStatusKind {
78 match status {
79 | Status::Scheduled => DeleteStatusKind::Scheduled,
80 | Status::Active => DeleteStatusKind::Active,
81 | Status::Complete => DeleteStatusKind::Complete,
82 | Status::Failed => DeleteStatusKind::Failed,
83 }
84}
85
86#[cfg(test)]
87mod tests {
88 use serde_json::json;
89 use tuwunel_service::tasks::Status;
90
91 use super::delete_status_kind;
92
93 #[test]
94 fn maps_each_stage_and_keeps_scheduled_distinct() {
95 let kind = |status| serde_json::to_value(delete_status_kind(status)).unwrap();
96
97 assert_eq!(kind(Status::Scheduled), json!("scheduled"));
98 assert_eq!(kind(Status::Active), json!("active"));
99 assert_eq!(kind(Status::Complete), json!("complete"));
100 assert_eq!(kind(Status::Failed), json!("failed"));
101 }
102}