Mercurial > prosody-hg
comparison plugins/muc/restrict_pm.lib.lua @ 13495:47e1df2d0a37
MUC: Add per-room PM restriction functionality (thanks Wirlaburla)
Based on mod_muc_restrict_pm in prosody-modules d82c0383106a
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Thu, 23 May 2024 17:39:20 +0100 |
| parents | |
| children | 5fb7b9a9346f |
comparison
equal
deleted
inserted
replaced
| 13494:4c3d6ed9c823 | 13495:47e1df2d0a37 |
|---|---|
| 1 -- Based on code from mod_muc_restrict_pm in prosody-modules@d82c0383106a | |
| 2 -- by Nicholas George <wirlaburla@worlio.com> | |
| 3 | |
| 4 local st = require "util.stanza"; | |
| 5 local muc_util = module:require "muc/util"; | |
| 6 local valid_roles = muc_util.valid_roles; | |
| 7 | |
| 8 -- COMPAT w/ prosody-modules allow_pm | |
| 9 local compat_map = { | |
| 10 everyone = "visitor"; | |
| 11 participants = "participant"; | |
| 12 moderators = "moderator"; | |
| 13 members = "affiliated"; | |
| 14 }; | |
| 15 | |
| 16 local function get_allow_pm(room) | |
| 17 local val = room._data.allow_pm; | |
| 18 return compat_map[val] or val or "visitor"; | |
| 19 end | |
| 20 | |
| 21 local function set_allow_pm(room, val) | |
| 22 if get_allow_pm(room) == val then return false; end | |
| 23 room._data.allow_pm = val; | |
| 24 return true; | |
| 25 end | |
| 26 | |
| 27 local function get_allow_modpm(room) | |
| 28 return room._data.allow_modpm or false; | |
| 29 end | |
| 30 | |
| 31 local function set_allow_modpm(room, val) | |
| 32 if get_allow_modpm(room) == val then return false; end | |
| 33 room._data.allow_modpm = val; | |
| 34 return true; | |
| 35 end | |
| 36 | |
| 37 module:hook("muc-config-form", function(event) | |
| 38 local pmval = get_allow_pm(event.room); | |
| 39 table.insert(event.form, { | |
| 40 name = 'muc#roomconfig_allowpm'; | |
| 41 type = 'list-single'; | |
| 42 label = 'Allow private messages from'; | |
| 43 options = { | |
| 44 { value = 'visitor', label = 'Everyone', default = pmval == 'visitor' }; | |
| 45 { value = 'participant', label = 'Participants', default = pmval == 'participant' }; | |
| 46 { value = 'moderator', label = 'Moderators', default = pmval == 'moderator' }; | |
| 47 { value = 'affiliated', label = "Members", default = pmval == "affiliated" }; | |
| 48 { value = 'none', label = 'No one', default = pmval == 'none' }; | |
| 49 } | |
| 50 }); | |
| 51 table.insert(event.form, { | |
| 52 name = '{xmpp:prosody.im}muc#allow_modpm'; | |
| 53 type = 'boolean'; | |
| 54 label = 'Always allow private messages to moderators'; | |
| 55 value = get_allow_modpm(event.room) | |
| 56 }); | |
| 57 end); | |
| 58 | |
| 59 module:hook("muc-config-submitted/muc#roomconfig_allowpm", function(event) | |
| 60 if set_allow_pm(event.room, event.value) then | |
| 61 event.status_codes["104"] = true; | |
| 62 end | |
| 63 end); | |
| 64 | |
| 65 module:hook("muc-config-submitted/{xmpp:prosody.im}muc#allow_modpm", function(event) | |
| 66 if set_allow_modpm(event.room, event.value) then | |
| 67 event.status_codes["104"] = true; | |
| 68 end | |
| 69 end); | |
| 70 | |
| 71 local who_restricted = { | |
| 72 none = "in this group"; | |
| 73 participant = "from guests"; | |
| 74 moderator = "from non-moderators"; | |
| 75 affiliated = "from non-members"; | |
| 76 }; | |
| 77 | |
| 78 module:hook("muc-private-message", function(event) | |
| 79 local stanza, room = event.stanza, event.room; | |
| 80 local from_occupant = room:get_occupant_by_nick(stanza.attr.from); | |
| 81 local to_occupant = room:get_occupant_by_nick(stanza.attr.to); | |
| 82 | |
| 83 -- To self is always okay | |
| 84 if to_occupant.bare_jid == from_occupant.bare_jid then return; end | |
| 85 | |
| 86 if get_allow_modpm(room) then | |
| 87 if to_occupant and to_occupant.role == 'moderator' | |
| 88 or from_occupant and from_occupant.role == "moderator" then | |
| 89 return; -- Allow to/from moderators | |
| 90 end | |
| 91 end | |
| 92 | |
| 93 local pmval = get_allow_pm(room); | |
| 94 | |
| 95 if pmval ~= "none" then | |
| 96 if pmval == "affiliated" and room:get_affiliation(from_occupant.bare_jid) then | |
| 97 return; -- Allow from affiliated users | |
| 98 elseif valid_roles[from_occupant.role] >= valid_roles[pmval] then | |
| 99 module:log("debug", "Allowing PM: %s(%d) >= %s(%d)", from_occupant.role, valid_roles[from_occupant.role], pmval, valid_roles[pmval]); | |
| 100 return; -- Allow from a permitted role | |
| 101 end | |
| 102 end | |
| 103 | |
| 104 local msg = ("Private messages are restricted %s"):format(who_restricted[pmval]); | |
| 105 module:log("debug", "Blocking PM from %s %s: %s", from_occupant.role, stanza.attr.from, msg); | |
| 106 | |
| 107 room:route_to_occupant( | |
| 108 from_occupant, | |
| 109 st.error_reply(stanza, "cancel", "policy-violation", msg, room.jid) | |
| 110 ); | |
| 111 return false; | |
| 112 end, 1); | |
| 113 | |
| 114 return { | |
| 115 get_allow_pm = get_allow_pm; | |
| 116 set_allow_pm = set_allow_pm; | |
| 117 get_allow_modpm = get_allow_modpm; | |
| 118 set_allow_modpm = set_allow_modpm; | |
| 119 }; |
