Software /
code /
prosody
Annotate
plugins/muc/occupant.lib.lua @ 11245:43b43e7156b8
MUC: Add support for presence probes (fixes #1535)
The following patch allows Prosody to respond to `probe` presences and send out the probed occupant's current presence.
This is based on line 17.3 in XEP-0045:
A MUC service MAY handle presence probes sent to the room JID <room@service> or an occupant JID <room@service/nick>
(e.g, these might be sent by an occupant's home server to determine if the room is still online or to synchronize
presence information if the user or the user's server has gone offline temporarily or has started sharing presence again,
as for instance when Stanza Interception and Filtering Technology (XEP-0273) is used).
author | JC Brand <jc@opkode.com> |
---|---|
date | Sun, 19 Apr 2020 21:49:45 +0200 |
parent | 7086:6cc7c9da29ed |
child | 12977:74b9e05af71e |
rev | line source |
---|---|
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
1 local pairs = pairs; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
2 local setmetatable = setmetatable; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
3 local st = require "util.stanza"; |
6271
006b0e0f0de2
plugins/muc: Move 'x' filtering from occupant to util
daurnimator <quae@daurnimator.com>
parents:
6251
diff
changeset
|
4 local util = module:require "muc/util"; |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
5 |
6271
006b0e0f0de2
plugins/muc: Move 'x' filtering from occupant to util
daurnimator <quae@daurnimator.com>
parents:
6251
diff
changeset
|
6 local function get_filtered_presence(stanza) |
006b0e0f0de2
plugins/muc: Move 'x' filtering from occupant to util
daurnimator <quae@daurnimator.com>
parents:
6251
diff
changeset
|
7 return util.filter_muc_x(st.clone(stanza)); |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
8 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
9 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
10 local occupant_mt = {}; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
11 occupant_mt.__index = occupant_mt; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
12 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
13 local function new_occupant(bare_real_jid, nick) |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
14 return setmetatable({ |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
15 bare_jid = bare_real_jid; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
16 nick = nick; -- in-room jid |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
17 sessions = {}; -- hash from real_jid to presence stanzas. stanzas should not be modified |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
18 role = nil; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
19 jid = nil; -- Primary session |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
20 }, occupant_mt); |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
21 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
22 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
23 -- Deep copy an occupant |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
24 local function copy_occupant(occupant) |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
25 local sessions = {}; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
26 for full_jid, presence_stanza in pairs(occupant.sessions) do |
6210
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
27 -- Don't keep unavailable presences, as they'll accumulate; unless they're the primary session |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
28 if presence_stanza.attr.type ~= "unavailable" or full_jid == occupant.jid then |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
29 sessions[full_jid] = presence_stanza; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
30 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
31 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
32 return setmetatable({ |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
33 bare_jid = occupant.bare_jid; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
34 nick = occupant.nick; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
35 sessions = sessions; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
36 role = occupant.role; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
37 jid = occupant.jid; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
38 }, occupant_mt); |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
39 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
40 |
6210
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
41 -- finds another session to be the primary (there might not be one) |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
42 function occupant_mt:choose_new_primary() |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
43 for jid, pr in self:each_session() do |
6251
41a5e5205fd9
plugins/muc/occupant: Check for type == nil rather than type ~= unavailable
daurnimator <quae@daurnimator.com>
parents:
6210
diff
changeset
|
44 if pr.attr.type == nil then |
6210
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
45 return jid; |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
46 end |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
47 end |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
48 return nil; |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
49 end |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
50 |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
51 function occupant_mt:set_session(real_jid, presence_stanza, replace_primary) |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
52 local pr = get_filtered_presence(presence_stanza); |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
53 pr.attr.from = self.nick; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
54 pr.attr.to = real_jid; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
55 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
56 self.sessions[real_jid] = pr; |
6210
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
57 if replace_primary then |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
58 self.jid = real_jid; |
6210
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
59 elseif self.jid == nil or (pr.attr.type == "unavailable" and self.jid == real_jid) then |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
60 -- Only leave an unavailable presence as primary when there are no other options |
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
61 self.jid = self:choose_new_primary() or real_jid; |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
62 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
63 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
64 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
65 function occupant_mt:remove_session(real_jid) |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
66 -- Delete original session |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
67 self.sessions[real_jid] = nil; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
68 if self.jid == real_jid then |
6210
e9d62fff82a8
plugins/muc/occupant.lib: Don't allow an unavailable session to be the primary jid
daurnimator <quae@daurnimator.com>
parents:
6179
diff
changeset
|
69 self.jid = self:choose_new_primary(); |
6179
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
70 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
71 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
72 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
73 function occupant_mt:each_session() |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
74 return pairs(self.sessions) |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
75 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
76 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
77 function occupant_mt:get_presence(real_jid) |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
78 return self.sessions[real_jid or self.jid] |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
79 end |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
80 |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
81 return { |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
82 new = new_occupant; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
83 copy = copy_occupant; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
84 mt = occupant_mt; |
e488a90195bc
plugins/muc: Massive refactor
daurnimator <quae@daurnimator.com>
parents:
diff
changeset
|
85 } |