# HG changeset patch # User Goffi # Date 1367792797 -7200 # Node ID f0cd02c032b32290bc314330bd54e3a973b8e3a3 # Parent 6fe7da6b4b32142a278a1694dbe37afe5889b601 publish model management diff -r 6fe7da6b4b32 -r f0cd02c032b3 db/pubsub.sql --- a/db/pubsub.sql Mon May 06 00:11:44 2013 +0200 +++ b/db/pubsub.sql Mon May 06 00:26:37 2013 +0200 @@ -13,7 +13,9 @@ persist_items boolean, deliver_payloads boolean NOT NULL DEFAULT TRUE, send_last_published_item text NOT NULL DEFAULT 'on_sub' - CHECK (send_last_published_item IN ('never', 'on_sub')) + CHECK (send_last_published_item IN ('never', 'on_sub')), + publish_model text NOT NULL DEFAULT 'publishers' + CHECK (publish_model IN ('publishers', 'subscribers', 'open')) ); INSERT INTO nodes (node, node_type) values ('', 'collection'); diff -r 6fe7da6b4b32 -r f0cd02c032b3 sat_pubsub/backend.py --- 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'] diff -r 6fe7da6b4b32 -r f0cd02c032b3 sat_pubsub/const.py --- a/sat_pubsub/const.py Mon May 06 00:11:44 2013 +0200 +++ b/sat_pubsub/const.py Mon May 06 00:26:37 2013 +0200 @@ -57,7 +57,12 @@ NS_ITEM_CONFIG = "http://jabber.org/protocol/pubsub#item-config" OPT_ACCESS_MODEL = 'pubsub#access_model' OPT_ROSTER_GROUPS_ALLOWED = 'pubsub#roster_groups_allowed' +OPT_PUBLISH_MODEL = 'pubsub#publish_model' VAL_AMODEL_OPEN = 'open' VAL_AMODEL_ROSTER = 'roster' VAL_AMODEL_JID = 'jid' VAL_AMODEL_DEFAULT = VAL_AMODEL_OPEN +VAL_PMODEL_PUBLISHERS = 'publishers' +VAL_PMODEL_SUBSCRIBERS = 'subscribers' +VAL_PMODEL_OPEN = 'open' +VAL_PMODEL_DEFAULT = VAL_PMODEL_PUBLISHERS diff -r 6fe7da6b4b32 -r f0cd02c032b3 sat_pubsub/pgsql_storage.py --- a/sat_pubsub/pgsql_storage.py Mon May 06 00:11:44 2013 +0200 +++ b/sat_pubsub/pgsql_storage.py Mon May 06 00:26:37 2013 +0200 @@ -74,11 +74,13 @@ "pubsub#deliver_payloads": True, "pubsub#send_last_published_item": 'on_sub', const.OPT_ACCESS_MODEL: const.VAL_AMODEL_DEFAULT, + const.OPT_PUBLISH_MODEL: const.VAL_PMODEL_DEFAULT, }, 'collection': { "pubsub#deliver_payloads": True, "pubsub#send_last_published_item": 'on_sub', const.OPT_ACCESS_MODEL: const.VAL_AMODEL_DEFAULT, + const.OPT_PUBLISH_MODEL: const.VAL_PMODEL_DEFAULT, } } @@ -96,6 +98,7 @@ deliver_payloads, send_last_published_item, access_model, + publish_model FROM nodes WHERE node=%s""", (nodeIdentifier,)) @@ -110,6 +113,7 @@ 'pubsub#deliver_payloads': row[2], 'pubsub#send_last_published_item': row[3], const.OPT_ACCESS_MODEL:row[4], + const.OPT_PUBLISH_MODEL:row[5], } node = LeafNode(nodeIdentifier, configuration) node.dbpool = self.dbpool @@ -119,6 +123,7 @@ 'pubsub#deliver_payloads': row[2], 'pubsub#send_last_published_item': row[3], const.OPT_ACCESS_MODEL: row[4], + const.OPT_PUBLISH_MODEL:row[5], } node = CollectionNode(nodeIdentifier, configuration) node.dbpool = self.dbpool @@ -145,14 +150,15 @@ try: cursor.execute("""INSERT INTO nodes (node, node_type, persist_items, - deliver_payloads, send_last_published_item, access_model) + deliver_payloads, send_last_published_item, access_model, publish_model) VALUES - (%s, 'leaf', %s, %s, %s, %s)""", + (%s, 'leaf', %s, %s, %s, %s, %s)""", (nodeIdentifier, config['pubsub#persist_items'], config['pubsub#deliver_payloads'], config['pubsub#send_last_published_item'], config[const.OPT_ACCESS_MODEL], + config[const.OPT_PUBLISH_MODEL], ) ) except cursor._pool.dbapi.IntegrityError: