Merge waqas with Tobias. Eww.
authorMatthew Wild <mwild1@gmail.com>
Tue, 18 Aug 2009 12:03:35 +0000 (13:03 +0100)
committerMatthew Wild <mwild1@gmail.com>
Tue, 18 Aug 2009 12:03:35 +0000 (13:03 +0100)
core/componentmanager.lua
core/discomanager.lua [deleted file]
core/modulemanager.lua
plugins/mod_disco.lua
plugins/mod_legacyauth.lua
plugins/mod_pep.lua
plugins/mod_posix.lua
plugins/mod_register.lua
util/discohelper.lua [deleted file]

index 08868236e76a8c7f1ef36f1c6897947bed020c85..536d16339e247c539c74978743476d08b29e4e37 100644 (file)
@@ -6,8 +6,6 @@
 -- COPYING file in the source package for more information.
 --
 
-
-
 local prosody = prosody;
 local log = require "util.logger".init("componentmanager");
 local configmanager = require "core.configmanager";
@@ -25,14 +23,6 @@ local components = {};
 
 local disco_items = require "util.multitable".new();
 local NULL = {};
-require "core.discomanager".addDiscoItemsHandler("*host", function(reply, to, from, node)
-       if #node == 0 and hosts[to] then
-               for jid in pairs(disco_items:get(to) or NULL) do
-                       reply:tag("item", {jid = jid}):up();
-               end
-               return true;
-       end
-end);
 
 prosody.events.add_handler("server-starting", function () core_route_stanza = _G.core_route_stanza; end);
 
@@ -138,4 +128,8 @@ function set_component_handler(host, handler)
        components[host] = handler;
 end
 
+function get_children(host)
+       return disco_items:get(host) or NULL;
+end
+
 return _M;
diff --git a/core/discomanager.lua b/core/discomanager.lua
deleted file mode 100644 (file)
index 742907d..0000000
+++ /dev/null
@@ -1,66 +0,0 @@
--- Prosody IM
--- Copyright (C) 2008-2009 Matthew Wild
--- Copyright (C) 2008-2009 Waqas Hussain
--- 
--- This project is MIT/X11 licensed. Please see the
--- COPYING file in the source package for more information.
---
-
-
-
-local helper = require "util.discohelper".new();
-local hosts = hosts;
-local jid_split = require "util.jid".split;
-local jid_bare = require "util.jid".bare;
-local usermanager_user_exists = require "core.usermanager".user_exists;
-local rostermanager_is_contact_subscribed = require "core.rostermanager".is_contact_subscribed;
-local print = print;
-
-do
-       helper:addDiscoInfoHandler("*host", function(reply, to, from, node)
-               if hosts[to] then
-                       reply:tag("identity", {category="server", type="im", name="Prosody"}):up();
-                       return true;
-               end
-       end);
-       helper:addDiscoInfoHandler("*node", function(reply, to, from, node)
-               local node, host = jid_split(to);
-               if hosts[host] and rostermanager_is_contact_subscribed(node, host, jid_bare(from)) then
-                       reply:tag("identity", {category="account", type="registered"}):up();
-                       return true;
-               end
-       end);
-       helper:addDiscoItemsHandler("*host", function(reply, to, from, node)
-               if hosts[to] and hosts[to].type == "local" then
-                       return true;
-               end
-       end);
-end
-
-module "discomanager"
-
-function handle(stanza)
-       return helper:handle(stanza);
-end
-
-function addDiscoItemsHandler(jid, func)
-       return helper:addDiscoItemsHandler(jid, func);
-end
-
-function addDiscoInfoHandler(jid, func)
-       return helper:addDiscoInfoHandler(jid, func);
-end
-
-function set(plugin, var, origin)
-       -- TODO handle origin and host based on plugin.
-       local handler = function(reply, to, from, node) -- service discovery
-               if #node == 0 then
-                       reply:tag("feature", {var = var}):up();
-                       return true;
-               end
-       end
-       addDiscoInfoHandler("*node", handler);
-       addDiscoInfoHandler("*host", handler);
-end
-
-return _M;
index c2e6e68e4760f236f49d11583436f8707106d1dd..7037fc90cb09924ec83f255360d1dc16a90b7657 100644 (file)
@@ -6,13 +6,10 @@
 -- COPYING file in the source package for more information.
 --
 
