split admin-room branch from build_and_append_pdu (fixes large stack warning)
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
56dd0f5139
commit
89a3c80700
1 changed files with 68 additions and 78 deletions
|
@ -8,13 +8,13 @@ use std::{
|
||||||
};
|
};
|
||||||
|
|
||||||
use conduit::{
|
use conduit::{
|
||||||
debug, err, error, info,
|
debug, err, error, implement, info,
|
||||||
pdu::{EventHash, PduBuilder, PduCount, PduEvent},
|
pdu::{EventHash, PduBuilder, PduCount, PduEvent},
|
||||||
utils,
|
utils,
|
||||||
utils::{stream::TryIgnore, IterStream, MutexMap, MutexMapGuard, ReadyExt},
|
utils::{stream::TryIgnore, IterStream, MutexMap, MutexMapGuard, ReadyExt},
|
||||||
validated, warn, Err, Error, Result, Server,
|
validated, warn, Err, Error, Result, Server,
|
||||||
};
|
};
|
||||||
use futures::{future, future::ready, Future, Stream, StreamExt, TryStreamExt};
|
use futures::{future, future::ready, Future, FutureExt, Stream, StreamExt, TryStreamExt};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::{client::error::ErrorKind, federation},
|
api::{client::error::ErrorKind, federation},
|
||||||
canonical_json::to_canonical_value,
|
canonical_json::to_canonical_value,
|
||||||
|
@ -858,82 +858,7 @@ impl Service {
|
||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
if self.services.admin.is_admin_room(&pdu.room_id).await {
|
if self.services.admin.is_admin_room(&pdu.room_id).await {
|
||||||
match pdu.event_type() {
|
self.check_pdu_for_admin_room(&pdu, sender).boxed().await?;
|
||||||
TimelineEventType::RoomEncryption => {
|
|
||||||
warn!("Encryption is not allowed in the admins room");
|
|
||||||
return Err(Error::BadRequest(
|
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Encryption is not allowed in the admins room",
|
|
||||||
));
|
|
||||||
},
|
|
||||||
TimelineEventType::RoomMember => {
|
|
||||||
let target = pdu
|
|
||||||
.state_key()
|
|
||||||
.filter(|v| v.starts_with('@'))
|
|
||||||
.unwrap_or(sender.as_str());
|
|
||||||
let server_user = &self.services.globals.server_user.to_string();
|
|
||||||
|
|
||||||
let content = serde_json::from_str::<RoomMemberEventContent>(pdu.content.get())
|
|
||||||
.map_err(|_| Error::bad_database("Invalid content in pdu"))?;
|
|
||||||
|
|
||||||
if content.membership == MembershipState::Leave {
|
|
||||||
if target == server_user {
|
|
||||||
warn!("Server user cannot leave from admins room");
|
|
||||||
return Err(Error::BadRequest(
|
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Server user cannot leave from admins room.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let count = self
|
|
||||||
.services
|
|
||||||
.state_cache
|
|
||||||
.room_members(&pdu.room_id)
|
|
||||||
.ready_filter(|user| self.services.globals.user_is_local(user))
|
|
||||||
.ready_filter(|user| *user != target)
|
|
||||||
.boxed()
|
|
||||||
.count()
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if count < 2 {
|
|
||||||
warn!("Last admin cannot leave from admins room");
|
|
||||||
return Err(Error::BadRequest(
|
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Last admin cannot leave from admins room.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if content.membership == MembershipState::Ban && pdu.state_key().is_some() {
|
|
||||||
if target == server_user {
|
|
||||||
warn!("Server user cannot be banned in admins room");
|
|
||||||
return Err(Error::BadRequest(
|
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Server user cannot be banned in admins room.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
|
|
||||||
let count = self
|
|
||||||
.services
|
|
||||||
.state_cache
|
|
||||||
.room_members(&pdu.room_id)
|
|
||||||
.ready_filter(|user| self.services.globals.user_is_local(user))
|
|
||||||
.ready_filter(|user| *user != target)
|
|
||||||
.boxed()
|
|
||||||
.count()
|
|
||||||
.await;
|
|
||||||
|
|
||||||
if count < 2 {
|
|
||||||
warn!("Last admin cannot be banned in admins room");
|
|
||||||
return Err(Error::BadRequest(
|
|
||||||
ErrorKind::forbidden(),
|
|
||||||
"Last admin cannot be banned in admins room.",
|
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// If redaction event is not authorized, do not append it to the timeline
|
// If redaction event is not authorized, do not append it to the timeline
|
||||||
|
@ -1298,6 +1223,71 @@ impl Service {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[implement(Service)]
|
||||||
|
#[tracing::instrument(skip_all, level = "debug")]
|
||||||
|
async fn check_pdu_for_admin_room(&self, pdu: &PduEvent, sender: &UserId) -> Result<()> {
|
||||||
|
match pdu.event_type() {
|
||||||
|
TimelineEventType::RoomEncryption => {
|
||||||
|
return Err!(Request(Forbidden(error!("Encryption not supported in admins room."))));
|
||||||
|
},
|
||||||
|
TimelineEventType::RoomMember => {
|
||||||
|
let target = pdu
|
||||||
|
.state_key()
|
||||||
|
.filter(|v| v.starts_with('@'))
|
||||||
|
.unwrap_or(sender.as_str());
|
||||||
|
|
||||||
|
let server_user = &self.services.globals.server_user.to_string();
|
||||||
|
|
||||||
|
let content: RoomMemberEventContent = pdu.get_content()?;
|
||||||
|
match content.membership {
|
||||||
|
MembershipState::Leave => {
|
||||||
|
if target == server_user {
|
||||||
|
return Err!(Request(Forbidden(error!("Server user cannot leave the admins room."))));
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = self
|
||||||
|
.services
|
||||||
|
.state_cache
|
||||||
|
.room_members(&pdu.room_id)
|
||||||
|
.ready_filter(|user| self.services.globals.user_is_local(user))
|
||||||
|
.ready_filter(|user| *user != target)
|
||||||
|
.boxed()
|
||||||
|
.count()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if count < 2 {
|
||||||
|
return Err!(Request(Forbidden(error!("Last admin cannot leave the admins room."))));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
MembershipState::Ban if pdu.state_key().is_some() => {
|
||||||
|
if target == server_user {
|
||||||
|
return Err!(Request(Forbidden(error!("Server cannot be banned from admins room."))));
|
||||||
|
}
|
||||||
|
|
||||||
|
let count = self
|
||||||
|
.services
|
||||||
|
.state_cache
|
||||||
|
.room_members(&pdu.room_id)
|
||||||
|
.ready_filter(|user| self.services.globals.user_is_local(user))
|
||||||
|
.ready_filter(|user| *user != target)
|
||||||
|
.boxed()
|
||||||
|
.count()
|
||||||
|
.await;
|
||||||
|
|
||||||
|
if count < 2 {
|
||||||
|
return Err!(Request(Forbidden(error!("Last admin cannot be banned from admins room."))));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
|
},
|
||||||
|
_ => {},
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue