mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
feat: Run visibility checks on bundled relations
This commit is contained in:
@@ -31,8 +31,6 @@ pub(crate) async fn get_threads_route(
|
|||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or_else(PduCount::max);
|
.unwrap_or_else(PduCount::max);
|
||||||
|
|
||||||
// TODO: user_can_see_event and set_unsigned should be at the same level /
|
|
||||||
// function, so unsigned is only set for seen events.
|
|
||||||
let threads: Vec<(PduCount, PduEvent)> = services
|
let threads: Vec<(PduCount, PduEvent)> = services
|
||||||
.rooms
|
.rooms
|
||||||
.threads
|
.threads
|
||||||
|
|||||||
@@ -41,9 +41,6 @@ impl super::Service {
|
|||||||
// The relations database code still handles the basic unsigned data
|
// The relations database code still handles the basic unsigned data
|
||||||
// We don't want to recursively fetch relations
|
// We don't want to recursively fetch relations
|
||||||
|
|
||||||
// TODO: Event visibility check
|
|
||||||
// TODO: ignored users?
|
|
||||||
|
|
||||||
if relations.is_empty() {
|
if relations.is_empty() {
|
||||||
return Ok(None);
|
return Ok(None);
|
||||||
}
|
}
|
||||||
@@ -84,8 +81,17 @@ impl super::Service {
|
|||||||
// Handle m.replace relations - find the most recent valid one (lazy load
|
// Handle m.replace relations - find the most recent valid one (lazy load
|
||||||
// original event)
|
// original event)
|
||||||
if !replace_events.is_empty() {
|
if !replace_events.is_empty() {
|
||||||
if let Some(replacement) =
|
if let Some(replacement) = Self::find_most_recent_valid_replacement(
|
||||||
Self::find_most_recent_valid_replacement(pdu, &replace_events).await?
|
pdu,
|
||||||
|
&replace_events,
|
||||||
|
async |pdu: &PduEvent| {
|
||||||
|
self.services
|
||||||
|
.state_accessor
|
||||||
|
.user_can_see_event(user_id, &pdu.room_id_or_hash(), &pdu.event_id())
|
||||||
|
.await
|
||||||
|
},
|
||||||
|
)
|
||||||
|
.await?
|
||||||
{
|
{
|
||||||
bundled.replace = Some(Self::serialize_replacement(replacement)?);
|
bundled.replace = Some(Self::serialize_replacement(replacement)?);
|
||||||
}
|
}
|
||||||
@@ -124,6 +130,7 @@ impl super::Service {
|
|||||||
async fn find_most_recent_valid_replacement<'a>(
|
async fn find_most_recent_valid_replacement<'a>(
|
||||||
original_event: &PduEvent,
|
original_event: &PduEvent,
|
||||||
replacement_events: &[&'a PdusIterItem],
|
replacement_events: &[&'a PdusIterItem],
|
||||||
|
visible: impl AsyncFn(&PduEvent) -> bool,
|
||||||
) -> Result<Option<&'a PduEvent>> {
|
) -> Result<Option<&'a PduEvent>> {
|
||||||
// Filter valid replacements and find the maximum in a single pass
|
// Filter valid replacements and find the maximum in a single pass
|
||||||
let mut result: Option<&PduEvent> = None;
|
let mut result: Option<&PduEvent> = None;
|
||||||
@@ -136,17 +143,23 @@ impl super::Service {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
result = Some(match result {
|
let next = match result {
|
||||||
| None => pdu,
|
| None => Some(pdu),
|
||||||
| Some(current) => {
|
| Some(current) => {
|
||||||
// Compare by origin_server_ts first, then event_id lexicographically
|
// Compare by origin_server_ts first, then event_id lexicographically
|
||||||
match pdu.origin_server_ts().cmp(¤t.origin_server_ts()) {
|
match pdu.origin_server_ts().cmp(¤t.origin_server_ts()) {
|
||||||
| std::cmp::Ordering::Greater => pdu,
|
| std::cmp::Ordering::Greater => Some(pdu),
|
||||||
| std::cmp::Ordering::Equal if pdu.event_id() > current.event_id() => pdu,
|
| std::cmp::Ordering::Equal if pdu.event_id() > current.event_id() =>
|
||||||
| _ => current,
|
Some(pdu),
|
||||||
|
| _ => None,
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
if let Some(pdu) = next
|
||||||
|
&& visible(pdu).await
|
||||||
|
{
|
||||||
|
result = Some(pdu);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(result)
|
Ok(result)
|
||||||
|
|||||||
@@ -20,6 +20,7 @@ pub struct Service {
|
|||||||
struct Services {
|
struct Services {
|
||||||
short: Dep<rooms::short::Service>,
|
short: Dep<rooms::short::Service>,
|
||||||
timeline: Dep<rooms::timeline::Service>,
|
timeline: Dep<rooms::timeline::Service>,
|
||||||
|
state_accessor: Dep<rooms::state_accessor::Service>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl crate::Service for Service {
|
impl crate::Service for Service {
|
||||||
@@ -28,6 +29,8 @@ impl crate::Service for Service {
|
|||||||
services: Services {
|
services: Services {
|
||||||
short: args.depend::<rooms::short::Service>("rooms::short"),
|
short: args.depend::<rooms::short::Service>("rooms::short"),
|
||||||
timeline: args.depend::<rooms::timeline::Service>("rooms::timeline"),
|
timeline: args.depend::<rooms::timeline::Service>("rooms::timeline"),
|
||||||
|
state_accessor: args
|
||||||
|
.depend::<rooms::state_accessor::Service>("rooms::state_accessor"),
|
||||||
},
|
},
|
||||||
db: Data::new(&args),
|
db: Data::new(&args),
|
||||||
}))
|
}))
|
||||||
|
|||||||
Reference in New Issue
Block a user