Mercurial > libervia-backend
comparison sat/core/xmpp.py @ 3911:8289ac1b34f4
plugin XEP-0384: Fully reworked to adjust to the reworked python-omemo:
- support for both (modern) OMEMO under the `urn:xmpp:omemo:2` namespace and (legacy) OMEMO under the `eu.siacs.conversations.axolotl` namespace
- maintains one identity across both versions of OMEMO
- migrates data from the old plugin
- includes more features for protocol stability
- uses SCE for modern OMEMO
- fully type-checked, linted and format-checked
- added type hints to various pieces of backend code used by the plugin
- added stubs for some Twisted APIs used by the plugin under stubs/ (use `export MYPYPATH=stubs/` before running mypy)
- core (xmpp): enabled `send` trigger and made it an asyncPoint
fix 375
author | Syndace <me@syndace.dev> |
---|---|
date | Tue, 23 Aug 2022 21:06:24 +0200 |
parents | 967a8e109cda |
children | 944f51f9c2b4 |
comparison
equal
deleted
inserted
replaced
3910:199598223f82 | 3911:8289ac1b34f4 |
---|---|
548 iq_error_elt = error.StanzaError( | 548 iq_error_elt = error.StanzaError( |
549 condition, text=text, appCondition=appCondition | 549 condition, text=text, appCondition=appCondition |
550 ).toResponse(iq_elt) | 550 ).toResponse(iq_elt) |
551 self.xmlstream.send(iq_error_elt) | 551 self.xmlstream.send(iq_error_elt) |
552 | 552 |
553 def generateMessageXML(self, data, post_xml_treatments=None): | 553 def generateMessageXML( |
554 self, | |
555 data: core_types.MessageData, | |
556 post_xml_treatments: Optional[defer.Deferred] = None | |
557 ) -> core_types.MessageData: | |
554 """Generate <message/> stanza from message data | 558 """Generate <message/> stanza from message data |
555 | 559 |
556 @param data(dict): message data | 560 @param data: message data |
557 domish element will be put in data['xml'] | 561 domish element will be put in data['xml'] |
558 following keys are needed: | 562 following keys are needed: |
559 - from | 563 - from |
560 - to | 564 - to |
561 - uid: can be set to '' if uid attribute is not wanted | 565 - uid: can be set to '' if uid attribute is not wanted |
562 - message | 566 - message |
563 - type | 567 - type |
564 - subject | 568 - subject |
565 - extra | 569 - extra |
566 @param post_xml_treatments(Deferred): a Deferred which will be called with data | 570 @param post_xml_treatments: a Deferred which will be called with data once XML is |
567 once XML is generated | 571 generated |
568 @return (dict) message data | 572 @return: message data |
569 """ | 573 """ |
570 data["xml"] = message_elt = domish.Element((None, "message")) | 574 data["xml"] = message_elt = domish.Element((None, "message")) |
571 message_elt["to"] = data["to"].full() | 575 message_elt["to"] = data["to"].full() |
572 message_elt["from"] = data["from"].full() | 576 message_elt["from"] = data["from"].full() |
573 message_elt["type"] = data["type"] | 577 message_elt["type"] = data["type"] |
610 | 614 |
611 @param post_xml_treatments(D): the same Deferred as in sendMessage trigger | 615 @param post_xml_treatments(D): the same Deferred as in sendMessage trigger |
612 """ | 616 """ |
613 raise NotImplementedError | 617 raise NotImplementedError |
614 | 618 |
615 def send(self, obj): | 619 async def send(self, obj): |
616 # original send method accept string | 620 # original send method accept string |
617 # but we restrict to domish.Element to make trigger treatments easier | 621 # but we restrict to domish.Element to make trigger treatments easier |
618 assert isinstance(obj, domish.Element) | 622 assert isinstance(obj, domish.Element) |
619 # XXX: this trigger is the last one before sending stanza on wire | 623 # XXX: this trigger is the last one before sending stanza on wire |
620 # it is intended for things like end 2 end encryption. | 624 # it is intended for things like end 2 end encryption. |
621 # *DO NOT* cancel (i.e. return False) without very good reason | 625 # *DO NOT* cancel (i.e. return False) without very good reason |
622 # (out of band transmission for instance). | 626 # (out of band transmission for instance). |
623 # e2e should have a priority of 0 here, and out of band transmission | 627 # e2e should have a priority of 0 here, and out of band transmission |
624 # a lower priority | 628 # a lower priority |
625 # FIXME: trigger not used yet, can be uncommented when e2e full stanza | 629 if not (await self.host_app.trigger.asyncPoint("send", self, obj)): |
626 # encryption is implemented | 630 return |
627 # if not self.host_app.trigger.point("send", self, obj): | |
628 # return | |
629 super().send(obj) | 631 super().send(obj) |
630 | 632 |
631 @defer.inlineCallbacks | 633 async def sendMessageData(self, mess_data): |
632 def sendMessageData(self, mess_data): | |
633 """Convenient method to send message data to stream | 634 """Convenient method to send message data to stream |
634 | 635 |
635 This method will send mess_data[u'xml'] to stream, but a trigger is there | 636 This method will send mess_data[u'xml'] to stream, but a trigger is there |
636 The trigger can't be cancelled, it's a good place for e2e encryption which | 637 The trigger can't be cancelled, it's a good place for e2e encryption which |
637 don't handle full stanza encryption | 638 don't handle full stanza encryption |
642 # XXX: This is the last trigger before u"send" (last but one globally) | 643 # XXX: This is the last trigger before u"send" (last but one globally) |
643 # for sending message. | 644 # for sending message. |
644 # This is intented for e2e encryption which doesn't do full stanza | 645 # This is intented for e2e encryption which doesn't do full stanza |
645 # encryption (e.g. OTR) | 646 # encryption (e.g. OTR) |
646 # This trigger point can't cancel the method | 647 # This trigger point can't cancel the method |
647 yield self.host_app.trigger.asyncPoint("sendMessageData", self, mess_data, | 648 await self.host_app.trigger.asyncPoint("sendMessageData", self, mess_data, |
648 triggers_no_cancel=True) | 649 triggers_no_cancel=True) |
649 self.send(mess_data["xml"]) | 650 await self.send(mess_data["xml"]) |
650 defer.returnValue(mess_data) | 651 return mess_data |
651 | 652 |
652 def sendMessage( | 653 def sendMessage( |
653 self, to_jid, message, subject=None, mess_type="auto", extra=None, uid=None, | 654 self, to_jid, message, subject=None, mess_type="auto", extra=None, uid=None, |
654 no_trigger=False): | 655 no_trigger=False): |
655 r"""Send a message to an entity | 656 r"""Send a message to an entity |
820 @return (object): requested plugin wrapper, or default value | 821 @return (object): requested plugin wrapper, or default value |
821 The plugin wrapper will return the method with client set as first | 822 The plugin wrapper will return the method with client set as first |
822 positional argument | 823 positional argument |
823 """ | 824 """ |
824 return ClientPluginWrapper(self, plugin_name, missing) | 825 return ClientPluginWrapper(self, plugin_name, missing) |
826 | |
827 | |
828 ExtraDict = dict # TODO | |
825 | 829 |
826 | 830 |
827 @implementer(iwokkel.IDisco) | 831 @implementer(iwokkel.IDisco) |
828 class SatXMPPClient(SatXMPPEntity, wokkel_client.XMPPClient): | 832 class SatXMPPClient(SatXMPPEntity, wokkel_client.XMPPClient): |
829 trigger_suffix = "" | 833 trigger_suffix = "" |
928 post_xml_treatments.addCallback( | 932 post_xml_treatments.addCallback( |
929 lambda ret: defer.ensureDeferred(self.messageAddToHistory(ret)) | 933 lambda ret: defer.ensureDeferred(self.messageAddToHistory(ret)) |
930 ) | 934 ) |
931 post_xml_treatments.addCallback(self.messageSendToBridge) | 935 post_xml_treatments.addCallback(self.messageSendToBridge) |
932 | 936 |
933 def feedback(self, to_jid, message, extra=None): | 937 def feedback( |
938 self, | |
939 to_jid: jid.JID, | |
940 message: str, | |
941 extra: Optional[ExtraDict] = None | |
942 ) -> None: | |
934 """Send message to frontends | 943 """Send message to frontends |
935 | 944 |
936 This message will be an info message, not recorded in history. | 945 This message will be an info message, not recorded in history. |
937 It can be used to give feedback of a command | 946 It can be used to give feedback of a command |
938 @param to_jid(jid.JID): destinee jid | 947 @param to_jid: destinee jid |
939 @param message(unicode): message to send to frontends | 948 @param message: message to send to frontends |
940 @param extra(None, dict): extra data to use | 949 @param extra: extra data to use in particular, info subtype can be specified with |
941 in particular, info subtype can be specified with MESS_EXTRA_INFO | 950 MESS_EXTRA_INFO |
942 """ | 951 """ |
943 if extra is None: | 952 if extra is None: |
944 extra = {} | 953 extra = {} |
945 self.host_app.bridge.messageNew( | 954 self.host_app.bridge.messageNew( |
946 uid=str(uuid.uuid4()), | 955 uid=str(uuid.uuid4()), |