-
-
 local plugin_dir = CFG_PLUGINDIR or "./plugins/";
 
 local logger = require "util.logger";
 local log = logger.init("modulemanager");
-local addDiscoInfoHandler = require "core.discomanager".addDiscoInfoHandler;
 local eventmanager = require "core.eventmanager";
 local config = require "core.configmanager";
 local multitable_new = require "util.multitable".new;
@@ -50,8 +47,6 @@ local handler_info = {};
 
 local modulehelpers = setmetatable({}, { __index = _G });
 
-local features_table = multitable_new();
-local identities_table = multitable_new();
 local handler_table = multitable_new();
 local hooked = multitable_new();
 local hooks = multitable_new();
@@ -171,8 +166,6 @@ function unload(host, name, ...)
                end
        end
        modulemap[host][name] = nil;
-       features_table:remove(host, name);
-       identities_table:remove(host, name);
        local params = handler_table:get(host, name); -- , {module.host, origin_type, tag, xmlns}
        for _, param in pairs(params or NULL) do
                local handlers = stanza_handlers:get(param[1], param[2], param[3], param[4]);
@@ -328,50 +321,11 @@ function api:add_iq_handler(origin_type, xmlns, handler)
        self:add_handler(origin_type, "iq", xmlns, handler);
 end
 
-addDiscoInfoHandler("*host", function(reply, to, from, node)
-       if #node == 0 then
-               local done = {};
-               for module, identities in pairs(identities_table:get(to) or NULL) do -- for each module
-                       for identity, attr in pairs(identities) do
-                               if not done[identity] then
-                                       reply:tag("identity", attr):up(); -- TODO cache
-                                       done[identity] = true;
-                               end
-                       end
-               end
-               for module, identities in pairs(identities_table:get("*") or NULL) do -- for each module
-                       for identity, attr in pairs(identities) do
-                               if not done[identity] then
-                                       reply:tag("identity", attr):up(); -- TODO cache
-                                       done[identity] = true;
-                               end
-                       end
-               end
-               for module, features in pairs(features_table:get(to) or NULL) do -- for each module
-                       for feature in pairs(features) do
-                               if not done[feature] then
-                                       reply:tag("feature", {var = feature}):up(); -- TODO cache
-                                       done[feature] = true;
-                               end
-                       end
-               end
-               for module, features in pairs(features_table:get("*") or NULL) do -- for each module
-                       for feature in pairs(features) do
-                               if not done[feature] then
-                                       reply:tag("feature", {var = feature}):up(); -- TODO cache
-                                       done[feature] = true;
-                               end
-                       end
-               end
-               return next(done) ~= nil;
-       end
-end);
-
 function api:add_feature(xmlns)
-       features_table:set(self.host, self.name, xmlns, true);
+       self:add_item("feature", xmlns);
 end
-function api:add_identity(category, type)
-       identities_table:set(self.host, self.name, category.."\0"..type, {category = category, type = type});
+function api:add_identity(category, type, name)
+       self:add_item("identity", {category = category, type = type, name = name});
 end
 
 local event_hook = function(host, mod_name, event_name, ...)
@@ -422,6 +376,38 @@ function api:get_option(name, default_value)
        return config.get(self.host, self.name, name) or config.get(self.host, "core", name) or default_value;
 end
 
+local t_remove = _G.table.remove;
+local module_items = multitable_new();
+function api:add_item(key, value)
+       self.items = self.items or {};
+       self.items[key] = self.items[key] or {};
+       t_insert(self.items[key], value);
+       self:fire_event("item-added/"..key, {source = self, item = value});
+end
+function api:remove_item(key, value)
+       local t = self.items and self.items[key] or NULL;
+       for i = #t,1,-1 do
+               if t[i] == value then
+                       t_remove(self.items[key], i);
+                       self:fire_event("item-removed/"..key, {source = self, item = value});
+                       return value;
+               end
+       end
+end
+
+function api:get_host_items(key)
+       local result = {};
+       for mod_name, module in pairs(modulemap[self.host]) do
+               module = module.module;
+               if module.items then
+                       for _, item in ipairs(module.items[key] or NULL) do
+                               t_insert(result, item);
+                       end
+               end
+       end
+       return result;
+end
+
 --------------------------------------------------------------------
 
 local actions = {};
