Mercurial > prosody-modules
view mod_http_muc_kick/mod_http_muc_kick.lua @ 4651:8231774f5bfd
mod_cloud_notify_encrypted: Ensure body substring remains valid UTF-8
The `body:sub()` call risks splitting the string in the middle of a
multi-byte UTF-8 sequence. This should have been caught by util.stanza
validation, but that would have caused some havoc, at the very least causing
the notification to not be sent.
There have been no reports of this happening. Likely because this module
isn't widely deployed among users with languages that use many longer UTF-8
sequences.
The util.encodings.utf8.valid() function is O(n) where only the last
sequence really needs to be checked, but it's in C and expected to be fast.
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sun, 22 Aug 2021 13:22:59 +0200 |
parents | df09f9ce0b1b |
children | e524a97730eb |
line wrap: on
line source
local jid_split = require "util.jid".prepped_split; local json = require "util.json"; module:depends("http"); local authorization = assert( module:get_option_string("http_muc_kick_authorization_header", nil), "http_muc_kick_authorization_header setting is missing, please add it to the Prosody config before using mod_http_muc_kick" ); local function is_authorized(request) return request.headers.authorization == authorization; end local function check_muc(jid) local muc_node, host = jid_split(jid); if not hosts[host] then return nil, nil, "No such host: "..host; elseif not hosts[host].modules.muc then return nil, nil, "Host '"..host.."' is not a MUC service"; end return muc_node, host; end local function get_muc(muc_jid) local muc_node, host, err = check_muc(muc_jid); if not muc_node then return nil, host, err; end muc = prosody.hosts[host].modules.muc.get_room_from_jid(muc_jid); if not muc then return nil, host, "No MUC '"..muc_node.."' found for host: "..host; end return muc; end local function handle_error(response, status_code, error) response.headers.content_type = "application/json"; response.status_code = status_code; response:send(json.encode({error = error})); -- return true to keep the connection open, and prevent other handlers from executing. -- https://prosody.im/doc/developers/http#return_value return true; end module:provides("http", { route = { ["POST"] = function (event) local request, response = event.request, event.response; if not is_authorized(request) then return handle_error(response, 401, "Authorization failed"); end local body = json.decode(request.body or "") or {}; if not body then return handle_error(response, 400, "JSON body not found"); end local nickname, muc_jid, reason = body.nickname, body.muc, body.reason or ""; if not nickname or not muc_jid then return handle_error(response, 400, "Missing nickname and/or MUC"); end local muc, _, err = get_muc(muc_jid); if not muc then return handle_error(response, 404, "MUC not found: " .. err); end local occupant_jid = muc.jid .. "/" .. nickname; -- Kick user by giving them the "none" role -- https://xmpp.org/extensions/xep-0045.html#kick local success, error, condition = muc:set_role(true, occupant_jid, nil, reason); if not success then return handle_error(response, 400, "Couldn't kick user: ".. error .. ": " .. condition); end -- Kick was successful return 200; end; }; });