# HG changeset patch # User Mikael Berthe # Date 1343751460 -7200 # Node ID dc4eb8fe8b94db3b84253c2a85bbc883bf67358d mod_admin_messageconsole.lua, initial version Initial version for Prosody development version (0.9) diff -r 000000000000 -r dc4eb8fe8b94 mod_admin_messageconsole.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_admin_messageconsole.lua Tue Jul 31 18:17:40 2012 +0200 @@ -0,0 +1,135 @@ +-- Prosody IM +-- +-- This module depends on Prosody's admin_telnet module +-- +-- Copyright (C) 2008-2010 Matthew Wild +-- Copyright (C) 2008-2010 Waqas Hussain +-- Copyright (C) 2012 Mikael Berthe +-- +-- This project is MIT/X11 licensed. Please see the +-- COPYING file in the source package for more information. +-- + +local st = require "util.stanza"; -- Import Prosody's stanza API into 'st' +local um_is_admin = require "core.usermanager".is_admin; + +local admin_telnet = module:depends("admin_telnet"); +local telnet_def_env = module:shared("/*/admin_telnet/env"); +local telnet_commands = module:shared("/*/admin_telnet/commands") +local default_env_mt = { __index = telnet_def_env }; + +local host = module.host; + +-- Create our own session. print() will store the results in a text +-- string. send(), quit(), disconnect() are no-op. +local function new_session () + local session = { + send = function () end; + quit = function () end; + disconnect = function () end; + }; + + session.print = function (...) + local t = {}; + for i=1,select("#", ...) do + t[i] = tostring(select(i, ...)); + end + local text = "| "..table.concat(t, "\t"); + if session.fulltext then + session.fulltext = session.fulltext .. "\n" .. text; + else + session.fulltext = text; + end + end; + + session.env = setmetatable({}, default_env_mt); + + -- Load up environment with helper objects + for name, t in pairs(telnet_def_env) do + if type(t) == "table" then + session.env[name] = setmetatable({ session = session }, + { __index = t }); + end + end + + return session; +end + +local function on_message(event) + -- Check the type of the incoming stanza to avoid loops: + if event.stanza.attr.type == "error" then + return; -- We do not want to reply to these, so leave. + end + + local userjid = event.stanza.attr.from; + local bodytag = event.stanza:get_child("body"); + local body = bodytag and bodytag:get_text() or ""; + if not body or body == "" then + -- We do not reply to empty messages (chatstates, etc.) + return true; + end + + -- Check the requester is an admin user + if not um_is_admin(userjid, module.host) then + module:log("info", "Ignored request from non-admin: %s", + userjid); + return; + end + + -- Create a session in order to use an admin_telnet-like environment + local session = new_session(); + + -- Process the message using admin_telnet's onincoming function + admin_telnet.console_incoming_message(session, body.."\n"); + + -- Strip trailing blank line + session.fulltext = tostring(session.fulltext):gsub("\n\|%s*$", "") + + -- Send the reply stanza + local reply_stanza = st.message({ from = host, to = userjid, + type = "chat" }); + reply_stanza = reply_stanza:body(session.fulltext); + module:send(reply_stanza); + + return true; +end + +local function on_presence(event) + + local send_presence = false; + + local userjid = event.stanza.attr.from; + + -- Check the requester is an admin user + if not um_is_admin(userjid, module.host) then + module:log("info", "Ignored presence from non-admin: %s", + userjid); + return; + end + + if (event.stanza.attr.type == "subscribe") then + module:log("info", "Subscription request from %s", userjid); + send_presence = true; + -- Send a subscription ack + local presence_stanza = st.presence({ from = host, + to = userjid, type = "subscribed", + id = event.stanza.attr.id }); + module:send(presence_stanza); + elseif (event.stanza.attr.type == "probe") then + send_presence = true; + elseif (event.stanza.attr.type == "unsubscribe") then + -- For information only... + module:log("info", "Unsubscription request from %s", userjid); + end + + if (send_presence == true) then + -- Send a presence stanza + module:send(st.presence({ from = host, to = userjid })); + end + return true; +end + +module:hook("message/bare", on_message); +module:hook("presence/bare", on_presence); + +-- vim:set noet sts=8 sw=8: