general misc bug fixes and slight improvements

Signed-off-by: strawberry <strawberry@puppygock.gay>
This commit is contained in:
strawberry 2024-11-10 21:20:38 -05:00
parent fd2a002480
commit 4f0bdb5194
10 changed files with 127 additions and 100 deletions

View file

@ -8,7 +8,7 @@ use std::{
};
use conduit::{
checked, debug, debug_info, err,
checked, debug_info, err,
utils::{math::usize_from_f64, IterStream},
Error, Result,
};
@ -234,27 +234,25 @@ impl Service {
});
}
Ok(
if let Some(children_pdus) = self.get_stripped_space_child_events(current_room).await? {
let summary = self
.get_room_summary(current_room, children_pdus, &identifier)
.await;
if let Ok(summary) = summary {
self.roomid_spacehierarchy_cache.lock().await.insert(
current_room.clone(),
Some(CachedSpaceHierarchySummary {
summary: summary.clone(),
}),
);
if let Some(children_pdus) = self.get_stripped_space_child_events(current_room).await? {
let summary = self
.get_room_summary(current_room, children_pdus, &identifier)
.await;
if let Ok(summary) = summary {
self.roomid_spacehierarchy_cache.lock().await.insert(
current_room.clone(),
Some(CachedSpaceHierarchySummary {
summary: summary.clone(),
}),
);
Some(SummaryAccessibility::Accessible(Box::new(summary)))
} else {
None
}
Ok(Some(SummaryAccessibility::Accessible(Box::new(summary))))
} else {
None
},
)
Ok(None)
}
} else {
Ok(None)
}
}
/// Gets the summary of a space using solely federation
@ -393,7 +391,7 @@ impl Service {
.is_accessible_child(current_room, &join_rule.clone().into(), identifier, &allowed_room_ids)
.await
{
debug!("User is not allowed to see room {room_id}");
debug_info!("User is not allowed to see room {room_id}");
// This error will be caught later
return Err(Error::BadRequest(ErrorKind::forbidden(), "User is not allowed to see the room"));
}
@ -615,16 +613,13 @@ impl Service {
&self, current_room: &OwnedRoomId, join_rule: &SpaceRoomJoinRule, identifier: &Identifier<'_>,
allowed_room_ids: &Vec<OwnedRoomId>,
) -> bool {
// Note: unwrap_or_default for bool means false
match identifier {
Identifier::ServerName(server_name) => {
let room_id: &RoomId = current_room;
// Checks if ACLs allow for the server to participate
if self
.services
.event_handler
.acl_check(server_name, room_id)
.acl_check(server_name, current_room)
.await
.is_err()
{
@ -645,8 +640,9 @@ impl Service {
return true;
}
},
} // Takes care of join rules
match join_rule {
}
match &join_rule {
SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Knock | SpaceRoomJoinRule::KnockRestricted => true,
SpaceRoomJoinRule::Restricted => {
for room in allowed_room_ids {
match identifier {
@ -664,7 +660,6 @@ impl Service {
}
false
},
SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Knock | SpaceRoomJoinRule::KnockRestricted => true,
// Invite only, Private, or Custom join rule
_ => false,
}

View file

@ -295,20 +295,22 @@ impl Service {
}
#[tracing::instrument(skip_all, level = "debug")]
pub async fn summary_stripped(&self, invite: &PduEvent) -> Vec<Raw<AnyStrippedStateEvent>> {
pub async fn summary_stripped(&self, event: &PduEvent) -> Vec<Raw<AnyStrippedStateEvent>> {
let cells = [
(&StateEventType::RoomCreate, ""),
(&StateEventType::RoomJoinRules, ""),
(&StateEventType::RoomCanonicalAlias, ""),
(&StateEventType::RoomName, ""),
(&StateEventType::RoomAvatar, ""),
(&StateEventType::RoomMember, invite.sender.as_str()), // Add recommended events
(&StateEventType::RoomMember, event.sender.as_str()), // Add recommended events
(&StateEventType::RoomEncryption, ""),
(&StateEventType::RoomTopic, ""),
];
let fetches = cells.iter().map(|(event_type, state_key)| {
self.services
.state_accessor
.room_state_get(&invite.room_id, event_type, state_key)
.room_state_get(&event.room_id, event_type, state_key)
});
join_all(fetches)
@ -316,7 +318,7 @@ impl Service {
.into_iter()
.filter_map(Result::ok)
.map(|e| e.to_stripped_state_event())
.chain(once(invite.to_stripped_state_event()))
.chain(once(event.to_stripped_state_event()))
.collect()
}

View file

@ -10,7 +10,7 @@ use conduit::{
err, error,
pdu::PduBuilder,
utils::{math::usize_from_f64, ReadyExt},
Error, PduEvent, Result,
Err, Error, Event, PduEvent, Result,
};
use futures::StreamExt;
use lru_cache::LruCache;
@ -29,7 +29,7 @@ use ruma::{
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
topic::RoomTopicEventContent,
},
StateEventType,
StateEventType, TimelineEventType,
},
room::RoomType,
space::SpaceRoomJoinRule,
@ -408,34 +408,41 @@ impl Service {
pub async fn user_can_redact(
&self, redacts: &EventId, sender: &UserId, room_id: &RoomId, federation: bool,
) -> Result<bool> {
if let Ok(event) = self
let redacting_event = self.services.timeline.get_pdu(redacts).await;
if redacting_event
.as_ref()
.is_ok_and(|event| event.event_type() == &TimelineEventType::RoomCreate)
{
return Err!(Request(Forbidden("Redacting m.room.create is not safe, forbidding.")));
}
if let Ok(pl_event_content) = self
.room_state_get_content::<RoomPowerLevelsEventContent>(room_id, &StateEventType::RoomPowerLevels, "")
.await
{
let event: RoomPowerLevels = event.into();
Ok(event.user_can_redact_event_of_other(sender)
|| event.user_can_redact_own_event(sender)
&& if let Ok(pdu) = self.services.timeline.get_pdu(redacts).await {
let pl_event: RoomPowerLevels = pl_event_content.into();
Ok(pl_event.user_can_redact_event_of_other(sender)
|| pl_event.user_can_redact_own_event(sender)
&& if let Ok(redacting_event) = redacting_event {
if federation {
pdu.sender.server_name() == sender.server_name()
redacting_event.sender.server_name() == sender.server_name()
} else {
pdu.sender == sender
redacting_event.sender == sender
}
} else {
false
})
} else {
// Falling back on m.room.create to judge power level
if let Ok(pdu) = self
if let Ok(room_create) = self
.room_state_get(room_id, &StateEventType::RoomCreate, "")
.await
{
Ok(pdu.sender == sender
|| if let Ok(pdu) = self.services.timeline.get_pdu(redacts).await {
pdu.sender == sender
} else {
false
})
Ok(room_create.sender == sender
|| redacting_event
.as_ref()
.is_ok_and(|redacting_event| redacting_event.sender == sender))
} else {
Err(Error::bad_database(
"No m.room.power_levels or m.room.create events in database for room",
@ -454,7 +461,7 @@ impl Service {
/// Returns an empty vec if not a restricted room
pub fn allowed_room_ids(&self, join_rule: JoinRule) -> Vec<OwnedRoomId> {
let mut room_ids = vec![];
let mut room_ids = Vec::with_capacity(1);
if let JoinRule::Restricted(r) | JoinRule::KnockRestricted(r) = join_rule {
for rule in r.allow {
if let AllowRule::RoomMembership(RoomMembership {

View file

@ -39,7 +39,7 @@ impl super::Service {
.forbidden_remote_server_names
.contains(dest)
{
return Err!(Request(Forbidden(debug_warn!("Federation with this {dest} is not allowed."))));
return Err!(Request(Forbidden(debug_warn!("Federation with {dest} is not allowed."))));
}
let actual = self.services.resolver.get_actual_dest(dest).await?;

View file

@ -235,13 +235,15 @@ impl Service {
fn select_events_current(&self, dest: Destination, statuses: &mut CurTransactionStatus) -> Result<(bool, bool)> {
let (mut allow, mut retry) = (true, false);
statuses
.entry(dest)
.entry(dest.clone()) // TODO: can we avoid cloning?
.and_modify(|e| match e {
TransactionStatus::Failed(tries, time) => {
// Fail if a request has failed recently (exponential backoff)
let min = self.server.config.sender_timeout;
let max = self.server.config.sender_retry_backoff_limit;
if continue_exponential_backoff_secs(min, max, time.elapsed(), *tries) {
if continue_exponential_backoff_secs(min, max, time.elapsed(), *tries)
&& !matches!(dest, Destination::Appservice(_))
{
allow = false;
} else {
retry = true;