comparison sat_pubsub/backend.py @ 459:cebcb7f56889

backend, delegation: update to XEP-0355 v0.5 (namespace bump) + disco: - delegation now uses namespace `urn:xmpp:delegation:2` - restored node metadata and made it work with PEP - `delegated` attribute is also set on recipient when available (needed to know when a disco query is delegated as the original stanza is lost by wokkel)
author Goffi <goffi@goffi.org>
date Fri, 15 Oct 2021 09:32:04 +0200
parents 0b5233981671
children 607616f9ef5b
comparison
equal deleted inserted replaced
458:bc2e04a4d3c1 459:cebcb7f56889
65 from typing import Optional 65 from typing import Optional
66 66
67 from zope.interface import implementer 67 from zope.interface import implementer
68 68
69 from twisted.application import service 69 from twisted.application import service
70 from twisted.python import components, log 70 from twisted.python import components, failure, log
71 from twisted.internet import defer, reactor 71 from twisted.internet import defer, reactor
72 from twisted.words.protocols.jabber.error import StanzaError 72 from twisted.words.protocols.jabber.error import StanzaError
73 from twisted.words.protocols.jabber import jid 73 from twisted.words.protocols.jabber import jid
74 from twisted.words.xish import domish, utility 74 from twisted.words.xish import domish, utility
75 75
1636 else: 1636 else:
1637 exc = StanzaError(condition, text=msg) 1637 exc = StanzaError(condition, text=msg)
1638 1638
1639 raise exc 1639 raise exc
1640 1640
1641 def getInfo(self, requestor, service, nodeIdentifier, pep=None, recipient=None): 1641 async def _getInfo(
1642 return [] # FIXME: disabled for now, need to manage PEP 1642 self,
1643 requestor: jid.JID,
1644 service: jid.JID,
1645 nodeIdentifier: str,
1646 pep: bool = False,
1647 recipient: Optional[jid.JID] = None
1648 ) -> Optional[dict]:
1643 if not requestor.resource: 1649 if not requestor.resource:
1644 # this avoid error when getting a disco request from server during namespace delegation 1650 # this avoid error when getting a disco request from server during namespace
1645 return [] 1651 # delegation
1652 return None
1646 info = {} 1653 info = {}
1647 1654 try:
1648 def saveType(result): 1655 info["type"] = await self.backend.getNodeType(nodeIdentifier, pep, recipient)
1649 info['type'] = result 1656 info["meta-data"] = await self.backend.getNodeMetaData(
1650 return nodeIdentifier 1657 nodeIdentifier, pep, recipient
1651 1658 )
1652 def saveMetaData(result): 1659 except error.NodeNotFound:
1653 info['meta-data'] = result 1660 info["meta-data"] = None
1661 return None
1662 except failure.Failure as e:
1663 self._mapErrors(e)
1664 except Exception as e:
1665 self._mapErrors(failure.Failure(e))
1666 else:
1654 return info 1667 return info
1655 1668
1656 def trapNotFound(failure): 1669 def getInfo(self, requestor, service, nodeIdentifier):
1657 failure.trap(error.NodeNotFound) 1670 try:
1658 return info 1671 pep = service.delegated
1659 1672 except AttributeError:
1660 d = defer.succeed(nodeIdentifier) 1673 pep = False
1661 d.addCallback(self.backend.getNodeType) 1674 recipient = None
1662 d.addCallback(saveType) 1675 else:
1663 d.addCallback(self.backend.getNodeMetaData) 1676 recipient = service if pep else None
1664 d.addCallback(saveMetaData) 1677 return defer.ensureDeferred(
1665 d.addErrback(trapNotFound) 1678 self._getInfo(
1666 d.addErrback(self._mapErrors) 1679 requestor, service, nodeIdentifier, pep, recipient
1667 return d 1680 )
1668 1681 )
1669 def getNodes(self, requestor, service, nodeIdentifier): 1682
1683 async def _getNodes(self, requestor, service, nodeIdentifier):
1670 """return nodes for disco#items 1684 """return nodes for disco#items
1671 1685
1672 Pubsub/PEP nodes will be returned if disco node is not specified 1686 Pubsub/PEP nodes will be returned if disco node is not specified
1673 else Pubsub/PEP items will be returned 1687 else Pubsub/PEP items will be returned
1674 (according to what requestor can access) 1688 (according to what requestor can access)
1677 pep = service.pep 1691 pep = service.pep
1678 except AttributeError: 1692 except AttributeError:
1679 pep = False 1693 pep = False
1680 1694
1681 if service.resource: 1695 if service.resource:
1682 return defer.succeed([]) 1696 return []
1683 1697
1684 if nodeIdentifier: 1698 if nodeIdentifier:
1685 d = self.backend.getItemsIds(nodeIdentifier, 1699 items = await self.backend.getItemsIds(
1686 requestor, 1700 nodeIdentifier,
1687 [], 1701 requestor,
1688 requestor.userhostJID() == service, 1702 [],
1689 None, 1703 requestor.userhostJID() == service,
1690 None, 1704 None,
1691 pep, 1705 None,
1692 service) 1706 pep,
1707 service
1708 )
1693 # items must be set as name, not node 1709 # items must be set as name, not node
1694 d.addCallback(lambda items: [(None, item) for item in items]) 1710 return [(None, item) for item in items]
1695
1696 else: 1711 else:
1697 d = self.backend.getNodes(requestor.userhostJID(), 1712 try:
1698 pep, 1713 return await self.backend.getNodes(
1699 service) 1714 requestor.userhostJID(),
1700 return d.addErrback(self._mapErrors) 1715 pep,
1716 service
1717 )
1718 except failure.Failure as e:
1719 self._mapErrors(e)
1720 except Exception as e:
1721 self._mapErrors(failure.Failure(e))
1722
1723 def getNodes(self, requestor, service, nodeIdentifier):
1724 return defer.ensureDeferred(self._getNodes(requestor, service, nodeIdentifier))
1701 1725
1702 def getConfigurationOptions(self): 1726 def getConfigurationOptions(self):
1703 return self.backend.nodeOptions 1727 return self.backend.nodeOptions
1704 1728
1705 def _publish_errb(self, failure, request): 1729 def _publish_errb(self, failure, request):