16 local os_time = os.time; |
16 local os_time = os.time; |
17 local nodeprep = require "util.encodings".stringprep.nodeprep; |
17 local nodeprep = require "util.encodings".stringprep.nodeprep; |
18 |
18 |
19 module:add_feature("jabber:iq:register"); |
19 module:add_feature("jabber:iq:register"); |
20 |
20 |
21 module:add_iq_handler("c2s", "jabber:iq:register", function (session, stanza) |
21 module:hook("iq/self/jabber:iq:register:query", function(event) |
22 if stanza.tags[1].name == "query" then |
22 local session, stanza = event.origin, event.stanza; |
23 local query = stanza.tags[1]; |
23 |
24 if stanza.attr.type == "get" then |
24 local query = stanza.tags[1]; |
25 local reply = st.reply(stanza); |
25 if stanza.attr.type == "get" then |
26 reply:tag("query", {xmlns = "jabber:iq:register"}) |
26 local reply = st.reply(stanza); |
27 :tag("registered"):up() |
27 reply:tag("query", {xmlns = "jabber:iq:register"}) |
28 :tag("username"):text(session.username):up() |
28 :tag("registered"):up() |
29 :tag("password"):up(); |
29 :tag("username"):text(session.username):up() |
30 session.send(reply); |
30 :tag("password"):up(); |
31 elseif stanza.attr.type == "set" then |
31 session.send(reply); |
32 if query.tags[1] and query.tags[1].name == "remove" then |
32 else -- stanza.attr.type == "set" |
33 -- TODO delete user auth data, send iq response, kick all user resources with a <not-authorized/>, delete all user data |
33 if query.tags[1] and query.tags[1].name == "remove" then |
34 local username, host = session.username, session.host; |
34 -- TODO delete user auth data, send iq response, kick all user resources with a <not-authorized/>, delete all user data |
35 --session.send(st.error_reply(stanza, "cancel", "not-allowed")); |
35 local username, host = session.username, session.host; |
36 --return; |
36 --session.send(st.error_reply(stanza, "cancel", "not-allowed")); |
37 usermanager_set_password(username, nil, host); -- Disable account |
37 --return; |
38 -- FIXME the disabling currently allows a different user to recreate the account |
38 usermanager_set_password(username, nil, host); -- Disable account |
39 -- we should add an in-memory account block mode when we have threading |
39 -- FIXME the disabling currently allows a different user to recreate the account |
40 session.send(st.reply(stanza)); |
40 -- we should add an in-memory account block mode when we have threading |
41 local roster = session.roster; |
41 session.send(st.reply(stanza)); |
42 for _, session in pairs(hosts[host].sessions[username].sessions) do -- disconnect all resources |
42 local roster = session.roster; |
43 session:close({condition = "not-authorized", text = "Account deleted"}); |
43 for _, session in pairs(hosts[host].sessions[username].sessions) do -- disconnect all resources |
44 end |
44 session:close({condition = "not-authorized", text = "Account deleted"}); |
45 -- TODO datamanager should be able to delete all user data itself |
45 end |
46 datamanager.store(username, host, "vcard", nil); |
46 -- TODO datamanager should be able to delete all user data itself |
47 datamanager.store(username, host, "private", nil); |
47 datamanager.store(username, host, "vcard", nil); |
48 datamanager.list_store(username, host, "offline", nil); |
48 datamanager.store(username, host, "private", nil); |
49 local bare = username.."@"..host; |
49 datamanager.list_store(username, host, "offline", nil); |
50 for jid, item in pairs(roster) do |
50 local bare = username.."@"..host; |
51 if jid and jid ~= "pending" then |
51 for jid, item in pairs(roster) do |
52 if item.subscription == "both" or item.subscription == "from" or (roster.pending and roster.pending[jid]) then |
52 if jid and jid ~= "pending" then |
53 core_post_stanza(hosts[host], st.presence({type="unsubscribed", from=bare, to=jid})); |
53 if item.subscription == "both" or item.subscription == "from" or (roster.pending and roster.pending[jid]) then |
54 end |
54 core_post_stanza(hosts[host], st.presence({type="unsubscribed", from=bare, to=jid})); |
55 if item.subscription == "both" or item.subscription == "to" or item.ask then |
55 end |
56 core_post_stanza(hosts[host], st.presence({type="unsubscribe", from=bare, to=jid})); |
56 if item.subscription == "both" or item.subscription == "to" or item.ask then |
57 end |
57 core_post_stanza(hosts[host], st.presence({type="unsubscribe", from=bare, to=jid})); |
58 end |
58 end |
59 end |
59 end |
60 datamanager.store(username, host, "roster", nil); |
60 end |
61 datamanager.store(username, host, "privacy", nil); |
61 datamanager.store(username, host, "roster", nil); |
62 datamanager.store(username, host, "accounts", nil); -- delete accounts datastore at the end |
62 datamanager.store(username, host, "privacy", nil); |
63 module:log("info", "User removed their account: %s@%s", username, host); |
63 datamanager.store(username, host, "accounts", nil); -- delete accounts datastore at the end |
64 module:fire_event("user-deregistered", { username = username, host = host, source = "mod_register", session = session }); |
64 module:log("info", "User removed their account: %s@%s", username, host); |
65 else |
65 module:fire_event("user-deregistered", { username = username, host = host, source = "mod_register", session = session }); |
66 local username = query:child_with_name("username"); |
66 else |
67 local password = query:child_with_name("password"); |
67 local username = query:child_with_name("username"); |
68 if username and password then |
68 local password = query:child_with_name("password"); |
69 -- FIXME shouldn't use table.concat |
69 if username and password then |
70 username = nodeprep(table.concat(username)); |
70 -- FIXME shouldn't use table.concat |
71 password = table.concat(password); |
71 username = nodeprep(table.concat(username)); |
72 if username == session.username then |
72 password = table.concat(password); |
73 if usermanager_set_password(username, password, session.host) then |
73 if username == session.username then |
74 session.send(st.reply(stanza)); |
74 if usermanager_set_password(username, password, session.host) then |
75 else |
75 session.send(st.reply(stanza)); |
76 -- TODO unable to write file, file may be locked, etc, what's the correct error? |
|
77 session.send(st.error_reply(stanza, "wait", "internal-server-error")); |
|
78 end |
|
79 else |
76 else |
80 session.send(st.error_reply(stanza, "modify", "bad-request")); |
77 -- TODO unable to write file, file may be locked, etc, what's the correct error? |
|
78 session.send(st.error_reply(stanza, "wait", "internal-server-error")); |
81 end |
79 end |
82 else |
80 else |
83 session.send(st.error_reply(stanza, "modify", "bad-request")); |
81 session.send(st.error_reply(stanza, "modify", "bad-request")); |
84 end |
82 end |
|
83 else |
|
84 session.send(st.error_reply(stanza, "modify", "bad-request")); |
85 end |
85 end |
86 end |
86 end |
87 else |
87 end |
88 session.send(st.error_reply(stanza, "cancel", "service-unavailable")); |
88 return true; |
89 end; |
|
90 end); |
89 end); |
91 |
90 |
92 local recent_ips = {}; |
91 local recent_ips = {}; |
93 local min_seconds_between_registrations = module:get_option("min_seconds_between_registrations"); |
92 local min_seconds_between_registrations = module:get_option("min_seconds_between_registrations"); |
94 local whitelist_only = module:get_option("whitelist_registration_only"); |
93 local whitelist_only = module:get_option("whitelist_registration_only"); |