tuwunel_api/client/admin/media/
delete_user_media.rs1use axum::extract::State;
2use futures::StreamExt;
3use ruma::UInt;
4use synapse_admin_api::media::delete_user_media::v1 as delete_user_media;
5use tuwunel_core::{
6 Err, Result,
7 utils::stream::{IterStream, WidebandExt},
8};
9
10use super::{select_page, usize_from};
11use crate::{Ruma, client::admin::require_admin};
12
13pub(crate) async fn admin_delete_user_media_route(
19 State(services): State<crate::State>,
20 body: Ruma<delete_user_media::Request>,
21) -> Result<delete_user_media::Response> {
22 require_admin(&services, body.sender_user()).await?;
23
24 if !services
25 .globals
26 .server_is_ours(body.user_id.server_name())
27 {
28 return Err!(Request(InvalidParam("Can only look up local users")));
29 }
30
31 if !services.users.exists(&body.user_id).await {
32 return Err!(Request(NotFound("User not found")));
33 }
34
35 let entries = services.media.user_media(&body.user_id).await?;
36
37 let from = body.from.map(usize_from).unwrap_or(0);
38 let limit = body.limit.map(usize_from).unwrap_or(100);
39
40 let page = select_page(entries, body.order_by.as_ref(), body.dir, from, limit);
41
42 let deleted_media: Vec<String> = page
43 .iter()
44 .stream()
45 .wide_filter_map(async |entry| {
46 let mxc = entry.mxc.parts().ok()?;
47
48 services
49 .media
50 .delete(&mxc)
51 .await
52 .ok()
53 .map(|()| mxc.media_id.to_owned())
54 })
55 .collect()
56 .await;
57
58 let total = UInt::try_from(deleted_media.len()).unwrap_or(UInt::MAX);
59
60 Ok(delete_user_media::Response { deleted_media, total })
61}