forked from lavina/lavina
163 lines
5.0 KiB
Rust
163 lines
5.0 KiB
Rust
|
//! Handling of all client2server iq stanzas
|
||
|
|
||
|
use quick_xml::events::Event;
|
||
|
|
||
|
use lavina_core::room::RoomRegistry;
|
||
|
use proto_xmpp::bind::{BindResponse, Jid, Name, Resource, Server};
|
||
|
use proto_xmpp::client::{Iq, IqType};
|
||
|
use proto_xmpp::disco::{Feature, Identity, InfoQuery, Item, ItemQuery};
|
||
|
use proto_xmpp::roster::RosterQuery;
|
||
|
use proto_xmpp::session::Session;
|
||
|
|
||
|
use crate::proto::IqClientBody;
|
||
|
use crate::XmppConnection;
|
||
|
|
||
|
use proto_xmpp::xml::ToXml;
|
||
|
|
||
|
impl<'a> XmppConnection<'a> {
|
||
|
pub async fn handle_iq(&self, output: &mut Vec<Event<'static>>, iq: Iq<IqClientBody>) {
|
||
|
match iq.body {
|
||
|
IqClientBody::Bind(b) => {
|
||
|
let req = Iq {
|
||
|
from: None,
|
||
|
id: iq.id,
|
||
|
to: None,
|
||
|
r#type: IqType::Result,
|
||
|
body: BindResponse(Jid {
|
||
|
name: Some(Name("darova".into())),
|
||
|
server: Server("localhost".into()),
|
||
|
resource: Some(Resource("kek".into())),
|
||
|
}),
|
||
|
};
|
||
|
req.serialize(output);
|
||
|
}
|
||
|
IqClientBody::Session(_) => {
|
||
|
let req = Iq {
|
||
|
from: None,
|
||
|
id: iq.id,
|
||
|
to: None,
|
||
|
r#type: IqType::Result,
|
||
|
body: Session,
|
||
|
};
|
||
|
req.serialize(output);
|
||
|
}
|
||
|
IqClientBody::Roster(_) => {
|
||
|
let req = Iq {
|
||
|
from: None,
|
||
|
id: iq.id,
|
||
|
to: None,
|
||
|
r#type: IqType::Result,
|
||
|
body: RosterQuery,
|
||
|
};
|
||
|
req.serialize(output);
|
||
|
}
|
||
|
IqClientBody::DiscoInfo(info) => {
|
||
|
let response = disco_info(iq.to.as_deref(), &info);
|
||
|
let req = Iq {
|
||
|
from: iq.to,
|
||
|
id: iq.id,
|
||
|
to: None,
|
||
|
r#type: IqType::Result,
|
||
|
body: response,
|
||
|
};
|
||
|
req.serialize(output);
|
||
|
}
|
||
|
IqClientBody::DiscoItem(item) => {
|
||
|
let response = disco_items(iq.to.as_deref(), &item, self.rooms).await;
|
||
|
let req = Iq {
|
||
|
from: iq.to,
|
||
|
id: iq.id,
|
||
|
to: None,
|
||
|
r#type: IqType::Result,
|
||
|
body: response,
|
||
|
};
|
||
|
req.serialize(output);
|
||
|
}
|
||
|
_ => {
|
||
|
let req = Iq {
|
||
|
from: None,
|
||
|
id: iq.id,
|
||
|
to: None,
|
||
|
r#type: IqType::Error,
|
||
|
body: (),
|
||
|
};
|
||
|
req.serialize(output);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
fn disco_info(to: Option<&str>, req: &InfoQuery) -> InfoQuery {
|
||
|
let identity;
|
||
|
let feature;
|
||
|
match to {
|
||
|
Some("localhost") => {
|
||
|
identity = vec![Identity {
|
||
|
category: "server".into(),
|
||
|
name: None,
|
||
|
r#type: "im".into(),
|
||
|
}];
|
||
|
feature = vec![
|
||
|
Feature::new("http://jabber.org/protocol/disco#info"),
|
||
|
Feature::new("http://jabber.org/protocol/disco#items"),
|
||
|
Feature::new("iq"),
|
||
|
Feature::new("presence"),
|
||
|
]
|
||
|
}
|
||
|
Some("rooms.localhost") => {
|
||
|
identity = vec![Identity {
|
||
|
category: "conference".into(),
|
||
|
name: Some("Chat rooms".into()),
|
||
|
r#type: "text".into(),
|
||
|
}];
|
||
|
feature = vec![
|
||
|
Feature::new("http://jabber.org/protocol/disco#info"),
|
||
|
Feature::new("http://jabber.org/protocol/disco#items"),
|
||
|
Feature::new("http://jabber.org/protocol/muc"),
|
||
|
]
|
||
|
}
|
||
|
_ => {
|
||
|
identity = vec![];
|
||
|
feature = vec![];
|
||
|
}
|
||
|
};
|
||
|
InfoQuery {
|
||
|
node: None,
|
||
|
identity,
|
||
|
feature,
|
||
|
}
|
||
|
}
|
||
|
|
||
|
async fn disco_items(to: Option<&str>, req: &ItemQuery, rooms: &RoomRegistry) -> ItemQuery {
|
||
|
let item = match to {
|
||
|
Some("localhost") => {
|
||
|
vec![Item {
|
||
|
jid: Jid {
|
||
|
name: None,
|
||
|
server: Server("rooms.localhost".into()),
|
||
|
resource: None,
|
||
|
},
|
||
|
name: None,
|
||
|
node: None,
|
||
|
}]
|
||
|
}
|
||
|
Some("rooms.localhost") => {
|
||
|
let room_list = rooms.get_all_rooms().await;
|
||
|
room_list
|
||
|
.into_iter()
|
||
|
.map(|room_info| Item {
|
||
|
jid: Jid {
|
||
|
name: Some(Name(room_info.id.into_inner())),
|
||
|
server: Server("rooms.localhost".into()),
|
||
|
resource: None,
|
||
|
},
|
||
|
name: None,
|
||
|
node: None,
|
||
|
})
|
||
|
.collect()
|
||
|
}
|
||
|
_ => vec![],
|
||
|
};
|
||
|
ItemQuery { item }
|
||
|
}
|