fix: spaces with restricted rooms
This commit is contained in:
parent
edd4a3733f
commit
0b4e3de9c0
1 changed files with 74 additions and 51 deletions
|
@ -5,11 +5,10 @@ use ruma::{
|
||||||
api::{
|
api::{
|
||||||
client::{
|
client::{
|
||||||
error::ErrorKind,
|
error::ErrorKind,
|
||||||
space::{get_hierarchy, SpaceHierarchyRoomsChunk, SpaceRoomJoinRule},
|
space::{get_hierarchy, SpaceHierarchyRoomsChunk},
|
||||||
},
|
},
|
||||||
federation,
|
federation,
|
||||||
},
|
},
|
||||||
directory::PublicRoomJoinRule,
|
|
||||||
events::{
|
events::{
|
||||||
room::{
|
room::{
|
||||||
avatar::RoomAvatarEventContent,
|
avatar::RoomAvatarEventContent,
|
||||||
|
@ -18,11 +17,11 @@ use ruma::{
|
||||||
guest_access::{GuestAccess, RoomGuestAccessEventContent},
|
guest_access::{GuestAccess, RoomGuestAccessEventContent},
|
||||||
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
|
history_visibility::{HistoryVisibility, RoomHistoryVisibilityEventContent},
|
||||||
join_rules::{JoinRule, RoomJoinRulesEventContent},
|
join_rules::{JoinRule, RoomJoinRulesEventContent},
|
||||||
name::RoomNameEventContent,
|
|
||||||
topic::RoomTopicEventContent,
|
topic::RoomTopicEventContent,
|
||||||
},
|
},
|
||||||
StateEventType,
|
StateEventType,
|
||||||
},
|
},
|
||||||
|
space::SpaceRoomJoinRule,
|
||||||
OwnedRoomId, RoomId, UserId,
|
OwnedRoomId, RoomId, UserId,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -30,10 +29,15 @@ use tracing::{debug, error, warn};
|
||||||
|
|
||||||
use crate::{services, Error, PduEvent, Result};
|
use crate::{services, Error, PduEvent, Result};
|
||||||
|
|
||||||
|
pub enum CachedJoinRule {
|
||||||
|
Simplified(SpaceRoomJoinRule),
|
||||||
|
Full(JoinRule),
|
||||||
|
}
|
||||||
|
|
||||||
pub struct CachedSpaceChunk {
|
pub struct CachedSpaceChunk {
|
||||||
chunk: SpaceHierarchyRoomsChunk,
|
chunk: SpaceHierarchyRoomsChunk,
|
||||||
children: Vec<OwnedRoomId>,
|
children: Vec<OwnedRoomId>,
|
||||||
join_rule: JoinRule,
|
join_rule: CachedJoinRule,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct Service {
|
pub struct Service {
|
||||||
|
@ -79,9 +83,15 @@ impl Service {
|
||||||
.as_ref()
|
.as_ref()
|
||||||
{
|
{
|
||||||
if let Some(cached) = cached {
|
if let Some(cached) = cached {
|
||||||
if let Some(_join_rule) =
|
let allowed = match &cached.join_rule {
|
||||||
self.handle_join_rule(&cached.join_rule, sender_user, ¤t_room)?
|
CachedJoinRule::Simplified(s) => {
|
||||||
{
|
self.handle_simplified_join_rule(s, sender_user, ¤t_room)?
|
||||||
|
}
|
||||||
|
CachedJoinRule::Full(f) => {
|
||||||
|
self.handle_join_rule(f, sender_user, ¤t_room)?
|
||||||
|
}
|
||||||
|
};
|
||||||
|
if allowed {
|
||||||
if left_to_skip > 0 {
|
if left_to_skip > 0 {
|
||||||
left_to_skip -= 1;
|
left_to_skip -= 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -152,7 +162,7 @@ impl Service {
|
||||||
Some(CachedSpaceChunk {
|
Some(CachedSpaceChunk {
|
||||||
chunk,
|
chunk,
|
||||||
children: children_ids.clone(),
|
children: children_ids.clone(),
|
||||||
join_rule,
|
join_rule: CachedJoinRule::Full(join_rule),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -182,7 +192,6 @@ impl Service {
|
||||||
.await
|
.await
|
||||||
{
|
{
|
||||||
warn!("Got response from {server} for /hierarchy\n{response:?}");
|
warn!("Got response from {server} for /hierarchy\n{response:?}");
|
||||||
let join_rule = self.translate_pjoinrule(&response.room.join_rule)?;
|
|
||||||
let chunk = SpaceHierarchyRoomsChunk {
|
let chunk = SpaceHierarchyRoomsChunk {
|
||||||
canonical_alias: response.room.canonical_alias,
|
canonical_alias: response.room.canonical_alias,
|
||||||
name: response.room.name,
|
name: response.room.name,
|
||||||
|
@ -192,7 +201,7 @@ impl Service {
|
||||||
world_readable: response.room.world_readable,
|
world_readable: response.room.world_readable,
|
||||||
guest_can_join: response.room.guest_can_join,
|
guest_can_join: response.room.guest_can_join,
|
||||||
avatar_url: response.room.avatar_url,
|
avatar_url: response.room.avatar_url,
|
||||||
join_rule: self.translate_sjoinrule(&response.room.join_rule)?,
|
join_rule: response.room.join_rule.clone(),
|
||||||
room_type: response.room.room_type,
|
room_type: response.room.room_type,
|
||||||
children_state: response.room.children_state,
|
children_state: response.room.children_state,
|
||||||
};
|
};
|
||||||
|
@ -202,9 +211,11 @@ impl Service {
|
||||||
.map(|c| c.room_id.clone())
|
.map(|c| c.room_id.clone())
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
|
|
||||||
if let Some(_join_rule) =
|
if self.handle_simplified_join_rule(
|
||||||
self.handle_join_rule(&join_rule, sender_user, ¤t_room)?
|
&response.room.join_rule,
|
||||||
{
|
sender_user,
|
||||||
|
¤t_room,
|
||||||
|
)? {
|
||||||
if left_to_skip > 0 {
|
if left_to_skip > 0 {
|
||||||
left_to_skip -= 1;
|
left_to_skip -= 1;
|
||||||
} else {
|
} else {
|
||||||
|
@ -220,7 +231,7 @@ impl Service {
|
||||||
Some(CachedSpaceChunk {
|
Some(CachedSpaceChunk {
|
||||||
chunk,
|
chunk,
|
||||||
children,
|
children,
|
||||||
join_rule,
|
join_rule: CachedJoinRule::Simplified(response.room.join_rule),
|
||||||
}),
|
}),
|
||||||
);
|
);
|
||||||
|
|
||||||
|
@ -349,15 +360,17 @@ impl Service {
|
||||||
})
|
})
|
||||||
.transpose()?
|
.transpose()?
|
||||||
.unwrap_or(JoinRule::Invite);
|
.unwrap_or(JoinRule::Invite);
|
||||||
self.handle_join_rule(&join_rule, sender_user, room_id)?
|
|
||||||
.ok_or_else(|| {
|
if !self.handle_join_rule(&join_rule, sender_user, room_id)? {
|
||||||
debug!("User is not allowed to see room {room_id}");
|
debug!("User is not allowed to see room {room_id}");
|
||||||
// This error will be caught later
|
// This error will be caught later
|
||||||
Error::BadRequest(
|
return Err(Error::BadRequest(
|
||||||
ErrorKind::Forbidden,
|
ErrorKind::Forbidden,
|
||||||
"User is not allowed to see the room",
|
"User is not allowed to see the room",
|
||||||
)
|
));
|
||||||
})?
|
}
|
||||||
|
|
||||||
|
self.translate_joinrule(&join_rule)?
|
||||||
},
|
},
|
||||||
room_type: services()
|
room_type: services()
|
||||||
.rooms
|
.rooms
|
||||||
|
@ -378,20 +391,35 @@ impl Service {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_pjoinrule(&self, join_rule: &PublicRoomJoinRule) -> Result<JoinRule> {
|
fn translate_joinrule(&self, join_rule: &JoinRule) -> Result<SpaceRoomJoinRule> {
|
||||||
match join_rule {
|
match join_rule {
|
||||||
PublicRoomJoinRule::Knock => Ok(JoinRule::Knock),
|
JoinRule::Invite => Ok(SpaceRoomJoinRule::Invite),
|
||||||
PublicRoomJoinRule::Public => Ok(JoinRule::Public),
|
JoinRule::Knock => Ok(SpaceRoomJoinRule::Knock),
|
||||||
|
JoinRule::Private => Ok(SpaceRoomJoinRule::Private),
|
||||||
|
JoinRule::Restricted(_) => Ok(SpaceRoomJoinRule::Restricted),
|
||||||
|
JoinRule::KnockRestricted(_) => Ok(SpaceRoomJoinRule::KnockRestricted),
|
||||||
|
JoinRule::Public => Ok(SpaceRoomJoinRule::Public),
|
||||||
_ => Err(Error::BadServerResponse("Unknown join rule")),
|
_ => Err(Error::BadServerResponse("Unknown join rule")),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn translate_sjoinrule(&self, join_rule: &PublicRoomJoinRule) -> Result<SpaceRoomJoinRule> {
|
fn handle_simplified_join_rule(
|
||||||
match join_rule {
|
&self,
|
||||||
PublicRoomJoinRule::Knock => Ok(SpaceRoomJoinRule::Knock),
|
join_rule: &SpaceRoomJoinRule,
|
||||||
PublicRoomJoinRule::Public => Ok(SpaceRoomJoinRule::Public),
|
sender_user: &UserId,
|
||||||
_ => Err(Error::BadServerResponse("Unknown join rule")),
|
room_id: &RoomId,
|
||||||
}
|
) -> Result<bool> {
|
||||||
|
let allowed = match join_rule {
|
||||||
|
SpaceRoomJoinRule::Public => true,
|
||||||
|
SpaceRoomJoinRule::Knock => true,
|
||||||
|
SpaceRoomJoinRule::Invite => services()
|
||||||
|
.rooms
|
||||||
|
.state_cache
|
||||||
|
.is_joined(sender_user, &room_id)?,
|
||||||
|
_ => false,
|
||||||
|
};
|
||||||
|
|
||||||
|
Ok(allowed)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn handle_join_rule(
|
fn handle_join_rule(
|
||||||
|
@ -399,30 +427,25 @@ impl Service {
|
||||||
join_rule: &JoinRule,
|
join_rule: &JoinRule,
|
||||||
sender_user: &UserId,
|
sender_user: &UserId,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
) -> Result<Option<SpaceRoomJoinRule>> {
|
) -> Result<bool> {
|
||||||
|
if self.handle_simplified_join_rule(
|
||||||
|
&self.translate_joinrule(join_rule)?,
|
||||||
|
sender_user,
|
||||||
|
room_id,
|
||||||
|
)? {
|
||||||
|
return Ok(true);
|
||||||
|
}
|
||||||
|
|
||||||
match join_rule {
|
match join_rule {
|
||||||
JoinRule::Public => Ok::<_, Error>(Some(SpaceRoomJoinRule::Public)),
|
JoinRule::Restricted(_) => {
|
||||||
JoinRule::Knock => Ok(Some(SpaceRoomJoinRule::Knock)),
|
|
||||||
JoinRule::Invite => {
|
|
||||||
if services()
|
|
||||||
.rooms
|
|
||||||
.state_cache
|
|
||||||
.is_joined(sender_user, &room_id)?
|
|
||||||
{
|
|
||||||
Ok(Some(SpaceRoomJoinRule::Invite))
|
|
||||||
} else {
|
|
||||||
Ok(None)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
JoinRule::Restricted(_r) => {
|
|
||||||
// TODO: Check rules
|
// TODO: Check rules
|
||||||
Ok(None)
|
Ok(false)
|
||||||
}
|
}
|
||||||
JoinRule::KnockRestricted(_r) => {
|
JoinRule::KnockRestricted(_) => {
|
||||||
// TODO: Check rules
|
// TODO: Check rules
|
||||||
Ok(None)
|
Ok(false)
|
||||||
}
|
}
|
||||||
_ => Ok(None),
|
_ => Ok(false),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue