Compare commits

..

18 commits

Author SHA1 Message Date
Jacob Taylor
34d0599a13 more funny settings (part 3 of 12)
Some checks failed
Checks / Prefligit / prefligit (push) Failing after 3s
Release Docker Image / define-variables (push) Failing after 2s
Release Docker Image / build-image (linux/amd64, release, linux-amd64, base) (push) Has been skipped
Release Docker Image / build-image (linux/arm64, release, linux-arm64, base) (push) Has been skipped
Release Docker Image / merge (push) Has been skipped
Checks / Rust / Format (push) Failing after 1s
Checks / Rust / Clippy (push) Failing after 27s
Checks / Rust / Cargo Test (push) Failing after 30s
2025-07-12 14:41:49 -07:00
Jacob Taylor
79dac685c6 sender_workers scaling. this time, with feeling! 2025-07-12 14:41:49 -07:00
Jacob Taylor
791172d865 vehicle loan documentation now available at window 7 2025-07-12 14:41:49 -07:00
Jacob Taylor
7a72d872de lock the getter instead ??? c/o M 2025-07-12 14:41:49 -07:00
Jacob Taylor
a7186e15b6 make fetching key room events less smart 2025-07-12 14:41:49 -07:00
Jacob Taylor
bdb4165c5c change rocksdb stats level to 3
scale rocksdb background jobs and subcompactions

change rocksdb default error level to info from error

delete unused num_threads function

fix warns from cargo
2025-07-12 14:41:49 -07:00
nexy7574
54924b6629 log which room struggled to get mainline depth 2025-07-12 14:41:49 -07:00
nexy7574
0bf18889dc more logs 2025-07-12 14:41:49 -07:00
nexy7574
c7c15680e3 Fix room ID check 2025-07-12 14:41:49 -07:00
nexy7574
a4f2db21be Kick up a fuss when m.room.create is unfindable 2025-07-12 14:41:49 -07:00
nexy7574
b8c189a90a Note about ruma#2064 in TODO 2025-07-12 14:41:49 -07:00
nexy7574
fae7f18836 fix an auth rule not applying correctly 2025-07-12 14:41:49 -07:00
Jacob Taylor
e025587c76 upgrade some settings to enable 5g in continuwuity
enable converged 6g at the edge in continuwuity

better stateinfo_cache_capacity default

better roomid_spacehierarchy_cache_capacity

make sender workers default better and clamp value to core count

update sender workers documentation

add more parallelism_scaled and make them public

update 1 document
2025-07-12 14:41:49 -07:00
Jacob Taylor
c5f49ebaa1 bump the number of allowed immutable memtables by 1, to allow for greater flood protection
this should probably not be applied if you have rocksdb_atomic_flush = false (the default)
2025-07-12 14:41:49 -07:00
Jacob Taylor
339ff8c1b2 probably incorrectly delete support for non-standardized matrix srv record 2025-07-12 14:41:49 -07:00
nexy7574
1abe8f7835 fix: Creation bug
Some checks failed
Documentation / Build and Deploy Documentation (push) Has been skipped
Checks / Prefligit / prefligit (push) Failing after 13s
Release Docker Image / define-variables (push) Failing after 5s
Release Docker Image / build-image (linux/amd64, release, linux-amd64, base) (push) Has been skipped
Release Docker Image / build-image (linux/arm64, release, linux-arm64, base) (push) Has been skipped
Release Docker Image / merge (push) Has been skipped
Checks / Rust / Format (push) Failing after 6s
Checks / Rust / Clippy (push) Failing after 16s
Checks / Rust / Cargo Test (push) Failing after 11s
2025-07-12 22:37:49 +01:00
nexy7574
ce84c46459
style(902): Fix clippy complaining about cast
Some checks failed
Documentation / Build and Deploy Documentation (push) Has been skipped
Checks / Prefligit / prefligit (push) Failing after 1s
Release Docker Image / define-variables (push) Failing after 1s
Release Docker Image / build-image (linux/amd64, release, linux-amd64, base) (push) Has been skipped
Release Docker Image / build-image (linux/arm64, release, linux-arm64, base) (push) Has been skipped
Release Docker Image / merge (push) Has been skipped
Checks / Rust / Format (push) Failing after 3s
Checks / Rust / Clippy (push) Failing after 8s
Checks / Rust / Cargo Test (push) Failing after 11s
2025-07-09 15:28:31 +01:00
nexy7574
7b60f5368d
feat(902): Upload files for admin commands that are too long 2025-07-09 15:11:09 +01:00
3 changed files with 115 additions and 13 deletions

