Mercurial > libervia-backend
comparison sat/core/xmpp.py @ 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 | efc34a89e70b |
children | 8289ac1b34f4 |
comparison
equal
deleted
inserted
replaced
3794:a58715ffa445 | 3795:967a8e109cda |
---|---|
21 from functools import partial | 21 from functools import partial |
22 import mimetypes | 22 import mimetypes |
23 from pathlib import Path | 23 from pathlib import Path |
24 import sys | 24 import sys |
25 import time | 25 import time |
26 from typing import Tuple | 26 from typing import Tuple, Optional |
27 from urllib.parse import unquote, urlparse | 27 from urllib.parse import unquote, urlparse |
28 import uuid | 28 import uuid |
29 | 29 |
30 import shortuuid | 30 import shortuuid |
31 from twisted.internet import defer, error as internet_error | 31 from twisted.internet import defer, error as internet_error |
970 | 970 |
971 trigger_suffix = ( | 971 trigger_suffix = ( |
972 "Component" | 972 "Component" |
973 ) # used for to distinguish some trigger points set in SatXMPPEntity | 973 ) # used for to distinguish some trigger points set in SatXMPPEntity |
974 is_component = True | 974 is_component = True |
975 sendHistory = ( | 975 # XXX: set to True from entry plugin to keep messages in history for sent messages |
976 False | 976 sendHistory = False |
977 ) # XXX: set to True from entry plugin to keep messages in history for received | 977 # XXX: same as sendHistory but for received messaged |
978 # messages | 978 receiveHistory = False |
979 | 979 |
980 def __init__(self, host_app, profile, component_jid, password, host=None, port=None, | 980 def __init__(self, host_app, profile, component_jid, password, host=None, port=None, |
981 max_retries=C.XMPP_MAX_RETRIES): | 981 max_retries=C.XMPP_MAX_RETRIES): |
982 self.started = time.time() | 982 self.started = time.time() |
983 if port is None: | 983 if port is None: |
1013 return jid.JID(self.jid.host.split(".", 1)[-1]) | 1013 return jid.JID(self.jid.host.split(".", 1)[-1]) |
1014 | 1014 |
1015 @property | 1015 @property |
1016 def is_admin(self) -> bool: | 1016 def is_admin(self) -> bool: |
1017 return False | 1017 return False |
1018 | |
1019 def _createSubProtocols(self): | |
1020 self.messageProt = SatMessageProtocol(self.host_app) | |
1021 self.messageProt.setHandlerParent(self) | |
1018 | 1022 |
1019 def _buildDependencies(self, current, plugins, required=True): | 1023 def _buildDependencies(self, current, plugins, required=True): |
1020 """build recursively dependencies needed for a plugin | 1024 """build recursively dependencies needed for a plugin |
1021 | 1025 |
1022 this method build list of plugin needed for a component and raises | 1026 this method build list of plugin needed for a component and raises |
1149 | 1153 |
1150 @property | 1154 @property |
1151 def client(self): | 1155 def client(self): |
1152 return self.parent | 1156 return self.parent |
1153 | 1157 |
1158 def normalizeNS(self, elt: domish.Element, namespace: Optional[str]) -> None: | |
1159 if elt.uri == namespace: | |
1160 elt.defaultUri = elt.uri = C.NS_CLIENT | |
1161 for child in elt.elements(): | |
1162 self.normalizeNS(child, namespace) | |
1163 | |
1154 def parseMessage(self, message_elt): | 1164 def parseMessage(self, message_elt): |
1155 """Parse a message XML and return message_data | 1165 """Parse a message XML and return message_data |
1156 | 1166 |
1157 @param message_elt(domish.Element): raw <message> xml | 1167 @param message_elt(domish.Element): raw <message> xml |
1158 @param client(SatXMPPClient, None): client to map message id to uid | 1168 @param client(SatXMPPClient, None): client to map message id to uid |
1163 log.warning(_( | 1173 log.warning(_( |
1164 "parseMessage used with a non <message/> stanza, ignoring: {xml}" | 1174 "parseMessage used with a non <message/> stanza, ignoring: {xml}" |
1165 .format(xml=message_elt.toXml()))) | 1175 .format(xml=message_elt.toXml()))) |
1166 return {} | 1176 return {} |
1167 | 1177 |
1168 if message_elt.uri is None: | 1178 if message_elt.uri == None: |
1169 # wokkel element parsing strip out root namespace | 1179 # xmlns may be None when wokkel element parsing strip out root namespace |
1170 message_elt.defaultUri = message_elt.uri = C.NS_CLIENT | 1180 self.normalizeNS(message_elt, None) |
1171 for c in message_elt.elements(): | |
1172 if c.uri is None: | |
1173 c.uri = C.NS_CLIENT | |
1174 elif message_elt.uri != C.NS_CLIENT: | 1181 elif message_elt.uri != C.NS_CLIENT: |
1175 log.warning(_( | 1182 log.warning(_( |
1176 "received <message> with a wrong namespace: {xml}" | 1183 "received <message> with a wrong namespace: {xml}" |
1177 .format(xml=message_elt.toXml()))) | 1184 .format(xml=message_elt.toXml()))) |
1178 | 1185 |
1247 if not cont: | 1254 if not cont: |
1248 return | 1255 return |
1249 data = self.parseMessage(message_elt) | 1256 data = self.parseMessage(message_elt) |
1250 post_treat.addCallback(self.completeAttachments) | 1257 post_treat.addCallback(self.completeAttachments) |
1251 post_treat.addCallback(self.skipEmptyMessage) | 1258 post_treat.addCallback(self.skipEmptyMessage) |
1252 post_treat.addCallback( | 1259 if not client.is_component or client.receiveHistory: |
1253 lambda ret: defer.ensureDeferred(self.addToHistory(ret)) | 1260 post_treat.addCallback( |
1254 ) | 1261 lambda ret: defer.ensureDeferred(self.addToHistory(ret)) |
1255 post_treat.addCallback(self.bridgeSignal, data) | 1262 ) |
1263 if not client.is_component: | |
1264 post_treat.addCallback(self.bridgeSignal, data) | |
1256 post_treat.addErrback(self.cancelErrorTrap) | 1265 post_treat.addErrback(self.cancelErrorTrap) |
1257 post_treat.callback(data) | 1266 post_treat.callback(data) |
1258 | 1267 |
1259 def onMessage(self, message_elt): | 1268 def onMessage(self, message_elt): |
1260 # TODO: handle threads | 1269 # TODO: handle threads |
1261 message_elt._received_timestamp = time.time() | 1270 message_elt._received_timestamp = time.time() |
1262 client = self.parent | 1271 client = self.parent |
1263 if not "from" in message_elt.attributes: | 1272 if not "from" in message_elt.attributes: |
1264 message_elt["from"] = client.jid.host | 1273 message_elt["from"] = client.jid.host |
1265 log.debug(_("got message from: {from_}").format(from_=message_elt["from"])) | 1274 log.debug(_("got message from: {from_}").format(from_=message_elt["from"])) |
1275 if self.client.is_component and message_elt.uri == component.NS_COMPONENT_ACCEPT: | |
1276 # we use client namespace all the time to simplify parsing | |
1277 self.normalizeNS(message_elt, component.NS_COMPONENT_ACCEPT) | |
1266 | 1278 |
1267 # plugin can add their treatments to this deferred | 1279 # plugin can add their treatments to this deferred |
1268 post_treat = defer.Deferred() | 1280 post_treat = defer.Deferred() |
1269 | 1281 |
1270 d = self.host.trigger.asyncPoint( | 1282 d = self.host.trigger.asyncPoint( |