admin command to delete media via MXC url
Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
parent
27c29e6063
commit
4d624846ee
4 changed files with 85 additions and 41 deletions
|
@ -1,4 +1,5 @@
|
|||
use ruma::api::client::error::ErrorKind;
|
||||
use tracing::debug;
|
||||
|
||||
use crate::{
|
||||
database::KeyValueDatabase,
|
||||
|
@ -40,14 +41,46 @@ impl service::media::Data for KeyValueDatabase {
|
|||
}
|
||||
|
||||
fn delete_file_mxc(&self, mxc: String) -> Result<()> {
|
||||
let mut key = mxc.as_bytes().to_vec();
|
||||
key.push(0xff);
|
||||
debug!("MXC URI: {:?}", mxc);
|
||||
|
||||
self.mediaid_file.remove(&key)?;
|
||||
let mut prefix = mxc.as_bytes().to_vec();
|
||||
prefix.push(0xff);
|
||||
|
||||
debug!("MXC db prefix: {:?}", prefix);
|
||||
|
||||
for (key, _) in self.mediaid_file.scan_prefix(prefix) {
|
||||
debug!("Deleting key: {:?}", key);
|
||||
self.mediaid_file.remove(&key)?;
|
||||
}
|
||||
//return Err(Error::bad_database("Media not found."));
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Searches for all files with the given MXC (e.g. thumbnail and original image)
|
||||
fn search_mxc_metadata_prefix(&self, mxc: String) -> Result<Vec<Vec<u8>>> {
|
||||
debug!("MXC URI: {:?}", mxc);
|
||||
|
||||
let mut prefix = mxc.as_bytes().to_vec();
|
||||
prefix.push(0xff);
|
||||
|
||||
let mut keys: Vec<Vec<u8>> = vec![];
|
||||
|
||||
for (key, _) in self.mediaid_file.scan_prefix(prefix) {
|
||||
keys.push(key);
|
||||
}
|
||||
|
||||
if keys.is_empty() {
|
||||
return Err(Error::bad_database(
|
||||
"Failed to find any keys in database with the provided MXC.",
|
||||
));
|
||||
}
|
||||
|
||||
debug!("Got the following keys: {:?}", keys);
|
||||
|
||||
Ok(keys)
|
||||
}
|
||||
|
||||
fn search_file_metadata(
|
||||
&self,
|
||||
mxc: String,
|
||||
|
|
|
@ -27,8 +27,8 @@ use ruma::{
|
|||
},
|
||||
TimelineEventType,
|
||||
},
|
||||
EventId, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId, RoomOrAliasId,
|
||||
RoomVersionId, ServerName, UserId,
|
||||
EventId, MxcUri, OwnedRoomAliasId, OwnedRoomId, OwnedUserId, RoomAliasId, RoomId,
|
||||
RoomOrAliasId, RoomVersionId, ServerName, UserId,
|
||||
};
|
||||
use serde_json::value::to_raw_value;
|
||||
use tokio::sync::{mpsc, Mutex};
|
||||
|
@ -69,6 +69,10 @@ enum AdminCommand {
|
|||
/// - Commands for managing the server
|
||||
Server(ServerCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
/// - Commands for managing media
|
||||
Media(MediaCommand),
|
||||
|
||||
#[command(subcommand)]
|
||||
// TODO: should i split out debug commands to a separate thing? the
|
||||
// debug commands seem like they could fit in the other categories fine
|
||||
|
@ -77,6 +81,16 @@ enum AdminCommand {
|
|||
Debug(DebugCommand),
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
#[derive(Subcommand)]
|
||||
enum MediaCommand {
|
||||
/// - Deletes a single media file from our database and on the filesystem via a single MXC URI
|
||||
Delete {
|
||||
/// The MXC URI to delete
|
||||
mxc: Box<MxcUri>,
|
||||
},
|
||||
}
|
||||
|
||||
#[cfg_attr(test, derive(Debug))]
|
||||
#[derive(Subcommand)]
|
||||
enum AppserviceCommand {
|
||||
|
@ -606,6 +620,16 @@ impl Service {
|
|||
}
|
||||
}
|
||||
},
|
||||
AdminCommand::Media(command) => match command {
|
||||
MediaCommand::Delete { mxc } => {
|
||||
debug!("Got MXC URI: {}", mxc);
|
||||
services().media.delete(mxc.to_string()).await?;
|
||||
|
||||
return Ok(RoomMessageEventContent::text_plain(
|
||||
"Deleted the MXC from our database and on our filesystem.",
|
||||
));
|
||||
}
|
||||
},
|
||||
AdminCommand::Users(command) => match command {
|
||||
UserCommand::List => match services().users.list_local_users() {
|
||||
Ok(users) => {
|
||||
|
|
|
@ -20,6 +20,8 @@ pub trait Data: Send + Sync {
|
|||
height: u32,
|
||||
) -> Result<(Option<String>, Option<String>, Vec<u8>)>;
|
||||
|
||||
fn search_mxc_metadata_prefix(&self, mxc: String) -> Result<Vec<Vec<u8>>>;
|
||||
|
||||
fn remove_url_preview(&self, url: &str) -> Result<()>;
|
||||
|
||||
fn set_url_preview(
|
||||
|
|
|
@ -8,7 +8,7 @@ use std::{
|
|||
|
||||
pub(crate) use data::Data;
|
||||
use serde::Serialize;
|
||||
use tracing::{debug, error, warn};
|
||||
use tracing::{debug, error};
|
||||
|
||||
use crate::{services, Error, Result};
|
||||
use image::imageops::FilterType;
|
||||
|
@ -93,45 +93,30 @@ impl Service {
|
|||
|
||||
/// Deletes a file in the database and from the media directory via an MXC
|
||||
pub async fn delete(&self, mxc: String) -> Result<()> {
|
||||
if let Ok(filemeta) = self.get(mxc.clone()).await {
|
||||
match filemeta {
|
||||
Some(filemeta) => {
|
||||
debug!("Got file metadata: {:?}", filemeta);
|
||||
let file_key = filemeta.file;
|
||||
debug!("File key from file metadata: {:?}", file_key);
|
||||
if let Ok(keys) = self.db.search_mxc_metadata_prefix(mxc.clone()) {
|
||||
for key in keys {
|
||||
let file_path = if cfg!(feature = "sha256_media") {
|
||||
services().globals.get_media_file_new(&key)
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
services().globals.get_media_file(&key)
|
||||
};
|
||||
debug!("Got local file path: {:?}", file_path);
|
||||
|
||||
let file_path = if cfg!(feature = "sha256_media") {
|
||||
services().globals.get_media_file_new(&file_key)
|
||||
} else {
|
||||
#[allow(deprecated)]
|
||||
services().globals.get_media_file(&file_key)
|
||||
};
|
||||
debug!("Got local file path: {:?}", file_path);
|
||||
debug!(
|
||||
"Deleting local file {:?} from filesystem, original MXC: {}",
|
||||
file_path, mxc
|
||||
);
|
||||
tokio::fs::remove_file(file_path).await?;
|
||||
|
||||
debug!(
|
||||
"Deleting local file {:?} from filesystem, original MXC: {mxc}",
|
||||
file_path
|
||||
);
|
||||
tokio::fs::remove_file(file_path).await?;
|
||||
|
||||
debug!("Deleting MXC {mxc} from database");
|
||||
self.db.delete_file_mxc(mxc)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
None => {
|
||||
warn!(
|
||||
"MXC {mxc} does not exist in our database or file in MXC does not exist."
|
||||
);
|
||||
Err(Error::bad_database(
|
||||
"MXC does not exist in our database or file in MXC does not exist.",
|
||||
))
|
||||
}
|
||||
debug!("Deleting MXC {mxc} from database");
|
||||
self.db.delete_file_mxc(mxc.clone())?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
// we shouldn't get to this point as this is failing to actually attempt to get the file metadata (Result)
|
||||
error!("Failed getting file metadata for MXC \"{mxc}\" in database (does not exist or database issue?)");
|
||||
Err(Error::bad_database("Failed getting file metadata via MXC in database (does not exist or database issue?)"))
|
||||
error!("Failed to find any media keys for MXC \"{mxc}\" in our database (MXC does not exist)");
|
||||
Err(Error::bad_database("Failed to find any media keys for the provided MXC in our database (MXC does not exist)"))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue