Software /
code /
prosody
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 |
child | 13578: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 }; |