Merge branch 'authorized-user-search' into 'next'

fix(membership): perform stricter checks when choosing an authorized user

See merge request famedly/conduit!620
merge-requests/582/merge
Timo Kösters 4 months ago
commit a140bf8a6f

@ -15,7 +15,6 @@ use ruma::{
room::{ room::{
join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent}, join_rules::{AllowRule, JoinRule, RoomJoinRulesEventContent},
member::{MembershipState, RoomMemberEventContent}, member::{MembershipState, RoomMemberEventContent},
power_levels::RoomPowerLevelsEventContent,
}, },
StateEventType, TimelineEventType, StateEventType, TimelineEventType,
}, },
@ -858,11 +857,6 @@ async fn join_room_by_id_helper(
&StateEventType::RoomJoinRules, &StateEventType::RoomJoinRules,
"", "",
)?; )?;
let power_levels_event = services().rooms.state_accessor.room_state_get(
room_id,
&StateEventType::RoomPowerLevels,
"",
)?;
let join_rules_event_content: Option<RoomJoinRulesEventContent> = join_rules_event let join_rules_event_content: Option<RoomJoinRulesEventContent> = join_rules_event
.as_ref() .as_ref()
@ -873,15 +867,6 @@ async fn join_room_by_id_helper(
}) })
}) })
.transpose()?; .transpose()?;
let power_levels_event_content: Option<RoomPowerLevelsEventContent> = power_levels_event
.as_ref()
.map(|power_levels_event| {
serde_json::from_str(power_levels_event.content.get()).map_err(|e| {
warn!("Invalid power levels event: {}", e);
Error::bad_database("Invalid power levels event in db.")
})
})
.transpose()?;
let restriction_rooms = match join_rules_event_content { let restriction_rooms = match join_rules_event_content {
Some(RoomJoinRulesEventContent { Some(RoomJoinRulesEventContent {
@ -900,47 +885,37 @@ async fn join_room_by_id_helper(
_ => Vec::new(), _ => Vec::new(),
}; };
let authorized_user = restriction_rooms let authorized_user = if restriction_rooms.iter().any(|restriction_room_id| {
.iter() services()
.find_map(|restriction_room_id| {
if !services()
.rooms .rooms
.state_cache .state_cache
.is_joined(sender_user, restriction_room_id) .is_joined(sender_user, restriction_room_id)
.ok()? .unwrap_or(false)
}) {
let mut auth_user = None;
for user in services()
.rooms
.state_cache
.room_members(room_id)
.filter_map(Result::ok)
.collect::<Vec<_>>()
{ {
return None; if user.server_name() == services().globals.server_name()
}
let authorized_user = power_levels_event_content
.as_ref()
.and_then(|c| {
c.users
.iter()
.filter(|(uid, i)| {
uid.server_name() == services().globals.server_name()
&& **i > ruma::int!(0)
&& services() && services()
.rooms .rooms
.state_cache .state_accessor
.is_joined(uid, restriction_room_id) .user_can_invite(room_id, &user, sender_user, &state_lock)
.await
.unwrap_or(false) .unwrap_or(false)
}) {
.max_by_key(|(_, i)| *i) auth_user = Some(user);
.map(|(u, _)| u.to_owned()) break;
}) }
.or_else(|| { }
// TODO: Check here if user is actually allowed to invite. Currently the auth auth_user
// check will just fail in this case. } else {
services() None
.rooms };
.state_cache
.room_members(restriction_room_id)
.filter_map(|r| r.ok())
.find(|uid| uid.server_name() == services().globals.server_name())
});
Some(authorized_user)
})
.flatten();
let event = RoomMemberEventContent { let event = RoomMemberEventContent {
membership: MembershipState::Join, membership: MembershipState::Join,
@ -978,9 +953,7 @@ async fn join_room_by_id_helper(
if !restriction_rooms.is_empty() if !restriction_rooms.is_empty()
&& servers && servers
.iter() .iter()
.filter(|s| *s != services().globals.server_name()) .any(|s| *s != services().globals.server_name())
.count()
> 0
{ {
info!( info!(
"We couldn't do the join locally, maybe federation can help to satisfy the restricted join requirements" "We couldn't do the join locally, maybe federation can help to satisfy the restricted join requirements"

Loading…
Cancel
Save