Mercurial > libervia-backend
diff sat/plugins/plugin_xep_0166.py @ 3969:8e7d5796fb23
plugin XEP-0391: implement XEP-0391 (Jingle Encrypted Transports) + XEP-0396 (JET-OMEMO):
rel 378
author | Goffi <goffi@goffi.org> |
---|---|
date | Mon, 31 Oct 2022 04:09:34 +0100 |
parents | bbf92ef05f38 |
children | 524856bd7b19 |
line wrap: on
line diff
--- a/sat/plugins/plugin_xep_0166.py Mon Oct 31 04:04:32 2022 +0100 +++ b/sat/plugins/plugin_xep_0166.py Mon Oct 31 04:09:34 2022 +0100 @@ -17,21 +17,25 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. -import uuid +from collections import namedtuple import time -from typing import Tuple -from collections import namedtuple -from zope.interface import implementer -from twisted.words.protocols.jabber import jid +from typing import Any, Dict, Tuple +import uuid + from twisted.internet import defer from twisted.internet import reactor +from twisted.python import failure +from twisted.words.protocols.jabber import jid from twisted.words.protocols.jabber import error from twisted.words.protocols.jabber import xmlstream -from twisted.python import failure +from twisted.words.xish import domish from wokkel import disco, iwokkel +from zope.interface import implementer + from sat.core import exceptions -from sat.core.i18n import _, D_ from sat.core.constants import Const as C +from sat.core.core_types import SatXMPPEntity +from sat.core.i18n import D_, _ from sat.core.log import getLogger from sat.tools import xml_tools from sat.tools import utils @@ -65,7 +69,8 @@ TransportData = namedtuple("TransportData", ("namespace", "handler", "priority")) -class XEP_0166(object): +class XEP_0166: + namespace = NS_JINGLE ROLE_INITIATOR = "initiator" ROLE_RESPONDER = "responder" TRANSPORT_DATAGRAM = "UDP" @@ -372,7 +377,7 @@ content_name = content["name"] = str(uuid.uuid4()) return application, app_args, app_kwargs, content_name - async def initiate(self, client, peer_jid, contents): + async def initiate(self, client, peer_jid, contents, encrypted=False): """Send a session initiation request @param peer_jid(jid.JID): jid to establith session with @@ -387,6 +392,8 @@ default to BOTH (see XEP-0166 ยง7.3) - app_args(list): args to pass to the application plugin - app_kwargs(dict): keyword args to pass to the application plugin + @param encrypted: if True, session must be encrypted and "encryption" must be set + to all content data of session @return (unicode): jingle session id """ assert contents # there must be at least one content @@ -471,6 +478,18 @@ ) content_elt.addChild(transport_elt) + if not await self.host.trigger.asyncPoint( + "XEP-0166_initiate_elt_built", + client, session, iq_elt, jingle_elt + ): + return + if encrypted: + for content in session["contents"].values(): + if "encryption" not in content: + raise exceptions.EncryptionError( + "Encryption is requested, but no encryption has been set" + ) + try: await iq_elt.send() except Exception as e: @@ -514,7 +533,14 @@ ## jingle events ## - def _onJingleRequest(self, request, client): + def _on_jingle_request(self, request: domish.Element, client: SatXMPPEntity) -> None: + defer.ensureDeferred(self.on_jingle_request(client, request)) + + async def on_jingle_request( + self, + client: SatXMPPEntity, + request: domish.Element + ) -> None: """Called when any jingle request is received The request will then be dispatched to appropriate method @@ -594,7 +620,7 @@ raise exceptions.InternalError if action == XEP_0166.A_SESSION_INITIATE: - self.onSessionInitiate(client, request, jingle_elt, session) + await self.onSessionInitiate(client, request, jingle_elt, session) elif action == XEP_0166.A_SESSION_TERMINATE: self.onSessionTerminate(client, request, jingle_elt, session) elif action == XEP_0166.A_SESSION_ACCEPT: @@ -796,7 +822,13 @@ return defers_list - def onSessionInitiate(self, client, request, jingle_elt, session): + async def onSessionInitiate( + self, + client: SatXMPPEntity, + request: domish.Element, + jingle_elt: domish.Element, + session: Dict[str, Any] + ) -> None: """Called on session-initiate action The "jingleRequestConfirmation" method of each application will be called @@ -829,6 +861,13 @@ # at this point we can send the <iq/> result to confirm reception of the request client.send(xmlstream.toResponse(request, "result")) + + if not await self.host.trigger.asyncPoint( + "XEP-0166_on_session_initiate", + client, session, request, jingle_elt + ): + return + # we now request each application plugin confirmation # and if all are accepted, we can accept the session confirm_defers = self._callPlugins( @@ -1199,7 +1238,7 @@ def connectionInitialized(self): self.xmlstream.addObserver( - JINGLE_REQUEST, self.plugin_parent._onJingleRequest, client=self.parent + JINGLE_REQUEST, self.plugin_parent._on_jingle_request, client=self.parent ) def getDiscoInfo(self, requestor, target, nodeIdentifier=""):