Mercurial > prosody-modules
view mod_muc_limits/mod_muc_limits.lua @ 5519:83ebfc367169
mod_http_oauth2: Return Authentication Time per OpenID Core Section 2
Mandatory To Implement, either MUST include or OPTIONAL depending on
things we don't look at, so might as well include it all the time.
Since we do not persist authentication state with cookies or such, the
authentication time will always be some point between the user being
sent to the authorization endpoint and the time they are sent back to
the client application.
| author | Kim Alvefur <zash@zash.se> |
|---|---|
| date | Mon, 05 Jun 2023 22:32:44 +0200 |
| parents | 2b10e51d85a6 |
| children | 731ba9400c10 |
line wrap: on
line source
local mod_muc = module:depends"muc"; local rooms = rawget(mod_muc, "rooms"); -- Old MUC API local jid_split, jid_bare = require "util.jid".split, require "util.jid".bare; local st = require "util.stanza"; local new_throttle = require "util.throttle".create; local t_insert, t_concat = table.insert, table.concat; local xmlns_muc = "http://jabber.org/protocol/muc"; local period = math.max(module:get_option_number("muc_event_rate", 0.5), 0); local burst = math.max(module:get_option_number("muc_burst_factor", 6), 1); local max_nick_length = module:get_option_number("muc_max_nick_length", 23); -- Default chosen through scientific methods local join_only = module:get_option_boolean("muc_limit_joins_only", false); local dropped_count = 0; local dropped_jids; local function log_dropped() module:log("warn", "Dropped %d stanzas from %d JIDs: %s", dropped_count, #dropped_jids, t_concat(dropped_jids, ", ")); dropped_count = 0; dropped_jids = nil; end local function handle_stanza(event) local origin, stanza = event.origin, event.stanza; if stanza.name == "presence" and stanza.attr.type == "unavailable" then -- Don't limit room leaving return; end local dest_room, dest_host, dest_nick = jid_split(stanza.attr.to); local room = event.room or rooms[dest_room.."@"..dest_host]; if not room then return; end local from_jid = stanza.attr.from; if room:get_affiliation(jid_bare(from_jid)) then module:log("debug", "Skipping stanza from affiliated user..."); return; elseif dest_nick and max_nick_length and stanza.name == "presence" and not room._occupants[stanza.attr.to] and #dest_nick > max_nick_length then module:log("debug", "Forbidding long (%d bytes) nick in %s", #dest_nick, dest_room) origin.send(st.error_reply(stanza, "modify", "policy-violation", "Your nick name is too long, please use a shorter one") :up():tag("x", { xmlns = xmlns_muc })); return true; end local throttle = room.throttle; if not room.throttle then throttle = new_throttle(period*burst, burst); room.throttle = throttle; end if not throttle:poll(1) then module:log("debug", "Dropping stanza for %s@%s from %s, over rate limit", dest_room, dest_host, from_jid); if not dropped_jids then dropped_jids = { [from_jid] = true, from_jid }; module:add_timer(5, log_dropped); elseif not dropped_jids[from_jid] then dropped_jids[from_jid] = true; t_insert(dropped_jids, from_jid); end dropped_count = dropped_count + 1; if stanza.attr.type == "error" then -- We don't want to bounce errors return true; end local reply = st.error_reply(stanza, "wait", "policy-violation", "The room is currently overactive, please try again later"); local body = stanza:get_child_text("body"); if body then reply:up():tag("body"):text(body):up(); end local x = stanza:get_child("x", xmlns_muc); if x then reply:add_child(st.clone(x)); end origin.send(reply); return true; end end if rooms then function module.unload() for room_jid, room in pairs(rooms) do --luacheck: ignore 213/room_jid room.throttle = nil; end end module:hook("presence/full", handle_stanza, 501); if not join_only then module:hook("message/bare", handle_stanza, 501); module:hook("message/full", handle_stanza, 501); module:hook("presence/bare", handle_stanza, 501); end else module:hook("muc-occupant-pre-join", handle_stanza); if not join_only then module:hook("muc-occupant-pre-change", handle_stanza); module:hook("muc-occupant-groupchat", handle_stanza); end end
