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