Esempio n. 1
0
    def info(self, requestor, target, nodeIdentifier):
        """
        Gather data for a disco info request.

        @param requestor: The entity that sent the request.
        @type requestor: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param target: The entity the request was sent to.
        @type target: L{JID<twisted.words.protocols.jabber.jid.JID>}
        @param nodeIdentifier: The optional node being queried, or C{''}.
        @type nodeIdentifier: C{unicode}
        @return: Deferred with the gathered results from sibling handlers.
        @rtype: L{defer.Deferred}
        """

        xmpp_manager = self.parent.manager

        if target.host not in xmpp_manager.domains | xmpp_manager.muc_domains:
            return defer.fail(StanzaError('service-unavailable'))

        elements = [disco.DiscoFeature(disco.NS_DISCO_INFO),
                    disco.DiscoFeature(disco.NS_DISCO_ITEMS),
                    disco.DiscoFeature('http://sylkserver.com')]

        if target.host in xmpp_manager.muc_domains:
            elements.append(disco.DiscoIdentity('conference', 'text', 'SylkServer Chat Service'))
            elements.append(disco.DiscoFeature('http://jabber.org/protocol/muc'))
            elements.append(disco.DiscoFeature('urn:ietf:rfc:3264'))
            elements.append(disco.DiscoFeature('urn:xmpp:coin'))
            elements.append(disco.DiscoFeature(jingle.NS_JINGLE))
            elements.append(disco.DiscoFeature(jingle.NS_JINGLE_APPS_RTP))
            elements.append(disco.DiscoFeature(jingle.NS_JINGLE_APPS_RTP_AUDIO))
            #elements.append(disco.DiscoFeature(jingle.NS_JINGLE_APPS_RTP_VIDEO))
            elements.append(disco.DiscoFeature(jingle.NS_JINGLE_ICE_UDP_TRANSPORT))
            elements.append(disco.DiscoFeature(jingle.NS_JINGLE_RAW_UDP_TRANSPORT))
            if target.user:
                # We can't say much more here, because the actual conference may end up on a different server
                elements.append(disco.DiscoFeature('muc_temporary'))
                elements.append(disco.DiscoFeature('muc_unmoderated'))
        else:
            elements.append(disco.DiscoFeature(ping.NS_PING))
            if not target.user:
                elements.append(disco.DiscoIdentity('gateway', 'simple', 'SylkServer'))
                elements.append(disco.DiscoIdentity('server', 'im', 'SylkServer'))
            else:
                elements.append(disco.DiscoIdentity('client', 'pc'))
                elements.append(disco.DiscoFeature('http://jabber.org/protocol/caps'))
                elements.append(disco.DiscoFeature('http://jabber.org/protocol/chatstates'))
                elements.append(disco.DiscoFeature('urn:ietf:rfc:3264'))
                elements.append(disco.DiscoFeature('urn:xmpp:coin'))
                elements.append(disco.DiscoFeature(jingle.NS_JINGLE))
                elements.append(disco.DiscoFeature(jingle.NS_JINGLE_APPS_RTP))
                elements.append(disco.DiscoFeature(jingle.NS_JINGLE_APPS_RTP_AUDIO))
                #elements.append(disco.DiscoFeature(jingle.NS_JINGLE_APPS_RTP_VIDEO))
                elements.append(disco.DiscoFeature(jingle.NS_JINGLE_ICE_UDP_TRANSPORT))
                elements.append(disco.DiscoFeature(jingle.NS_JINGLE_RAW_UDP_TRANSPORT))

        return defer.succeed(elements)
Esempio n. 2
0
    def test_discoServerSupport(self):
        """Disco support from client to server.
        """
        test_srv = 'shakespeare.lit'

        def cb(query):
            # check namespace
            self.failUnless(query.uri == disco.NS_INFO, 'Wrong namespace')

        d = self.protocol.disco(test_srv)
        d.addCallback(cb)

        iq = self.stub.output[-1]

        # send back a response
        response = toResponse(iq, 'result')
        response.addElement('query', disco.NS_INFO)
        # need to add information to response
        response.query.addChild(disco.DiscoFeature(muc.NS_MUC))
        response.query.addChild(
            disco.DiscoIdentity(category='conference',
                                name='Macbeth Chat Service',
                                type='text'))

        self.stub.send(response)
        return d
