view modules/mod_publish.js @ 45:8b20f2efb939

Add an option to choose the host and port of the connection.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Tue, 08 Mar 2011 00:25:17 +0100
parents 023f767662d3
children 0d3f18bb1d36
line wrap: on
line source

/*
 *  Copyright (C) 2010  Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
 *
 *  This file is part of PSĜS, a PubSub server written in JavaScript.
 *
 *  PSĜS is free software: you can redistribute it and/or modify
 *  it under the terms of the GNU Affero General Public License as
 *  published by the Free Software Foundation, either version 3 of the
 *  License.
 *
 *  PSĜS is distributed in the hope that it will be useful,
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 *  GNU Affero General Public License for more details.
 *
 *  You should have received a copy of the GNU Affero General Public License
 *  along with PSĜS.  If not, see <http://www.gnu.org/licenses/>.
 */

'use strict';

// SECTION 7.1: Publish an Item to a Node
exports.publish = {
	type: 'set',
	child: 'pubsub',
	ns: NS.PUBSUB,
	child2: '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: fdsq.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 notifications = storage.purgeNode(nodeID);
			if (typeof notifications == '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.retract = {
	type: 'set',
	child: 'pubsub',
	ns: NS.PUBSUB,
	child2: '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;
	}
}