Compare commits

...

16 commits

Author SHA1 Message Date
e283dd3438
Merge remote-tracking branch 'origin/better-admin-commands' into custom 2024-08-22 15:17:12 -07:00
7e07d246df
split out room info into its own function 2024-08-22 15:14:19 -07:00
fbd8780600
Make commands plural 2024-08-22 15:13:48 -07:00
73ef497609
ran cargo fmt 2024-08-22 15:13:38 -07:00
6e105a8a41
Fix table headers and pagination 2024-08-22 15:12:58 -07:00
5443768b5c
List pagination and html tables 2024-08-22 15:12:58 -07:00
0328932c54
Room directory admin commands 2024-08-22 15:12:57 -07:00
048dfef76c
reply to messages 2024-08-22 15:12:55 -07:00
36dbf8ce89
Admin room alias commands
- room alias set
- room alias remove
- room alias which
- room alias list
2024-08-22 15:01:56 -07:00
7a0ae6c09a
Add appservice show command to show config 2024-08-22 14:52:03 -07:00
fc8d8df801
Allow using languages in code blocks.
```yaml
This works now
```
2024-08-22 14:52:02 -07:00
e972ef6891
Rework admin commands to use subcommands.
This commit doesn't add, remove, or change any
commands, it only organizes them
2024-08-22 14:51:57 -07:00
9b42845e0b
increase backfill limit 2024-08-22 14:24:21 -07:00
0a08025728
increase message export length 2024-08-22 14:24:21 -07:00
Matthias Ahouansou
a9c3867287 Merge branch 'content-disposition-type' into 'next'
chore: Use Content-Disposition type for HTTP header

Closes #463

See merge request famedly/conduit!713
2024-08-22 18:36:25 +00:00
avdb13
423b0928d5
use ruma content disposition type in place of string
Co-Authored-By: Matthias Ahouansou <matthias@ahouansou.cz>
2024-08-22 19:03:32 +01:00
11 changed files with 1099 additions and 715 deletions

37
Cargo.lock generated
View file

