diff sat_pubsub/backend.py @ 260:f0cd02c032b3

publish model management
author Goffi <goffi@goffi.org>
date Mon, 06 May 2013 00:26:37 +0200
parents 6fe7da6b4b32
children 65d4fed44edf
line wrap: on
line diff
--- a/sat_pubsub/backend.py	Mon May 06 00:11:44 2013 +0200
+++ b/sat_pubsub/backend.py	Mon May 06 00:26:37 2013 +0200
@@ -129,6 +129,15 @@
                 {"type": "list-multi",
                  "label": "Groups of the roster allowed to access the node",
                 },
+            const.OPT_PUBLISH_MODEL:
+                {"type": "list-single",
+                 "label": "Who can publish to this node",
+                 "options": {
+                     const.VAL_PMODEL_OPEN: "Everybody can publish",
+                     const.VAL_PMODEL_PUBLISHERS: "Only owner and publishers can publish",
+                     const.VAL_PMODEL_SUBSCRIBERS: "Everybody which subscribed to the node",
+                     }
+                },
             }
 
     subscriptionOptions = {
@@ -168,6 +177,10 @@
         return True
 
 
+    def supportsPublishModel(self):
+        return True
+
+
     def getNodeType(self, nodeIdentifier):
         d = self.storage.getNode(nodeIdentifier)
         d.addCallback(lambda node: node.getType())
@@ -198,13 +211,35 @@
 
 
     def _checkAuth(self, node, requestor):
-        def check(affiliation, node):
-            if affiliation not in ['owner', 'publisher']:
-                raise error.Forbidden()
-            return node
+        """ Check authorisation of publishing in node for requestor """
+
+        def check(affiliation):
+            d = defer.succeed(node)
+            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
+
+                    def checkSubscription(subscribed):
+                        if not subscribed:
+                            raise error.Forbidden()
+                        return node
+
+                    d.addCallback(lambda ignore: node.isSubscribed(requestor))
+                    d.addCallback(checkSubscription)
+            elif publish_model != const.VAL_PMODEL_OPEN:
+                raise Exception('Unexpected value') # publish_model must be publishers (default), subscribers or open.
+
+            return d
 
         d = node.getAffiliation(requestor)
-        d.addCallback(check, node)
+        d.addCallback(check)
         return d
 
     def parseItemConfig(self, item):
@@ -747,6 +782,9 @@
         if self.backend.supportsGroupBlog():
             self.features.append("groupblog")
 
+        # if self.backend.supportsPublishModel():       #XXX: this feature is not really described in XEP-0060, we just can see it in examples
+        #     self.features.append("publish_model")     #     but it's necessary for microblogging comments (see XEP-0277)
+
     def _notify(self, data):
         items = data['items']
         node = data['node']