mod_admin_telnet: Don't rely on getpeerchain returning an empty list
[prosody.git] / plugins / mod_register.lua
index 6c690c3bcaa17d59b44e8920eada90467909827d..141a4997966a7448a4b78f0f9a9b929e5206a354 100644 (file)
@@ -7,9 +7,7 @@
 --
 
 
-local hosts = _G.hosts;
 local st = require "util.stanza";
-local datamanager = require "util.datamanager";
 local dataform_new = require "util.dataforms".new;
 local usermanager_user_exists = require "core.usermanager".user_exists;
 local usermanager_create_user = require "core.usermanager".create_user;
@@ -23,6 +21,8 @@ local compat = module:get_option_boolean("registration_compat", true);
 local allow_registration = module:get_option_boolean("allow_registration", false);
 local additional_fields = module:get_option("additional_registration_fields", {});
 
+local account_details = module:open_store("account_details");
+
 local field_map = {
        username = { name = "username", type = "text-single", label = "Username", required = true };
        password = { name = "password", type = "text-private", label = "Password", required = true };
@@ -95,40 +95,23 @@ local function handle_registration_stanza(event)
                session.send(reply);
        else -- stanza.attr.type == "set"
                if query.tags[1] and query.tags[1].name == "remove" then
-                       -- TODO delete user auth data, send iq response, kick all user resources with a <not-authorized/>, delete all user data
                        local username, host = session.username, session.host;
+
+                       local old_session_close = session.close;
+                       session.close = function(session, ...)
+                               session.send(st.reply(stanza));
+                               return old_session_close(session, ...);
+                       end
                        
                        local ok, err = usermanager_delete_user(username, host);
                        
                        if not ok then
                                module:log("debug", "Removing user account %s@%s failed: %s", username, host, err);
+                               session.close = old_session_close;
                                session.send(st.error_reply(stanza, "cancel", "service-unavailable", err));
                                return true;
                        end
                        
-                       session.send(st.reply(stanza));
-                       local roster = session.roster;
-                       for _, session in pairs(hosts[host].sessions[username].sessions) do -- disconnect all resources
-                               session:close({condition = "not-authorized", text = "Account deleted"});
-                       end
-                       -- TODO datamanager should be able to delete all user data itself
-                       datamanager.store(username, host, "vcard", nil);
-                       datamanager.store(username, host, "private", nil);
-                       datamanager.store(username, host, "account_details", nil);
-                       datamanager.list_store(username, host, "offline", nil);
-                       local bare = username.."@"..host;
-                       for jid, item in pairs(roster) do
-                               if jid and jid ~= "pending" then
-                                       if item.subscription == "both" or item.subscription == "from" or (roster.pending and roster.pending[jid]) then
-                                               module:send(st.presence({type="unsubscribed", from=bare, to=jid}));
-                                       end
-                                       if item.subscription == "both" or item.subscription == "to" or item.ask then
-                                               module:send(st.presence({type="unsubscribe", from=bare, to=jid}));
-                                       end
-                               end
-                       end
-                       datamanager.store(username, host, "roster", nil);
-                       datamanager.store(username, host, "privacy", nil);
                        module:log("info", "User removed their account: %s@%s", username, host);
                        module:fire_event("user-deregistered", { username = username, host = host, source = "mod_register", session = session });
                else
@@ -240,13 +223,19 @@ module:hook("stanza/iq/jabber:iq:register:query", function(event)
                                        local host = module.host;
                                        if not username or username == "" then
                                                session.send(st.error_reply(stanza, "modify", "not-acceptable", "The requested username is invalid."));
+                                               return true;
+                                       end
+                                       local user = { username = username , host = host, allowed = true }
+                                       module:fire_event("user-registering", user);
+                                       if not user.allowed then
+                                               session.send(st.error_reply(stanza, "modify", "not-acceptable", "The requested username is forbidden."));
                                        elseif usermanager_user_exists(username, host) then
                                                session.send(st.error_reply(stanza, "cancel", "conflict", "The requested username already exists."));
                                        else
                                                -- TODO unable to write file, file may be locked, etc, what's the correct error?
                                                local error_reply = st.error_reply(stanza, "wait", "internal-server-error", "Failed to write data to disk.");
                                                if usermanager_create_user(username, password, host) then
-                                                       if next(data) and not datamanager.store(username, host, "account_details", data) then
+                                                       if next(data) and not account_details:set(username, data) then
                                                                usermanager_delete_user(username, host);
                                                                session.send(error_reply);
                                                                return true;