changeset 2713:19000c506d0c

plugin XEP-0313: improvments to prepare MUC MAM: - discard groupchat message when retrieving last stanza_id on connection - service can be specified in getMessageFromResult - service is also used when using getArchives from bridge
author Goffi <goffi@goffi.org>
date Fri, 07 Dec 2018 17:43:43 +0100
parents c3f59c1dcb0a
children 57eac4fd0ec0
files sat/plugins/plugin_xep_0313.py
diffstat 1 files changed, 18 insertions(+), 11 deletions(-) [+]
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0313.py	Sat Dec 01 14:40:32 2018 +0100
+++ b/sat/plugins/plugin_xep_0313.py	Fri Dec 07 17:43:43 2018 +0100
@@ -71,18 +71,17 @@
     @defer.inlineCallbacks
     def profileConnected(self, client):
         last_mess = yield self.host.memory.historyGet(
-            None, None, limit=1, filters={u'last_stanza_id': True},
+            None, None, limit=1, filters={u'not_types': C.MESS_TYPE_GROUPCHAT,
+                                          u'last_stanza_id': True},
             profile=client.profile)
         if not last_mess:
             log.info(_(u"It seems that we have no MAM history yet"))
             return
         stanza_id = last_mess[0][-1][u'stanza_id']
-        # XXX: test
-        # stanza_id = "IIheJOfiIhkPYkw6"
         rsm_req = rsm.RSMRequest(after=stanza_id)
         mam_req = mam.MAMRequest(rsm_=rsm_req)
         mam_data = yield self.getArchives(client, mam_req,
-                                         service=client.jid.userhostJID())
+                                          service=client.jid.userhostJID())
         elt_list, rsm_response = mam_data
         if not elt_list:
             log.info(_(u"We have received no message while offline"))
@@ -154,21 +153,28 @@
 
         return mam.MAMRequest(**mam_args) if mam_args else None
 
-    def getMessageFromResult(self, client, mess_elt, mam_req):
+    def getMessageFromResult(self, client, mess_elt, mam_req, service=None):
         """Extract usable <message/> from MAM query result
 
         The message will be validated, and stanza-id/delay will be added if necessary.
         @param mess_elt(domish.Element): result <message/> element wrapping the message
             to retrieve
         @param mam_req(mam.MAMRequest): request used
+        @param service(jid.JID, None): MAM service where the request has been sent
+            None if it's user server
         @return (domish.Element): <message/> that can be used directly with onMessage
         """
         if mess_elt.name != u"message":
             log.warning(u"unexpected stanza in archive: {xml}".format(
                 xml=mess_elt.toXml()))
             raise exceptions.DataError(u"Invalid element")
+        service_jid = client.jid.userhostJID() if service is None else service
         mess_from = mess_elt[u"from"]
-        if mess_from != client.jid.host and mess_from != client.jid.userhost():
+        # we check that the message has been sent by the right service
+        # if service is None (i.e. message expected from our own server)
+        # from can be server jid or user's bare jid
+        if (mess_from != service_jid.full()
+            and not (service is None and mess_from == client.jid.host)):
             log.error(u"Message is not from our server, something went wrong: "
                       u"{xml}".format(xml=mess_elt.toXml()))
             raise exceptions.DataError(u"Invalid element")
@@ -191,7 +197,7 @@
                     .format(query_id=mam.query_id, xml=mess_elt.toXml()))
                 raise exceptions.DataError(u"Invalid element")
             stanza_id = self._sid.getStanzaId(fwd_message_elt,
-                                              client.jid.userhostJID())
+                                              service_jid)
             if stanza_id is None:
                 # not stanza-id element is present, we add one so message
                 # will be archived with it, and we won't request several times
@@ -202,7 +208,7 @@
                     log.warning(u'Invalid MAM result: missing "id" attribute: {xml}'
                                 .format(xml=result_elt.toXml()))
                     raise exceptions.DataError(u"Invalid element")
-                self._sid.addStanzaId(client, fwd_message_elt, stanza_id)
+                self._sid.addStanzaId(client, fwd_message_elt, stanza_id, by=service_jid)
 
             if delay_elt is not None:
                 fwd_message_elt.addChild(delay_elt)
@@ -247,11 +253,12 @@
 
         return (elt_list, rsm_response)
 
-    def serializeArchiveResult(self, data, client, mam_req):
+    def serializeArchiveResult(self, data, client, mam_req, service):
         elt_list, rsm_response = data
         mess_list = []
         for elt in elt_list:
-            fwd_message_elt = self.getMessageFromResult(client, elt, mam_req)
+            fwd_message_elt = self.getMessageFromResult(client, elt, mam_req,
+                                                        service=service)
             mess_data = client.messageProt.parseMessage(fwd_message_elt)
             mess_list.append(client.messageGetBridgeArgs(mess_data))
         return mess_list, client.profile
@@ -263,7 +270,7 @@
         mam_req = self.parseExtra(extra)
 
         d = self.getArchives(client, mam_req, service=service)
-        d.addCallback(self.serializeArchiveResult, client, mam_req)
+        d.addCallback(self.serializeArchiveResult, client, mam_req, service)
         return d
 
     def getArchives(self, client, query, service=None, message_cb=None):