1// Copyright (c) 2023 xmpp-rs contributors.
2//
3// This Source Code Form is subject to the terms of the Mozilla Public
4// License, v. 2.0. If a copy of the MPL was not distributed with this
5// file, You can obtain one at http://mozilla.org/MPL/2.0/.
6
7use crate::{
8 Agent, Event, RoomNick, disco,
9 jid::Jid,
10 minidom::Element,
11 muc::room::JoinRoomSettings,
12 parsers::{disco::DiscoInfoResult, ns, private::Query as PrivateXMLQuery, roster::Roster},
13 pubsub, upload,
14};
15
16pub async fn handle_iq_result(
17 agent: &mut Agent,
18 events: &mut Vec<Event>,
19 from: Jid,
20 _to: Option<Jid>,
21 id: String,
22 payload: Element,
23) {
24 // TODO: move private iqs like this one somewhere else, for
25 // security reasons.
26 if payload.is("query", ns::ROSTER) && from == agent.client.bound_jid().unwrap().to_bare() {
27 let roster = Roster::try_from(payload).unwrap();
28 for item in roster.items.into_iter() {
29 events.push(Event::ContactAdded(item));
30 }
31 } else if payload.is("pubsub", ns::PUBSUB) {
32 let new_events = pubsub::handle_iq_result(&from, payload, agent).await;
33 events.extend(new_events);
34 } else if payload.is("slot", ns::HTTP_UPLOAD) {
35 let new_events = upload::receive::handle_upload_result(&from, id, payload, agent).await;
36 events.extend(new_events);
37 } else if payload.is("query", ns::PRIVATE) {
38 match PrivateXMLQuery::try_from(payload) {
39 Ok(query) => {
40 for conf in query.storage.conferences {
41 let (jid, room) = conf.into_bookmarks2();
42 agent
43 .join_room(JoinRoomSettings {
44 nick: room.nick.map(RoomNick::new),
45 password: room.password,
46 ..JoinRoomSettings::new(jid)
47 })
48 .await;
49 }
50 }
51 Err(e) => {
52 panic!("Wrong XEP-0048 v1.0 Bookmark format: {}", e);
53 }
54 }
55 } else if payload.is("query", ns::DISCO_INFO) {
56 match DiscoInfoResult::try_from(payload.clone()) {
57 Ok(disco) => {
58 disco::handle_disco_info_result(agent, disco, from).await;
59 }
60 Err(e) => match e {
61 _ => panic!("Wrong disco#info format: {}", e),
62 },
63 }
64 }
65}