changeset 30:b2faacfefb90

Rewrite of the module manager; fix of some modules; fix of the directory backend.
author Emmanuel Gil Peyrot <linkmauve@linkmauve.fr>
date Thu, 04 Nov 2010 17:50:52 +0100
parents e007a6364bf0
children 13011b26181c
files backends/directory.js modules.js modules/mod_adhoc.js modules/mod_configure.js modules/mod_manage.js modules/mod_options.js modules/mod_owner.js modules/mod_publish.js modules/mod_retrieve.js modules/mod_subscribe.js psgxs.js
diffstat 11 files changed, 148 insertions(+), 71 deletions(-) [+]
line wrap: on
line diff
--- a/backends/directory.js
+++ b/backends/directory.js
@@ -54,26 +54,19 @@ backend.save = function(dir) {
 
 			var inspect = require('sys').inspect;
 
+			for (var nodeID in data)
+				fs.writeFile(dir+'/'+nodeID+'.json', inspect(data[nodeID], false, null));
+
 			var toDelete = [];
 
 			for (var i in files) {
-				var nodeID = files[i];
-				if (nodeID in data) {
-					fs.writeFile(dir+'/'+nodeID+'.json', inspect(data[nodeID], false, null));
-					delete data[nodeID];
-				} else
-					toDelete.push(nodeID);
+				var file = files[i];
+				if (!(file.replace(/\.json$/, '') in data))
+					toDelete.push(file);
 			}
 
-			for (var nodeID in data) {
-				inspect(nodeID);
-				inspect(data[nodeID]);
-				fs.writeFile(dir+'/'+nodeID+'.json', inspect(data[nodeID], false, null));
-			}
-
-			for (var nodeID in toDelete) {
-				fs.unlink(toDelete[nodeID]);
-			}
+			for (var nodeID in toDelete)
+				fs.unlink(dir+'/'+toDelete[nodeID]);
 		});
 	});
 }
--- a/modules.js
+++ b/modules.js
@@ -9,6 +9,10 @@ for (var i in files) {
 		continue;
 
 	var module = require('./modules/' + files[i]);
-	for (var j in module)
+	for (var j in module) {
+		if (typeof modules[j] != 'undefined')
+			console.log('WARNING: module '+j+' already loaded.');
+
 		modules[j] = module[j];
+	}
 }
--- a/modules/mod_adhoc.js
+++ b/modules/mod_adhoc.js
@@ -7,7 +7,7 @@ var toBareJID = require('../util').toBar
 var NS = require('../namespaces');
 
 // XEP-0050: Ad-Hoc Commands
-exports.configureSub = {
+exports.adHoc = {
 	type: 'set',
 	child: 'command',
 	ns: NS.COMMANDS,
--- a/modules/mod_configure.js
+++ b/modules/mod_configure.js
@@ -11,7 +11,7 @@ exports.getConfigure = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'configure',
+	child2: 'configure',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('config-node'))
 			return makeError(response, errors.owner.configure.node_configuration_not_supported.n);
@@ -26,10 +26,14 @@ exports.getConfigure = {
 		if (affil != 'super-owner' && affil != 'owner' && affil != 'publish-only')
 			return makeError(response, errors.pub.publish.insufficient_privileges.n);
 
+		var conf = storage.getConfiguration(nodeID);
+		if (!conf)
+			return makeError(response, 42); // FIXME
+
 		response.c('pubsub', {xmlns: NS.PUBSUB_OWNER});
 		response.c('configure', {node: nodeID});
 
-		var form = forms.build('form', 'node_config', 'default', true);
+		var form = forms.build('form', 'node_config', conf, true);
 		response.cnode(form);
 
 		return response;
@@ -41,7 +45,7 @@ exports.default = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'default',
+	child2: 'default',
 	func: function(response) {
 		if (!config.enabled('config-node'))
 			return makeError(response, errors.owner.default_options.node_configuration_not_supported.n);
@@ -61,7 +65,7 @@ exports.setConfigure = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'configure',
+	child2: 'configure',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('config-node'))
 			return makeError(response, errors.owner.configure.node_configuration_not_supported.n);
@@ -92,7 +96,8 @@ exports.setConfigure = {
 		if (typeof form == 'number')
 			return makeError(response, form);
 
-		var conf = form;
+		// TODO: verify the form.
+		var conf = form.fields;
 
 		var set = storage.configure(nodeID, conf);
 		if (typeof set == 'number')
@@ -101,3 +106,51 @@ exports.setConfigure = {
 		return response;
 	}
 }
+
+// SECTION 8.1.3: Create and Configure a Node (configure)
+exports.setConfigure2 = {
+	type: 'set',
+	child: 'pubsub',
+	ns: NS.PUBSUB,
+	child2: 'configure',
+	number: 1,
+	func: function(response, stanza, request, to) {
+		if (!config.enabled('config-node'))
+			return makeError(response, errors.owner.configure.node_configuration_not_supported.n);
+
+		var nodeID = stanza.tags[0].tags[0].getAttribute('node');
+		if (!nodeID)
+			return makeError(response, errors.nodeid_required.n);
+		if (!storage.existsNode(nodeID))
+			return makeError(response, errors.node_does_not_exist.n);
+
+		var affil = storage.getAffiliation(toBareJID(to), nodeID);
+		if (affil != 'super-owner' && affil != 'owner' && affil != 'publish-only')
+			return makeError(response, errors.forbidden.n);
+
+		var x = request.getChild('x', 'jabber:x:data');
+		if (!x)
+			return makeError(response, errors.bad_request.n);
+
+		var type = x.getAttribute('type');
+		if (type == 'cancel') {
+			conn.send(response);
+			return;
+		}
+		if (type != 'submit')
+			return makeError(response, errors.bad_request.n);
+
+		var form = forms.parse(x, true);
+		if (typeof form == 'number')
+			return makeError(response, form);
+
+		// TODO: verify the form.
+		var conf = form.fields;
+
+		var set = storage.configure(nodeID, conf);
+		if (typeof set == 'number')
+			return makeError(response, set);
+
+		return null;
+	}
+}
--- a/modules/mod_manage.js
+++ b/modules/mod_manage.js
@@ -10,7 +10,7 @@ exports.manageRetrieveSub = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'subscriptions',
+	child2: 'subscriptions',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('manage-subscriptions'))
 			return makeError(response, errors.owner.manage_subscriptions.not_supported.n);
@@ -41,7 +41,7 @@ exports.manageRetrieveAff = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'affiliations',
+	child2: 'affiliations',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('modify-affiliations'))
 			return makeError(response, errors.owner.manage_affiliations.not_supported.n);
