changeset 3795:967a8e109cda

core (xmpp): adapt message workflow to components: message workflow were not used for components so far. This patch activate it, normalise namespace to the client one to simplify parsing, and use SatXMPPComponent.sendHistory and SatXMPPComponent.receiveHistory to indicate if a component should store sent and received message in database (they both default to False). OTR plugin is deactivated for components. rel 367
author Goffi <goffi@goffi.org>
date Fri, 17 Jun 2022 14:15:23 +0200
parents a58715ffa445
children 24c1c06c865b
files sat/core/xmpp.py sat/plugins/plugin_sec_otr.py
diffstat 2 files changed, 34 insertions(+), 15 deletions(-) [+]
line wrap: on
line diff
--- a/sat/core/xmpp.py	Fri Jun 17 14:15:23 2022 +0200
+++ b/sat/core/xmpp.py	Fri Jun 17 14:15:23 2022 +0200
@@ -23,7 +23,7 @@
 from pathlib import Path
 import sys
 import time
-from typing import Tuple
+from typing import Tuple, Optional
 from urllib.parse import unquote, urlparse
 import uuid
 
@@ -972,10 +972,10 @@
         "Component"
     )  # used for to distinguish some trigger points set in SatXMPPEntity
     is_component = True
-    sendHistory = (
-        False
-    )  # XXX: set to True from entry plugin to keep messages in history for received
-       #      messages
+    # XXX: set to True from entry plugin to keep messages in history for sent messages
+    sendHistory = False
+    # XXX: same as sendHistory but for received messaged
+    receiveHistory = False
 
     def __init__(self, host_app, profile, component_jid, password, host=None, port=None,
                  max_retries=C.XMPP_MAX_RETRIES):
@@ -1016,6 +1016,10 @@
     def is_admin(self) -> bool:
         return False
 
+    def _createSubProtocols(self):
+        self.messageProt = SatMessageProtocol(self.host_app)
+        self.messageProt.setHandlerParent(self)
+
     def _buildDependencies(self, current, plugins, required=True):
         """build recursively dependencies needed for a plugin
 
@@ -1151,6 +1155,12 @@
     def client(self):
         return self.parent
 
+    def normalizeNS(self, elt: domish.Element, namespace: Optional[str]) -> None:
+        if elt.uri == namespace:
+            elt.defaultUri = elt.uri = C.NS_CLIENT
+        for child in elt.elements():
+            self.normalizeNS(child, namespace)
+
     def parseMessage(self, message_elt):
         """Parse a message XML and return message_data
 
@@ -1165,12 +1175,9 @@
                 .format(xml=message_elt.toXml())))
             return {}
 
-        if message_elt.uri is None:
-            # wokkel element parsing strip out root namespace
-            message_elt.defaultUri = message_elt.uri = C.NS_CLIENT
-            for c in message_elt.elements():
-                if c.uri is None:
-                    c.uri = C.NS_CLIENT
+        if message_elt.uri == None:
+            # xmlns may be None when wokkel element parsing strip out root namespace
+            self.normalizeNS(message_elt, None)
         elif message_elt.uri != C.NS_CLIENT:
             log.warning(_(
                 "received <message> with a wrong namespace: {xml}"
@@ -1249,10 +1256,12 @@
         data = self.parseMessage(message_elt)
         post_treat.addCallback(self.completeAttachments)
         post_treat.addCallback(self.skipEmptyMessage)
-        post_treat.addCallback(
-            lambda ret: defer.ensureDeferred(self.addToHistory(ret))
-        )
-        post_treat.addCallback(self.bridgeSignal, data)
+        if not client.is_component or client.receiveHistory:
+            post_treat.addCallback(
+                lambda ret: defer.ensureDeferred(self.addToHistory(ret))
+            )
+        if not client.is_component:
+            post_treat.addCallback(self.bridgeSignal, data)
         post_treat.addErrback(self.cancelErrorTrap)
         post_treat.callback(data)
 
@@ -1263,6 +1272,9 @@
         if not "from" in message_elt.attributes:
             message_elt["from"] = client.jid.host
         log.debug(_("got message from: {from_}").format(from_=message_elt["from"]))
+        if self.client.is_component and message_elt.uri == component.NS_COMPONENT_ACCEPT:
+            # we use client namespace all the time to simplify parsing
+            self.normalizeNS(message_elt, component.NS_COMPONENT_ACCEPT)
 
         # plugin can add their treatments to this deferred
         post_treat = defer.Deferred()
--- a/sat/plugins/plugin_sec_otr.py	Fri Jun 17 14:15:23 2022 +0200
+++ b/sat/plugins/plugin_sec_otr.py	Fri Jun 17 14:15:23 2022 +0200
@@ -42,6 +42,7 @@
 PLUGIN_INFO = {
     C.PI_NAME: "OTR",
     C.PI_IMPORT_NAME: "OTR",
+    C.PI_MODES: [C.PLUG_MODE_CLIENT],
     C.PI_TYPE: "SEC",
     C.PI_PROTOCOLS: ["XEP-0364"],
     C.PI_DEPENDENCIES: ["XEP-0280", "XEP-0334"],
@@ -731,6 +732,8 @@
         return data
 
     def messageReceivedTrigger(self, client, message_elt, post_treat):
+        if client.is_component:
+            return True
         if message_elt.getAttribute("type") == C.MESS_TYPE_GROUPCHAT:
             # OTR is not possible in group chats
             return True
@@ -745,6 +748,8 @@
         return True
 
     def _sendMessageDataTrigger(self, client, mess_data):
+        if client.is_component:
+            return True
         encryption = mess_data.get(C.MESS_KEY_ENCRYPTION)
         if encryption is None or encryption['plugin'].namespace != NS_OTR:
             return
@@ -788,6 +793,8 @@
 
     def sendMessageTrigger(self, client, mess_data, pre_xml_treatments,
                            post_xml_treatments):
+        if client.is_component:
+            return True
         if mess_data["type"] == "groupchat":
             return True