Esempio n. 3
0
    def test_infoNotDeferred(self):
        """
        C{info} should gather disco info from sibling handlers.
        """
        discoItems = [
            disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'),
            disco.DiscoFeature('jabber:iq:version')
        ]

        class DiscoResponder(XMPPHandler):
            implements(disco.IDisco)

            def getDiscoInfo(self, requestor, target, nodeIdentifier):
                if not nodeIdentifier:
                    return discoItems
                else:
                    return []

        def cb(result):
            self.assertEquals(discoItems, result)

        self.service.parent = [self.service, DiscoResponder()]
        d = self.service.info(JID('*****@*****.**'), JID('example.com'), '')
        d.addCallback(cb)
        return d
Esempio n. 4
0
 def test_init(self):
     """
     Test initialization with a category, type and name.
     """
     identity = disco.DiscoIdentity(u'conference', u'text', u'The chatroom')
     self.assertEqual(u'conference', identity.category)
     self.assertEqual(u'text', identity.type)
     self.assertEqual(u'The chatroom', identity.name)
Esempio n. 5
0
 def getDiscoInfo(self, requestor, target, nodeIdentifier):
     if not nodeIdentifier:
         return defer.succeed([
             disco.DiscoIdentity('dummy', 'generic', 'Generic Dummy Entity'),
             disco.DiscoFeature('jabber:iq:version')
         ])
     else:
         return defer.succeed([])
Esempio n. 6
0
        def info(requestor, target, nodeIdentifier):
            self.assertEqual(JID('*****@*****.**'), requestor)

            return defer.succeed([
                disco.DiscoIdentity('dummy', 'generic',
                                    'Generic Dummy Entity'),
                disco.DiscoFeature('jabber:iq:version')
            ])
Esempio n. 7
0
    def getDiscoInfo(self, requestor, target, node):
        info = set()

        if node:
            info.add(disco.DiscoIdentity('automation', 'command-node'))
            info.add(disco.DiscoFeature('http://jabber.org/protocol/commands'))
        else:
            info.add(disco.DiscoFeature(NS_CMD))

        return defer.succeed(info)
Esempio n. 8
0
    def getDiscoInfo(self, requestor, target, nodeIdentifier=''):
        def toInfo(nodeInfo):
            if not nodeInfo:
                return

            (nodeType, metaData) = nodeInfo['type'], nodeInfo['meta-data']
            info.append(disco.DiscoIdentity('pubsub', nodeType))
            if metaData:
                form = data_form.Form(formType="result",
                                      formNamespace=NS_PUBSUB_META_DATA)
                form.addField(
                    data_form.Field(
                        var='pubsub#node_type',
                        value=nodeType,
                        label='The type of node (collection or leaf)'))

                for metaDatum in metaData:
                    form.addField(data_form.Field.fromDict(metaDatum))

                info.append(form)

            return

        info = []

        request = PubSubRequest('discoInfo')

        if self.resource is not None:
            resource = self.resource.locateResource(request)
            identity = resource.discoIdentity
            features = resource.features
            getInfo = resource.getInfo
        else:
            category = self.discoIdentity['category']
            idType = self.discoIdentity['type']
            name = self.discoIdentity['name']
            identity = disco.DiscoIdentity(category, idType, name)
            features = self.pubSubFeatures
            getInfo = self.getNodeInfo

        if not nodeIdentifier:
            info.append(identity)
            info.append(disco.DiscoFeature(disco.NS_DISCO_ITEMS))
            info.extend([
                disco.DiscoFeature("%s#%s" % (NS_PUBSUB, feature))
                for feature in features
            ])

        d = defer.maybeDeferred(getInfo, requestor, target, nodeIdentifier
                                or '')
        d.addCallback(toInfo)
        d.addErrback(log.err)
        d.addCallback(lambda _: info)
        return d
Esempio n. 9
0
    def test_toElementWithoutName(self):
        """
        Test proper rendering to a DOM representation without a name.

        The returned element should be properly named and have C{conference},
        C{type} attributes, no C{name} attribute.
        """
        identity = disco.DiscoIdentity(u'conference', u'text')
        element = identity.toElement()
        self.assertEqual(NS_DISCO_INFO, element.uri)
        self.assertEqual(u'identity', element.name)
        self.assertEqual(u'conference', element.getAttribute(u'category'))
        self.assertEqual(u'text', element.getAttribute(u'type'))
        self.assertFalse(element.hasAttribute(u'name'))