@@ -72,7 +72,7 @@ exports.modifySub = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'subscriptions',
+	child2: 'subscriptions',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('manage-subscriptions'))
 			return makeError(response, errors.owner.manage_subscriptions.not_supported.n); //XXX
@@ -124,7 +124,7 @@ exports.modifyAff = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'affiliations',
+	child2: 'affiliations',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('modify-affiliations'))
 			return makeError(response, errors.owner.manage_affiliations.not_supported.n); //XXX
--- a/modules/mod_options.js
+++ b/modules/mod_options.js
@@ -7,11 +7,11 @@ var toBareJID = require('../util').toBar
 var NS = require('../namespaces');
 
 // SECTION 6.3.2: Configure Subscription Options (Request)
-exports.configureSub = {
+exports.getConfigureSub = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'options',
+	child2: 'options',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('subscription-options'))
 			return makeError(response, errors.sub.configure.subscription_options_not_supported.n);
@@ -47,7 +47,7 @@ exports.configureSub = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'options',
+	child2: 'options',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('subscription-options'))
 			return makeError(response, errors.sub.subscribe.not_supported.n);
@@ -83,7 +83,7 @@ exports.defaultSub = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'default',
+	child2: 'default',
 	func: function(response, stanza, request) {
 		if (!config.enabled('retrieve-default-sub'))
 			return makeError(response, errors.sub.default_options.default_subscription_configuration_retrieval_not_supported.n);
--- a/modules/mod_owner.js
+++ b/modules/mod_owner.js
@@ -8,11 +8,11 @@ var toBareJID = require('../util').toBar
 var NS = require('../namespaces');
 
 // SECTION 8.1: Create a Node
-exports.getConfigure = {
+exports.create = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'create',
+	child2: 'create',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('create-nodes'))
 			return makeError(response, errors.owner.create.node_creation_not_supported.n);
@@ -45,7 +45,10 @@ exports.getConfigure = {
 		if (!right)
 			return makeError(response, errors.forbidden.n);
 
-		var r = storage.createNode(nodeID);
+		conf = {};
+		conf['pubsub#creator'] = bare;
+
+		var r = storage.createNode(nodeID, conf);
 		if (typeof r == 'number')
 			return makeError(response, r);
 
@@ -62,7 +65,7 @@ exports['delete'] = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'delete',
+	child2: 'delete',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('delete-nodes'))
 			return makeError(response, errors.feature_not_implemented.n); //XXX
@@ -77,11 +80,11 @@ exports['delete'] = {
 		if (affil != 'super-owner' && affil != 'owner')
 			return makeError(response, errors.forbidden.n);
 
-		var notifs = storage.deleteNode(nodeID);
-		if (typeof notifs == 'number')
+		var notifications = storage.deleteNode(nodeID);
+		if (typeof notifications == 'number')
 			return makeError(response, r);
 
-		notifs.send(notifs, 'delete', nodeID);
+		notifs.send(notifications, 'delete', nodeID);
 
 		return response;
 	}
@@ -92,7 +95,7 @@ exports.purge = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB_OWNER,
-	pschild: 'purge',
+	child2: 'purge',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('purge-nodes'))
 			return makeError(response, errors.owner.purge.node_purging_not_supported.n); //XXX
