1
0
Fork 0
forked from mirror/grapevine

Compare commits

...

3 commits

Author SHA1 Message Date
Benjamin Lee
697c5ac534
allow searching in left rooms
The spec states that

> The search API allows clients to perform full text search across
> events in all rooms that the user has been in, including those that they
> have left. Only events that the user is allowed to see will be
> searched, e.g. it won’t include events in rooms that happened after
> you left.

<https://spec.matrix.org/v1.10/client-server-api/#server-side-search>
2024-06-03 19:54:50 -07:00
Benjamin Lee
857131e959
allow seeing state from visibility=shared left rooms 2024-06-03 19:54:03 -07:00
Benjamin Lee
52af998f7b
allow seeing events from visibility=shared left rooms 2024-06-03 19:52:40 -07:00
5 changed files with 60 additions and 7 deletions

View file

@ -35,7 +35,7 @@ pub(crate) async fn search_events_route(
services()
.rooms
.state_cache
.rooms_joined(sender_user)
.rooms_once_joined(sender_user)
.filter_map(Result::ok)
.collect()
});
@ -51,7 +51,7 @@ pub(crate) async fn search_events_route(
let mut searches = Vec::new();
for room_id in room_ids {
if !services().rooms.state_cache.is_joined(sender_user, &room_id)? {
if !services().rooms.state_cache.once_joined(sender_user, &room_id)? {
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"You don't have permission to view this room.",

View file

@ -615,6 +615,39 @@ impl service::rooms::state_cache::Data for KeyValueDatabase {
))
}
/// Returns an iterator over all rooms a user has been in.
#[tracing::instrument(skip(self))]
fn rooms_once_joined<'a>(
&'a self,
user_id: &UserId,
) -> Box<dyn Iterator<Item = Result<OwnedRoomId>> + 'a> {
let mut prefix = user_id.as_bytes().to_vec();
prefix.push(0xFF);
Box::new(self.roomuseroncejoinedids.scan_prefix(prefix).map(
|(key, _)| {
RoomId::parse(
utils::string_from_bytes(
key.rsplit(|&b| b == 0xFF)
.next()
.expect("rsplit always returns an element"),
)
.map_err(|_| {
Error::bad_database(
"Room ID in roomuseroncejoinedids is invalid \
unicode.",
)
})?,
)
.map_err(|_| {
Error::bad_database(
"Room ID in roomuseroncejoinedids is invalid.",
)
})
},
))
}
#[tracing::instrument(skip(self))]
fn once_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool> {
let mut userroom_id = user_id.as_bytes().to_vec();

View file

@ -222,8 +222,8 @@ impl Service {
return Ok(*visibility);
}
let currently_member =
services().rooms.state_cache.is_joined(user_id, room_id)?;
let once_member =
services().rooms.state_cache.once_joined(user_id, room_id)?;
let history_visibility = self
.state_get(
@ -245,7 +245,7 @@ impl Service {
let visibility = match history_visibility {
HistoryVisibility::WorldReadable => true,
HistoryVisibility::Shared => currently_member,
HistoryVisibility::Shared => once_member,
HistoryVisibility::Invited => {
// Allow if any member on requesting server was AT LEAST
// invited, else deny
@ -280,6 +280,8 @@ impl Service {
) -> Result<bool> {
let currently_member =
services().rooms.state_cache.is_joined(user_id, room_id)?;
let once_member =
services().rooms.state_cache.once_joined(user_id, room_id)?;
let history_visibility = self
.room_state_get(
@ -299,8 +301,11 @@ impl Service {
})
})?;
Ok(currently_member
|| history_visibility == HistoryVisibility::WorldReadable)
Ok(match history_visibility {
HistoryVisibility::WorldReadable => true,
HistoryVisibility::Shared => once_member,
_ => currently_member,
})
}
/// Returns the state hash for this pdu.

View file

@ -387,6 +387,15 @@ impl Service {
self.db.rooms_left(user_id)
}
/// Returns an iterator over all rooms a user has been in.
#[tracing::instrument(skip(self))]
pub(crate) fn rooms_once_joined<'a>(
&'a self,
user_id: &UserId,
) -> impl Iterator<Item = Result<OwnedRoomId>> + 'a {
self.db.rooms_once_joined(user_id)
}
#[tracing::instrument(skip(self))]
pub(crate) fn once_joined(
&self,

View file

@ -125,6 +125,12 @@ pub(crate) trait Data: Send + Sync {
+ 'a,
>;
/// Returns an iterator over all rooms a user has been in.
fn rooms_once_joined<'a>(
&'a self,
user_id: &UserId,
) -> Box<dyn Iterator<Item = Result<OwnedRoomId>> + 'a>;
fn once_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool>;
fn is_joined(&self, user_id: &UserId, room_id: &RoomId) -> Result<bool>;