simplify space join rules related
Signed-off-by: Jason Volk <jason@zemos.net>
This commit is contained in:
parent
d6cc447add
commit
500faa8d7f
5 changed files with 113 additions and 128 deletions
|
@ -121,21 +121,22 @@ pub async fn get_summary_and_children_local(
|
|||
| None => (), // cache miss
|
||||
| Some(None) => return Ok(None),
|
||||
| Some(Some(cached)) => {
|
||||
return Ok(Some(
|
||||
if self
|
||||
.is_accessible_child(
|
||||
current_room,
|
||||
&cached.summary.join_rule,
|
||||
identifier,
|
||||
&cached.summary.allowed_room_ids,
|
||||
)
|
||||
.await
|
||||
{
|
||||
SummaryAccessibility::Accessible(cached.summary.clone())
|
||||
} else {
|
||||
SummaryAccessibility::Inaccessible
|
||||
},
|
||||
));
|
||||
let allowed_rooms = cached.summary.allowed_room_ids.iter().map(AsRef::as_ref);
|
||||
|
||||
let is_accessible_child = self.is_accessible_child(
|
||||
current_room,
|
||||
&cached.summary.join_rule,
|
||||
identifier,
|
||||
allowed_rooms,
|
||||
);
|
||||
|
||||
let accessibility = if is_accessible_child.await {
|
||||
SummaryAccessibility::Accessible(cached.summary.clone())
|
||||
} else {
|
||||
SummaryAccessibility::Inaccessible
|
||||
};
|
||||
|
||||
return Ok(Some(accessibility));
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -145,12 +146,11 @@ pub async fn get_summary_and_children_local(
|
|||
.collect()
|
||||
.await;
|
||||
|
||||
let summary = self
|
||||
let Ok(summary) = self
|
||||
.get_room_summary(current_room, children_pdus, identifier)
|
||||
.boxed()
|
||||
.await;
|
||||
|
||||
let Ok(summary) = summary else {
|
||||
.await
|
||||
else {
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
|
@ -217,20 +217,19 @@ async fn get_summary_and_children_federation(
|
|||
.await;
|
||||
|
||||
let identifier = Identifier::UserId(user_id);
|
||||
let allowed_room_ids = summary.allowed_room_ids.iter().map(AsRef::as_ref);
|
||||
|
||||
let is_accessible_child = self
|
||||
.is_accessible_child(
|
||||
current_room,
|
||||
&summary.join_rule,
|
||||
&identifier,
|
||||
&summary.allowed_room_ids,
|
||||
)
|
||||
.is_accessible_child(current_room, &summary.join_rule, &identifier, allowed_room_ids)
|
||||
.await;
|
||||
|
||||
if is_accessible_child {
|
||||
return Ok(Some(SummaryAccessibility::Accessible(summary)));
|
||||
}
|
||||
let accessibility = if is_accessible_child {
|
||||
SummaryAccessibility::Accessible(summary)
|
||||
} else {
|
||||
SummaryAccessibility::Inaccessible
|
||||
};
|
||||
|
||||
Ok(Some(SummaryAccessibility::Inaccessible))
|
||||
Ok(Some(accessibility))
|
||||
}
|
||||
|
||||
/// Simply returns the stripped m.space.child events of a room
|
||||
|
@ -305,14 +304,15 @@ async fn get_room_summary(
|
|||
children_state: Vec<Raw<HierarchySpaceChildEvent>>,
|
||||
identifier: &Identifier<'_>,
|
||||
) -> Result<SpaceHierarchyParentSummary, Error> {
|
||||
let (join_rule, allowed_room_ids) = self
|
||||
.services
|
||||
.state_accessor
|
||||
.get_space_join_rule(room_id)
|
||||
.await;
|
||||
let join_rule = self.services.state_accessor.get_join_rules(room_id).await;
|
||||
|
||||
let is_accessible_child = self
|
||||
.is_accessible_child(room_id, &join_rule, identifier, &allowed_room_ids)
|
||||
.is_accessible_child(
|
||||
room_id,
|
||||
&join_rule.clone().into(),
|
||||
identifier,
|
||||
join_rule.allowed_rooms(),
|
||||
)
|
||||
.await;
|
||||
|
||||
if !is_accessible_child {
|
||||
|
@ -379,7 +379,7 @@ async fn get_room_summary(
|
|||
encryption,
|
||||
);
|
||||
|
||||
Ok(SpaceHierarchyParentSummary {
|
||||
let summary = SpaceHierarchyParentSummary {
|
||||
canonical_alias,
|
||||
name,
|
||||
topic,
|
||||
|
@ -388,24 +388,29 @@ async fn get_room_summary(
|
|||
avatar_url,
|
||||
room_type,
|
||||
children_state,
|
||||
allowed_room_ids,
|
||||
join_rule,
|
||||
room_id: room_id.to_owned(),
|
||||
num_joined_members: num_joined_members.try_into().unwrap_or_default(),
|
||||
encryption,
|
||||
room_version,
|
||||
})
|
||||
room_id: room_id.to_owned(),
|
||||
num_joined_members: num_joined_members.try_into().unwrap_or_default(),
|
||||
allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(),
|
||||
join_rule: join_rule.clone().into(),
|
||||
};
|
||||
|
||||
Ok(summary)
|
||||
}
|
||||
|
||||
/// With the given identifier, checks if a room is accessable
|
||||
#[implement(Service)]
|
||||
async fn is_accessible_child(
|
||||
async fn is_accessible_child<'a, I>(
|
||||
&self,
|
||||
current_room: &RoomId,
|
||||
join_rule: &SpaceRoomJoinRule,
|
||||
identifier: &Identifier<'_>,
|
||||
allowed_room_ids: &[OwnedRoomId],
|
||||
) -> bool {
|
||||
allowed_rooms: I,
|
||||
) -> bool
|
||||
where
|
||||
I: Iterator<Item = &'a RoomId> + Send,
|
||||
{
|
||||
if let Identifier::ServerName(server_name) = identifier {
|
||||
// Checks if ACLs allow for the server to participate
|
||||
if self
|
||||
|
@ -430,21 +435,18 @@ async fn is_accessible_child(
|
|||
}
|
||||
}
|
||||
|
||||
match join_rule {
|
||||
match *join_rule {
|
||||
| SpaceRoomJoinRule::Public
|
||||
| SpaceRoomJoinRule::Knock
|
||||
| SpaceRoomJoinRule::KnockRestricted => true,
|
||||
| SpaceRoomJoinRule::Restricted =>
|
||||
allowed_room_ids
|
||||
.iter()
|
||||
allowed_rooms
|
||||
.stream()
|
||||
.any(|room| async {
|
||||
match identifier {
|
||||
| Identifier::UserId(user) =>
|
||||
self.services.state_cache.is_joined(user, room).await,
|
||||
| Identifier::ServerName(server) =>
|
||||
self.services.state_cache.server_in_room(server, room).await,
|
||||
}
|
||||
.any(async |room| match identifier {
|
||||
| Identifier::UserId(user) =>
|
||||
self.services.state_cache.is_joined(user, room).await,
|
||||
| Identifier::ServerName(server) =>
|
||||
self.services.state_cache.server_in_room(server, room).await,
|
||||
})
|
||||
.await,
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ use async_trait::async_trait;
|
|||
use conduwuit::{Result, err};
|
||||
use database::Map;
|
||||
use ruma::{
|
||||
EventEncryptionAlgorithm, JsOption, OwnedRoomAliasId, OwnedRoomId, RoomId, UserId,
|
||||
EventEncryptionAlgorithm, JsOption, OwnedRoomAliasId, RoomId, UserId,
|
||||
events::{
|
||||
StateEventType,
|
||||
room::{
|
||||
|
@ -19,14 +19,13 @@ use ruma::{
|
|||
encryption::RoomEncryptionEventContent,
|
||||
guest_access::{GuestAccess, RoomGuestAccessEventContent},
|
||||
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
|
||||
join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent, RoomMembership},
|
||||
join_rules::{JoinRule, RoomJoinRulesEventContent},
|
||||
member::RoomMemberEventContent,
|
||||
name::RoomNameEventContent,
|
||||
topic::RoomTopicEventContent,
|
||||
},
|
||||
},
|
||||
room::RoomType,
|
||||
space::SpaceRoomJoinRule,
|
||||
};
|
||||
|
||||
use crate::{Dep, rooms};
|
||||
|
@ -129,42 +128,12 @@ impl Service {
|
|||
.map(|c: RoomTopicEventContent| c.topic)
|
||||
}
|
||||
|
||||
/// Returns the space join rule (`SpaceRoomJoinRule`) for a given room and
|
||||
/// any allowed room IDs if available. Will default to Invite and empty vec
|
||||
/// if doesnt exist or invalid,
|
||||
pub async fn get_space_join_rule(
|
||||
&self,
|
||||
room_id: &RoomId,
|
||||
) -> (SpaceRoomJoinRule, Vec<OwnedRoomId>) {
|
||||
self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "")
|
||||
.await
|
||||
.map_or_else(
|
||||
|_| (SpaceRoomJoinRule::Invite, vec![]),
|
||||
|c: RoomJoinRulesEventContent| {
|
||||
(c.join_rule.clone().into(), self.allowed_room_ids(c.join_rule))
|
||||
},
|
||||
)
|
||||
}
|
||||
|
||||
/// Returns the join rules for a given room (`JoinRule` type). Will default
|
||||
/// to Invite if doesnt exist or invalid
|
||||
pub async fn get_join_rules(&self, room_id: &RoomId) -> JoinRule {
|
||||
self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "")
|
||||
.await
|
||||
.map_or_else(|_| JoinRule::Invite, |c: RoomJoinRulesEventContent| (c.join_rule))
|
||||
}
|
||||
|
||||
/// 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::with_capacity(1); // restricted rooms generally only have 1 allowed room ID
|
||||
if let JoinRule::Restricted(r) | JoinRule::KnockRestricted(r) = join_rule {
|
||||
for rule in r.allow {
|
||||
if let AllowRule::RoomMembership(RoomMembership { room_id: membership }) = rule {
|
||||
room_ids.push(membership.clone());
|
||||
}
|
||||
}
|
||||
}
|
||||
room_ids
|
||||
.map_or(JoinRule::Invite, |c: RoomJoinRulesEventContent| c.join_rule)
|
||||
}
|
||||
|
||||
pub async fn get_room_type(&self, room_id: &RoomId) -> Result<RoomType> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue