Compare commits

..

No commits in common. "3cc92b32ec97667bbabfb44edc305a972a7d3437" and "e28ae8fb4d442cba0eb52728a129372289c85ccd" have entirely different histories.

8 changed files with 145 additions and 130 deletions

25
Cargo.lock generated
View file

@ -3625,7 +3625,8 @@ dependencies = [
[[package]] [[package]]
name = "resolv-conf" name = "resolv-conf"
version = "0.7.1" version = "0.7.1"
source = "git+https://github.com/girlbossceo/resolv-conf?rev=200e958941d522a70c5877e3d846f55b5586c68d#200e958941d522a70c5877e3d846f55b5586c68d" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48375394603e3dd4b2d64371f7148fd8c7baa2680e28741f2cb8d23b59e3d4c4"
dependencies = [ dependencies = [
"hostname", "hostname",
] ]
@ -3653,7 +3654,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma" name = "ruma"
version = "0.10.1" version = "0.10.1"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"assign", "assign",
"js_int", "js_int",
@ -3673,7 +3674,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-appservice-api" name = "ruma-appservice-api"
version = "0.10.0" version = "0.10.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -3685,7 +3686,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-client-api" name = "ruma-client-api"
version = "0.18.0" version = "0.18.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"assign", "assign",
@ -3708,7 +3709,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-common" name = "ruma-common"
version = "0.13.0" version = "0.13.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"base64 0.22.1", "base64 0.22.1",
@ -3740,7 +3741,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-events" name = "ruma-events"
version = "0.28.1" version = "0.28.1"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"as_variant", "as_variant",
"indexmap 2.8.0", "indexmap 2.8.0",
@ -3765,7 +3766,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-federation-api" name = "ruma-federation-api"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"bytes", "bytes",
"headers", "headers",
@ -3787,7 +3788,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-identifiers-validation" name = "ruma-identifiers-validation"
version = "0.9.5" version = "0.9.5"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"thiserror 2.0.12", "thiserror 2.0.12",
@ -3796,7 +3797,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-identity-service-api" name = "ruma-identity-service-api"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -3806,7 +3807,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-macros" name = "ruma-macros"
version = "0.13.0" version = "0.13.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"cfg-if", "cfg-if",
"proc-macro-crate", "proc-macro-crate",
@ -3821,7 +3822,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-push-gateway-api" name = "ruma-push-gateway-api"
version = "0.9.0" version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"js_int", "js_int",
"ruma-common", "ruma-common",
@ -3833,7 +3834,7 @@ dependencies = [
[[package]] [[package]]
name = "ruma-signatures" name = "ruma-signatures"
version = "0.15.0" version = "0.15.0"
source = "git+https://github.com/girlbossceo/ruwuma?rev=920148dca1076454ca0ca5d43b5ce1aa708381d4#920148dca1076454ca0ca5d43b5ce1aa708381d4" source = "git+https://github.com/girlbossceo/ruwuma?rev=edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef#edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
dependencies = [ dependencies = [
"base64 0.22.1", "base64 0.22.1",
"ed25519-dalek", "ed25519-dalek",

View file

@ -20,7 +20,7 @@ license = "Apache-2.0"
# See also `rust-toolchain.toml` # See also `rust-toolchain.toml`
readme = "README.md" readme = "README.md"
repository = "https://github.com/girlbossceo/conduwuit" repository = "https://github.com/girlbossceo/conduwuit"
rust-version = "1.86.0" rust-version = "1.85.0"
version = "0.5.0" version = "0.5.0"
[workspace.metadata.crane] [workspace.metadata.crane]
@ -350,7 +350,7 @@ version = "0.1.2"
[workspace.dependencies.ruma] [workspace.dependencies.ruma]
git = "https://github.com/girlbossceo/ruwuma" git = "https://github.com/girlbossceo/ruwuma"
#branch = "conduwuit-changes" #branch = "conduwuit-changes"
rev = "920148dca1076454ca0ca5d43b5ce1aa708381d4" rev = "edbdc79e560d01d9e4a76f7421e70ea4fd4c54ef"
features = [ features = [
"compat", "compat",
"rand", "rand",
@ -580,13 +580,6 @@ rev = "9c8e51510c35077df888ee72a36b4b05637147da"
git = "https://github.com/girlbossceo/hyper-util" git = "https://github.com/girlbossceo/hyper-util"
rev = "e4ae7628fe4fcdacef9788c4c8415317a4489941" rev = "e4ae7628fe4fcdacef9788c4c8415317a4489941"
# allows no-aaaa option in resolv.conf
# bumps rust edition and toolchain to 1.86.0 and 2024
# use sat_add on line number errors
[patch.crates-io.resolv-conf]
git = "https://github.com/girlbossceo/resolv-conf"
rev = "200e958941d522a70c5877e3d846f55b5586c68d"
# #
# Our crates # Our crates
# #

View file

@ -26,7 +26,7 @@
file = ./rust-toolchain.toml; file = ./rust-toolchain.toml;
# See also `rust-toolchain.toml` # See also `rust-toolchain.toml`
sha256 = "sha256-X/4ZBHO3iW0fOenQ3foEvscgAPJYl2abspaBThDOukI="; sha256 = "sha256-AJ6LX/Q/Er9kS15bn9iflkUwcgYqRQxiOIL2ToVAXaU=";
}; };
mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: { mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {

View file

@ -9,7 +9,7 @@
# If you're having trouble making the relevant changes, bug a maintainer. # If you're having trouble making the relevant changes, bug a maintainer.
[toolchain] [toolchain]
channel = "1.86.0" channel = "1.85.0"
profile = "minimal" profile = "minimal"
components = [ components = [
# For rust-analyzer # For rust-analyzer

View file

@ -4,13 +4,9 @@ use conduwuit::{
Err, Result, debug_warn, Err, Result, debug_warn,
utils::{IterStream, future::TryExtExt}, utils::{IterStream, future::TryExtExt},
}; };
use futures::{ use futures::{FutureExt, StreamExt, future::join3, stream::FuturesUnordered};
FutureExt, StreamExt,
future::{OptionFuture, join3},
stream::FuturesUnordered,
};
use ruma::{ use ruma::{
OwnedServerName, RoomId, UserId, OwnedRoomId, OwnedServerName, RoomId, UserId,
api::{ api::{
client::room::get_summary, client::room::get_summary,
federation::space::{SpaceHierarchyParentSummary, get_hierarchy}, federation::space::{SpaceHierarchyParentSummary, get_hierarchy},
@ -95,9 +91,13 @@ async fn room_summary_response(
join_rule: room.join_rule, join_rule: room.join_rule,
room_type: room.room_type, room_type: room.room_type,
room_version: room.room_version, room_version: room.room_version,
membership: if sender_user.is_none() {
None
} else {
Some(MembershipState::Leave)
},
encryption: room.encryption, encryption: room.encryption,
allowed_room_ids: room.allowed_room_ids, allowed_room_ids: room.allowed_room_ids,
membership: sender_user.is_some().then_some(MembershipState::Leave),
}) })
} }
@ -106,22 +106,20 @@ async fn local_room_summary_response(
room_id: &RoomId, room_id: &RoomId,
sender_user: Option<&UserId>, sender_user: Option<&UserId>,
) -> Result<get_summary::msc3266::Response> { ) -> Result<get_summary::msc3266::Response> {
let join_rule = services.rooms.state_accessor.get_join_rules(room_id); let join_rule = services.rooms.state_accessor.get_space_join_rule(room_id);
let world_readable = services.rooms.state_accessor.is_world_readable(room_id); let world_readable = services.rooms.state_accessor.is_world_readable(room_id);
let guest_can_join = services.rooms.state_accessor.guest_can_join(room_id); let guest_can_join = services.rooms.state_accessor.guest_can_join(room_id);
let (join_rule, world_readable, guest_can_join) = let ((join_rule, allowed_room_ids), world_readable, guest_can_join) =
join3(join_rule, world_readable, guest_can_join).await; join3(join_rule, world_readable, guest_can_join).await;
user_can_see_summary( user_can_see_summary(
services, services,
room_id, room_id,
&join_rule.clone().into(), &join_rule,
guest_can_join, guest_can_join,
world_readable, world_readable,
join_rule.allowed_rooms(), &allowed_room_ids,
sender_user, sender_user,
) )
.await?; .await?;
@ -131,43 +129,26 @@ async fn local_room_summary_response(
.state_accessor .state_accessor
.get_canonical_alias(room_id) .get_canonical_alias(room_id)
.ok(); .ok();
let name = services.rooms.state_accessor.get_name(room_id).ok(); let name = services.rooms.state_accessor.get_name(room_id).ok();
let topic = services.rooms.state_accessor.get_room_topic(room_id).ok(); let topic = services.rooms.state_accessor.get_room_topic(room_id).ok();
let room_type = services.rooms.state_accessor.get_room_type(room_id).ok(); let room_type = services.rooms.state_accessor.get_room_type(room_id).ok();
let avatar_url = services let avatar_url = services
.rooms .rooms
.state_accessor .state_accessor
.get_avatar(room_id) .get_avatar(room_id)
.map(|res| res.into_option().unwrap_or_default().url); .map(|res| res.into_option().unwrap_or_default().url);
let room_version = services.rooms.state.get_room_version(room_id).ok(); let room_version = services.rooms.state.get_room_version(room_id).ok();
let encryption = services let encryption = services
.rooms .rooms
.state_accessor .state_accessor
.get_room_encryption(room_id) .get_room_encryption(room_id)
.ok(); .ok();
let num_joined_members = services let num_joined_members = services
.rooms .rooms
.state_cache .state_cache
.room_joined_count(room_id) .room_joined_count(room_id)
.unwrap_or(0); .unwrap_or(0);
let membership: OptionFuture<_> = sender_user
.map(|sender_user| {
services
.rooms
.state_accessor
.get_member(room_id, sender_user)
.map_ok_or(MembershipState::Leave, |content| content.membership)
})
.into();
let ( let (
canonical_alias, canonical_alias,
name, name,
@ -177,7 +158,6 @@ async fn local_room_summary_response(
room_type, room_type,
room_version, room_version,
encryption, encryption,
membership,
) = futures::join!( ) = futures::join!(
canonical_alias, canonical_alias,
name, name,
@ -187,7 +167,6 @@ async fn local_room_summary_response(
room_type, room_type,
room_version, room_version,
encryption, encryption,
membership,
); );
Ok(get_summary::msc3266::Response { Ok(get_summary::msc3266::Response {
@ -199,12 +178,21 @@ async fn local_room_summary_response(
num_joined_members: num_joined_members.try_into().unwrap_or_default(), num_joined_members: num_joined_members.try_into().unwrap_or_default(),
topic, topic,
world_readable, world_readable,
join_rule,
room_type, room_type,
room_version, room_version,
membership: if let Some(sender_user) = sender_user {
services
.rooms
.state_accessor
.get_member(room_id, sender_user)
.await
.map_or(Some(MembershipState::Leave), |content| Some(content.membership))
} else {
None
},
encryption, encryption,
membership, allowed_room_ids,
allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(),
join_rule: join_rule.into(),
}) })
} }
@ -253,7 +241,7 @@ async fn remote_room_summary_hierarchy_response(
&room.join_rule, &room.join_rule,
room.guest_can_join, room.guest_can_join,
room.world_readable, room.world_readable,
room.allowed_room_ids.iter().map(AsRef::as_ref), &room.allowed_room_ids,
sender_user, sender_user,
) )
.await .await
@ -266,18 +254,15 @@ async fn remote_room_summary_hierarchy_response(
))) )))
} }
async fn user_can_see_summary<'a, I>( async fn user_can_see_summary(
services: &Services, services: &Services,
room_id: &RoomId, room_id: &RoomId,
join_rule: &SpaceRoomJoinRule, join_rule: &SpaceRoomJoinRule,
guest_can_join: bool, guest_can_join: bool,
world_readable: bool, world_readable: bool,
allowed_room_ids: I, allowed_room_ids: &[OwnedRoomId],
sender_user: Option<&UserId>, sender_user: Option<&UserId>,
) -> Result ) -> Result {
where
I: Iterator<Item = &'a RoomId> + Send,
{
match sender_user { match sender_user {
| Some(sender_user) => { | Some(sender_user) => {
let user_can_see_state_events = services let user_can_see_state_events = services
@ -286,6 +271,7 @@ where
.user_can_see_state_events(sender_user, room_id); .user_can_see_state_events(sender_user, room_id);
let is_guest = services.users.is_deactivated(sender_user).unwrap_or(false); let is_guest = services.users.is_deactivated(sender_user).unwrap_or(false);
let user_in_allowed_restricted_room = allowed_room_ids let user_in_allowed_restricted_room = allowed_room_ids
.iter()
.stream() .stream()
.any(|room| services.rooms.state_cache.is_joined(sender_user, room)); .any(|room| services.rooms.state_cache.is_joined(sender_user, room));

View file

@ -211,7 +211,7 @@ async fn allowed_to_send_state_event(
// irreversible mistakes // irreversible mistakes
match json.deserialize_as::<RoomServerAclEventContent>() { match json.deserialize_as::<RoomServerAclEventContent>() {
| Ok(acl_content) => { | Ok(acl_content) => {
if acl_content.allow_is_empty() { if acl_content.allow.is_empty() {
return Err!(Request(BadJson(debug_warn!( return Err!(Request(BadJson(debug_warn!(
?room_id, ?room_id,
"Sending an ACL event with an empty allow key will permanently \ "Sending an ACL event with an empty allow key will permanently \
@ -220,7 +220,9 @@ async fn allowed_to_send_state_event(
)))); ))));
} }
if acl_content.deny_contains("*") && acl_content.allow_contains("*") { if acl_content.deny.contains(&String::from("*"))
&& acl_content.allow.contains(&String::from("*"))
{
return Err!(Request(BadJson(debug_warn!( return Err!(Request(BadJson(debug_warn!(
?room_id, ?room_id,
"Sending an ACL event with a deny and allow key value of \"*\" will \ "Sending an ACL event with a deny and allow key value of \"*\" will \
@ -229,9 +231,11 @@ async fn allowed_to_send_state_event(
)))); ))));
} }
if acl_content.deny_contains("*") if acl_content.deny.contains(&String::from("*"))
&& !acl_content.is_allowed(services.globals.server_name()) && !acl_content.is_allowed(services.globals.server_name())
&& !acl_content.allow_contains(services.globals.server_name().as_str()) && !acl_content
.allow
.contains(&services.globals.server_name().to_string())
{ {
return Err!(Request(BadJson(debug_warn!( return Err!(Request(BadJson(debug_warn!(
?room_id, ?room_id,
@ -241,9 +245,11 @@ async fn allowed_to_send_state_event(
)))); ))));
} }
if !acl_content.allow_contains("*") if !acl_content.allow.contains(&String::from("*"))
&& !acl_content.is_allowed(services.globals.server_name()) && !acl_content.is_allowed(services.globals.server_name())
&& !acl_content.allow_contains(services.globals.server_name().as_str()) && !acl_content
.allow
.contains(&services.globals.server_name().to_string())
{ {
return Err!(Request(BadJson(debug_warn!( return Err!(Request(BadJson(debug_warn!(
?room_id, ?room_id,

View file

@ -121,22 +121,21 @@ pub async fn get_summary_and_children_local(
| None => (), // cache miss | None => (), // cache miss
| Some(None) => return Ok(None), | Some(None) => return Ok(None),
| Some(Some(cached)) => { | Some(Some(cached)) => {
let allowed_rooms = cached.summary.allowed_room_ids.iter().map(AsRef::as_ref); return Ok(Some(
if self
let is_accessible_child = self.is_accessible_child( .is_accessible_child(
current_room, current_room,
&cached.summary.join_rule, &cached.summary.join_rule,
identifier, identifier,
allowed_rooms, &cached.summary.allowed_room_ids,
); )
.await
let accessibility = if is_accessible_child.await { {
SummaryAccessibility::Accessible(cached.summary.clone()) SummaryAccessibility::Accessible(cached.summary.clone())
} else { } else {
SummaryAccessibility::Inaccessible SummaryAccessibility::Inaccessible
}; },
));
return Ok(Some(accessibility));
}, },
} }
@ -146,11 +145,12 @@ pub async fn get_summary_and_children_local(
.collect() .collect()
.await; .await;
let Ok(summary) = self let summary = self
.get_room_summary(current_room, children_pdus, identifier) .get_room_summary(current_room, children_pdus, identifier)
.boxed() .boxed()
.await .await;
else {
let Ok(summary) = summary else {
return Ok(None); return Ok(None);
}; };
@ -217,19 +217,20 @@ async fn get_summary_and_children_federation(
.await; .await;
let identifier = Identifier::UserId(user_id); let identifier = Identifier::UserId(user_id);
let allowed_room_ids = summary.allowed_room_ids.iter().map(AsRef::as_ref);
let is_accessible_child = self let is_accessible_child = self
.is_accessible_child(current_room, &summary.join_rule, &identifier, allowed_room_ids) .is_accessible_child(
current_room,
&summary.join_rule,
&identifier,
&summary.allowed_room_ids,
)
.await; .await;
let accessibility = if is_accessible_child { if is_accessible_child {
SummaryAccessibility::Accessible(summary) return Ok(Some(SummaryAccessibility::Accessible(summary)));
} else { }
SummaryAccessibility::Inaccessible
};
Ok(Some(accessibility)) Ok(Some(SummaryAccessibility::Inaccessible))
} }
/// Simply returns the stripped m.space.child events of a room /// Simply returns the stripped m.space.child events of a room
@ -304,15 +305,14 @@ async fn get_room_summary(
children_state: Vec<Raw<HierarchySpaceChildEvent>>, children_state: Vec<Raw<HierarchySpaceChildEvent>>,
identifier: &Identifier<'_>, identifier: &Identifier<'_>,
) -> Result<SpaceHierarchyParentSummary, Error> { ) -> Result<SpaceHierarchyParentSummary, Error> {
let join_rule = self.services.state_accessor.get_join_rules(room_id).await; let (join_rule, allowed_room_ids) = self
.services
.state_accessor
.get_space_join_rule(room_id)
.await;
let is_accessible_child = self let is_accessible_child = self
.is_accessible_child( .is_accessible_child(room_id, &join_rule, identifier, &allowed_room_ids)
room_id,
&join_rule.clone().into(),
identifier,
join_rule.allowed_rooms(),
)
.await; .await;
if !is_accessible_child { if !is_accessible_child {
@ -379,7 +379,7 @@ async fn get_room_summary(
encryption, encryption,
); );
let summary = SpaceHierarchyParentSummary { Ok(SpaceHierarchyParentSummary {
canonical_alias, canonical_alias,
name, name,
topic, topic,
@ -388,29 +388,24 @@ async fn get_room_summary(
avatar_url, avatar_url,
room_type, room_type,
children_state, children_state,
encryption, allowed_room_ids,
room_version, join_rule,
room_id: room_id.to_owned(), room_id: room_id.to_owned(),
num_joined_members: num_joined_members.try_into().unwrap_or_default(), num_joined_members: num_joined_members.try_into().unwrap_or_default(),
allowed_room_ids: join_rule.allowed_rooms().map(Into::into).collect(), encryption,
join_rule: join_rule.clone().into(), room_version,
}; })
Ok(summary)
} }
/// With the given identifier, checks if a room is accessable /// With the given identifier, checks if a room is accessable
#[implement(Service)] #[implement(Service)]
async fn is_accessible_child<'a, I>( async fn is_accessible_child(
&self, &self,
current_room: &RoomId, current_room: &RoomId,
join_rule: &SpaceRoomJoinRule, join_rule: &SpaceRoomJoinRule,
identifier: &Identifier<'_>, identifier: &Identifier<'_>,
allowed_rooms: I, allowed_room_ids: &[OwnedRoomId],
) -> bool ) -> bool {
where
I: Iterator<Item = &'a RoomId> + Send,
{
if let Identifier::ServerName(server_name) = identifier { if let Identifier::ServerName(server_name) = identifier {
// Checks if ACLs allow for the server to participate // Checks if ACLs allow for the server to participate
if self if self
@ -435,18 +430,21 @@ where
} }
} }
match *join_rule { match join_rule {
| SpaceRoomJoinRule::Public | SpaceRoomJoinRule::Public
| SpaceRoomJoinRule::Knock | SpaceRoomJoinRule::Knock
| SpaceRoomJoinRule::KnockRestricted => true, | SpaceRoomJoinRule::KnockRestricted => true,
| SpaceRoomJoinRule::Restricted => | SpaceRoomJoinRule::Restricted =>
allowed_rooms allowed_room_ids
.iter()
.stream() .stream()
.any(async |room| match identifier { .any(|room| async {
| Identifier::UserId(user) => match identifier {
self.services.state_cache.is_joined(user, room).await, | Identifier::UserId(user) =>
| Identifier::ServerName(server) => self.services.state_cache.is_joined(user, room).await,
self.services.state_cache.server_in_room(server, room).await, | Identifier::ServerName(server) =>
self.services.state_cache.server_in_room(server, room).await,
}
}) })
.await, .await,

View file

@ -9,7 +9,7 @@ use async_trait::async_trait;
use conduwuit::{Result, err}; use conduwuit::{Result, err};
use database::Map; use database::Map;
use ruma::{ use ruma::{
EventEncryptionAlgorithm, JsOption, OwnedRoomAliasId, RoomId, UserId, EventEncryptionAlgorithm, JsOption, OwnedRoomAliasId, OwnedRoomId, RoomId, UserId,
events::{ events::{
StateEventType, StateEventType,
room::{ room::{
@ -19,13 +19,14 @@ use ruma::{
encryption::RoomEncryptionEventContent, encryption::RoomEncryptionEventContent,
guest_access::{GuestAccess, RoomGuestAccessEventContent}, guest_access::{GuestAccess, RoomGuestAccessEventContent},
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent}, history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
join_rules::{JoinRule, RoomJoinRulesEventContent}, join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent, RoomMembership},
member::RoomMemberEventContent, member::RoomMemberEventContent,
name::RoomNameEventContent, name::RoomNameEventContent,
topic::RoomTopicEventContent, topic::RoomTopicEventContent,
}, },
}, },
room::RoomType, room::RoomType,
space::SpaceRoomJoinRule,
}; };
use crate::{Dep, rooms}; use crate::{Dep, rooms};
@ -128,12 +129,42 @@ impl Service {
.map(|c: RoomTopicEventContent| c.topic) .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 /// Returns the join rules for a given room (`JoinRule` type). Will default
/// to Invite if doesnt exist or invalid /// to Invite if doesnt exist or invalid
pub async fn get_join_rules(&self, room_id: &RoomId) -> JoinRule { pub async fn get_join_rules(&self, room_id: &RoomId) -> JoinRule {
self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "") self.room_state_get_content(room_id, &StateEventType::RoomJoinRules, "")
.await .await
.map_or(JoinRule::Invite, |c: RoomJoinRulesEventContent| c.join_rule) .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
} }
pub async fn get_room_type(&self, room_id: &RoomId) -> Result<RoomType> { pub async fn get_room_type(&self, room_id: &RoomId) -> Result<RoomType> {