Software / code / prosody
Comparison
plugins/mod_presence.lua @ 11120:b2331f3dfeea
Merge 0.11->trunk
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Wed, 30 Sep 2020 09:50:33 +0100 |
| parent | 10813:4a9ff4f61796 |
| child | 12977:74b9e05af71e |
comparison
equal
deleted
inserted
replaced
| 11119:68df52bf08d5 | 11120:b2331f3dfeea |
|---|---|
| 12 local pairs = pairs; | 12 local pairs = pairs; |
| 13 local s_find = string.find; | 13 local s_find = string.find; |
| 14 local tonumber = tonumber; | 14 local tonumber = tonumber; |
| 15 | 15 |
| 16 local core_post_stanza = prosody.core_post_stanza; | 16 local core_post_stanza = prosody.core_post_stanza; |
| 17 local core_process_stanza = prosody.core_process_stanza; | |
| 17 local st = require "util.stanza"; | 18 local st = require "util.stanza"; |
| 18 local jid_split = require "util.jid".split; | 19 local jid_split = require "util.jid".split; |
| 19 local jid_bare = require "util.jid".bare; | 20 local jid_bare = require "util.jid".bare; |
| 20 local datetime = require "util.datetime"; | 21 local datetime = require "util.datetime"; |
| 21 local hosts = prosody.hosts; | 22 local hosts = prosody.hosts; |
| 27 local sessionmanager = require "core.sessionmanager"; | 28 local sessionmanager = require "core.sessionmanager"; |
| 28 | 29 |
| 29 local recalc_resource_map = require "util.presence".recalc_resource_map; | 30 local recalc_resource_map = require "util.presence".recalc_resource_map; |
| 30 | 31 |
| 31 local ignore_presence_priority = module:get_option_boolean("ignore_presence_priority", false); | 32 local ignore_presence_priority = module:get_option_boolean("ignore_presence_priority", false); |
| 33 | |
| 34 local pre_approval_stream_feature = st.stanza("sub", {xmlns="urn:xmpp:features:pre-approval"}); | |
| 35 module:hook("stream-features", function(event) | |
| 36 local origin, features = event.origin, event.features; | |
| 37 if origin.username then | |
| 38 features:add_child(pre_approval_stream_feature); | |
| 39 end | |
| 40 end); | |
| 32 | 41 |
| 33 function handle_normal_presence(origin, stanza) | 42 function handle_normal_presence(origin, stanza) |
| 34 if ignore_presence_priority then | 43 if ignore_presence_priority then |
| 35 local priority = stanza:get_child("priority"); | 44 local priority = stanza:get_child("priority"); |
| 36 if priority and priority[1] ~= "0" then | 45 if priority and priority[1] ~= "0" then |
| 79 res.presence.attr.to = origin.full_jid; | 88 res.presence.attr.to = origin.full_jid; |
| 80 core_post_stanza(res, res.presence, true); | 89 core_post_stanza(res, res.presence, true); |
| 81 res.presence.attr.to = nil; | 90 res.presence.attr.to = nil; |
| 82 end | 91 end |
| 83 end | 92 end |
| 84 for jid in pairs(roster[false].pending) do -- resend incoming subscription requests | 93 for jid, pending_request in pairs(roster[false].pending) do -- resend incoming subscription requests |
| 85 origin.send(st.presence({type="subscribe", from=jid})); -- TODO add to attribute? Use original? | 94 if type(pending_request) == "table" then |
| 95 local subscribe = st.deserialize(pending_request); | |
| 96 subscribe.attr.type, subscribe.attr.from = "subscribe", jid; | |
| 97 origin.send(subscribe); | |
| 98 else | |
| 99 origin.send(st.presence({type="subscribe", from=jid})); | |
| 100 end | |
| 86 end | 101 end |
| 87 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); | 102 local request = st.presence({type="subscribe", from=origin.username.."@"..origin.host}); |
| 88 for jid, item in pairs(roster) do -- resend outgoing subscription requests | 103 for jid, item in pairs(roster) do -- resend outgoing subscription requests |
| 89 if item.ask then | 104 if item.ask then |
| 90 request.attr.to = jid; | 105 request.attr.to = jid; |
| 173 -- 2. roster_push () | 188 -- 2. roster_push () |
| 174 -- 3. send_presence_of_available_resources | 189 -- 3. send_presence_of_available_resources |
| 175 if rostermanager.subscribed(node, host, to_bare) then | 190 if rostermanager.subscribed(node, host, to_bare) then |
| 176 rostermanager.roster_push(node, host, to_bare); | 191 rostermanager.roster_push(node, host, to_bare); |
| 177 end | 192 end |
| 178 core_post_stanza(origin, stanza); | 193 if rostermanager.is_contact_subscribed(node, host, to_bare) then |
| 179 send_presence_of_available_resources(node, host, to_bare, origin); | 194 core_post_stanza(origin, stanza); |
| 195 send_presence_of_available_resources(node, host, to_bare, origin); | |
| 196 end | |
| 180 if rostermanager.is_user_subscribed(node, host, to_bare) then | 197 if rostermanager.is_user_subscribed(node, host, to_bare) then |
| 181 core_post_stanza(origin, st.presence({ type = "probe", from = from_bare, to = to_bare })); | 198 core_post_stanza(origin, st.presence({ type = "probe", from = from_bare, to = to_bare })); |
| 182 end | 199 end |
| 183 elseif stanza.attr.type == "unsubscribed" then | 200 elseif stanza.attr.type == "unsubscribed" then |
| 184 -- 1. send unavailable | 201 -- 1. send unavailable |
| 185 -- 2. route stanza | 202 -- 2. route stanza |
| 186 -- 3. roster push (subscription = from or both) | 203 -- 3. roster push (subscription = from or both) |
| 204 -- luacheck: ignore 211/pending_in | |
| 205 -- Is pending_in meant to be used? | |
| 187 local success, pending_in, subscribed = rostermanager.unsubscribed(node, host, to_bare); | 206 local success, pending_in, subscribed = rostermanager.unsubscribed(node, host, to_bare); |
| 188 if success then | 207 if success then |
| 189 if subscribed then | 208 if subscribed then |
| 190 rostermanager.roster_push(node, host, to_bare); | 209 rostermanager.roster_push(node, host, to_bare); |
| 191 end | 210 end |
| 221 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"}), true); -- already subscribed | 240 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"}), true); -- already subscribed |
| 222 -- Sending presence is not clearly stated in the RFC, but it seems appropriate | 241 -- Sending presence is not clearly stated in the RFC, but it seems appropriate |
| 223 if 0 == send_presence_of_available_resources(node, host, from_bare, origin) then | 242 if 0 == send_presence_of_available_resources(node, host, from_bare, origin) then |
| 224 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- TODO send last activity | 243 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- TODO send last activity |
| 225 end | 244 end |
| 245 elseif rostermanager.is_contact_preapproved(node, host, from_bare) then | |
| 246 if not rostermanager.is_contact_pending_in(node, host, from_bare) then | |
| 247 if rostermanager.set_contact_pending_in(node, host, from_bare, stanza) then | |
| 248 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="subscribed"}), true); | |
| 249 end -- TODO else return error, unable to save | |
| 250 end | |
| 226 else | 251 else |
| 227 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- acknowledging receipt | 252 core_post_stanza(hosts[host], st.presence({from=to_bare, to=from_bare, type="unavailable"}), true); -- acknowledging receipt |
| 228 if not rostermanager.is_contact_pending_in(node, host, from_bare) then | 253 if not rostermanager.is_contact_pending_in(node, host, from_bare) then |
| 229 if rostermanager.set_contact_pending_in(node, host, from_bare) then | 254 if rostermanager.set_contact_pending_in(node, host, from_bare, stanza) then |
| 230 sessionmanager.send_to_available_resources(node, host, stanza); | 255 sessionmanager.send_to_available_resources(node, host, stanza); |
| 231 end -- TODO else return error, unable to save | 256 end -- TODO else return error, unable to save |
| 232 end | 257 end |
| 233 end | 258 end |
| 234 elseif stanza.attr.type == "unsubscribe" then | 259 elseif stanza.attr.type == "unsubscribe" then |
| 344 if session.presence then | 369 if session.presence then |
| 345 local pres = st.presence{ type = "unavailable" }; | 370 local pres = st.presence{ type = "unavailable" }; |
| 346 if err then | 371 if err then |
| 347 pres:tag("status"):text("Disconnected: "..err):up(); | 372 pres:tag("status"):text("Disconnected: "..err):up(); |
| 348 end | 373 end |
| 349 session:dispatch_stanza(pres); | 374 core_process_stanza(session, pres); |
| 350 elseif session.directed then | 375 elseif session.directed then |
| 351 local pres = st.presence{ type = "unavailable", from = session.full_jid }; | 376 local pres = st.presence{ type = "unavailable", from = session.full_jid }; |
| 352 if err then | 377 if err then |
| 353 pres:tag("status"):text("Disconnected: "..err):up(); | 378 pres:tag("status"):text("Disconnected: "..err):up(); |
| 354 end | 379 end |