From a1421105a2eabc7b9c19a2ac7a4d4f372c6696cf Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 28 Apr 2014 16:30:53 -0400 Subject: plugins/muc/mod_muc: Move affiliation monkey patch into own scope --- plugins/muc/mod_muc.lua | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 865e07b9..2aa55a37 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -26,6 +26,7 @@ end local muclib = module:require "muc"; local muc_new_room = muclib.new_room; +room_mt = muclib.room_mt; -- Yes, global. local persistent = module:require "muc/persistent"; local jid_split = require "util.jid".split; local jid_bare = require "util.jid".bare; @@ -52,16 +53,18 @@ local function is_admin(jid) return um_is_admin(jid, module.host); end -room_mt = muclib.room_mt; -- Yes, global. -local _set_affiliation = room_mt.set_affiliation; -local _get_affiliation = room_mt.get_affiliation; -function muclib.room_mt:get_affiliation(jid) - if is_admin(jid) then return "owner"; end - return _get_affiliation(self, jid); -end -function muclib.room_mt:set_affiliation(actor, jid, affiliation, callback, reason) - if is_admin(jid) then return nil, "modify", "not-acceptable"; end - return _set_affiliation(self, actor, jid, affiliation, callback, reason); +do -- Monkey patch to make server admins room owners + local _get_affiliation = room_mt.get_affiliation; + function room_mt:get_affiliation(jid) + if is_admin(jid) then return "owner"; end + return _get_affiliation(self, jid); + end + + local _set_affiliation = room_mt.set_affiliation; + function room_mt:set_affiliation(actor, jid, ...) + if is_admin(jid) then return nil, "modify", "not-acceptable"; end + return _set_affiliation(self, actor, jid, ...); + end end local function room_save(room, forced) -- cgit v1.2.3 From de1d66aad0e12f9985623f051dc88f4ee509121c Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 28 Apr 2014 16:33:54 -0400 Subject: plugins/muc/mod_muc: Use get_option_string instead of get_option and checking --- plugins/muc/mod_muc.lua | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 2aa55a37..8a7ae9c7 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -13,8 +13,6 @@ if module:get_host_type() ~= "component" then end local muc_host = module:get_host(); -local muc_name = module:get_option("name"); -if type(muc_name) ~= "string" then muc_name = "Prosody Chatrooms"; end local restrict_room_creation = module:get_option("restrict_room_creation"); if restrict_room_creation then if restrict_room_creation == true then @@ -44,7 +42,7 @@ local room_configs = module:open_store("config"); muclib.set_max_history_length(module:get_option_number("max_history_messages")); module:depends("disco"); -module:add_identity("conference", "text", muc_name); +module:add_identity("conference", "text", module:get_option_string("name", "Prosody Chatrooms")); module:add_feature("http://jabber.org/protocol/muc"); module:depends "muc_unique" module:require "muc/lock"; -- cgit v1.2.3 From d14f2b82f19d187dcc22eb3a58cec7647900036e Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 28 Apr 2014 16:31:21 -0400 Subject: plugins/muc/mod_muc: No need to treat the host room specially --- plugins/muc/mod_muc.lua | 6 ------ 1 file changed, 6 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 8a7ae9c7..ecc136f1 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -12,7 +12,6 @@ if module:get_host_type() ~= "component" then error("MUC should be loaded as a component, please see http://prosody.im/doc/components", 0); end -local muc_host = module:get_host(); local restrict_room_creation = module:get_option("restrict_room_creation"); if restrict_room_creation then if restrict_room_creation == true then @@ -120,10 +119,6 @@ for jid in pairs(persistent_rooms) do end if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end -local host_room = muc_new_room(muc_host); -host_room.save = room_save; -rooms[muc_host] = host_room; - module:hook("host-disco-items", function(event) local reply = event.reply; module:log("debug", "host-disco-items called"); @@ -227,7 +222,6 @@ function shutdown_component() for roomjid, room in pairs(rooms) do room:clear(x); end - host_room:clear(x); end end module.unload = shutdown_component; -- cgit v1.2.3 From 8a13710f6f44199de9eb227e5a6401cb0bc45857 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 12:54:04 -0400 Subject: plugins/muc: Add room:has_occupant() method --- plugins/muc/mod_muc.lua | 2 +- plugins/muc/muc.lib.lua | 4 ++++ 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index ecc136f1..f0458e16 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -136,7 +136,7 @@ end) module:hook("muc-occupant-left",function(event) local room = event.room - if not next(room._occupants) and not persistent.get(room) then -- empty, non-persistent room + if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room module:fire_event("muc-room-destroyed", { room = room }); end end); diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 6aca5c62..7c039ce3 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -79,6 +79,10 @@ do end end +function room_mt:has_occupant() + return next(self._occupants, nil) ~= nil +end + function room_mt:get_occupant_by_real_jid(real_jid) local occupant_jid = self:get_occupant_jid(real_jid); if occupant_jid == nil then return nil end -- cgit v1.2.3 From 19f4fafa22434ec32c4707184da910bbce75bb85 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 14:24:50 -0400 Subject: plugins/muc/mod_muc: Move room persistence to own block --- plugins/muc/mod_muc.lua | 104 ++++++++++++++++++++++++++---------------------- 1 file changed, 56 insertions(+), 48 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index f0458e16..3262905e 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -24,7 +24,6 @@ end local muclib = module:require "muc"; local muc_new_room = muclib.new_room; room_mt = muclib.room_mt; -- Yes, global. -local persistent = module:require "muc/persistent"; local jid_split = require "util.jid".split; local jid_bare = require "util.jid".bare; local st = require "util.stanza"; @@ -33,9 +32,6 @@ local hosts = prosody.hosts; rooms = {}; local rooms = rooms; -local persistent_rooms_storage = module:open_store("persistent"); -local persistent_rooms = persistent_rooms_storage:get() or {}; -local room_configs = module:open_store("config"); -- Configurable options muclib.set_max_history_length(module:get_option_number("max_history_messages")); @@ -64,32 +60,8 @@ do -- Monkey patch to make server admins room owners end end -local function room_save(room, forced) - local node = jid_split(room.jid); - local is_persistent = persistent.get(room); - persistent_rooms[room.jid] = is_persistent; - if is_persistent then - local history = room._data.history; - room._data.history = nil; - local data = { - jid = room.jid; - _data = room._data; - _affiliations = room._affiliations; - }; - room_configs:set(node, data); - room._data.history = history; - elseif forced then - room_configs:set(node, nil); - if not next(room._occupants) then -- Room empty - rooms[room.jid] = nil; - end - end - if forced then persistent_rooms_storage:set(nil, persistent_rooms); end -end - function create_room(jid) local room = muc_new_room(jid); - room.save = room_save; rooms[jid] = room; module:fire_event("muc-room-created", { room = room }); return room; @@ -103,21 +75,64 @@ function get_room_from_jid(room_jid) return rooms[room_jid] end -local persistent_errors = false; -for jid in pairs(persistent_rooms) do - local node = jid_split(jid); - local data = room_configs:get(node); - if data then - local room = create_room(jid); - room._data = data._data; - room._affiliations = data._affiliations; - else -- missing room data - persistent_rooms[jid] = nil; - module:log("error", "Missing data for room '%s', removing from persistent room list", jid); - persistent_errors = true; +do -- Persistent rooms + local persistent = module:require "muc/persistent"; + local persistent_rooms_storage = module:open_store("persistent"); + local persistent_rooms = persistent_rooms_storage:get() or {}; + local room_configs = module:open_store("config"); + + local function room_save(room, forced) + local node = jid_split(room.jid); + local is_persistent = persistent.get(room); + persistent_rooms[room.jid] = is_persistent; + if is_persistent then + local history = room._data.history; + room._data.history = nil; + local data = { + jid = room.jid; + _data = room._data; + _affiliations = room._affiliations; + }; + room_configs:set(node, data); + room._data.history = history; + elseif forced then + room_configs:set(node, nil); + if not next(room._occupants) then -- Room empty + rooms[room.jid] = nil; + end + end + if forced then persistent_rooms_storage:set(nil, persistent_rooms); end end + + -- When room is created, over-ride 'save' method + module:hook("muc-room-created", function(event) + event.room.save = room_save; + end); + + -- Automatically destroy empty non-persistent rooms + module:hook("muc-occupant-left",function(event) + local room = event.room + if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room + module:fire_event("muc-room-destroyed", { room = room }); + end + end); + + local persistent_errors = false; + for jid in pairs(persistent_rooms) do + local node = jid_split(jid); + local data = room_configs:get(node); + if data then + local room = create_room(jid); + room._data = data._data; + room._affiliations = data._affiliations; + else -- missing room data + persistent_rooms[jid] = nil; + module:log("error", "Missing data for room '%s', removing from persistent room list", jid); + persistent_errors = true; + end + end + if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end end -if persistent_errors then persistent_rooms_storage:set(nil, persistent_rooms); end module:hook("host-disco-items", function(event) local reply = event.reply; @@ -134,13 +149,6 @@ module:hook("muc-room-destroyed",function(event) forget_room(room.jid) end) -module:hook("muc-occupant-left",function(event) - local room = event.room - if not room:has_occupant() and not persistent.get(room) then -- empty, non-persistent room - module:fire_event("muc-room-destroyed", { room = room }); - end -end); - -- Watch presence to create rooms local function attempt_room_creation(event) local origin, stanza = event.origin, event.stanza; -- cgit v1.2.3 From c010a538d09eaa0a958590329f7fc7ae62e695a5 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 14:50:13 -0400 Subject: plugins/muc/mod_muc: Remove support for `host_session.muc` --- plugins/muc/mod_muc.lua | 3 --- 1 file changed, 3 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 3262905e..d7d3ac37 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -205,8 +205,6 @@ for event_name, method in pairs { end, -2) end -hosts[module:get_host()].muc = { rooms = rooms }; - local saved = false; module.save = function() saved = true; @@ -220,7 +218,6 @@ module.restore = function(data) room._data = oldroom._data; room._affiliations = oldroom._affiliations; end - hosts[module:get_host()].muc = { rooms = rooms }; end function shutdown_component() -- cgit v1.2.3 From 184b7839475c004c55eb6bda315a69ae3ccaee95 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 15:13:06 -0400 Subject: plugins/muc: Move 'module:get_option_number("max_history_messages")' from mod_muc into history lib; remove from muclib exports --- plugins/muc/history.lib.lua | 3 ++- plugins/muc/mod_muc.lua | 2 -- plugins/muc/muc.lib.lua | 2 -- 3 files changed, 2 insertions(+), 5 deletions(-) diff --git a/plugins/muc/history.lib.lua b/plugins/muc/history.lib.lua index 596f92da..1c14cf84 100644 --- a/plugins/muc/history.lib.lua +++ b/plugins/muc/history.lib.lua @@ -11,7 +11,8 @@ local gettime = os.time; local datetime = require "util.datetime"; local st = require "util.stanza"; -local default_history_length, max_history_length = 20, math.huge; +local default_history_length = 20; +local max_history_length = module:get_option_number("max_history_messages", math.huge); local function set_max_history_length(_max_history_length) max_history_length = _max_history_length or math.huge; diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index d7d3ac37..91b69829 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -33,8 +33,6 @@ local hosts = prosody.hosts; rooms = {}; local rooms = rooms; --- Configurable options -muclib.set_max_history_length(module:get_option_number("max_history_messages")); module:depends("disco"); module:add_identity("conference", "text", module:get_option_string("name", "Prosody Chatrooms")); diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 7c039ce3..27d738de 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -1114,8 +1114,6 @@ room_mt.set_historylength = history.set_length; local _M = {}; -- module "muc" -_M.set_max_history_length = history.set_max_length; - function _M.new_room(jid, config) return setmetatable({ jid = jid; -- cgit v1.2.3 From f0e4ed8339ed677c644bd2bf8d17aa31a18472da Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 17:18:14 -0400 Subject: plugins/muc/mod_muc: Use module:shared instead of save/restore --- plugins/muc/mod_muc.lua | 31 ++++++------------------------- 1 file changed, 6 insertions(+), 25 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 91b69829..751491c2 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -30,9 +30,8 @@ local st = require "util.stanza"; local um_is_admin = require "core.usermanager".is_admin; local hosts = prosody.hosts; -rooms = {}; -local rooms = rooms; - +local rooms = module:shared "rooms"; +_G.rooms = rooms; module:depends("disco"); module:add_identity("conference", "text", module:get_option_string("name", "Prosody Chatrooms")); @@ -203,31 +202,13 @@ for event_name, method in pairs { end, -2) end -local saved = false; -module.save = function() - saved = true; - return {rooms = rooms}; -end -module.restore = function(data) - for jid, oldroom in pairs(data.rooms or {}) do - local room = create_room(jid); - room._jid_nick = oldroom._jid_nick; - room._occupants = oldroom._occupants; - room._data = oldroom._data; - room._affiliations = oldroom._affiliations; - end -end - function shutdown_component() - if not saved then - local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"}) - :tag("status", { code = "332"}):up(); - for roomjid, room in pairs(rooms) do - room:clear(x); - end + local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"}) + :tag("status", { code = "332"}):up(); + for roomjid, room in pairs(rooms) do + room:clear(x); end end -module.unload = shutdown_component; module:hook_global("server-stopping", shutdown_component); -- Ad-hoc commands -- cgit v1.2.3 From dec7312aa52711ea86d95d697916f8a4e2d07888 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 18:50:30 -0400 Subject: plugins/muc/lock.lib: lock inside of pre-create instead of 'created' --- plugins/muc/lock.lib.lua | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/plugins/muc/lock.lib.lua b/plugins/muc/lock.lib.lua index 7cf19be3..319a6973 100644 --- a/plugins/muc/lock.lib.lua +++ b/plugins/muc/lock.lib.lua @@ -23,7 +23,10 @@ local function is_locked(room) end if lock_rooms then - module:hook("muc-room-created", function(event) + module:hook("muc-room-pre-create", function(event) + -- Older groupchat protocol doesn't lock + if not event.stanza:get_child("x", "http://jabber.org/protocol/muc") then return end + -- Lock room at creation local room = event.room; lock(room); if lock_room_timeout and lock_room_timeout > 0 then @@ -33,16 +36,9 @@ if lock_rooms then end end); end - end); + end, 10); end --- Older groupchat protocol doesn't lock -module:hook("muc-room-pre-create", function(event) - if is_locked(event.room) and not event.stanza:get_child("x", "http://jabber.org/protocol/muc") then - unlock(event.room); - end -end, 10); - -- Don't let users into room while it is locked module:hook("muc-occupant-pre-join", function(event) if not event.is_new_room and is_locked(event.room) then -- Deny entry -- cgit v1.2.3 From 0b8ddb3f56709f829959041ff470837b1e861f4c Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 19:00:45 -0400 Subject: plugins/muc/mod_muc: Move `restrict_room_creation` into own area. now uses pre-create hook --- plugins/muc/mod_muc.lua | 40 +++++++++++++++++++++------------------- 1 file changed, 21 insertions(+), 19 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 751491c2..0940bc43 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -12,15 +12,6 @@ if module:get_host_type() ~= "component" then error("MUC should be loaded as a component, please see http://prosody.im/doc/components", 0); end -local restrict_room_creation = module:get_option("restrict_room_creation"); -if restrict_room_creation then - if restrict_room_creation == true then - restrict_room_creation = "admin"; - elseif restrict_room_creation ~= "admin" and restrict_room_creation ~= "local" then - restrict_room_creation = nil; - end -end - local muclib = module:require "muc"; local muc_new_room = muclib.new_room; room_mt = muclib.room_mt; -- Yes, global. @@ -146,20 +137,31 @@ module:hook("muc-room-destroyed",function(event) forget_room(room.jid) end) +do + local restrict_room_creation = module:get_option("restrict_room_creation"); + if restrict_room_creation == true then + restrict_room_creation = "admin"; + end + if restrict_room_creation then + local host_suffix = module.host:gsub("^[^%.]+%.", ""); + module:hook("muc-room-pre-create", function(event) + local user_jid = event.stanza.attr.from; + if not is_admin(user_jid) and not ( + restrict_room_creation == "local" and + select(2, jid_split(user_jid)) == host_suffix + ) then + origin.send(st.error_reply(stanza, "cancel", "not-allowed")); + return true; + end + end); + end +end + -- Watch presence to create rooms local function attempt_room_creation(event) local origin, stanza = event.origin, event.stanza; local room_jid = jid_bare(stanza.attr.to); - if stanza.attr.type == nil and - get_room_from_jid(room_jid) == nil and - ( - not(restrict_room_creation) or - is_admin(stanza.attr.from) or - ( - restrict_room_creation == "local" and - select(2, jid_split(stanza.attr.from)) == module.host:gsub("^[^%.]+%.", "") - ) - ) then + if stanza.attr.type == nil and get_room_from_jid(room_jid) == nil then create_room(room_jid); end end -- cgit v1.2.3 From 6e37374435557c2c1b8c8fd67c7c2ec8e209abcd Mon Sep 17 00:00:00 2001 From: daurnimator Date: Tue, 29 Apr 2014 19:35:25 -0400 Subject: plugins/muc/mod_muc: Remove attempt_room_creation and create_room function. Instead have a 'track_room' function called from the end of the pre-create hook, and just create an un-tracked room object when we get a presence --- plugins/muc/mod_muc.lua | 43 +++++++++++++++++++------------------------ 1 file changed, 19 insertions(+), 24 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 0940bc43..519b1e34 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -13,7 +13,6 @@ if module:get_host_type() ~= "component" then end local muclib = module:require "muc"; -local muc_new_room = muclib.new_room; room_mt = muclib.room_mt; -- Yes, global. local jid_split = require "util.jid".split; local jid_bare = require "util.jid".bare; @@ -48,11 +47,8 @@ do -- Monkey patch to make server admins room owners end end -function create_room(jid) - local room = muc_new_room(jid); - rooms[jid] = room; - module:fire_event("muc-room-created", { room = room }); - return room; +function track_room(room) + rooms[room.jid] = room; end function forget_room(jid) @@ -93,9 +89,9 @@ do -- Persistent rooms end -- When room is created, over-ride 'save' method - module:hook("muc-room-created", function(event) + module:hook("muc-occupant-pre-create", function(event) event.room.save = room_save; - end); + end, 1000); -- Automatically destroy empty non-persistent rooms module:hook("muc-occupant-left",function(event) @@ -110,9 +106,10 @@ do -- Persistent rooms local node = jid_split(jid); local data = room_configs:get(node); if data then - local room = create_room(jid); + local room = muclib.new_room(jid); room._data = data._data; room._affiliations = data._affiliations; + track_room(room); else -- missing room data persistent_rooms[jid] = nil; module:log("error", "Missing data for room '%s', removing from persistent room list", jid); @@ -132,6 +129,10 @@ module:hook("host-disco-items", function(event) end end); +module:hook("muc-room-pre-create", function(event) + track_room(event.room); +end, -1000); + module:hook("muc-room-destroyed",function(event) local room = event.room forget_room(room.jid) @@ -157,18 +158,6 @@ do end end --- Watch presence to create rooms -local function attempt_room_creation(event) - local origin, stanza = event.origin, event.stanza; - local room_jid = jid_bare(stanza.attr.to); - if stanza.attr.type == nil and get_room_from_jid(room_jid) == nil then - create_room(room_jid); - end -end -module:hook("presence/full", attempt_room_creation, -1) -module:hook("presence/bare", attempt_room_creation, -1) -module:hook("presence/host", attempt_room_creation, -1) - for event_name, method in pairs { -- Normal room interactions ["iq-get/bare/http://jabber.org/protocol/disco#info:query"] = "handle_disco_info_get_query" ; @@ -195,10 +184,16 @@ for event_name, method in pairs { } do module:hook(event_name, function (event) local origin, stanza = event.origin, event.stanza; - local room = get_room_from_jid(jid_bare(stanza.attr.to)) + local room_jid = jid_bare(stanza.attr.to); + local room = get_room_from_jid(room_jid); if room == nil then - origin.send(st.error_reply(stanza, "cancel", "not-allowed")); - return true; + -- Watch presence to create rooms + if stanza.attr.type == nil and stanza.name == "presence" then + room = muclib.new_room(room_jid); + else + origin.send(st.error_reply(stanza, "cancel", "not-allowed")); + return true; + end end return room[method](room, origin, stanza); end, -2) -- cgit v1.2.3 From aeb3c041440a149cc47ab960c16cba021b16ac14 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 30 Apr 2014 13:12:32 -0400 Subject: plugins/muc/mod_muc.lua: Add "each_room" function to iterate over rooms (instead of accessing directly) --- plugins/muc/mod_muc.lua | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 519b1e34..5ad86025 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -14,6 +14,7 @@ end local muclib = module:require "muc"; room_mt = muclib.room_mt; -- Yes, global. +local iterators = require "util.iterators"; local jid_split = require "util.jid".split; local jid_bare = require "util.jid".bare; local st = require "util.stanza"; @@ -59,6 +60,10 @@ function get_room_from_jid(room_jid) return rooms[room_jid] end +function each_room() + return iterators.values(rooms); +end + do -- Persistent rooms local persistent = module:require "muc/persistent"; local persistent_rooms_storage = module:open_store("persistent"); @@ -122,9 +127,9 @@ end module:hook("host-disco-items", function(event) local reply = event.reply; module:log("debug", "host-disco-items called"); - for jid, room in pairs(rooms) do + for room in each_room() do if not room:get_hidden() then - reply:tag("item", {jid=jid, name=room:get_name()}):up(); + reply:tag("item", {jid=room.jid, name=room:get_name()}):up(); end end end); @@ -202,7 +207,7 @@ end function shutdown_component() local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"}) :tag("status", { code = "332"}):up(); - for roomjid, room in pairs(rooms) do + for room in each_room() do room:clear(x); end end @@ -211,7 +216,6 @@ module:hook_global("server-stopping", shutdown_component); -- Ad-hoc commands module:depends("adhoc") local t_concat = table.concat; -local keys = require "util.iterators".keys; local adhoc_new = module:require "adhoc".new; local adhoc_initial = require "util.adhoc".new_initial_data_form; local dataforms_new = require "util.dataforms".new; @@ -225,7 +229,7 @@ local destroy_rooms_layout = dataforms_new { }; local destroy_rooms_handler = adhoc_initial(destroy_rooms_layout, function() - return { rooms = array.collect(keys(rooms)):sort() }; + return { rooms = array.collect(each_room):pluck("jid"):sort(); }; end, function(fields, errors) if errors then local errmsg = {}; -- cgit v1.2.3 From 7df6f92a24114e8087f4585a093a799fab21da7f Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 30 Apr 2014 12:43:04 -0400 Subject: plugins/muc/mod_muc: Don't use rooms object directory in adhoc section --- plugins/muc/mod_muc.lua | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 5ad86025..9f022b3a 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -239,8 +239,7 @@ end, function(fields, errors) return { status = "completed", error = { message = t_concat(errmsg, "\n") } }; end for _, room in ipairs(fields.rooms) do - rooms[room]:destroy(); - rooms[room] = nil; + get_room_from_jid(room):destroy(); end return { status = "completed", info = "The following rooms were destroyed:\n"..t_concat(fields.rooms, "\n") }; end); -- cgit v1.2.3 From 169df15f6cec44c23deda5c8274c30fbb357fef2 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 30 Apr 2014 12:43:47 -0400 Subject: plugins/muc/mod_muc: Place adhoc section into own scope --- plugins/muc/mod_muc.lua | 66 ++++++++++++++++++++++++------------------------- 1 file changed, 33 insertions(+), 33 deletions(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 9f022b3a..79123ab5 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -6,8 +6,6 @@ -- COPYING file in the source package for more information. -- -local array = require "util.array"; - if module:get_host_type() ~= "component" then error("MUC should be loaded as a component, please see http://prosody.im/doc/components", 0); end @@ -213,36 +211,38 @@ function shutdown_component() end module:hook_global("server-stopping", shutdown_component); --- Ad-hoc commands -module:depends("adhoc") -local t_concat = table.concat; -local adhoc_new = module:require "adhoc".new; -local adhoc_initial = require "util.adhoc".new_initial_data_form; -local dataforms_new = require "util.dataforms".new; - -local destroy_rooms_layout = dataforms_new { - title = "Destroy rooms"; - instructions = "Select the rooms to destroy"; - - { name = "FORM_TYPE", type = "hidden", value = "http://prosody.im/protocol/muc#destroy" }; - { name = "rooms", type = "list-multi", required = true, label = "Rooms to destroy:"}; -}; - -local destroy_rooms_handler = adhoc_initial(destroy_rooms_layout, function() - return { rooms = array.collect(each_room):pluck("jid"):sort(); }; -end, function(fields, errors) - if errors then - local errmsg = {}; - for name, err in pairs(errors) do - errmsg[#errmsg + 1] = name .. ": " .. err; +do -- Ad-hoc commands + module:depends "adhoc"; + local t_concat = table.concat; + local adhoc_new = module:require "adhoc".new; + local adhoc_initial = require "util.adhoc".new_initial_data_form; + local array = require "util.array"; + local dataforms_new = require "util.dataforms".new; + + local destroy_rooms_layout = dataforms_new { + title = "Destroy rooms"; + instructions = "Select the rooms to destroy"; + + { name = "FORM_TYPE", type = "hidden", value = "http://prosody.im/protocol/muc#destroy" }; + { name = "rooms", type = "list-multi", required = true, label = "Rooms to destroy:"}; + }; + + local destroy_rooms_handler = adhoc_initial(destroy_rooms_layout, function() + return { rooms = array.collect(each_room):pluck("jid"):sort(); }; + end, function(fields, errors) + if errors then + local errmsg = {}; + for name, err in pairs(errors) do + errmsg[#errmsg + 1] = name .. ": " .. err; + end + return { status = "completed", error = { message = t_concat(errmsg, "\n") } }; end - return { status = "completed", error = { message = t_concat(errmsg, "\n") } }; - end - for _, room in ipairs(fields.rooms) do - get_room_from_jid(room):destroy(); - end - return { status = "completed", info = "The following rooms were destroyed:\n"..t_concat(fields.rooms, "\n") }; -end); -local destroy_rooms_desc = adhoc_new("Destroy Rooms", "http://prosody.im/protocol/muc#destroy", destroy_rooms_handler, "admin"); + for _, room in ipairs(fields.rooms) do + get_room_from_jid(room):destroy(); + end + return { status = "completed", info = "The following rooms were destroyed:\n"..t_concat(fields.rooms, "\n") }; + end); + local destroy_rooms_desc = adhoc_new("Destroy Rooms", "http://prosody.im/protocol/muc#destroy", destroy_rooms_handler, "admin"); -module:provides("adhoc", destroy_rooms_desc); + module:provides("adhoc", destroy_rooms_desc); +end -- cgit v1.2.3 From c7f704026295901fadf0be6407110bd67075e0e3 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 19 May 2014 13:39:45 -0400 Subject: plugins/muc/mod_muc: Get rid of room global; use module:shared to get it --- plugins/muc/mod_muc.lua | 1 - 1 file changed, 1 deletion(-) diff --git a/plugins/muc/mod_muc.lua b/plugins/muc/mod_muc.lua index 79123ab5..628c72b3 100644 --- a/plugins/muc/mod_muc.lua +++ b/plugins/muc/mod_muc.lua @@ -20,7 +20,6 @@ local um_is_admin = require "core.usermanager".is_admin; local hosts = prosody.hosts; local rooms = module:shared "rooms"; -_G.rooms = rooms; module:depends("disco"); module:add_identity("conference", "text", module:get_option_string("name", "Prosody Chatrooms")); -- cgit v1.2.3 From 61778d912d7b8eaf29609c0c928eb0f031e4583a Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 19 May 2014 13:40:24 -0400 Subject: plugins/muc/muc: Always send occupant list to joining sessions --- plugins/muc/muc.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 27d738de..df823180 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -453,7 +453,7 @@ function room_mt:handle_presence_to_occupant(origin, stanza) end self:save_occupant(dest_occupant); - if orig_occupant == nil and is_first_dest_session then + if orig_occupant == nil then -- Send occupant list to newly joined user self:send_occupant_list(real_jid, function(nick, occupant) -- Don't include self -- cgit v1.2.3 From 75357b0f410a3e344b5e4c7cbbcbb24ba7d9d140 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 19 May 2014 13:40:54 -0400 Subject: plugins/muc/muc: Better check for live sessions --- plugins/muc/muc.lib.lua | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index df823180..5838cbe9 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -100,11 +100,21 @@ function room_mt:save_occupant(occupant) self._jid_nick[real_jid] = nil; end end - if occupant.role ~= nil and next(occupant.sessions) then + + local has_live_session = false + if occupant.role ~= nil then for real_jid, presence in occupant:each_session() do - self._jid_nick[real_jid] = occupant.nick; + if presence.attr.type == nil then + has_live_session = true + self._jid_nick[real_jid] = occupant.nick; + end end - else + if not has_live_session then + -- Has no live sessions left; they have left the room. + occupant.role = nil + end + end + if not has_live_session then occupant = nil end self._occupants[id] = occupant -- cgit v1.2.3 From d6b18f4e20e7ac945426acf5d869b446c61d57e0 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Mon, 19 May 2014 13:47:28 -0400 Subject: plugins/muc/occupant: Check for type == nil rather than type ~= unavailable --- plugins/muc/occupant.lib.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/plugins/muc/occupant.lib.lua b/plugins/muc/occupant.lib.lua index 5cecb139..6a3f7df4 100644 --- a/plugins/muc/occupant.lib.lua +++ b/plugins/muc/occupant.lib.lua @@ -53,7 +53,7 @@ end -- finds another session to be the primary (there might not be one) function occupant_mt:choose_new_primary() for jid, pr in self:each_session() do - if pr.attr.type ~= "unavailable" then + if pr.attr.type == nil then return jid; end end -- cgit v1.2.3 From 347202819d3fd42945160856f0c409a245b4d1f1 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 21 May 2014 13:11:00 -0400 Subject: plugins/muc/muc: Only set role to nil if it's the last session to leave --- plugins/muc/muc.lib.lua | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 5838cbe9..34934213 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -410,7 +410,9 @@ function room_mt:handle_presence_to_occupant(origin, stanza) local dest_nick; if dest_occupant == nil then -- Session is leaving log("debug", "session %s is leaving occupant %s", real_jid, orig_occupant.nick); - orig_occupant.role = nil; + if is_last_orig_session then + orig_occupant.role = nil; + end orig_occupant:set_session(real_jid, stanza); else log("debug", "session %s is changing from occupant %s to %s", real_jid, orig_occupant.nick, dest_occupant.nick); -- cgit v1.2.3 From 4d7106bee63fe544a4bec49c201d56b93d3794d3 Mon Sep 17 00:00:00 2001 From: daurnimator Date: Wed, 21 May 2014 13:19:57 -0400 Subject: plugins/muc/muc.lib: Even unavailable session need to be routed to sometimes (e.g. their own leave) --- plugins/muc/muc.lib.lua | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/plugins/muc/muc.lib.lua b/plugins/muc/muc.lib.lua index 34934213..0b361763 100644 --- a/plugins/muc/muc.lib.lua +++ b/plugins/muc/muc.lib.lua @@ -123,10 +123,8 @@ end function room_mt:route_to_occupant(occupant, stanza) local to = stanza.attr.to; for jid, pr in occupant:each_session() do - if pr.attr.type ~= "unavailable" then - stanza.attr.to = jid; - self:route_stanza(stanza); - end + stanza.attr.to = jid; + self:route_stanza(stanza); end stanza.attr.to = to; end -- cgit v1.2.3