Software /
code /
prosody
Comparison
plugins/muc/muc.lib.lua @ 10353:7b602e13c3b6
MUC: Add controls for whose presence is broadcast (closes #1335)
Committed by Zash
author | Lance Stout <lancestout@gmail.com> |
---|---|
date | Sun, 20 Oct 2019 21:58:16 +0200 |
parent | 10294:b61a7173f838 |
child | 10361:6e051bfca12d |
comparison
equal
deleted
inserted
replaced
10352:dc1e6c2fb50a | 10353:7b602e13c3b6 |
---|---|
216 end | 216 end |
217 end | 217 end |
218 | 218 |
219 -- Broadcasts an occupant's presence to the whole room | 219 -- Broadcasts an occupant's presence to the whole room |
220 -- Takes the x element that goes into the stanzas | 220 -- Takes the x element that goes into the stanzas |
221 function room_mt:publicise_occupant_status(occupant, x, nick, actor, reason) | 221 function room_mt:publicise_occupant_status(occupant, x, nick, actor, reason, prev_role, force_unavailable) |
222 local base_x = x.base or x; | 222 local base_x = x.base or x; |
223 -- Build real jid and (optionally) occupant jid template presences | 223 -- Build real jid and (optionally) occupant jid template presences |
224 local base_presence do | 224 local base_presence do |
225 -- Try to use main jid's presence | 225 -- Try to use main jid's presence |
226 local pr = occupant:get_presence(); | 226 local pr = occupant:get_presence(); |
227 if pr and (occupant.role ~= nil or pr.attr.type == "unavailable") then | 227 if pr and (occupant.role ~= nil or pr.attr.type == "unavailable") and not force_unavailable then |
228 base_presence = st.clone(pr); | 228 base_presence = st.clone(pr); |
229 else -- user is leaving but didn't send a leave presence. make one for them | 229 else -- user is leaving but didn't send a leave presence. make one for them |
230 base_presence = st.presence {from = occupant.nick; type = "unavailable";}; | 230 base_presence = st.presence {from = occupant.nick; type = "unavailable";}; |
231 end | 231 end |
232 end | 232 end |
277 -- But not allowed to see actor's | 277 -- But not allowed to see actor's |
278 self_x = st.clone(x.self or base_x); | 278 self_x = st.clone(x.self or base_x); |
279 self:build_item_list(occupant, self_x, false, nick, actor_nick, nil, reason); | 279 self:build_item_list(occupant, self_x, false, nick, actor_nick, nil, reason); |
280 self_p = st.clone(base_presence):add_child(self_x); | 280 self_p = st.clone(base_presence):add_child(self_x); |
281 end | 281 end |
282 | |
283 local broadcast_roles = self:get_presence_broadcast(); | |
282 | 284 |
283 -- General populace | 285 -- General populace |
284 for occupant_nick, n_occupant in self:each_occupant() do | 286 for occupant_nick, n_occupant in self:each_occupant() do |
285 if occupant_nick ~= occupant.nick then | 287 if occupant_nick ~= occupant.nick then |
286 local pr; | 288 local pr; |
289 elseif occupant.bare_jid == n_occupant.bare_jid then | 291 elseif occupant.bare_jid == n_occupant.bare_jid then |
290 pr = self_p; | 292 pr = self_p; |
291 else | 293 else |
292 pr = get_anon_p(); | 294 pr = get_anon_p(); |
293 end | 295 end |
294 self:route_to_occupant(n_occupant, pr); | 296 if broadcast_roles[occupant.role or "none"] or force_unavailable then |
297 self:route_to_occupant(n_occupant, pr); | |
298 elseif prev_role and broadcast_roles[prev_role] then | |
299 pr.attr.type = 'unavailable'; | |
300 self:route_to_occupant(n_occupant, pr); | |
301 end | |
302 | |
295 end | 303 end |
296 end | 304 end |
297 | 305 |
298 -- Presences for occupant itself | 306 -- Presences for occupant itself |
299 self_x:tag("status", {code = "110";}):up(); | 307 self_x:tag("status", {code = "110";}):up(); |
313 | 321 |
314 function room_mt:send_occupant_list(to, filter) | 322 function room_mt:send_occupant_list(to, filter) |
315 local to_bare = jid_bare(to); | 323 local to_bare = jid_bare(to); |
316 local is_anonymous = false; | 324 local is_anonymous = false; |
317 local whois = self:get_whois(); | 325 local whois = self:get_whois(); |
326 local broadcast_roles = self:get_presence_broadcast(); | |
318 if whois ~= "anyone" then | 327 if whois ~= "anyone" then |
319 local affiliation = self:get_affiliation(to); | 328 local affiliation = self:get_affiliation(to); |
320 if affiliation ~= "admin" and affiliation ~= "owner" then | 329 if affiliation ~= "admin" and affiliation ~= "owner" then |
321 local occupant = self:get_occupant_by_real_jid(to); | 330 local occupant = self:get_occupant_by_real_jid(to); |
322 if not (occupant and can_see_real_jids(whois, occupant)) then | 331 if not (occupant and can_see_real_jids(whois, occupant)) then |
329 local x = st.stanza("x", {xmlns='http://jabber.org/protocol/muc#user'}); | 338 local x = st.stanza("x", {xmlns='http://jabber.org/protocol/muc#user'}); |
330 self:build_item_list(occupant, x, is_anonymous and to_bare ~= occupant.bare_jid); -- can always see your own jids | 339 self:build_item_list(occupant, x, is_anonymous and to_bare ~= occupant.bare_jid); -- can always see your own jids |
331 local pres = st.clone(occupant:get_presence()); | 340 local pres = st.clone(occupant:get_presence()); |
332 pres.attr.to = to; | 341 pres.attr.to = to; |
333 pres:add_child(x); | 342 pres:add_child(x); |
334 self:route_stanza(pres); | 343 if to_bare == occupant.bare_jid or broadcast_roles[occupant.role or "none"] then |
344 self:route_stanza(pres); | |
345 end | |
335 end | 346 end |
336 end | 347 end |
337 end | 348 end |
338 | 349 |
339 function room_mt:get_disco_info(stanza) | 350 function room_mt:get_disco_info(stanza) |
1440 | 1451 |
1441 local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"}); | 1452 local x = st.stanza("x", {xmlns = "http://jabber.org/protocol/muc#user"}); |
1442 if not role then | 1453 if not role then |
1443 x:tag("status", {code = "307"}):up(); | 1454 x:tag("status", {code = "307"}):up(); |
1444 end | 1455 end |
1456 | |
1457 local prev_role = occupant.role; | |
1445 occupant.role = role; | 1458 occupant.role = role; |
1446 self:save_occupant(occupant); | 1459 self:save_occupant(occupant); |
1447 self:publicise_occupant_status(occupant, x, nil, actor, reason); | 1460 self:publicise_occupant_status(occupant, x, nil, actor, reason, prev_role); |
1448 if role == nil then | 1461 if role == nil then |
1449 module:fire_event("muc-occupant-left", { | 1462 module:fire_event("muc-occupant-left", { |
1450 room = self; | 1463 room = self; |
1451 nick = occupant.nick; | 1464 nick = occupant.nick; |
1452 occupant = occupant; | 1465 occupant = occupant; |