comparison plugins/adhoc/mod_adhoc.lua @ 6054:7a5ddbaf758d

Merge 0.9->0.10
author Matthew Wild <mwild1@gmail.com>
date Wed, 02 Apr 2014 17:41:38 +0100
parents 785da1854eb9
children be87ab2d611c
comparison
equal deleted inserted replaced
6053:2f93a04564b2 6054:7a5ddbaf758d
4 -- This file is MIT/X11 licensed. Please see the 4 -- This file is MIT/X11 licensed. Please see the
5 -- COPYING file in the source package for more information. 5 -- COPYING file in the source package for more information.
6 -- 6 --
7 7
8 local st = require "util.stanza"; 8 local st = require "util.stanza";
9 local keys = require "util.iterators".keys;
10 local array_collect = require "util.array".collect;
9 local is_admin = require "core.usermanager".is_admin; 11 local is_admin = require "core.usermanager".is_admin;
12 local jid_split = require "util.jid".split;
10 local adhoc_handle_cmd = module:require "adhoc".handle_cmd; 13 local adhoc_handle_cmd = module:require "adhoc".handle_cmd;
11 local xmlns_cmd = "http://jabber.org/protocol/commands"; 14 local xmlns_cmd = "http://jabber.org/protocol/commands";
12 local xmlns_disco = "http://jabber.org/protocol/disco";
13 local commands = {}; 15 local commands = {};
14 16
15 module:add_feature(xmlns_cmd); 17 module:add_feature(xmlns_cmd);
16 18
17 module:hook("iq/host/"..xmlns_disco.."#info:query", function (event) 19 module:hook("host-disco-info-node", function (event)
18 local origin, stanza = event.origin, event.stanza; 20 local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node;
19 local node = stanza.tags[1].attr.node; 21 if commands[node] then
20 if stanza.attr.type == "get" and node then 22 local from = stanza.attr.from;
21 if commands[node] then 23 local privileged = is_admin(from, stanza.attr.to);
22 local privileged = is_admin(stanza.attr.from, stanza.attr.to); 24 local global_admin = is_admin(from);
23 if (commands[node].permission == "admin" and privileged) 25 local username, hostname = jid_split(from);
24 or (commands[node].permission == "user") then 26 local command = commands[node];
25 reply = st.reply(stanza); 27 if (command.permission == "admin" and privileged)
26 reply:tag("query", { xmlns = xmlns_disco.."#info", 28 or (command.permission == "global_admin" and global_admin)
27 node = node }); 29 or (command.permission == "local_user" and hostname == module.host)
28 reply:tag("identity", { name = commands[node].name, 30 or (command.permission == "user") then
29 category = "automation", type = "command-node" }):up(); 31 reply:tag("identity", { name = command.name,
30 reply:tag("feature", { var = xmlns_cmd }):up(); 32 category = "automation", type = "command-node" }):up();
31 reply:tag("feature", { var = "jabber:x:data" }):up(); 33 reply:tag("feature", { var = xmlns_cmd }):up();
32 else 34 reply:tag("feature", { var = "jabber:x:data" }):up();
33 reply = st.error_reply(stanza, "auth", "forbidden", "This item is not available to you"); 35 event.exists = true;
34 end 36 else
35 origin.send(reply); 37 return origin.send(st.error_reply(stanza, "auth", "forbidden", "This item is not available to you"));
36 return true;
37 elseif node == xmlns_cmd then
38 reply = st.reply(stanza);
39 reply:tag("query", { xmlns = xmlns_disco.."#info",
40 node = node });
41 reply:tag("identity", { name = "Ad-Hoc Commands",
42 category = "automation", type = "command-list" }):up();
43 origin.send(reply);
44 return true;
45
46 end 38 end
39 elseif node == xmlns_cmd then
40 reply:tag("identity", { name = "Ad-Hoc Commands",
41 category = "automation", type = "command-list" }):up();
42 event.exists = true;
47 end 43 end
48 end); 44 end);
49 45
50 module:hook("iq/host/"..xmlns_disco.."#items:query", function (event) 46 module:hook("host-disco-items-node", function (event)
51 local origin, stanza = event.origin, event.stanza; 47 local stanza, origin, reply, node = event.stanza, event.origin, event.reply, event.node;
52 if stanza.attr.type == "get" and stanza.tags[1].attr.node 48 if node ~= xmlns_cmd then
53 and stanza.tags[1].attr.node == xmlns_cmd then 49 return;
54 local admin = is_admin(stanza.attr.from, stanza.attr.to); 50 end
55 local global_admin = is_admin(stanza.attr.from); 51
56 reply = st.reply(stanza); 52 local from = stanza.attr.from;
57 reply:tag("query", { xmlns = xmlns_disco.."#items", 53 local admin = is_admin(from, stanza.attr.to);
58 node = xmlns_cmd }); 54 local global_admin = is_admin(from);
59 for node, command in pairs(commands) do 55 local username, hostname = jid_split(from);
60 if (command.permission == "admin" and admin) 56 local nodes = array_collect(keys(commands)):sort();
61 or (command.permission == "global_admin" and global_admin) 57 for _, node in ipairs(nodes) do
62 or (command.permission == "user") then 58 local command = commands[node];
63 reply:tag("item", { name = command.name, 59 if (command.permission == "admin" and admin)
64 node = node, jid = module:get_host() }); 60 or (command.permission == "global_admin" and global_admin)
65 reply:up(); 61 or (command.permission == "local_user" and hostname == module.host)
66 end 62 or (command.permission == "user") then
63 reply:tag("item", { name = command.name,
64 node = node, jid = module:get_host() });
65 reply:up();
67 end 66 end
68 origin.send(reply);
69 return true;
70 end 67 end
71 end, 500); 68 event.exists = true;
69 end);
72 70
73 module:hook("iq/host/"..xmlns_cmd..":command", function (event) 71 module:hook("iq/host/"..xmlns_cmd..":command", function (event)
74 local origin, stanza = event.origin, event.stanza; 72 local origin, stanza = event.origin, event.stanza;
75 if stanza.attr.type == "set" then 73 if stanza.attr.type == "set" then
76 local node = stanza.tags[1].attr.node 74 local node = stanza.tags[1].attr.node
77 if commands[node] then 75 local command = commands[node];
78 local admin = is_admin(stanza.attr.from, stanza.attr.to); 76 if command then
79 local global_admin = is_admin(stanza.attr.from); 77 local from = stanza.attr.from;
80 if (commands[node].permission == "admin" and not admin) 78 local admin = is_admin(from, stanza.attr.to);
81 or (commands[node].permission == "global_admin" and not global_admin) then 79 local global_admin = is_admin(from);
80 local username, hostname = jid_split(from);
81 if (command.permission == "admin" and not admin)
82 or (command.permission == "global_admin" and not global_admin)
83 or (command.permission == "local_user" and hostname ~= module.host) then
82 origin.send(st.error_reply(stanza, "auth", "forbidden", "You don't have permission to execute this command"):up() 84 origin.send(st.error_reply(stanza, "auth", "forbidden", "You don't have permission to execute this command"):up()
83 :add_child(commands[node]:cmdtag("canceled") 85 :add_child(commands[node]:cmdtag("canceled")
84 :tag("note", {type="error"}):text("You don't have permission to execute this command"))); 86 :tag("note", {type="error"}):text("You don't have permission to execute this command")));
85 return true 87 return true
86 end 88 end