index 00ea01d880fd50d7cd4def14a04f03b390219ab1..06b29f0e4a203dafb3b18d50393c57b6e6ba4f93 100644 (file)
@@ -6,16 +6,47 @@
 -- COPYING file in the source package for more information.
 --
 
+local componentmanager_get_children = require "core.componentmanager".get_children;
+local st = require "util.stanza"
 
-
-local discomanager_handle = require "core.discomanager".handle;
-
+module:add_identity("server", "im", "Prosody"); -- FIXME should be in the non-existing mod_router
 module:add_feature("http://jabber.org/protocol/disco#info");
 module:add_feature("http://jabber.org/protocol/disco#items");
 
-module:add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#info", function (session, stanza)
-       session.send(discomanager_handle(stanza));
+module:hook("iq/host/http://jabber.org/protocol/disco#info:query", function(event)
+       local origin, stanza = event.origin, event.stanza;
+       if stanza.attr.type ~= "get" then return; end
+       local node = stanza.tags[1].attr.node;
+       if node and node ~= "" then return; end -- TODO fire event?
+
+       local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#info");
+       local done = {};
+       for _,identity in ipairs(module:get_host_items("identity")) do
+               local identity_s = identity.category.."\0"..identity.type;
+               if not done[identity_s] then
+                       reply:tag("identity", identity):up();
+                       done[identity_s] = true;
+               end
+       end
+       for _,feature in ipairs(module:get_host_items("feature")) do
+               if not done[feature] then
+                       reply:tag("feature", {var=feature}):up();
+                       done[feature] = true;
+               end
+       end
+       origin.send(reply);
+       return true;
 end);
