fixup! feat(federation): support /make_join and /send_join for restricted rooms

check event is join membership, state_key user is the same as the sender, and state_key is from the origin

Co-Authored-By: Matthias Ahouansou <matthias@ahouansou.cz>
This commit is contained in:
strawberry 2024-07-01 14:46:10 +01:00 committed by Matthias Ahouansou
parent 7fa0025c43
commit ddcfcb9302
No known key found for this signature in database

View file

@ -1708,6 +1708,56 @@ async fn create_join_event(
}
};
let state_key: OwnedUserId = serde_json::from_value(
value
.get("state_key")
.ok_or_else(|| Error::BadRequest(ErrorKind::BadJson, "State key is missing"))?
.clone()
.into(),
)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "State key is not a valid user ID"))?;
let sender: OwnedUserId = serde_json::from_value(
value
.get("sender")
.ok_or_else(|| Error::BadRequest(ErrorKind::BadJson, "Sender is missing"))?
.clone()
.into(),
)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Sender is not a valid user ID"))?;
if state_key != sender {
return Err(Error::BadRequest(
ErrorKind::BadJson,
"Sender and state key don't match",
));
}
// Security-wise, we only really need to check the event is not from us, cause otherwise it must be signed by that server,
// but we might as well check this since this event shouldn't really be sent on behalf of another server
if state_key.server_name() != sender_servername {
return Err(Error::BadRequest(
ErrorKind::forbidden(),
"User's server and origin don't match",
));
}
let event_type: StateEventType = serde_json::from_value(
value
.get("type")
.ok_or_else(|| Error::BadRequest(ErrorKind::BadJson, "Missing event type"))?
.clone()
.into(),
)
.map_err(|_| Error::BadRequest(ErrorKind::BadJson, "Invalid event type"))?;
if event_type != StateEventType::RoomMember {
return Err(Error::BadRequest(
ErrorKind::BadJson,
"Event type is not membership",
));
}
ruma::signatures::hash_and_sign_event(
services().globals.server_name().as_str(),
services().globals.keypair(),