diff modules/mod_publish.js @ 24:b80ab94da447

Add new modules files.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Mon, 01 Nov 2010 00:02:27 +0100
parents
children b2faacfefb90
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/modules/mod_publish.js
@@ -0,0 +1,130 @@
+var config = require('../configuration');
+var storage = require('../storage');
+var toBareJID = require('../util').toBareJID;
+var NS = require('../namespaces');
+
+// SECTION 7.1: Publish an Item to a Node
+exports.retrieveSub = {
+	type: 'set',
+	child: 'pubsub',
+	ns: NS.PUBSUB,
+	pschild: 'publish',
+	func: function(response, stanza, request, to) {
+		if (!config.enabled('publish'))
+			return makeError(response, errors.pub.publish.item_publication_not_supported.n);
+
+		var nodeID = request.getAttribute('node');
+		if (!nodeID || nodeID == '')
+			return makeError(response, errors.nodeid_required.n);
+
+		var autocreate = false;
+		if (!storage.existsNode(nodeID)) {
+			if (config.enabled('auto-create'))
+				autocreate = true;
+			else
+				return makeError(response, errors.node_does_not_exist.n);
+		}
+
+		var affil = storage.getAffiliation(toBareJID(to), nodeID);
+		if (typeof affil == 'number' && affil != errors.node_does_not_exist.n)
+			return makeError(response, affil);
+		if (!autocreate && affil != 'super-owner' && affil != 'owner' && affil != 'publisher' && affil != 'publish-only')
+			return makeError(response, errors.forbidden.n);
+
+		var item = request.getChild('item');
+		var itemID = item.getAttribute('id');
+		if (!config.enabled('item-ids') && itemID)
+			return makeError(response, errors.itemid_required.n);
+		itemID = itemID? itemID: utils.makeRandomId();
+
+		if (item.tags.length != 1)
+			return makeError(response, errors.pub.publish.bad_payload.n);
+
+		var conf = storage.getConfiguration(nodeID);
+		var publishOptions = pubsub.getChild('publish-options');
+		if (publishOptions && config.enabled('publish-options')) {
+			var x = publishOptions.getChild('x', 'jabber:x:data');
+			if (!x || x.getAttribute('type') != 'submit')
+				return makeError(response, errors.bad_request.n);
+
+			var form = forms.parse(x, true);
+			if (form.access_model != conf['pubsub#access_model'] && !autocreate)
+				return makeError(response, errors.pub.configuration.precondition.n);
+		}
+
+		if (!config.enabled('persistent-items')) {
+			var notifs = storage.purgeNode(nodeID);
+			if (typeof notifs == 'number')
+				return makeError(response, r);
+		}
+
+		if (autocreate) {
+			if (!form)
+				form = {};
+			form['pubsub#creator'] = toBareJID(to);
+
+			var r = storage.createNode(nodeID, form);
+			if (typeof r == 'number')
+				return makeError(response, r);
+		}
+
+		var content = item.getChild();
+
+		subscribers = storage.setItem(nodeID, itemID, content);
+		if (typeof subscribers == 'number')
+			return makeError(response, subscribers);
+
+		var attrs = {};
+		if (content)
+			attrs[itemID] = {content: content};
+		else
+			attrs[itemID] = {};
+		notifs.send(subscribers, 'items', nodeID, attrs);
+
+		response.c('pubsub', {xmlns: NS.PUBSUB})
+			.c('publish', {node: nodeID})
+			.c('item', {id: itemID});
+
+		return response;
+	}
+}
+
+// SECTION 7.2: Delete an Item from a Node
+exports.retrieveSub = {
+	type: 'set',
+	child: 'pubsub',
+	ns: NS.PUBSUB,
+	pschild: 'retract',
+	func: function(response, stanza, request, to) {
+		if (!config.enabled('retract-items'))
+			return makeError(response, errors.pub.retract.item_deletion_not_supported.n);
+
+		var nodeID = request.getAttribute('node');
+		if (!nodeID || nodeID == '')
+			return makeError(response, errors.nodeid_required.n);
+		if (!storage.existsNode(nodeID))
+			return makeError(response, errors.node_does_not_exist.n);
+
+		var item = request.getChild('item');
+		if (!item)
+			return makeError(response, errors.pub.retract.item_or_itemid_required.n);
+
+		var itemID = item.getAttribute('id')
+		if (!itemID || itemID == '')
+			return makeError(response, errors.pub.retract.item_or_itemid_required.n);
+
+		var affil = storage.getAffiliation(toBareJID(to), nodeID);
+		if (affil != 'super-owner' && affil != 'owner' && affil != 'publish-only')
+			return makeError(response, errors.forbidden.n);
+
+		var subscribers = storage.deleteItem(nodeID, itemID);
+		if (typeof subscribers == 'number')
+			return makeError(response, subscribers);
+
+		var attrs = {};
+		attrs[itemID] = {};
+		notifs.send(subscribers, 'items', nodeID, attrs, 'retract')
+
+		return response;
+	}
+}