plugins/adhoc/mod_adhoc.lua

1
-- Copyright (C) 2009 Thilo Cestonaro
2
-- Copyright (C) 2009-2010 Florian Zeitz
3
--
4
-- This file is MIT/X11 licensed. Please see the
5
-- COPYING file in the source package for more information.
6
--
7
 
8
local st = require "util.stanza";
9
local is_admin = require "core.usermanager".is_admin;
10
local adhoc_handle_cmd = module:require "adhoc".handle_cmd;
11
local xmlns_cmd = "http://jabber.org/protocol/commands";
12
local xmlns_disco = "http://jabber.org/protocol/disco";
13
local commands = {};
14
 
15
module:add_feature(xmlns_cmd);
16
 
17
module:hook("iq/host/"..xmlns_disco.."#info:query", function (event)
18
	local origin, stanza = event.origin, event.stanza;
19
	local node = stanza.tags[1].attr.node;
20
	if stanza.attr.type == "get" and node then
21
		if commands[node] then
22
			local privileged = is_admin(stanza.attr.from, stanza.attr.to);
23
			if (commands[node].permission == "admin" and privileged)
24
			    or (commands[node].permission == "user") then
25
				reply = st.reply(stanza);
26
				reply:tag("query", { xmlns = xmlns_disco.."#info",
27
				    node = node });
28
				reply:tag("identity", { name = commands[node].name,
29
				    category = "automation", type = "command-node" }):up();
30
				reply:tag("feature", { var = xmlns_cmd }):up();
31
				reply:tag("feature", { var = "jabber:x:data" }):up();
32
			else
33
				reply = st.error_reply(stanza, "auth", "forbidden", "This item is not available to you");
34
			end
35
			origin.send(reply);
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
47
	end
48
end);
49
 
50
module:hook("iq/host/"..xmlns_disco.."#items:query", function (event)
51
	local origin, stanza = event.origin, event.stanza;
52
	if stanza.attr.type == "get" and stanza.tags[1].attr.node
53
	    and stanza.tags[1].attr.node == xmlns_cmd then
54
		local privileged = is_admin(stanza.attr.from, stanza.attr.to);
55
		reply = st.reply(stanza);
56
		reply:tag("query", { xmlns = xmlns_disco.."#items",
57
		    node = xmlns_cmd });
58
		for node, command in pairs(commands) do
59
			if (command.permission == "admin" and privileged)
60
			    or (command.permission == "user") then
61
				reply:tag("item", { name = command.name,
62
				    node = node, jid = module:get_host() });
63
				reply:up();
64
			end
65
		end
66
		origin.send(reply);
67
		return true;
68
	end
69
end, 500);
70
 
71
module:hook("iq/host/"..xmlns_cmd..":command", function (event)
72
	local origin, stanza = event.origin, event.stanza;
73
	if stanza.attr.type == "set" then
74
		local node = stanza.tags[1].attr.node
75
		if commands[node] then
76
			local privileged = is_admin(stanza.attr.from, stanza.attr.to);
77
			if commands[node].permission == "admin"
78
			    and not privileged then
79
				origin.send(st.error_reply(stanza, "auth", "forbidden", "You don't have permission to execute this command"):up()
80
				    :add_child(commands[node]:cmdtag("canceled")
81
					:tag("note", {type="error"}):text("You don't have permission to execute this command")));
82
				return true
83
			end
84
			-- User has permission now execute the command
85
			return adhoc_handle_cmd(commands[node], origin, stanza);
86
		end
87
	end
88
end, 500);
89
 
90
local function handle_item_added(item)
91
	commands[item.node] = item;
92
end
93
 
94
module:hook("item-added/adhoc", function (event)
95
	return handle_item_added(event.item);
96
end, 500);
97
 
98
module:hook("item-removed/adhoc", function (event)
99
	commands[event.item.node] = nil;
100
end, 500);
101
 
102
-- Pick up any items that are already added
103
for _, item in ipairs(module:get_host_items("adhoc")) do
104
	handle_item_added(item);
105
end