Esempio n. 10
0
    def test_toElement(self):
        """
        Test proper rendering to a DOM representation.

        The returned element should be properly named and have C{conference},
        C{type}, and C{name} attributes.
        """
        identity = disco.DiscoIdentity(u'conference', u'text', u'The chatroom')
        element = identity.toElement()
        self.assertEqual(NS_DISCO_INFO, element.uri)
        self.assertEqual(u'identity', element.name)
        self.assertEqual(u'conference', element.getAttribute(u'category'))
        self.assertEqual(u'text', element.getAttribute(u'type'))
        self.assertEqual(u'The chatroom', element.getAttribute(u'name'))
Esempio n. 11
0
 def getDiscoInfo(self, requestor, target, nodeIdentifier):
     if not nodeIdentifier:
         return defer.succeed([
             disco.DiscoIdentity('sms', 'generic', 'SMS77.de Gateway'),
             disco.DiscoFeature('jabber:iq:version'),
             disco.DiscoFeature('jabber:iq:register'),
             #disco.DiscoFeature('jabber:iq:search'),
             disco.DiscoFeature('jabber:iq:gateway'),
             disco.DiscoFeature('vcard-temp'),
             disco.DiscoFeature('http://jabber.org/protocol/disco#info'),
             disco.DiscoFeature('http://jabber.org/protocol/disco#items')
         ])
     else:
         return defer.succeed([])
Esempio n. 12
0
File: xmpp.py Progetto: monoid/w4
    def getDiscoInfo(self, req, target, ni):
        group, nick = resolveGroup(target)
        if group in self.groupset and not ni:
            gr = self.groupset.get(group)
            if nick:
                if XMPPChannel.isMember(req.full(), gr):
                    # TODO
                    raise error.StanzaError('service-unavailable')
                else:
                    raise error.StanzaError('bad-request')
            else:
                di = [disco.DiscoIdentity(u'conference', u'text', name=gr.name)]
                for f in gr.getDiscoFeatures():
                    di.append(f)

                return di
        else:
            # TODO
            raise error.StanzaError('not-implemented')
Esempio n. 13
0
        def toInfo(nodeInfo):
            if not nodeInfo:
                return

            (nodeType, metaData) = nodeInfo['type'], nodeInfo['meta-data']
            info.append(disco.DiscoIdentity('pubsub', nodeType))
            if metaData:
                form = data_form.Form(formType="result",
                                      formNamespace=NS_PUBSUB_META_DATA)
                form.addField(
                        data_form.Field(
                            var='pubsub#node_type',
                            value=nodeType,
                            label='The type of node (collection or leaf)'
                        )
                )

                for metaDatum in metaData:
                    form.addField(data_form.Field.fromDict(metaDatum))

                info.append(form.toElement())
Esempio n. 14
0
    def test_toElementChildren(self):
        """
        Test C{toElement} creates a DOM with proper childs.
        """
        info = disco.DiscoInfo()
        info.append(disco.DiscoFeature(u'jabber:iq:register'))
        info.append(disco.DiscoIdentity(u'conference', u'text'))
        info.append(data_form.Form(u'result'))
        element = info.toElement()

        featureElements = domish.generateElementsQNamed(
            element.children, u'feature', NS_DISCO_INFO)
        self.assertEqual(1, len(list(featureElements)))

        identityElements = domish.generateElementsQNamed(
            element.children, u'identity', NS_DISCO_INFO)
        self.assertEqual(1, len(list(identityElements)))

        extensionElements = domish.generateElementsQNamed(
            element.children, u'x', data_form.NS_X_DATA)
        self.assertEqual(1, len(list(extensionElements)))
Esempio n. 15
0
    def getDiscoInfo(self, requestor, target, nodeIdentifier):
        info = []

        if not nodeIdentifier:
            info.append(disco.DiscoIdentity(**self.discoIdentity))

            info.append(disco.DiscoFeature(disco.NS_ITEMS))
            info.extend([disco.DiscoFeature("%s#%s" % (NS_PUBSUB, feature))
                         for feature in self.pubSubFeatures])

        def toInfo(nodeInfo):
            if not nodeInfo:
                return

            (nodeType, metaData) = nodeInfo['type'], nodeInfo['meta-data']
            info.append(disco.DiscoIdentity('pubsub', nodeType))
            if metaData:
                form = data_form.Form(formType="result",
                                      formNamespace=NS_PUBSUB_META_DATA)
                form.addField(
                        data_form.Field(
                            var='pubsub#node_type',
                            value=nodeType,
                            label='The type of node (collection or leaf)'
                        )
                )

                for metaDatum in metaData:
                    form.addField(data_form.Field.fromDict(metaDatum))

                info.append(form.toElement())

        d = self.getNodeInfo(requestor, target, nodeIdentifier or '')
        d.addCallback(toInfo)
        d.addBoth(lambda result: info)
        return d
Esempio n. 16
0
class PubSubResource(object):

    implements(IPubSubResource)

    features = []
    discoIdentity = disco.DiscoIdentity('pubsub',
                                        'service',
                                        'Publish-Subscribe Service')


    def locateResource(self, request):
        return self


    def getInfo(self, requestor, service, nodeIdentifier):
        return defer.succeed(None)


    def getNodes(self, requestor, service, nodeIdentifier):
        return defer.succeed([])


    def getConfigurationOptions(self):
        return {}


    def publish(self, request):
        return defer.fail(Unsupported('publish'))


    def subscribe(self, request):
        return defer.fail(Unsupported('subscribe'))


    def unsubscribe(self, request):
        return defer.fail(Unsupported('subscribe'))


    def subscriptions(self, request):
        return defer.fail(Unsupported('retrieve-subscriptions'))


    def affiliations(self, request):
        return defer.fail(Unsupported('retrieve-affiliations'))


    def create(self, request):
        return defer.fail(Unsupported('create-nodes'))


    def default(self, request):
        return defer.fail(Unsupported('retrieve-default'))


    def configureGet(self, request):
        return defer.fail(Unsupported('config-node'))


    def configureSet(self, request):
        return defer.fail(Unsupported('config-node'))


    def items(self, request):
        return defer.fail(Unsupported('retrieve-items'))


    def retract(self, request):
        return defer.fail(Unsupported('retract-items'))


    def purge(self, request):
        return defer.fail(Unsupported('purge-nodes'))


    def delete(self, request):
        return defer.fail(Unsupported('delete-nodes'))


    def affiliationsGet(self, request):
        return defer.fail(Unsupported('modify-affiliations'))


    def affiliationsSet(self, request):
        return defer.fail(Unsupported('modify-affiliations'))


    def subscriptionsGet(self, request):
        return defer.fail(Unsupported('manage-subscriptions'))


    def subscriptionsSet(self, request):
        return defer.fail(Unsupported('manage-subscriptions'))
