view modules/mod_subscribe.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 6.1: Subscribe to a Node
exports.subscribe = {
	type: 'set',
	child: 'pubsub',
	ns: NS.PUBSUB,
	child2: 'subscribe',
	func: function(response, stanza, request, to) {
		if (!config.enabled('subscribe'))
			return makeError(response, errors.sub.subscribe.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 configuration = storage.getConfiguration(nodeID);
		if (!configuration['pubsub#subscribe'])
			return makeError(response, errors.sub.subscribe.not_supported.n);

		var affil = storage.getAffiliation(toBareJID(to), nodeID);
		if (affil == 'publish-only' || affil == 'outcast')
			return makeError(response, errors.pub.publish.insufficient_privileges.n);

		var jid = request.getAttribute('jid');
		if (!jid || toBareJID(jid) != toBareJID(to))
			return makeError(response, errors.sub.subscribe.jids_do_not_match.n);

		/*
		// SECTION 6.3.7
		var options = pubsub.getChild('options');
		if (options && config.enabled('subscription-options')) {
			if (options.getAttribute('node') || options.getAttribute('jid'))
				return makeError(response, errors.bad_request.n);

			var x = options.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 (typeof form == 'number')
				return makeError(response, form);

			var conf = form;
		}*/

		var subID;
		if (configuration['pubsub#access_model'] == 'open') {
			subID = storage.subscribe(nodeID, jid, 'subscribe');
			if (typeof subID == 'number')
				return makeError(response, subID);
		} else if (configuration['pubsub#access_model'] == 'authorize') {
			subID = storage.subscribe(nodeID, jid, 'pending');
			if (typeof subID == 'number')
				return makeError(response, subID);

			var affiliates = storage.getAffiliationsFromNodeID(nodeID);
			var form = forms.build('form', 'subscribe_authorization', {allow: false, node: nodeID, subscriber_jid: jid}, true); //168

			for (var i in affiliates) {
				if (affiliates[i] == 'super-owner' || affiliates[i] == 'owner') {
					var message = xmpp.message({to: i}).cnode(form);
					conn.send(message); // FIXME: impossible à faire d’ici
				}
			}
		} else if (configuration['pubsub#access_model'] == 'whitelist') {
			var affil = storage.getAffiliation(jid, nodeID);
			if (affil != 'super-owner' && affil != 'owner' && affil != 'publisher' && affil != 'member')
				return makeError(response, errors.sub.subscribe.not_on_whitelist.n);

			subID = storage.subscribe(nodeID, jid);
			if (typeof subID == 'number')
				return makeError(response, subID);
		}

		response.c('pubsub', {xmlns: NS.PUBSUB})
			.c('subscription', {node: nodeID, jid: jid, subid: subID.subid, subscription: subID.type});

		if (config.enabled('last-published')) {
			var last = storage.getLastItem(nodeID);
			if (typeof last != 'number') {
				var item = storage.getItem(nodeID, last);
				if (typeof item != 'number') {
					var attr = {};
					attr[last] = {content: item};
					notifs.send(jid, 'items', nodeID, attr);
				}
			}
		}

		return response;
	}
}

// SECTION 6.2: Unsubscribe from a Node
exports.unsubscribe = {
	type: 'set',
	child: 'pubsub',
	ns: NS.PUBSUB,
	child2: 'unsubscribe',
	func: function(response, stanza, request, to) {
		if (!config.enabled('subscribe'))
			return makeError(response, errors.sub.subscribe.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 jid = request.getAttribute('jid');
		if (!jid || toBareJID(jid) != toBareJID(to))
			return makeError(response, errors.sub.unsubscribe.insufficient_privileges.n);

		var subID = storage.subscribe(nodeID, jid, 'none');
		if (typeof subID == 'number')
			return makeError(response, subID);

		return response;
	}
}