Mercurial > prosody-hg
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 |
| parents | b61a7173f838 |
| children | 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; |
