mod_profile: Mark as Unmaintained
[prosody-modules.git] / mod_admin_message / mod_admin_message.lua
blob4b4d920f444cebccd92c5270551808789fdb9cf3
1 -- Prosody IM
2 --
3 -- mod_admin_message -- Console-over-XMPP implementation.
4 --
5 -- This module depends on Prosody's admin_telnet module
6 --
7 -- Copyright (C) 2008-2010 Matthew Wild
8 -- Copyright (C) 2008-2010 Waqas Hussain
9 -- Copyright (C) 2012-2013 Mikael Berthe
11 -- This project is MIT/X11 licensed. Please see the
12 -- COPYING file in the source package for more information.
15 local st = require "util.stanza";
16 local um_is_admin = require "core.usermanager".is_admin;
18 local admin_telnet = module:depends("admin_telnet");
19 local telnet_def_env = module:shared("/*/admin_telnet/env");
20 local telnet_commands = module:shared("/*/admin_telnet/commands");
21 local default_env_mt = { __index = telnet_def_env };
23 local host = module.host;
25 -- Create our own session. print() will store the results in a text
26 -- string. send(), quit(), disconnect() are no-op.
27 local function new_session ()
28 local session = {
29 send = function () end;
30 quit = function () end;
31 disconnect = function () end;
34 session.print = function (...)
35 local t = {};
36 for i=1,select("#", ...) do
37 t[i] = tostring(select(i, ...));
38 end
39 local text = "| "..table.concat(t, "\t");
40 if session.fulltext then
41 session.fulltext = session.fulltext .. "\n" .. text;
42 else
43 session.fulltext = text;
44 end
45 end
47 session.env = setmetatable({}, default_env_mt);
49 -- Load up environment with helper objects
50 for name, t in pairs(telnet_def_env) do
51 if type(t) == "table" then
52 session.env[name] = setmetatable({ session = session },
53 { __index = t });
54 end
55 end
57 return session;
58 end
60 local function on_message(event)
61 -- Check the type of the incoming stanza to avoid loops:
62 if event.stanza.attr.type == "error" then
63 return; -- We do not want to reply to these, so leave.
64 end
66 local userjid = event.stanza.attr.from;
67 local bodytag = event.stanza:get_child("body");
68 local body = bodytag and bodytag:get_text() or "";
69 if not body or body == "" then
70 -- We do not reply to empty messages (chatstates, etc.)
71 return true;
72 end
74 -- Check the requester is an admin user
75 if not um_is_admin(userjid, module.host) then
76 module:log("info", "Ignored request from non-admin: %s",
77 userjid);
78 return;
79 end
81 -- Create a session in order to use an admin_telnet-like environment
82 local session = new_session();
84 -- Process the message using admin_telnet's onincoming function
85 admin_telnet.console:process_line(session, body.."\n");
87 -- Strip trailing blank line
88 session.fulltext = tostring(session.fulltext):gsub("\n|%s*$", "")
90 -- Send the reply stanza
91 local reply_stanza = st.message({ from = host, to = userjid,
92 type = "chat" }, session.fulltext);
93 module:send(reply_stanza);
95 return true;
96 end
98 local function on_presence(event)
100 local send_presence = false;
102 local userjid = event.stanza.attr.from;
104 -- Check the requester is an admin user
105 if not um_is_admin(userjid, module.host) then
106 module:log("info", "Ignored presence from non-admin: %s",
107 userjid);
108 return;
111 if (event.stanza.attr.type == "subscribe") then
112 module:log("info", "Subscription request from %s", userjid);
113 send_presence = true;
114 -- Send a subscription ack
115 local presence_stanza = st.presence({ from = host,
116 to = userjid, type = "subscribed",
117 id = event.stanza.attr.id });
118 module:send(presence_stanza);
119 elseif (event.stanza.attr.type == "probe") then
120 send_presence = true;
121 elseif (event.stanza.attr.type == "unsubscribe") then
122 -- For information only...
123 module:log("info", "Unsubscription request from %s", userjid);
126 if (send_presence == true) then
127 -- Send a presence stanza
128 module:send(st.presence({ from = host, to = userjid }));
130 return true;
133 module:hook("message/bare", on_message);
134 module:hook("presence/bare", on_presence);