diff sat_pubsub/privilege.py @ 293:b96a4ac25f8b

privilege: added methods to send privileged messages and notifications
author Goffi <goffi@goffi.org>
date Sun, 16 Aug 2015 01:15:13 +0200
parents 2f87fa282dfd
children 5d7c3787672e
line wrap: on
line diff
--- a/sat_pubsub/privilege.py	Sun Aug 16 01:13:23 2015 +0200
+++ b/sat_pubsub/privilege.py	Sun Aug 16 01:15:13 2015 +0200
@@ -25,10 +25,15 @@
 
 from wokkel import xmppim
 from wokkel.compat import IQ
+from wokkel import pubsub
+from wokkel.iwokkel import IPubSubService
 from wokkel.subprotocols import XMPPHandler
 from twisted.python import log
 from twisted.python import failure
+from twisted.words.xish import domish
+from twisted.words.protocols.jabber import jid
 
+FORWARDED_NS = 'urn:xmpp:forward:0'
 PRIV_ENT_NS = 'urn:xmpp:privilege:1'
 PRIV_ENT_ADV_XPATH = '/message/privilege[@xmlns="{}"]'.format(PRIV_ENT_NS)
 ROSTER_NS = 'jabber:iq:roster'
@@ -56,12 +61,17 @@
         self._permissions = {PERM_ROSTER: 'none',
                              PERM_MESSAGE: 'none',
                              PERM_PRESENCE: 'none'}
+        self._pubsub_service = None
 
     @property
     def permissions(self):
         return self._permissions
 
     def connectionInitialized(self):
+        for handler in self.parent.handlers:
+            if IPubSubService.providedBy(handler):
+                self._pubsub_service = handler
+                break
         self.xmlstream.addObserver(PRIV_ENT_ADV_XPATH, self.onAdvertise)
 
     def onAdvertise(self, message):
@@ -91,6 +101,7 @@
 
         log.msg('Privileges updated: roster={roster}, message={message}, presence={presence}'.format(**self._permissions))
 
+    ## roster ##
 
     def getRoster(self, to_jid):
         """
@@ -117,3 +128,59 @@
         d = iq.send()
         d.addCallback(processRoster)
         return d
+
+    ## message ##
+
+    def sendMessage(self, to_jid, priv_message):
+        """ Send privileged message (in the name of the server)
+
+        @param to_jid(jid.JID): main message destinee
+        @param priv_message(domish.Element): privileged message
+        """
+        if self._permissions[PERM_MESSAGE] not in ('outgoing',):
+            log.msg("WARNING: permission not allowed to send privileged messages")
+            raise failure.Failure(NotAllowedError('privileged messages are not allowed'))
+
+        main_message = domish.Element((None, "message"))
+        main_message['to'] = to_jid.full()
+        privilege_elt = main_message.addElement((PRIV_ENT_NS, 'privilege'))
+        forwarded_elt = privilege_elt.addElement((FORWARDED_NS, 'forwarded'))
+        priv_message['xmlns'] = 'jabber:client'
+        forwarded_elt.addChild(priv_message)
+        self.send(main_message)
+
+    def notifyPublish(self, pep_jid, nodeIdentifier, notifications):
+        """Do notifications using privileges"""
+        for subscriber, subscriptions, items in notifications:
+            message = self._pubsub_service._createNotification('items', pep_jid,
+                                               nodeIdentifier, subscriber,
+                                               subscriptions)
+            for item in items:
+                item.uri = pubsub.NS_PUBSUB_EVENT
+                message.event.items.addChild(item)
+            self.sendMessage(jid.JID(pep_jid.host), message)
+
+
+    def notifyRetract(self, pep_jid, nodeIdentifier, notifications):
+        for subscriber, subscriptions, items in notifications:
+            message = self._pubsub_service._createNotification('items', pep_jid,
+                                               nodeIdentifier, subscriber,
+                                               subscriptions)
+            for item in items:
+                retract = domish.Element((None, "retract"))
+                retract['id'] = item['id']
+                message.event.items.addChild(retract)
+            self.sendMessage(jid.JID(pep_jid.host), message)
+
+
+    # def notifyDelete(self, service, nodeIdentifier, subscribers,
+    #                        redirectURI=None):
+    #     # TODO
+    #     for subscriber in subscribers:
+    #         message = self._createNotification('delete', service,
+    #                                            nodeIdentifier,
+    #                                            subscriber)
+    #         if redirectURI:
+    #             redirect = message.event.delete.addElement('redirect')
+    #             redirect['uri'] = redirectURI
+    #         self.send(message)