- log("debug", "%s joining as %s", from, to);
- if not next(self._affiliations) then -- new room, no owners
- self._affiliations[jid_bare(from)] = "owner";
- if self.locked and not stanza:get_child("x", "http://jabber.org/protocol/muc") then
- self.locked = nil; -- Older groupchat protocol doesn't lock
- end
- elseif self.locked then -- Deny entry
- origin.send(st.error_reply(stanza, "cancel", "item-not-found"));
+ local password = stanza:get_child("x", "http://jabber.org/protocol/muc");
+ password = password and password:get_child_text("password", "http://jabber.org/protocol/muc");
+ if not password or password == "" then password = nil; end
+ if room:get_password() ~= password then
+ local from, to = stanza.attr.from, stanza.attr.to;
+ log("debug", "%s couldn't join due to invalid password: %s", from, to);
+ local reply = st.error_reply(stanza, "auth", "not-authorized"):up();
+ reply.tags[1].attr.code = "401";
+ event.origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
+ return true;
+ end
+end, -1)
+
+module:hook("muc-occupant-pre-join/nick-conflict", function(event)
+ local room, stanza = event.room, event.stanza;
+ local from, to = stanza.attr.from, stanza.attr.to;
+ local occupant = room._occupants[to]
+ if occupant -- occupant already exists
+ and jid_bare(from) ~= jid_bare(occupant.jid) then -- and has different bare real jid
+ log("debug", "%s couldn't join due to nick conflict: %s", from, to);
+ local reply = st.error_reply(stanza, "cancel", "conflict"):up();
+ reply.tags[1].attr.code = "409";
+ event.origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"}));
+ return true;
+ end
+end, -1)
+
+module:hook("muc-occupant-pre-join/locked", function(event)
+ if event.room:is_locked() then -- Deny entry
+ event.origin.send(st.error_reply(event.stanza, "cancel", "item-not-found"));