Esempio n. 17
0
class PubSubResourceFromBackend(PubSubResource):
    """
    Adapts a backend to an xmpp publish-subscribe service.
    """

    features = [
        "config-node",
        "create-nodes",
        "delete-any",
        "delete-nodes",
        "item-ids",
        "meta-data",
        "publish",
        "purge-nodes",
        "retract-items",
        "retrieve-affiliations",
        "retrieve-default",
        "retrieve-items",
        "retrieve-subscriptions",
        "subscribe",
    ]

    discoIdentity = disco.DiscoIdentity('pubsub',
                                        'service',
                                        'Idavoll publish-subscribe service')

    pubsubService = None

    _errorMap = {
        error.NodeNotFound: ('item-not-found', None, None),
        error.NodeExists: ('conflict', None, None),
        error.Forbidden: ('forbidden', None, None),
        error.ItemForbidden: ('bad-request', 'item-forbidden', None),
        error.ItemRequired: ('bad-request', 'item-required', None),
        error.NoInstantNodes: ('not-acceptable',
                               'unsupported',
                               'instant-nodes'),
        error.NotSubscribed: ('unexpected-request', 'not-subscribed', None),
        error.InvalidConfigurationOption: ('not-acceptable', None, None),
        error.InvalidConfigurationValue: ('not-acceptable', None, None),
        error.NodeNotPersistent: ('feature-not-implemented',
                                  'unsupported',
                                  'persistent-node'),
        error.NoRootNode: ('bad-request', None, None),
        error.NoCollections: ('feature-not-implemented',
                              'unsupported',
                              'collections'),
        error.NoPublishing: ('feature-not-implemented',
                             'unsupported',
                             'publish'),
    }

    def __init__(self, backend):
        PubSubResource.__init__(self)

        self.backend = backend
        self.hideNodes = False

        self.backend.registerNotifier(self._notify)
        self.backend.registerPreDelete(self._preDelete)

        if self.backend.supportsInstantNodes():
            self.features.append("instant-nodes")

        if self.backend.supportsOutcastAffiliation():
            self.features.append("outcast-affiliation")

        if self.backend.supportsPersistentItems():
            self.features.append("persistent-items")

        if self.backend.supportsPublisherAffiliation():
            self.features.append("publisher-affiliation")


    def _notify(self, data):
        items = data['items']
        nodeIdentifier = data['nodeIdentifier']
        if 'subscription' not in data:
            d = self.backend.getNotifications(nodeIdentifier, items)
        else:
            subscription = data['subscription']
            d = defer.succeed([(subscription.subscriber, [subscription],
                                items)])
        d.addCallback(lambda notifications: self.pubsubService.notifyPublish(
                                                self.serviceJID,
                                                nodeIdentifier,
                                                notifications))


    def _preDelete(self, data):
        nodeIdentifier = data['nodeIdentifier']
        redirectURI = data.get('redirectURI', None)
        d = self.backend.getSubscribers(nodeIdentifier)
        d.addCallback(lambda subscribers: self.pubsubService.notifyDelete(
                                                self.serviceJID,
                                                nodeIdentifier,
                                                subscribers,
                                                redirectURI))
        return d


    def _mapErrors(self, failure):
        e = failure.trap(*self._errorMap.keys())

        condition, pubsubCondition, feature = self._errorMap[e]
        msg = failure.value.msg

        if pubsubCondition:
            exc = PubSubError(condition, pubsubCondition, feature, msg)
        else:
            exc = StanzaError(condition, text=msg)

        raise exc


    def getInfo(self, requestor, service, nodeIdentifier):
        info = {}

        def saveType(result):
            info['type'] = result
            return nodeIdentifier

        def saveMetaData(result):
            info['meta-data'] = result
            return info

        def trapNotFound(failure):
            failure.trap(error.NodeNotFound)
            return info

        d = defer.succeed(nodeIdentifier)
        d.addCallback(self.backend.getNodeType)
        d.addCallback(saveType)
        d.addCallback(self.backend.getNodeMetaData)
        d.addCallback(saveMetaData)
        d.addErrback(trapNotFound)
        d.addErrback(self._mapErrors)
        return d


    def getNodes(self, requestor, service, nodeIdentifier):
        if service.resource:
            return defer.succeed([])
        d = self.backend.getNodes()
        return d.addErrback(self._mapErrors)


    def getConfigurationOptions(self):
        return self.backend.nodeOptions


    def publish(self, request):
        d = self.backend.publish(request.nodeIdentifier,
                                 request.items,
                                 request.sender)
        return d.addErrback(self._mapErrors)


    def subscribe(self, request):
        d = self.backend.subscribe(request.nodeIdentifier,
                                   request.subscriber,
                                   request.sender)
        return d.addErrback(self._mapErrors)


    def unsubscribe(self, request):
        d = self.backend.unsubscribe(request.nodeIdentifier,
                                     request.subscriber,
                                     request.sender)
        return d.addErrback(self._mapErrors)


    def subscriptions(self, request):
        d = self.backend.getSubscriptions(request.sender)
        return d.addErrback(self._mapErrors)


    def affiliations(self, request):
        d = self.backend.getAffiliations(request.sender)
        return d.addErrback(self._mapErrors)


    def create(self, request):
        d = self.backend.createNode(request.nodeIdentifier,
                                    request.sender)
        return d.addErrback(self._mapErrors)


    def default(self, request):
        d = self.backend.getDefaultConfiguration(request.nodeType)
        return d.addErrback(self._mapErrors)


    def configureGet(self, request):
        d = self.backend.getNodeConfiguration(request.nodeIdentifier)
        return d.addErrback(self._mapErrors)


    def configureSet(self, request):
        d = self.backend.setNodeConfiguration(request.nodeIdentifier,
                                              request.options,
                                              request.sender)
        return d.addErrback(self._mapErrors)


    def items(self, request):
        d = self.backend.getItems(request.nodeIdentifier,
                                  request.sender,
                                  request.maxItems,
                                  request.itemIdentifiers)
        return d.addErrback(self._mapErrors)


    def retract(self, request):
        d = self.backend.retractItem(request.nodeIdentifier,
                                     request.itemIdentifiers,
                                     request.sender)
        return d.addErrback(self._mapErrors)


    def purge(self, request):
        d = self.backend.purgeNode(request.nodeIdentifier,
                                   request.sender)
        return d.addErrback(self._mapErrors)


    def delete(self, request):
        d = self.backend.deleteNode(request.nodeIdentifier,
                                    request.sender)
        return d.addErrback(self._mapErrors)