@ -1203,9 +1203,9 @@ dependencies = [
[[package]]
name = "httparse"
version = "1.8.0"
version = "1.9.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904"
checksum = "0fcc0b4a115bf80b728eb8ea024ad5bd707b615bfed49e0665b6e0f86fd082d9"
[[package]]
name = "httpdate"
@ -2232,7 +2232,7 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.10.1"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"assign",
"js_int",
@ -2253,7 +2253,7 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.10.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"js_int",
"ruma-common",
@ -2265,7 +2265,7 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.18.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"as_variant",
"assign",
@ -2288,7 +2288,7 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.13.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"as_variant",
"base64 0.22.1",
@ -2318,7 +2318,7 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.28.1"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"as_variant",
"indexmap 2.2.6",
@ -2334,15 +2334,22 @@ dependencies = [
"thiserror",
"tracing",
"url",
"web-time",
"wildmatch",
]
[[package]]
name = "ruma-federation-api"
version = "0.9.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"bytes",
"http 1.1.0",
"httparse",
"js_int",
"memchr",
"mime",
"rand",
"ruma-common",
"ruma-events",
"serde",
@ -2352,7 +2359,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.9.5"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"js_int",
"thiserror",
@ -2361,7 +2368,7 @@ dependencies = [
[[package]]
name = "ruma-identity-service-api"
version = "0.9.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"js_int",
"ruma-common",
@ -2371,7 +2378,7 @@ dependencies = [
[[package]]
name = "ruma-macros"
version = "0.13.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"once_cell",
"proc-macro-crate",
@ -2386,7 +2393,7 @@ dependencies = [
[[package]]
name = "ruma-push-gateway-api"
version = "0.9.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"js_int",
"ruma-common",
@ -2398,7 +2405,7 @@ dependencies = [
[[package]]
name = "ruma-server-util"
version = "0.3.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"headers",
"http 1.1.0",
@ -2411,7 +2418,7 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.15.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"base64 0.22.1",
"ed25519-dalek",
@ -2427,7 +2434,7 @@ dependencies = [
[[package]]
name = "ruma-state-res"
version = "0.11.0"
source = "git+https://github.com/ruma/ruma#fec2152d879a6c6c2bccce984d4b8f424f460cb2"
source = "git+https://github.com/ruma/ruma#82417e394076440089cd8ada87485d9a44cc4ba0"
dependencies = [
"itertools",
"js_int",

View file

@ -4,12 +4,15 @@
use std::time::Duration;
use crate::{service::media::FileMeta, services, utils, Error, Result, Ruma};
use ruma::api::client::{
error::ErrorKind,
media::{
create_content, get_content, get_content_as_filename, get_content_thumbnail,
get_media_config,
use ruma::{
api::client::{
error::ErrorKind,
media::{
create_content, get_content, get_content_as_filename, get_content_thumbnail,
get_media_config,
},
},
http_headers::{ContentDisposition, ContentDispositionType},
};
const MXC_LENGTH: usize = 32;
@ -44,10 +47,10 @@ pub async fn create_content_route(
.media
.create(
mxc.clone(),
body.filename
.as_ref()
.map(|filename| "inline; filename=".to_owned() + filename)
.as_deref(),
Some(
ContentDisposition::new(ContentDispositionType::Inline)
.with_filename(body.filename.clone()),
),
body.content_type.as_deref(),
&body.file,
)
@ -82,7 +85,7 @@ pub async fn get_remote_content(
.media
.create(
mxc.to_owned(),
content_response.content_disposition.as_deref(),
content_response.content_disposition.clone(),
content_response.content_type.as_deref(),
&content_response.file,
)
@ -110,7 +113,7 @@ pub async fn get_content_route(
Ok(get_content::v3::Response {
file,
content_type,
content_disposition,
content_disposition: Some(content_disposition),
cross_origin_resource_policy: Some("cross-origin".to_owned()),
})
} else if &*body.server_name != services().globals.server_name() && body.allow_remote {
@ -145,7 +148,10 @@ pub async fn get_content_as_filename_route(
Ok(get_content_as_filename::v3::Response {
file,
content_type,
content_disposition: Some(format!("inline; filename={}", body.filename)),
content_disposition: Some(
ContentDisposition::new(ContentDispositionType::Inline)
.with_filename(Some(body.filename.clone())),
),
cross_origin_resource_policy: Some("cross-origin".to_owned()),
})
} else if &*body.server_name != services().globals.server_name() && body.allow_remote {
@ -153,7 +159,10 @@ pub async fn get_content_as_filename_route(
get_remote_content(&mxc, &body.server_name, body.media_id.clone()).await?;
Ok(get_content_as_filename::v3::Response {
content_disposition: Some(format!("inline: filename={}", body.filename)),
content_disposition: Some(
ContentDisposition::new(ContentDispositionType::Inline)
.with_filename(Some(body.filename.clone())),
),
content_type: remote_content_response.content_type,
file: remote_content_response.file,
cross_origin_resource_policy: Some("cross-origin".to_owned()),
@ -216,7 +225,6 @@ pub async fn get_content_thumbnail_route(
.media
.upload_thumbnail(
mxc,
None,
get_thumbnail_response.content_type.as_deref(),
body.width.try_into().expect("all UInts are valid u32s"),
body.height.try_into().expect("all UInts are valid u32s"),

View file

@ -141,7 +141,7 @@ pub async fn get_message_events_route(
.lazy_load_confirm_delivery(sender_user, sender_device, &body.room_id, from)
.await?;
let limit = u64::from(body.limit).min(100) as usize;
let limit = u64::from(body.limit).min(2000) as usize;
let next_token;

View file

@ -1,4 +1,4 @@
use ruma::api::client::error::ErrorKind;
use ruma::{api::client::error::ErrorKind, http_headers::ContentDisposition};
use crate::{database::KeyValueDatabase, service, utils, Error, Result};
@ -8,7 +8,7 @@ impl service::media::Data for KeyValueDatabase {
mxc: String,
width: u32,
height: u32,
content_disposition: Option<&str>,
content_disposition: &ContentDisposition,
content_type: Option<&str>,
) -> Result<Vec<u8>> {
let mut key = mxc.as_bytes().to_vec();
@ -16,12 +16,7 @@ impl service::media::Data for KeyValueDatabase {
key.extend_from_slice(&width.to_be_bytes());
key.extend_from_slice(&height.to_be_bytes());
key.push(0xff);
key.extend_from_slice(
content_disposition
.as_ref()
.map(|f| f.as_bytes())
.unwrap_or_default(),
);
key.extend_from_slice(content_disposition.to_string().as_bytes());
key.push(0xff);
key.extend_from_slice(
content_type
@ -40,7 +35,7 @@ impl service::media::Data for KeyValueDatabase {
mxc: String,
width: u32,
height: u32,
) -> Result<(Option<String>, Option<String>, Vec<u8>)> {
) -> Result<(ContentDisposition, Option<String>, Vec<u8>)> {
let mut prefix = mxc.as_bytes().to_vec();
prefix.push(0xff);
prefix.extend_from_slice(&width.to_be_bytes());
@ -68,15 +63,9 @@ impl service::media::Data for KeyValueDatabase {
.next()
.ok_or_else(|| Error::bad_database("Media ID in db is invalid."))?;
let content_disposition = if content_disposition_bytes.is_empty() {
None
} else {
Some(
utils::string_from_bytes(content_disposition_bytes).map_err(|_| {
Error::bad_database("Content Disposition in mediaid_file is invalid unicode.")
})?,
)
};
let content_disposition = content_disposition_bytes
.try_into()
.map_err(|_| Error::bad_database("Content Disposition in mediaid_file is invalid."))?;
Ok((content_disposition, content_type, key))
}
}

View file

@ -75,4 +75,28 @@ impl service::rooms::alias::Data for KeyValueDatabase {
})
.transpose()
}
fn all_local_aliases<'a>(
&'a self,
) -> Box<dyn Iterator<Item = Result<(OwnedRoomId, String)>> + 'a> {
Box::new(
self.alias_roomid
.iter()
.map(|(room_alias_bytes, room_id_bytes)| {
let room_alias_localpart = utils::string_from_bytes(&room_alias_bytes)
.map_err(|_| {
Error::bad_database("Invalid alias bytes in aliasid_alias.")
})?;
let room_id = utils::string_from_bytes(&room_id_bytes)
.map_err(|_| {
Error::bad_database("Invalid room_id bytes in aliasid_alias.")
})?
.try_into()
.map_err(|_| Error::bad_database("Invalid room_id in aliasid_alias."))?;
Ok((room_id, room_alias_localpart))
}),
)
}
}

File diff suppressed because it is too large Load diff

View file

@ -1,3 +1,5 @@
use ruma::http_headers::ContentDisposition;
use crate::Result;
pub trait Data: Send + Sync {
@ -6,7 +8,7 @@ pub trait Data: Send + Sync {
mxc: String,
width: u32,
height: u32,
content_disposition: Option<&str>,
content_disposition: &ContentDisposition,
content_type: Option<&str>,
) -> Result<Vec<u8>>;
@ -16,5 +18,5 @@ pub trait Data: Send + Sync {
mxc: String,
width: u32,
height: u32,
) -> Result<(Option<String>, Option<String>, Vec<u8>)>;
) -> Result<(ContentDisposition, Option<String>, Vec<u8>)>;
}

View file

@ -2,6 +2,7 @@ mod data;
use std::io::Cursor;
pub use data::Data;
use ruma::http_headers::{ContentDisposition, ContentDispositionType};
use crate::{services, Result};
use image::imageops::FilterType;
@ -12,7 +13,7 @@ use tokio::{
};
pub struct FileMeta {
pub content_disposition: Option<String>,
pub content_disposition: ContentDisposition,
pub content_type: Option<String>,
pub file: Vec<u8>,
}
@ -26,14 +27,17 @@ impl Service {
pub async fn create(
&self,
mxc: String,
content_disposition: Option<&str>,
content_disposition: Option<ContentDisposition>,
content_type: Option<&str>,
file: &[u8],
) -> Result<()> {
let content_disposition =
content_disposition.unwrap_or(ContentDisposition::new(ContentDispositionType::Inline));
// Width, Height = 0 if it's not a thumbnail
let key = self
.db
.create_file_metadata(mxc, 0, 0, content_disposition, content_type)?;
.create_file_metadata(mxc, 0, 0, &content_disposition, content_type)?;
let path = services().globals.get_media_file(&key);
let mut f = File::create(path).await?;
@ -46,15 +50,18 @@ impl Service {
pub async fn upload_thumbnail(
&self,
mxc: String,
content_disposition: Option<&str>,
content_type: Option<&str>,
width: u32,
height: u32,
file: &[u8],
) -> Result<()> {
let key =
self.db
.create_file_metadata(mxc, width, height, content_disposition, content_type)?;
let key = self.db.create_file_metadata(
mxc,
width,
height,
&ContentDisposition::new(ContentDispositionType::Inline),
content_type,
)?;
let path = services().globals.get_media_file(&key);
let mut f = File::create(path).await?;
@ -198,7 +205,7 @@ impl Service {
mxc,
width,
height,
content_disposition.as_deref(),
&content_disposition,
content_type.as_deref(),
)?;

View file

@ -19,4 +19,9 @@ pub trait Data: Send + Sync {
&'a self,
room_id: &RoomId,
) -> Box<dyn Iterator<Item = Result<OwnedRoomAliasId>> + 'a>;
/// Returns all local aliases on the server
fn all_local_aliases<'a>(
&'a self,
) -> Box<dyn Iterator<Item = Result<(OwnedRoomId, String)>> + 'a>;
}

View file

@ -98,4 +98,11 @@ impl Service {
) -> Box<dyn Iterator<Item = Result<OwnedRoomAliasId>> + 'a> {
self.db.local_aliases_for_room(room_id)
}
#[tracing::instrument(skip(self))]
pub fn all_local_aliases<'a>(
&'a self,
) -> Box<dyn Iterator<Item = Result<(OwnedRoomId, String)>> + 'a> {
self.db.all_local_aliases()
}
}

View file

@ -506,7 +506,11 @@ impl Service {
.state_cache
.is_joined(server_user, &admin_room)?
{
services().admin.process_message(body);
services().admin.process_message(
body,
pdu.event_id.clone(),
pdu.sender.clone(),
);
}
}
}
@ -1187,7 +1191,7 @@ impl Service {
federation::backfill::get_backfill::v1::Request {
room_id: room_id.to_owned(),
v: vec![first_pdu.1.event_id.as_ref().to_owned()],
limit: uint!(100),
limit: uint!(1000),
},
)
.await;