23 end |
23 end |
24 stream:debug("adhoc calling callback") |
24 stream:debug("adhoc calling callback") |
25 return callback(command_list); |
25 return callback(command_list); |
26 end); |
26 end); |
27 end |
27 end |
28 |
28 |
29 function stream:execute_command(jid, command, callback) |
29 function stream:execute_command(jid, command, callback) |
30 local cmd = setmetatable({ |
30 local cmd = setmetatable({ |
31 stream = stream, jid = jid, |
31 stream = stream, jid = jid, |
32 command = command, callback = callback |
32 command = command, callback = callback |
33 }, command_mt); |
33 }, command_mt); |
34 return cmd:execute(); |
34 return cmd:execute(); |
35 end |
35 end |
36 |
36 |
37 -- ACL checker for commands we provide |
37 -- ACL checker for commands we provide |
38 local function has_affiliation(jid, aff) |
38 local function has_affiliation(jid, aff) |
39 if not(aff) or aff == "user" then return true; end |
39 if not(aff) or aff == "user" then return true; end |
40 if type(aff) == "function" then |
40 if type(aff) == "function" then |
41 return aff(jid); |
41 return aff(jid); |
42 end |
42 end |
43 -- TODO: Support 'roster', etc. |
43 -- TODO: Support 'roster', etc. |
44 end |
44 end |
45 |
45 |
46 function stream:add_adhoc_command(name, node, handler, permission) |
46 function stream:add_adhoc_command(name, node, handler, permission) |
47 commands[node] = adhoc.new(name, node, handler, permission); |
47 commands[node] = adhoc.new(name, node, handler, permission); |
48 stream:add_disco_item({ jid = stream.jid, node = node, name = name }, xmlns_commands); |
48 stream:add_disco_item({ jid = stream.jid, node = node, name = name }, xmlns_commands); |
49 return commands[node]; |
49 return commands[node]; |
50 end |
50 end |
51 |
51 |
52 local function handle_command(stanza) |
52 local function handle_command(stanza) |
53 local command_tag = stanza.tags[1]; |
53 local command_tag = stanza.tags[1]; |
54 local node = command_tag.attr.node; |
54 local node = command_tag.attr.node; |
55 |
55 |
56 local handler = commands[node]; |
56 local handler = commands[node]; |
57 if not handler then return; end |
57 if not handler then return; end |
58 |
58 |
59 if not has_affiliation(stanza.attr.from, handler.permission) then |
59 if not has_affiliation(stanza.attr.from, handler.permission) then |
60 stream:send(verse.error_reply(stanza, "auth", "forbidden", "You don't have permission to execute this command"):up() |
60 stream:send(verse.error_reply(stanza, "auth", "forbidden", "You don't have permission to execute this command"):up() |
61 :add_child(handler:cmdtag("canceled") |
61 :add_child(handler:cmdtag("canceled") |
62 :tag("note", {type="error"}):text("You don't have permission to execute this command"))); |
62 :tag("note", {type="error"}):text("You don't have permission to execute this command"))); |
63 return true |
63 return true |
64 end |
64 end |
65 |
65 |
66 -- User has permission now execute the command |
66 -- User has permission now execute the command |
67 return adhoc.handle_cmd(handler, { send = function (d) return stream:send(d) end }, stanza); |
67 return adhoc.handle_cmd(handler, { send = function (d) return stream:send(d) end }, stanza); |
68 end |
68 end |
69 |
69 |
70 stream:hook("iq/"..xmlns_commands, function (stanza) |
70 stream:hook("iq/"..xmlns_commands, function (stanza) |
71 local type = stanza.attr.type; |
71 local type = stanza.attr.type; |
72 local name = stanza.tags[1].name; |
72 local name = stanza.tags[1].name; |
73 if type == "set" and name == "command" then |
73 if type == "set" and name == "command" then |
74 return handle_command(stanza); |
74 return handle_command(stanza); |