diff --git a/src/admin/query/pusher.rs b/src/admin/query/pusher.rs index 76a4147de..e3c2cfa8f 100644 --- a/src/admin/query/pusher.rs +++ b/src/admin/query/pusher.rs @@ -1,6 +1,10 @@ use clap::Subcommand; -use conduwuit::Result; -use ruma::OwnedUserId; +use conduwuit::{ + Result, + utils::{IterStream, stream::BroadbandExt}, +}; +use futures::StreamExt; +use ruma::{OwnedDeviceId, OwnedUserId}; use crate::Context; @@ -11,6 +15,23 @@ pub enum PusherCommand { /// Full user ID user_id: OwnedUserId, }, + + /// Deletes a specific pusher by ID + DeletePusher { + user_id: OwnedUserId, + pusher_id: String, + }, + + /// Deletes all pushers for a user + DeleteAllUser { + user_id: OwnedUserId, + }, + + /// Deletes all pushers associated with a device ID + DeleteAllDevice { + user_id: OwnedUserId, + device_id: OwnedDeviceId, + }, } pub(super) async fn process(subcommand: PusherCommand, context: &Context<'_>) -> Result { @@ -24,6 +45,51 @@ pub(super) async fn process(subcommand: PusherCommand, context: &Context<'_>) -> write!(context, "Query completed in {query_time:?}:\n\n```rs\n{results:#?}\n```") }, + | PusherCommand::DeletePusher { user_id, pusher_id } => { + services.pusher.delete_pusher(&user_id, &pusher_id).await; + write!(context, "Deleted pusher {pusher_id} for {user_id}.") + }, + | PusherCommand::DeleteAllUser { user_id } => { + let pushers = services + .pusher + .get_pushkeys(&user_id) + .collect::>() + .await; + let pusher_count = pushers.len(); + pushers + .stream() + .for_each(async |pushkey| { + services.pusher.delete_pusher(&user_id, pushkey).await; + }) + .await; + write!(context, "Deleted {pusher_count} pushers for {user_id}.") + }, + | PusherCommand::DeleteAllDevice { user_id, device_id } => { + let pushers = services + .pusher + .get_pushkeys(&user_id) + .map(ToOwned::to_owned) + .broad_filter_map(async |pushkey| { + services + .pusher + .get_pusher_device(&pushkey) + .await + .ok() + .as_ref() + .is_some_and(|pusher_device| pusher_device == &device_id) + .then_some(pushkey) + }) + .collect::>() + .await; + let pusher_count = pushers.len(); + pushers + .stream() + .for_each(async |pushkey| { + services.pusher.delete_pusher(&user_id, &pushkey).await; + }) + .await; + write!(context, "Deleted {pusher_count} pushers for {device_id}.") + }, } .await }