# HG changeset patch # User Goffi # Date 1634283127 -7200 # Node ID c9238fca1fb36ef01384ecdcc82b115d4a424a4e # Parent 607616f9ef5b2aa6d7be9426d7c8562283907502 backend: fix node creation permission check for PEP diff -r 607616f9ef5b -r c9238fca1fb3 sat_pubsub/backend.py --- a/sat_pubsub/backend.py Fri Oct 15 09:32:07 2021 +0200 +++ b/sat_pubsub/backend.py Fri Oct 15 09:32:07 2021 +0200 @@ -302,37 +302,26 @@ return options - def _checkAuth(self, node, requestor): + async def _checkAuth(self, node, requestor): """ Check authorisation of publishing in node for requestor """ - - def check(affiliation): - d = defer.succeed((affiliation, node)) - configuration = node.getConfiguration() - publish_model = configuration[const.OPT_PUBLISH_MODEL] - if publish_model == const.VAL_PMODEL_PUBLISHERS: - if affiliation not in ['owner', 'publisher']: + affiliation = await node.getAffiliation(requestor) + configuration = node.getConfiguration() + publish_model = configuration[const.OPT_PUBLISH_MODEL] + if publish_model == const.VAL_PMODEL_PUBLISHERS: + if affiliation not in ['owner', 'publisher']: + raise error.Forbidden() + elif publish_model == const.VAL_PMODEL_SUBSCRIBERS: + if affiliation not in ['owner', 'publisher']: + # we are in subscribers publish model, we must check that + # the requestor is a subscriber to allow him to publish + subscribed = await node.isSubscribed(requestor) + if not subscribed: raise error.Forbidden() - elif publish_model == const.VAL_PMODEL_SUBSCRIBERS: - if affiliation not in ['owner', 'publisher']: - # we are in subscribers publish model, we must check that - # the requestor is a subscriber to allow him to publish + elif publish_model != const.VAL_PMODEL_OPEN: + # publish_model must be publishers (default), subscribers or open. + raise ValueError('Unexpected value') - def checkSubscription(subscribed): - if not subscribed: - raise error.Forbidden() - return (affiliation, node) - - d.addCallback(lambda __: node.isSubscribed(requestor)) - d.addCallback(checkSubscription) - elif publish_model != const.VAL_PMODEL_OPEN: - # publish_model must be publishers (default), subscribers or open. - raise ValueError('Unexpected value') - - return d - - d = node.getAffiliation(requestor) - d.addCallback(check) - return d + return (affiliation, node) def parseItemConfig(self, item): """Get and remove item configuration information @@ -705,7 +694,21 @@ def supportsInstantNodes(self): return True - def createNode(self, nodeIdentifier, requestor, options=None, pep=False, recipient=None): + async def _createNode( + self, + nodeIdentifier: Optional[str], + requestor: jid.JID, + options: Optional[dict] = None, + pep: bool = False, + recipient: Optional[jid.JID] = None + ) -> str: + if pep: + if recipient == self.server_jid: + if not self.isAdmin(requestor): + raise error.Forbidden() + elif requestor.userhostJID() != recipient.userhostJID(): + raise error.Forbidden() + if not nodeIdentifier: nodeIdentifier = 'generic/%s' % uuid.uuid4() @@ -718,9 +721,26 @@ config.update(options) # TODO: handle schema on creation - d = self.storage.createNode(nodeIdentifier, requestor, config, None, pep, recipient) - d.addCallback(lambda _: nodeIdentifier) - return d + await self.storage.createNode( + nodeIdentifier, requestor, config, None, pep, recipient + ) + return nodeIdentifier + + def createNode( + self, + nodeIdentifier: Optional[str], + requestor: jid.JID, + options: Optional[dict] = None, + pep: bool = False, + recipient: Optional[jid.JID] = None + ) -> defer.Deferred: + return defer.ensureDeferred(self._createNode( + nodeIdentifier=nodeIdentifier, + requestor=requestor, + options=options, + pep=pep, + recipient=recipient + )) def getDefaultConfiguration(self, nodeType): d = defer.succeed(self.storage.getDefaultConfiguration(nodeType))