summaryrefslogtreecommitdiff
path: root/src/api/client_server/membership.rs
diff options
context:
space:
mode:
Diffstat (limited to 'src/api/client_server/membership.rs')
-rw-r--r--src/api/client_server/membership.rs99
1 files changed, 67 insertions, 32 deletions
diff --git a/src/api/client_server/membership.rs b/src/api/client_server/membership.rs
index 61c67cb..4a1f374 100644
--- a/src/api/client_server/membership.rs
+++ b/src/api/client_server/membership.rs
@@ -17,7 +17,7 @@ use ruma::{
member::{MembershipState, RoomMemberEventContent},
power_levels::RoomPowerLevelsEventContent,
},
- RoomEventType, StateEventType,
+ StateEventType, TimelineEventType,
},
serde::Base64,
state_res, CanonicalJsonObject, CanonicalJsonValue, EventId, OwnedEventId, OwnedRoomId,
@@ -29,7 +29,7 @@ use std::{
sync::{Arc, RwLock},
time::{Duration, Instant},
};
-use tracing::{debug, error, warn};
+use tracing::{debug, error, info, warn};
use crate::{
service::pdu::{gen_event_id_canonical_json, PduBuilder},
@@ -106,12 +106,13 @@ pub async fn join_room_by_id_or_alias_route(
);
servers.push(room_id.server_name().to_owned());
+
(servers, room_id)
}
Err(room_alias) => {
let response = get_alias_helper(room_alias).await?;
- (response.servers.into_iter().collect(), response.room_id)
+ (response.servers, response.room_id)
}
};
@@ -209,7 +210,7 @@ pub async fn kick_user_route(
services().rooms.timeline.build_and_append_pdu(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content: to_raw_value(&event).expect("event is valid, we just created it"),
unsigned: None,
state_key: Some(body.user_id.to_string()),
@@ -273,7 +274,7 @@ pub async fn ban_user_route(body: Ruma<ban_user::v3::Request>) -> Result<ban_use
services().rooms.timeline.build_and_append_pdu(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content: to_raw_value(&event).expect("event is valid, we just created it"),
unsigned: None,
state_key: Some(body.user_id.to_string()),
@@ -331,7 +332,7 @@ pub async fn unban_user_route(
services().rooms.timeline.build_and_append_pdu(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content: to_raw_value(&event).expect("event is valid, we just created it"),
unsigned: None,
state_key: Some(body.user_id.to_string()),
@@ -396,11 +397,10 @@ pub async fn get_member_events_route(
) -> Result<get_member_events::v3::Response> {
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
- // TODO: check history visibility?
if !services()
.rooms
- .state_cache
- .is_joined(sender_user, &body.room_id)?
+ .state_accessor
+ .user_can_see_state_events(&sender_user, &body.room_id)?
{
return Err(Error::BadRequest(
ErrorKind::Forbidden,
@@ -434,12 +434,12 @@ pub async fn joined_members_route(
if !services()
.rooms
- .state_cache
- .is_joined(sender_user, &body.room_id)?
+ .state_accessor
+ .user_can_see_state_events(&sender_user, &body.room_id)?
{
return Err(Error::BadRequest(
ErrorKind::Forbidden,
- "You aren't a member of the room.",
+ "You don't have permission to view this room.",
));
}
@@ -491,9 +491,13 @@ async fn join_room_by_id_helper(
.state_cache
.server_in_room(services().globals.server_name(), room_id)?
{
+ info!("Joining {room_id} over federation.");
+
let (make_join_response, remote_server) =
make_join_request(sender_user, room_id, servers).await?;
+ info!("make_join finished");
+
let room_version_id = match make_join_response.room_version {
Some(room_version)
if services()
@@ -578,6 +582,7 @@ async fn join_room_by_id_helper(
// It has enough fields to be called a proper event now
let mut join_event = join_event_stub;
+ info!("Asking {remote_server} for send_join");
let send_join_response = services()
.sending
.send_federation_request(
@@ -586,11 +591,15 @@ async fn join_room_by_id_helper(
room_id: room_id.to_owned(),
event_id: event_id.to_owned(),
pdu: PduEvent::convert_to_outgoing_federation_event(join_event.clone()),
+ omit_members: false,
},
)
.await?;
+ info!("send_join finished");
+
if let Some(signed_raw) = &send_join_response.room_state.event {
+ info!("There is a signed event. This room is probably using restricted joins. Adding signature to our event");
let (signed_event_id, signed_value) =
match gen_event_id_canonical_json(signed_raw, &room_version_id) {
Ok(t) => t,
@@ -630,24 +639,29 @@ async fn join_room_by_id_helper(
.expect("we created a valid pdu")
.insert(remote_server.to_string(), signature.clone());
} else {
- warn!("Server {} sent invalid sendjoin event", remote_server);
+ warn!(
+ "Server {remote_server} sent invalid signature in sendjoin signatures for event {signed_value:?}",
+ );
}
}
services().rooms.short.get_or_create_shortroomid(room_id)?;
+ info!("Parsing join event");
let parsed_join_pdu = PduEvent::from_id_val(event_id, join_event.clone())
.map_err(|_| Error::BadServerResponse("Invalid join event PDU."))?;
let mut state = HashMap::new();
let pub_key_map = RwLock::new(BTreeMap::new());
+ info!("Fetching join signing keys");
services()
.rooms
.event_handler
.fetch_join_signing_keys(&send_join_response, &room_version_id, &pub_key_map)
.await?;
+ info!("Going through send_join response room_state");
for result in send_join_response
.room_state
.state
@@ -660,7 +674,7 @@ async fn join_room_by_id_helper(
};
let pdu = PduEvent::from_id_val(&event_id, value.clone()).map_err(|e| {
- warn!("{:?}: {}", value, e);
+ warn!("Invalid PDU in send_join response: {} {:?}", e, value);
Error::BadServerResponse("Invalid PDU in send_join response.")
})?;
@@ -677,6 +691,7 @@ async fn join_room_by_id_helper(
}
}
+ info!("Going through send_join response auth_chain");
for result in send_join_response
.room_state
.auth_chain
@@ -694,6 +709,7 @@ async fn join_room_by_id_helper(
.add_pdu_outlier(&event_id, &value)?;
}
+ info!("Running send_join auth check");
if !state_res::event_auth::auth_check(
&state_res::RoomVersion::new(&room_version_id).expect("room version is supported"),
&parsed_join_pdu,
@@ -714,25 +730,30 @@ async fn join_room_by_id_helper(
.ok()?
},
)
- .map_err(|_e| Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed"))?
- {
+ .map_err(|e| {
+ warn!("Auth check failed: {e}");
+ Error::BadRequest(ErrorKind::InvalidParam, "Auth check failed")
+ })? {
return Err(Error::BadRequest(
ErrorKind::InvalidParam,
"Auth check failed",
));
}
+ info!("Saving state from send_join");
let (statehash_before_join, new, removed) = services().rooms.state_compressor.save_state(
room_id,
- state
- .into_iter()
- .map(|(k, id)| {
- services()
- .rooms
- .state_compressor
- .compress_state_event(k, &id)
- })
- .collect::<Result<_>>()?,
+ Arc::new(
+ state
+ .into_iter()
+ .map(|(k, id)| {
+ services()
+ .rooms
+ .state_compressor
+ .compress_state_event(k, &id)
+ })
+ .collect::<Result<_>>()?,
+ ),
)?;
services()
@@ -741,12 +762,14 @@ async fn join_room_by_id_helper(
.force_state(room_id, statehash_before_join, new, removed, &state_lock)
.await?;
+ info!("Updating joined counts for new room");
services().rooms.state_cache.update_joined_count(room_id)?;
// We append to state before appending the pdu, so we don't have a moment in time with the
// pdu without it's state. This is okay because append_pdu can't fail.
let statehash_after_join = services().rooms.state.append_to_state(&parsed_join_pdu)?;
+ info!("Appending new room join event");
services().rooms.timeline.append_pdu(
&parsed_join_pdu,
join_event,
@@ -754,6 +777,7 @@ async fn join_room_by_id_helper(
&state_lock,
)?;
+ info!("Setting final room state for new room");
// We set the room state after inserting the pdu, so that we never have a moment in time
// where events in the current room state do not exist
services()
@@ -761,6 +785,8 @@ async fn join_room_by_id_helper(
.state
.set_room_state(room_id, statehash_after_join, &state_lock)?;
} else {
+ info!("We can join locally");
+
let join_rules_event = services().rooms.state_accessor.room_state_get(
room_id,
&StateEventType::RoomJoinRules,
@@ -864,7 +890,7 @@ async fn join_room_by_id_helper(
// Try normal join first
let error = match services().rooms.timeline.build_and_append_pdu(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content: to_raw_value(&event).expect("event is valid, we just created it"),
unsigned: None,
state_key: Some(sender_user.to_string()),
@@ -878,9 +904,16 @@ async fn join_room_by_id_helper(
Err(e) => e,
};
- if !restriction_rooms.is_empty() {
- // We couldn't do the join locally, maybe federation can help to satisfy the restricted
- // join requirements
+ if !restriction_rooms.is_empty()
+ && servers
+ .iter()
+ .filter(|s| *s != services().globals.server_name())
+ .count()
+ > 0
+ {
+ info!(
+ "We couldn't do the join locally, maybe federation can help to satisfy the restricted join requirements"
+ );
let (make_join_response, remote_server) =
make_join_request(sender_user, room_id, servers).await?;
@@ -973,6 +1006,7 @@ async fn join_room_by_id_helper(
room_id: room_id.to_owned(),
event_id: event_id.to_owned(),
pdu: PduEvent::convert_to_outgoing_federation_event(join_event.clone()),
+ omit_members: false,
},
)
.await?;
@@ -1038,6 +1072,7 @@ async fn make_join_request(
if remote_server == services().globals.server_name() {
continue;
}
+ info!("Asking {remote_server} for make_join");
let make_join_response = services()
.sending
.send_federation_request(
@@ -1162,7 +1197,7 @@ pub(crate) async fn invite_helper<'a>(
let (pdu, pdu_json) = services().rooms.timeline.create_hash_and_sign_event(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content,
unsigned: None,
state_key: Some(user_id.to_string()),
@@ -1271,7 +1306,7 @@ pub(crate) async fn invite_helper<'a>(
services().rooms.timeline.build_and_append_pdu(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content: to_raw_value(&RoomMemberEventContent {
membership: MembershipState::Invite,
displayname: services().users.displayname(user_id)?,
@@ -1396,7 +1431,7 @@ pub async fn leave_room(user_id: &UserId, room_id: &RoomId, reason: Option<Strin
services().rooms.timeline.build_and_append_pdu(
PduBuilder {
- event_type: RoomEventType::RoomMember,
+ event_type: TimelineEventType::RoomMember,
content: to_raw_value(&event).expect("event is valid, we just created it"),
unsigned: None,
state_key: Some(user_id.to_string()),