diff options
Diffstat (limited to 'plugins/muc/register.lib.lua')
-rw-r--r-- | plugins/muc/register.lib.lua | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/plugins/muc/register.lib.lua b/plugins/muc/register.lib.lua index 95ed1a84..84045f33 100644 --- a/plugins/muc/register.lib.lua +++ b/plugins/muc/register.lib.lua @@ -8,6 +8,10 @@ local allow_unaffiliated = module:get_option_boolean("allow_unaffiliated_registe local enforce_nick = module:get_option_boolean("enforce_registered_nickname", false); +-- Whether to include the current registration data as a dataform. Disabled +-- by default currently as it hasn't been widely tested with clients. +local include_reg_form = module:get_option_boolean("muc_registration_include_form", false); + -- reserved_nicks[nick] = jid local function get_reserved_nicks(room) if room._reserved_nicks then @@ -15,8 +19,7 @@ local function get_reserved_nicks(room) end module:log("debug", "Refreshing reserved nicks..."); local reserved_nicks = {}; - for jid in room:each_affiliation() do - local data = room._affiliation_data[jid]; + for jid, _, data in room:each_affiliation() do local nick = data and data.reserved_nickname; module:log("debug", "Refreshed for %s: %s", jid, nick); if nick then @@ -54,9 +57,23 @@ end); local registration_form = dataforms.new { { name = "FORM_TYPE", type = "hidden", value = "http://jabber.org/protocol/muc#register" }, - { name = "muc#register_roomnick", type = "text-single", label = "Nickname"}, + { name = "muc#register_roomnick", type = "text-single", required = true, label = "Nickname"}, }; +module:handle_items("muc-registration-field", function (event) + module:log("debug", "Adding MUC registration form field: %s", event.item.name); + table.insert(registration_form, event.item); +end, function (event) + module:log("debug", "Removing MUC registration form field: %s", event.item.name); + local removed_field_name = event.item.name; + for i, field in ipairs(registration_form) do + if field.name == removed_field_name then + table.remove(registration_form, i); + break; + end + end +end); + local function enforce_nick_policy(event) local origin, stanza = event.origin, event.stanza; local room = assert(event.room); -- FIXME @@ -67,8 +84,8 @@ local function enforce_nick_policy(event) local reserved_by = get_registered_jid(room, requested_nick); if reserved_by and reserved_by ~= jid_bare(stanza.attr.from) then module:log("debug", "%s attempted to use nick %s reserved by %s", stanza.attr.from, requested_nick, reserved_by); - local reply = st.error_reply(stanza, "cancel", "conflict"):up(); - origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"})); + local reply = st.error_reply(stanza, "cancel", "conflict", nil, room.jid):up(); + origin.send(reply); return true; end @@ -80,8 +97,8 @@ local function enforce_nick_policy(event) event.occupant.nick = jid_bare(event.occupant.nick) .. "/" .. nick; elseif event.dest_occupant.nick ~= jid_bare(event.dest_occupant.nick) .. "/" .. nick then module:log("debug", "Attempt by %s to join as %s, but their reserved nick is %s", stanza.attr.from, requested_nick, nick); - local reply = st.error_reply(stanza, "cancel", "not-acceptable"):up(); - origin.send(reply:tag("x", {xmlns = "http://jabber.org/protocol/muc"})); + local reply = st.error_reply(stanza, "cancel", "not-acceptable", nil, room.jid):up(); + origin.send(reply); return true; end end @@ -116,7 +133,13 @@ local function handle_register_iq(room, origin, stanza) reply:query("jabber:iq:register"); if registered_nick then reply:tag("registered"):up(); - reply:tag("username"):text(registered_nick); + reply:tag("username"):text(registered_nick):up(); + if include_reg_form then + local aff_data = room:get_affiliation_data(user_jid); + if aff_data then + reply:add_child(registration_form:form(aff_data, "result")); + end + end origin.send(reply); return true; end @@ -135,13 +158,25 @@ local function handle_register_iq(room, origin, stanza) return true; end local form_tag = query:get_child("x", "jabber:x:data"); - local reg_data = form_tag and registration_form:data(form_tag); + if not form_tag then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Missing dataform")); + return true; + end + local form_type, err = dataforms.get_type(form_tag); + if not form_type then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Error with form: "..err)); + return true; + elseif form_type ~= "http://jabber.org/protocol/muc#register" then + origin.send(st.error_reply(stanza, "modify", "bad-request", "Error in form")); + return true; + end + local reg_data = registration_form:data(form_tag); if not reg_data then origin.send(st.error_reply(stanza, "modify", "bad-request", "Error in form")); return true; end -- Is the nickname valid? - local desired_nick = resourceprep(reg_data["muc#register_roomnick"]); + local desired_nick = resourceprep(reg_data["muc#register_roomnick"], true); if not desired_nick then origin.send(st.error_reply(stanza, "modify", "bad-request", "Invalid Nickname")); return true; @@ -172,6 +207,13 @@ local function handle_register_iq(room, origin, stanza) -- Checks passed, save the registration if registered_nick ~= desired_nick then local registration_data = { reserved_nickname = desired_nick }; + module:fire_event("muc-registration-submitted", { + room = room; + origin = origin; + stanza = stanza; + submitted_data = reg_data; + affiliation_data = registration_data; + }); local ok, err_type, err_condition = room:set_affiliation(true, user_jid, affiliation or "member", nil, registration_data); if not ok then origin.send(st.error_reply(stanza, err_type, err_condition)); |