@@ -110,11 +113,11 @@ exports.purge = {
 		if (!config.enabled('persistent-items')) //FIXME: autre condition, supporté par le node
 			return makeError(response, errors.owner.purge.node_does_not_persist_items.n);
 
-		var notifs = storage.purgeNode(nodeID);
-		if (typeof notifs == 'number')
+		var notifications = storage.purgeNode(nodeID);
+		if (typeof notifications == 'number')
 			return makeError(response, r);
 
-		notifs.send(notifs, 'purge', nodeID);
+		notifs.send(notifications, 'purge', nodeID);
 
 		return response;
 	}
--- a/modules/mod_publish.js
+++ b/modules/mod_publish.js
@@ -8,7 +8,7 @@ exports.retrieveSub = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'publish',
+	child2: 'publish',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('publish'))
 			return makeError(response, errors.pub.publish.item_publication_not_supported.n);
@@ -94,7 +94,7 @@ exports.retrieveSub = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'retract',
+	child2: 'retract',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('retract-items'))
 			return makeError(response, errors.pub.retract.item_deletion_not_supported.n);
--- a/modules/mod_retrieve.js
+++ b/modules/mod_retrieve.js
@@ -10,7 +10,7 @@ exports.retrieveSubscriptions = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'subscriptions',
+	child2: 'subscriptions',
 	func: function(response, stanza, request) {
 		if (!config.enabled('retrieve-subscriptions'))
 			return makeError(response, errors.subscriptions_retrieval_not_supported.n);
@@ -38,7 +38,7 @@ exports.retrieveAffiliations = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'affiliations',
+	child2: 'affiliations',
 	func: function(response, stanza, request) {
 		if (!config.enabled('retrieve-affiliations'))
 			return makeError(response, errors.affiliations_retrieval_not_supported.n);
@@ -67,7 +67,7 @@ exports.retrieveItems = {
 	type: 'get',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'items',
+	child2: 'items',
 	func: function(response, stanza, request) {
 		if (!config.enabled('retrieve-items'))
 			return makeError(response, errors.sub.default_options.node_configuration_not_supported.n);
--- a/modules/mod_subscribe.js
+++ b/modules/mod_subscribe.js
@@ -10,7 +10,7 @@ exports.subscribe = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'subscribe',
+	child2: 'subscribe',
 	func: function(response, stanza, request, to) {
 		if (!config.enabled('subscribe'))
 			return makeError(response, errors.sub.subscribe.not_supported.n);
@@ -104,7 +104,7 @@ exports.unsubscribe = {
 	type: 'set',
 	child: 'pubsub',
 	ns: NS.PUBSUB,
-	pschild: 'unsubscribe',
+	child2: 'unsubscribe',
 	func: function(response, stanza, request) {
 		if (!config.enabled('subscribe'))
 			return makeError(response, errors.sub.subscribe.not_supported.n);
--- a/psgxs.js
+++ b/psgxs.js
@@ -77,40 +77,64 @@ function onIq(stanza) {
 	else
 		response = xmpp.iq({to: to, from: from, type: 'result'});
 
-	var sent = false;
+	var send = false;
+
+	for (var i in stanza.tags) {
+		var child1 = stanza.tags[i];
+		if (child1.name == 'pubsub') {
+			for (var j in child1.tags) {
+				var child2 = child1.tags[j];
+
+				for (var k in modules) {
+					var module = modules[k];
 
-	for (var i in modules) {
-		var module = modules[i];
-		if (module.type && (type != module.type))
-			continue;
+					if (module.type && (module.type != type))
+						continue;
+
+					if (module.child2 && (module.child2 != child2.name))
+						continue;
 
-		for (var j in stanza.tags) {
-			var child = stanza.tags[j];
-			if (module.child && (child.name != module.child))
-				continue;
+					if (module.ns && (module.ns != child2.attr.xmlns))
+						continue;
+
+					if (module.number && (module.number != j))
+						continue;
 
-			if (module.ns && (child.attr.xmlns != module.ns))
-				continue;
+					var toSend = module.func(response, stanza, child2, to);
+					if (toSend) {
+						response = toSend;
+						send = true;
+						delete toSend;
+					}
+				}
+			}
+		} else {
+			for (var k in modules) {
+				var module = modules[k];
 
-			if (module.child == 'pubsub') {
-				var child2 = child.getChild(module.pschild, child.attr.xmlns);
-				if (child2)
-					child = child2;
+				if (module.type && (module.type != type))
+					continue;
 
-				if (module.pschild && (!child || module.pschild != child.name))
+				if (module.child && (module.child != child1.name))
 					continue;
-			}
+
+				if (module.ns && (module.ns != child1.attr.xmlns))
+					continue;
 
-			var toSend = module.func(response, stanza, child, to);
-			if (toSend) {
-				conn.send(toSend);
-				sent = true;
+				if (module.number && (module.number != k))
+					continue;
+
+				var toSend = module.func(response, stanza, child2, to);
+				if (toSend) {
+					response = toSend;
+					send = true;
+					delete toSend;
+				}
 			}
 		}
 	}
 
-	if (!sent)
-		conn.send(makeError(response, errors.feature_not_implemented.n));
+	conn.send(send? response: makeError(response, errors.feature_not_implemented.n));
 }
 
 function onMessage(stanza) {