MUC: Hide new MUC room storage format behind an off-by-default option
[prosody.git] / plugins / muc / muc.lib.lua
index 71f199dd48206d1d4dce2ab350b54f88478faec3..ac8ebaddfb746525a9cb3747511e62bec844e8f8 100644 (file)
@@ -446,7 +446,6 @@ end
 
 function room_mt:handle_normal_presence(origin, stanza)
        local type = stanza.attr.type;
-       local muc_x = stanza:get_child("x", "http://jabber.org/protocol/muc");
        local real_jid = stanza.attr.from;
        local bare_jid = jid_bare(real_jid);
        local orig_occupant = self:get_occupant_by_real_jid(real_jid);
@@ -456,18 +455,13 @@ function room_mt:handle_normal_presence(origin, stanza)
        if type == "unavailable" then -- luacheck: ignore 542
                -- FIXME Why the empty if branch?
                -- dest_occupant = nil
-       elseif orig_occupant and not muc_x and orig_occupant.nick == stanza.attr.to then -- Just a presence update
+       elseif orig_occupant and orig_occupant.nick == stanza.attr.to then -- Just a presence update
                log("debug", "presence update for %s from session %s", orig_occupant.nick, real_jid);
                dest_occupant = orig_occupant;
        else
                local dest_jid = stanza.attr.to;
                dest_occupant = self:get_occupant_by_nick(dest_jid);
-               if muc_x then
-                       dest_occupant = self:new_occupant(bare_jid, dest_jid);
-                       if dest_occupant == nil then
-                               is_first_dest_session = true;
-                       end
-               elseif dest_occupant == nil then
+               if dest_occupant == nil then
                        log("debug", "no occupant found for %s; creating new occupant object for %s", dest_jid, real_jid);
                        is_first_dest_session = true;
                        dest_occupant = self:new_occupant(bare_jid, dest_jid);
@@ -483,6 +477,7 @@ function room_mt:handle_normal_presence(origin, stanza)
        end
 
        -- TODO Handle these cases sensibly
+       local muc_x = stanza:get_child("x", "http://jabber.org/protocol/muc");
        if orig_occupant == nil and not muc_x then
                module:log("debug", "Join without <x>, possibly desynced");
        elseif orig_occupant ~= nil and muc_x then
@@ -582,7 +577,7 @@ function room_mt:handle_normal_presence(origin, stanza)
                end
                self:save_occupant(dest_occupant);
 
-               if orig_occupant == nil then
+               if orig_occupant == nil or muc_x then
                        -- Send occupant list to newly joined user
                        self:send_occupant_list(real_jid, function(nick, occupant) -- luacheck: ignore 212
                                -- Don't include self
@@ -603,7 +598,7 @@ function room_mt:handle_normal_presence(origin, stanza)
                        self:route_stanza(pr);
                end
 
-               if orig_occupant == nil then
+               if orig_occupant == nil or muc_x then
                        if is_first_dest_session then
                                module:fire_event("muc-occupant-joined", {
                                        room = self;
@@ -877,7 +872,8 @@ function room_mt:handle_admin_query_get_command(origin, stanza)
                -- You need to be at least an admin, and be requesting info about your affifiliation or lower
                -- e.g. an admin can't ask for a list of owners
                local affiliation_rank = valid_affiliations[affiliation or "none"];
-               if affiliation_rank >= valid_affiliations.admin and affiliation_rank >= _aff_rank then
+               if affiliation_rank >= valid_affiliations.admin and affiliation_rank >= _aff_rank
+               or self:get_members_only() and self:get_whois() == "anyone" and affiliation_rank >= valid_affiliations.member then
                        local reply = st.reply(stanza):query("http://jabber.org/protocol/muc#admin");
                        for jid in self:each_affiliation(_aff or "none") do
                                reply:tag("item", {affiliation = _aff, jid = jid}):up();
@@ -1308,13 +1304,24 @@ function _M.new_room(jid, config)
        }, room_mt);
 end
 
+local new_format = module:get_option_boolean("new_muc_storage_format", false);
+
 function room_mt:freeze(live)
-       local frozen, state = {
-               _jid = self.jid;
-               _data = self._data;
-       };
-       for user, affiliation in pairs(self._affiliations) do
-               frozen[user] = affiliation;
+       local frozen, state;
+       if new_format then
+               frozen = {
+                       _jid = self.jid;
+                       _data = self._data;
+               };
+               for user, affiliation in pairs(self._affiliations) do
+                       frozen[user] = affiliation;
+               end
+       else
+               frozen = {
+                       jid = self.jid;
+                       _data = self._data;
+                       _affiliations = self._affiliations;
+               };
        end
        if live then
                state = {};