xmpp: Add XEP-0070 authentification support

PulkoMandy created

Change summary

xmpp/ChangeLog                   |  2 ++
xmpp/src/event.rs                | 11 +++++++++++
xmpp/src/message/receive/chat.rs | 18 +++++++++++++++++-
xmpp/src/message/receive/mod.rs  |  4 ++++
4 files changed, 34 insertions(+), 1 deletion(-)

Detailed changes

xmpp/ChangeLog 🔗

@@ -32,6 +32,8 @@ XXXX-YY-ZZ [ RELEASER <admin@localhost> ]
       - Event::ChatMessageCorrection, Event::RoomMessageCorrection, and
         Event::RoomPrivateMessageCorrection signal XEP-0308 message corrections; they're
         not checked how old the corrected entry is, which has security concerns (!496)
+      - Event::AuthConfirm and Event::AuthReject signal XEP-0070 authentication requests and
+        responses.
       - Agent::new helper method.
       - Handle SIGINT, SIGTERM and SIGKILL in hello_bot example to avoid leaving
         hibernating resources around.

xmpp/src/event.rs 🔗

@@ -9,6 +9,7 @@ use tokio_xmpp::jid::BareJid;
 use tokio_xmpp::jid::Jid;
 use tokio_xmpp::parsers::roster::Item as RosterItem;
 
+use crate::parsers::confirm::Confirm;
 use crate::{delay::StanzaTimeInfo, Error, MessageId, RoomNick};
 
 /// An Event notifying the client something has happened that may require attention.
@@ -56,6 +57,16 @@ pub enum Event {
     /// - The [`String`] is the new body of the message, to replace the old one.
     /// - The [`StanzaTimeInfo`] is the time the message correction was sent/received
     ChatMessageCorrection(MessageId, BareJid, String, StanzaTimeInfo),
+    /// A XEP-0070 authentication request or confirmation was received.
+    /// - The [`BareJid`] is the sender's JID.
+    /// - The [`Confirm`] is the info about the authentication request.
+    /// - The [`StanzaTimeInfo`] about when message was received, and when the message was claimed sent.
+    AuthConfirm(BareJid, Confirm, StanzaTimeInfo),
+    /// A XEP-0070 authentication rejection was received.
+    /// - The [`BareJid`] is the sender's JID.
+    /// - The [`Confirm`] is the info about the authentication request that was rejected.
+    /// - The [`StanzaTimeInfo`] about when message was received, and when the message was claimed sent.
+    AuthReject(BareJid, Confirm, StanzaTimeInfo),
     /// Room joined; client may receive and send messages from/to this BareJid.
     RoomJoined(BareJid),
     /// Room left; client may not receive and send messages from/to this BareJid

xmpp/src/message/receive/chat.rs 🔗

@@ -6,7 +6,7 @@
 
 use tokio_xmpp::{
     jid::Jid,
-    parsers::{message::Message, message_correct::Replace, muc::user::MucUser},
+    parsers::{confirm::Confirm, message::Message, message_correct::Replace, muc::user::MucUser},
 };
 
 use crate::{delay::StanzaTimeInfo, Agent, Event, RoomNick};
@@ -27,6 +27,7 @@ pub async fn handle_message_chat(
 
     let is_muc_pm = message.extract_valid_payload::<MucUser>().is_some();
     let correction = message.extract_valid_payload::<Replace>();
+    let confirm = message.extract_valid_payload::<Confirm>();
 
     if is_muc_pm {
         if from.resource().is_none() {
@@ -57,9 +58,24 @@ pub async fn handle_message_chat(
         let event = if let Some(correction) = correction {
             // TODO: Check that correction is valid (only for last N minutes or last N messages)
             Event::ChatMessageCorrection(correction.id, from.to_bare(), body.clone(), time_info)
+        } else if let Some(confirm) = confirm {
+            Event::AuthConfirm(from.to_bare(), confirm, time_info)
         } else {
             Event::ChatMessage(message.id.clone(), from.to_bare(), body, time_info)
         };
         events.push(event);
     }
 }
+
+pub async fn handle_message_error(
+    _agent: &mut Agent,
+    events: &mut Vec<Event>,
+    from: Jid,
+    message: &mut Message,
+    time_info: StanzaTimeInfo,
+) {
+    let confirm = message.extract_valid_payload::<Confirm>();
+    if let Some(confirm) = confirm {
+        events.push(Event::AuthReject(from.to_bare(), confirm, time_info));
+    }
+}

xmpp/src/message/receive/mod.rs 🔗

@@ -34,6 +34,10 @@ pub async fn handle_message(agent: &mut Agent, mut message: Message) -> Vec<Even
             chat::handle_message_chat(agent, &mut events, from.clone(), &mut message, time_info)
                 .await;
         }
+        MessageType::Error => {
+            chat::handle_message_error(agent, &mut events, from.clone(), &mut message, time_info)
+                .await;
+        }
         _ => {}
     }