-module:add_iq_handler({"c2s", "s2sin"}, "http://jabber.org/protocol/disco#items", function (session, stanza)
-       session.send(discomanager_handle(stanza));
+module:hook("iq/host/http://jabber.org/protocol/disco#items:query", function(event)
+       local origin, stanza = event.origin, event.stanza;
+       if stanza.attr.type ~= "get" then return; end
+       local node = stanza.tags[1].attr.node;
+       if node and node ~= "" then return; end -- TODO fire event?
+
+       local reply = st.reply(stanza):query("http://jabber.org/protocol/disco#items");
+       for jid in pairs(componentmanager_get_children(module.host)) do
+               reply:tag("item", {jid = jid}):up();
+       end
+       origin.send(reply);
+       return true;
 end);
index de94411ebac76278d725d4910a549b06e79e0619..9a9c3902f0dfe242ce3b435056fb06787edd21ca 100644 (file)
@@ -11,8 +11,7 @@
 local st = require "util.stanza";
 local t_concat = table.concat;
 
-local config = require "core.configmanager";
-local secure_auth_only = config.get(module:get_host(), "core", "require_encryption");
+local secure_auth_only = module:get_option("require_encryption");
 
 local sessionmanager = require "core.sessionmanager";
 local usermanager = require "core.usermanager";
@@ -43,11 +42,9 @@ module:add_iq_handler("c2s_unauthed", "jabber:iq:auth",
                                        :tag("username"):up()
                                        :tag("password"):up()
                                        :tag("resource"):up());
-                               return true;                    
                        else
                                username, password, resource = t_concat(username), t_concat(password), t_concat(resource);
                                local reply = st.reply(stanza);
-                               require "core.usermanager"
                                if usermanager.validate_credentials(session.host, username, password) then
                                        -- Authentication successful!
                                        local success, err = sessionmanager.make_authenticated(session, username);
@@ -56,19 +53,13 @@ module:add_iq_handler("c2s_unauthed", "jabber:iq:auth",
                                                success, err_type, err, err_msg = sessionmanager.bind_resource(session, resource);
                                                if not success then
                                                        session.send(st.error_reply(stanza, err_type, err, err_msg));
-                                                       return true;
+                                                       return true; -- FIXME need to unauthenticate here
                                                end
                                        end
                                        session.send(st.reply(stanza));
-                                       return true;
                                else
-                                       local reply = st.reply(stanza);
-                                       reply.attr.type = "error";
-                                       reply:tag("error", { code = "401", type = "auth" })
-                                               :tag("not-authorized", { xmlns = "urn:ietf:params:xml:ns:xmpp-stanzas" });
-                                       session.send(reply);
-                                       return true;
+                                       session.send(st.error_reply(stanza, "auth", "not-authorized"));
                                end
                        end
-                       
+                       return true;
                end);
index e07759f04189357bbcfe0ad7bee04804da92f304..842f1fcec04af2609b2513b28f25eaef64957edf 100644 (file)
@@ -25,7 +25,7 @@ local data = {};
 local recipients = {};
 local hash_map = {};
 
-module:add_identity("pubsub", "pep");
+module:add_identity("pubsub", "pep", "Prosody");
 module:add_feature("http://jabber.org/protocol/pubsub#publish");
 
 local function publish(session, node, item)
index af4cdb1685d6ec6d02c868d4d21e73a99005ea18..5f7dfc5b1884e9c8b857b851c1aa43764b936c4f 100644 (file)
@@ -17,7 +17,6 @@ if type(signal) == "string" then
        module:log("warn", "Couldn't load signal library, won't respond to SIGTERM");
 end
 
-local config_get = require "core.configmanager".get;
 local logger_set = require "util.logger".setwriter;
 
 local prosody = _G.prosody;
@@ -26,8 +25,8 @@ module.host = "*"; -- we're a global module
 
 -- Allow switching away from root, some people like strange ports.
 module:add_event_hook("server-started", function ()
-               local uid = config_get("*", "core", "setuid");
-               local gid = config_get("*", "core", "setgid");
+               local uid = module:get_option("setuid");
+               local gid = module:get_option("setgid");
                if gid then
                        local success, msg = pposix.setgid(gid);
                        if success then
@@ -50,9 +49,9 @@ module:add_event_hook("server-started", function ()
 
 -- Don't even think about it!
 module:add_event_hook("server-starting", function ()
-               local suid = config_get("*", "core", "setuid");
+               local suid = module:get_option("setuid");
                if not suid or suid == 0 or suid == "root" then
-                       if pposix.getuid() == 0 and not config_get("*", "core", "run_as_root") then
+                       if pposix.getuid() == 0 and not module:get_option("run_as_root") then
                                module:log("error", "Danger, Will Robinson! Prosody doesn't need to be run as root, so don't do it!");
                                module:log("error", "For more information on running Prosody as root, see http://prosody.im/doc/root");
                                prosody.shutdown("Refusing to run as root");
@@ -73,7 +72,7 @@ local function write_pidfile()
        if pidfile_written then
                remove_pidfile();
        end
-       local pidfile = config_get("*", "core", "pidfile");
+       local pidfile = module:get_option("pidfile");
        if pidfile then
                local pf, err = io.open(pidfile, "w+");
                if not pf then
@@ -103,7 +102,7 @@ function syslog_sink_maker(config)
 end
 require "core.loggingmanager".register_sink_type("syslog", syslog_sink_maker);
 
-if not config_get("*", "core", "no_daemonize") then
+if not module:get_option("no_daemonize") then
        local function daemonize_server()
                local ok, ret = pposix.daemonize();
                if not ok then
index 383ab811c7af002f31853c9929bb1830984d771f..0cb8d7715c4ac58fbbfa02bc5a539ad0f8752c1e 100644 (file)
@@ -9,7 +9,6 @@
 
 local hosts = _G.hosts;
 local st = require "util.stanza";
-local config = require "core.configmanager";
 local datamanager = require "util.datamanager";
 local usermanager_user_exists = require "core.usermanager".user_exists;
 local usermanager_create_user = require "core.usermanager".create_user;
@@ -90,16 +89,16 @@ module:add_iq_handler("c2s", "jabber:iq:register", function (session, stanza)
 end);
 
 local recent_ips = {};
-local min_seconds_between_registrations = config.get(module.host, "core", "min_seconds_between_registrations");
-local whitelist_only = config.get(module.host, "core", "whitelist_registration_only");
-local whitelisted_ips = config.get(module.host, "core", "registration_whitelist") or { "127.0.0.1" };
-local blacklisted_ips = config.get(module.host, "core", "registration_blacklist") or {};
+local min_seconds_between_registrations = module:get_option("min_seconds_between_registrations");
+local whitelist_only = module:get_option("whitelist_registration_only");
+local whitelisted_ips = module:get_option("registration_whitelist") or { "127.0.0.1" };
+local blacklisted_ips = module:get_option("registration_blacklist") or {};
 
 for _, ip in ipairs(whitelisted_ips) do whitelisted_ips[ip] = true; end
 for _, ip in ipairs(blacklisted_ips) do blacklisted_ips[ip] = true; end
 
 module:add_iq_handler("c2s_unauthed", "jabber:iq:register", function (session, stanza)
-       if config.get(module.host, "core", "allow_registration") == false then
+       if module:get_option("allow_registration") == false then
                session.send(st.error_reply(stanza, "cancel", "service-unavailable"));
        elseif stanza.tags[1].name == "query" then
                local query = stanza.tags[1];
diff --git a/util/discohelper.lua b/util/discohelper.lua
deleted file mode 100644 (file)
index 5d9bf28..0000000
+++ /dev/null
@@ -1,89 +0,0 @@
--- Prosody IM
--- Copyright (C) 2008-2009 Matthew Wild
--- Copyright (C) 2008-2009 Waqas Hussain
--- 
--- This project is MIT/X11 licensed. Please see the
--- COPYING file in the source package for more information.
---
-
-
-
-local t_insert = table.insert;
-local jid_split = require "util.jid".split;
-local ipairs = ipairs;
-local st = require "util.stanza";
-
-module "discohelper";
-
-local function addDiscoItemsHandler(self, jid, func)
-       if self.item_handlers[jid] then
-               t_insert(self.item_handlers[jid], func);
-       else
-               self.item_handlers[jid] = {func};
-       end
-end
-
-local function addDiscoInfoHandler(self, jid, func)
-       if self.info_handlers[jid] then
-               t_insert(self.info_handlers[jid], func);
-       else
-               self.info_handlers[jid] = {func};
-       end
-end
-
-local function handle(self, stanza)
-       if stanza.name == "iq" and stanza.tags[1].name == "query" then
-               local query = stanza.tags[1];
-               local to = stanza.attr.to;
-               local from = stanza.attr.from
-               local node = query.attr.node or "";
-               local to_node, to_host = jid_split(to);
-
-               local reply = st.reply(stanza):query(query.attr.xmlns);
-               local handlers;
-               if query.attr.xmlns == "http://jabber.org/protocol/disco#info" then -- select handler set
-                       handlers = self.info_handlers;
-               elseif query.attr.xmlns == "http://jabber.org/protocol/disco#items" then
-                       handlers = self.item_handlers;
-               end
-               local handler;
-               local found; -- to keep track of any handlers found
-               if to_node then -- handlers which get called always
-                       handler = handlers["*node"];
-               else
-                       handler = handlers["*host"];
-               end
-               if handler then -- call always called handler
-                       for _, h in ipairs(handler) do
-                               if h(reply, to, from, node) then found = true; end
-                       end
-               end
-               handler = handlers[to]; -- get the handler
-               if not handler then -- if not found then use default handler
-                       if to_node then
-                               handler = handlers["*defaultnode"];
-                       else
-                               handler = handlers["*defaulthost"];
-                       end
-               end
-               if handler then
-                       for _, h in ipairs(handler) do
-                               if h(reply, to, from, node) then found = true; end
-                       end
-               end
-               if found then return reply; end -- return the reply if there was one
-               return st.error_reply(stanza, "cancel", "service-unavailable");
-       end
-end
-
-function new()
-       return {
-               item_handlers = {};
-               info_handlers = {};
-               addDiscoItemsHandler = addDiscoItemsHandler;
-               addDiscoInfoHandler = addDiscoInfoHandler;
-               handle = handle;
-       };
-end
-
-return _M;