Skip to content
Snippets Groups Projects
membership.rs 36.4 KiB
Newer Older
  • Learn to ignore specific revisions
  •                     .expect("server name is a valid CanonicalJsonValue"),
                );
    
                ruma::signatures::hash_and_sign_event(
                    db.globals.server_name().as_str(),
                    db.globals.keypair(),
                    &mut pdu_json,
                    &room_version_id,
                )
                .expect("event is valid, we just created it");
    
                let invite_room_state = db.rooms.calculate_invite_state(&pdu)?;
    
    
    Timo Kösters's avatar
    Timo Kösters committed
                drop(state_lock);
    
    
                (room_version_id, pdu_json, invite_room_state)
            };
    
            // Generate event id
            let expected_event_id = EventId::try_from(&*format!(
                "${}",
                ruma::signatures::reference_hash(&pdu_json, &room_version_id)
                    .expect("ruma can calculate reference hashes")
            ))
            .expect("ruma's reference hashes are valid event ids");
    
    
            let response = db
                .sending
                .send_federation_request(
                    &db.globals,
                    user_id.server_name(),
                    create_invite::v2::Request {
    
    Jonas Platte's avatar
    Jonas Platte committed
                        room_id,
                        event_id: &expected_event_id,
                        room_version: &room_version_id,
                        event: &PduEvent::convert_to_outgoing_federation_event(pdu_json.clone()),
                        invite_room_state: &invite_room_state,
    
                    },
                )
                .await?;
    
            let pub_key_map = RwLock::new(BTreeMap::new());
    
            // We do not add the event_id field to the pdu here because of signature and hashes checks
            let (event_id, value) = match crate::pdu::gen_event_id_canonical_json(&response.event) {
                Ok(t) => t,
                Err(_) => {
                    // Event could not be converted to canonical json
                    return Err(Error::BadRequest(
                        ErrorKind::InvalidParam,
                        "Could not convert event to canonical json.",
                    ));
                }
            };
    
    
            if expected_event_id != event_id {
                warn!("Server {} changed invite event, that's not allowed in the spec: ours: {:?}, theirs: {:?}", user_id.server_name(), pdu_json, value);
            }
    
    
            let origin = serde_json::from_value::<Box<ServerName>>(
                serde_json::to_value(value.get("origin").ok_or(Error::BadRequest(
                    ErrorKind::InvalidParam,
                    "Event needs an origin field.",
                ))?)
                .expect("CanonicalJson is valid json value"),
            )
            .map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Origin field is invalid."))?;
    
    
            let pdu_id = server_server::handle_incoming_pdu(
                &origin,
                &event_id,
    
                &pub_key_map,
            )
            .await
            .map_err(|_| {
                Error::BadRequest(
                    ErrorKind::InvalidParam,
                    "Error while handling incoming PDU.",
                )
            })?
            .ok_or(Error::BadRequest(
                ErrorKind::InvalidParam,
                "Could not accept incoming PDU as timeline event.",
            ))?;
    
                .rooms
                .room_servers(room_id)
                .filter_map(|r| r.ok())
    
                .filter(|server| &**server != db.globals.server_name());
    
            db.sending.send_pdu(servers, &pdu_id)?;
    
    Timo Kösters's avatar
    Timo Kösters committed
        let mutex_state = Arc::clone(
    
    Timo Kösters's avatar
    Timo Kösters committed
                .roomid_mutex_state
    
                .write()
                .unwrap()
                .entry(room_id.clone())
                .or_default(),
        );
    
    Timo Kösters's avatar
    Timo Kösters committed
        let state_lock = mutex_state.lock().await;
    
        db.rooms.build_and_append_pdu(
            PduBuilder {
                event_type: EventType::RoomMember,
    
    Jonas Platte's avatar
    Jonas Platte committed
                content: to_raw_value(&RoomMemberEventContent {
                    membership: MembershipState::Invite,
    
                    displayname: db.users.displayname(user_id)?,
                    avatar_url: db.users.avatar_url(user_id)?,
    
                    is_direct: Some(is_direct),
    
                    third_party_invite: None,
    
                    blurhash: db.users.blurhash(user_id)?,
    
                })
                .expect("event is valid, we just created it"),
                unsigned: None,
                state_key: Some(user_id.to_string()),
                redacts: None,
            },
    
    Timo Kösters's avatar
    Timo Kösters committed
            &state_lock,
    
    Timo Kösters's avatar
    Timo Kösters committed
        drop(state_lock);