View file

@ -298,7 +298,9 @@ pub(crate) async fn register_route(
session: None, session: None,
auth_error: None, auth_error: None,
}; };
let mut skip_auth = body.appservice_info.is_some(); let skip_auth = body.appservice_info.is_some() || is_guest;
// Populate required UIAA flows
if services.globals.registration_token.is_some() { if services.globals.registration_token.is_some() {
// Registration token required // Registration token required
uiaainfo.flows.push(AuthFlow { uiaainfo.flows.push(AuthFlow {
@ -317,9 +319,10 @@ pub(crate) async fn register_route(
}, },
})) }))
.expect("Failed to serialize recaptcha params"); .expect("Failed to serialize recaptcha params");
skip_auth = skip_auth || is_guest;
} }
} else { }
if uiaainfo.flows.is_empty() && !skip_auth {
// No registration token necessary, but clients must still go through the flow // No registration token necessary, but clients must still go through the flow
uiaainfo = UiaaInfo { uiaainfo = UiaaInfo {
flows: vec![AuthFlow { stages: vec![AuthType::Dummy] }], flows: vec![AuthFlow { stages: vec![AuthType::Dummy] }],
@ -328,7 +331,6 @@ pub(crate) async fn register_route(
session: None, session: None,
auth_error: None, auth_error: None,
}; };
skip_auth = skip_auth || is_guest;
} }
if !skip_auth { if !skip_auth {

View file

@ -192,8 +192,9 @@ pub async fn revoke_admin(&self, user_id: &UserId) -> Result {
| Err(e) => return Err!(error!(?e, "Failure occurred while attempting revoke.")), | Err(e) => return Err!(error!(?e, "Failure occurred while attempting revoke.")),
| Ok(event) if !matches!(event.membership, Invite | Knock | Join) => | Ok(event) if !matches!(event.membership, Invite | Knock | Join) => {
return Err!("Cannot revoke {user_id} in membership state {:?}.", event.membership), return Err!("Cannot revoke {user_id} in membership state {:?}.", event.membership);
},
| Ok(event) => { | Ok(event) => {
assert!( assert!(

View file

@ -9,6 +9,7 @@ use std::{
}; };
use async_trait::async_trait; use async_trait::async_trait;
use conduwuit::{Err, utils};
use conduwuit_core::{ use conduwuit_core::{
Error, Event, Result, Server, debug, err, error, error::default_log, pdu::PduBuilder, Error, Event, Result, Server, debug, err, error, error::default_log, pdu::PduBuilder,
}; };
@ -16,15 +17,20 @@ pub use create::create_admin_room;
use futures::{Future, FutureExt, TryFutureExt}; use futures::{Future, FutureExt, TryFutureExt};
use loole::{Receiver, Sender}; use loole::{Receiver, Sender};
use ruma::{ use ruma::{
OwnedEventId, OwnedRoomId, RoomId, UserId, Mxc, OwnedEventId, OwnedMxcUri, OwnedRoomId, RoomId, UInt, UserId,
events::{ events::{
Mentions, Mentions,
room::message::{Relation, RoomMessageEventContent}, room::{
MediaSource,
message::{
FileInfo, FileMessageEventContent, MessageType, Relation, RoomMessageEventContent,
},
},
}, },
}; };
use tokio::sync::RwLock; use tokio::sync::RwLock;
use crate::{Dep, account_data, globals, rooms, rooms::state::RoomMutexGuard}; use crate::{Dep, account_data, globals, media::MXC_LENGTH, rooms, rooms::state::RoomMutexGuard};
pub struct Service { pub struct Service {
services: Services, services: Services,
@ -45,6 +51,7 @@ struct Services {
state_accessor: Dep<rooms::state_accessor::Service>, state_accessor: Dep<rooms::state_accessor::Service>,
account_data: Dep<account_data::Service>, account_data: Dep<account_data::Service>,
services: StdRwLock<Option<Weak<crate::Services>>>, services: StdRwLock<Option<Weak<crate::Services>>>,
media: Dep<crate::media::Service>,
} }
/// Inputs to a command are a multi-line string, optional reply_id, and optional /// Inputs to a command are a multi-line string, optional reply_id, and optional
@ -94,6 +101,7 @@ impl crate::Service for Service {
.depend::<rooms::state_accessor::Service>("rooms::state_accessor"), .depend::<rooms::state_accessor::Service>("rooms::state_accessor"),
account_data: args.depend::<account_data::Service>("account_data"), account_data: args.depend::<account_data::Service>("account_data"),
services: None.into(), services: None.into(),
media: args.depend::<crate::media::Service>("media"),
}, },
channel: loole::bounded(COMMAND_QUEUE_LIMIT), channel: loole::bounded(COMMAND_QUEUE_LIMIT),
handle: RwLock::new(None), handle: RwLock::new(None),
@ -157,8 +165,65 @@ impl Service {
.ok(); .ok();
} }
/// Sends a message to the admin room as the admin user (see send_text() for /// Either returns a small-enough message, or converts a large message into
/// convenience). /// a file
pub async fn text_or_file(
&self,
message_content: RoomMessageEventContent,
) -> RoomMessageEventContent {
let body_len = Self::collate_msg_size(&message_content);
if body_len > 60000 {
// Intercept and send as file
let file = self
.text_to_file(message_content.body())
.await
.expect("failed to create text file");
let size_u64: u64 = message_content.body().len().try_into().map_or(0, |n| n);
let metadata = FileInfo {
mimetype: Some("text/markdown".to_owned()),
size: Some(UInt::new_saturating(size_u64)),
thumbnail_info: None,
thumbnail_source: None,
};
let content = FileMessageEventContent {
body: "Output was too large to send as text.".to_owned(),
formatted: None,
filename: Some("output.md".to_owned()),
source: MediaSource::Plain(file),
info: Some(Box::new(metadata)),
};
RoomMessageEventContent::new(MessageType::File(content))
} else {
message_content
}
}
#[must_use]
pub fn collate_msg_size(content: &RoomMessageEventContent) -> u64 {
content
.body()
.len()
.saturating_add(match &content.msgtype {
| MessageType::Text(t) =>
if t.formatted.is_some() {
t.formatted.as_ref().map_or(0, |f| f.body.len())
} else {
0
},
| MessageType::Notice(n) =>
if n.formatted.is_some() {
n.formatted.as_ref().map_or(0, |f| f.body.len())
} else {
0
},
| _ => 0,
})
.try_into()
.expect("size too large")
}
/// Sends a message to the admin room as the admin user (see send_text()
/// for convenience).
pub async fn send_message(&self, message_content: RoomMessageEventContent) -> Result<()> { pub async fn send_message(&self, message_content: RoomMessageEventContent) -> Result<()> {
let user_id = &self.services.globals.server_user; let user_id = &self.services.globals.server_user;
let room_id = self.get_admin_room().await?; let room_id = self.get_admin_room().await?;
@ -178,6 +243,36 @@ impl Service {
self.send_message(message_content).await self.send_message(message_content).await
} }
/// Casts a text body into a file and creates a file for it.
pub async fn text_to_file(&self, body: &str) -> Result<OwnedMxcUri> {
let mxc = Mxc {
server_name: self.services.globals.server_name(),
media_id: &utils::random_string(MXC_LENGTH),
};
match self
.services
.media
.create(
&mxc,
Some(self.services.globals.server_user.as_ref()),
Some(&utils::content_disposition::make_content_disposition(
None,
Some("text/markdown"),
Some("output.md"),
)),
Some("text/markdown"),
body.as_bytes(),
)
.await
{
| Ok(()) => Ok(mxc.to_string().into()),
| Err(e) => {
error!("Failed to upload text to file: {e}");
Err!(Request(Unknown("Failed to upload text to file")))
},
}
}
/// Posts a command to the command processor queue and returns. Processing /// Posts a command to the command processor queue and returns. Processing
/// will take place on the service worker's task asynchronously. Errors if /// will take place on the service worker's task asynchronously. Errors if
/// the queue is full. /// the queue is full.
@ -325,11 +420,15 @@ impl Service {
assert!(self.user_is_admin(user_id).await, "sender is not admin"); assert!(self.user_is_admin(user_id).await, "sender is not admin");
let state_lock = self.services.state.mutex.lock(room_id).await; let state_lock = self.services.state.mutex.lock(room_id).await;
if let Err(e) = self if let Err(e) = self
.services .services
.timeline .timeline
.build_and_append_pdu(PduBuilder::timeline(&content), user_id, room_id, &state_lock) .build_and_append_pdu(
PduBuilder::timeline(&self.text_or_file(content).await),
user_id,
room_id,
&state_lock,
)
.await .await
{ {
self.handle_response_error(e, room_id, user_id, &state_lock) self.handle_response_error(e, room_id, user_id, &state_lock)