MUC: Don't limit affiliation changes to owners, and allow owners to remove themselves...
[prosody.git] / plugins / adhoc / mod_adhoc.lua
index 6a5165ed32da9c7bf0bbd445d59e037266dbeb8d..20c0f2beffeeaff33456cfdcf6f989243073d05f 100644 (file)
@@ -1,5 +1,6 @@
 -- Copyright (C) 2009 Thilo Cestonaro
--- 
+-- Copyright (C) 2009-2010 Florian Zeitz
+--
 -- This file is MIT/X11 licensed. Please see the
 -- COPYING file in the source package for more information.
 --
@@ -13,13 +14,44 @@ local commands = {};
 
 module:add_feature(xmlns_cmd);
 
+module:hook("iq/host/"..xmlns_disco.."#info:query", function (event)
+       local origin, stanza = event.origin, event.stanza;
+       local node = stanza.tags[1].attr.node;
+       if stanza.attr.type == "get" and node then
+               if commands[node] then
+                       local privileged = is_admin(stanza.attr.from, stanza.attr.to);
+                       if (commands[node].permission == "admin" and privileged)
+                           or (commands[node].permission == "user") then
+                               reply = st.reply(stanza);
+                               reply:tag("query", { xmlns = xmlns_disco.."#info",
+                                   node = node });
+                               reply:tag("identity", { name = commands[node].name,
+                                   category = "automation", type = "command-node" }):up();
+                               reply:tag("feature", { var = xmlns_cmd }):up();
+                               reply:tag("feature", { var = "jabber:x:data" }):up();
+                       else
+                               reply = st.error_reply(stanza, "auth", "forbidden", "This item is not available to you");
+                       end
+                       origin.send(reply);
+                       return true;
+               elseif node == xmlns_cmd then
+                       reply = st.reply(stanza);
+                       reply:tag("query", { xmlns = xmlns_disco.."#info",
+                           node = node });
+                       reply:tag("identity", { name = "Ad-Hoc Commands",
+                           category = "automation", type = "command-list" }):up();
+                       origin.send(reply);
+                       return true;
+
+               end
+       end
+end);
+
 module:hook("iq/host/"..xmlns_disco.."#items:query", function (event)
        local origin, stanza = event.origin, event.stanza;
-       -- TODO: Is this correct, or should is_admin be changed?
-       local privileged = is_admin(stanza.attr.from)
-           or is_admin(stanza.attr.from, stanza.attr.to); 
        if stanza.attr.type == "get" and stanza.tags[1].attr.node
            and stanza.tags[1].attr.node == xmlns_cmd then
+               local privileged = is_admin(stanza.attr.from, stanza.attr.to);
                reply = st.reply(stanza);
                reply:tag("query", { xmlns = xmlns_disco.."#items",
                    node = xmlns_cmd });
@@ -36,15 +68,12 @@ module:hook("iq/host/"..xmlns_disco.."#items:query", function (event)
        end
 end, 500);
 
-module:hook("iq/host", function (event)
+module:hook("iq/host/"..xmlns_cmd..":command", function (event)
        local origin, stanza = event.origin, event.stanza;
-       if stanza.attr.type == "set" and stanza.tags[1]
-           and stanza.tags[1].name == "command" then 
+       if stanza.attr.type == "set" then
                local node = stanza.tags[1].attr.node
-               -- TODO: Is this correct, or should is_admin be changed?
-               local privileged = is_admin(event.stanza.attr.from)
-                   or is_admin(stanza.attr.from, stanza.attr.to);
                if commands[node] then
+                       local privileged = is_admin(stanza.attr.from, stanza.attr.to);
                        if commands[node].permission == "admin"
                            and not privileged then
                                origin.send(st.error_reply(stanza, "auth", "forbidden", "You don't have permission to execute this command"):up()
@@ -58,10 +87,19 @@ module:hook("iq/host", function (event)
        end
 end, 500);
 
+local function handle_item_added(item)
+       commands[item.node] = item;
+end
+
 module:hook("item-added/adhoc", function (event)
-       commands[event.item.node] = event.item;
+       return handle_item_added(event.item);
 end, 500);
 
 module:hook("item-removed/adhoc", function (event)
        commands[event.item.node] = nil;
 end, 500);
+
+-- Pick up any items that are already added
+for _, item in ipairs(module:get_host_items("adhoc")) do
+       handle_item_added(item);
+end