Mercurial > prosody-modules
changeset 1954:050cd7b6fa96
mod_muc_access_control: Module to allow restricting rooms to a list of JIDs, which can include domains
author | Matthew Wild <mwild1@gmail.com> |
---|---|
date | Sun, 22 Nov 2015 19:33:09 +0000 (2015-11-22) |
parents | 0c3ba5ff7a3b |
children | 1a5be0ecc876 |
files | mod_muc_access_control/mod_muc_access_control.lua |
diffstat | 1 files changed, 57 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_muc_access_control/mod_muc_access_control.lua Sun Nov 22 19:33:09 2015 +0000 @@ -0,0 +1,57 @@ +local st = require "util.stanza"; +local jid = require "util.jid"; +local nodeprep = require "util.encodings".stringprep.nodeprep; + +local unprepped_access_lists = module:get_option("muc_access_lists", {}); +local access_lists = {}; + +-- Make sure all input is prepped +for unprepped_room_name, unprepped_list in pairs(unprepped_access_lists) do + local prepped_room_name = nodeprep(unprepped_room_name); + if not prepped_room_name then + module:log("error", "Invalid room name: %s", unprepped_room_name); + else + local prepped_list = {}; + for _, unprepped_jid in ipairs(unprepped_list) do + local prepped_jid = jid.prep(jid); + if not prepped_jid then + module:log("error", "Invalid JID: %s", unprepped_jid); + else + table.insert(prepped_list, jid.pep(jid)); + end + end + end +end + +local function is_restricted(room, who) + local allowed = access_lists[room]; + + if allowed == nil or allowed[who] or allowed[select(2, jid.split(who))] then + return nil; + end + + return "forbidden"; +end + +module:hook("presence/full", function(event) + local stanza = event.stanza; + + if stanza.name == "presence" and stanza.attr.type == "unavailable" then -- Leaving events get discarded + return; + end + + -- Get the room + local room = jid.split(stanza.attr.to); + if not room then return; end + + -- Get who has tried to join it + local who = jid.bare(stanza.attr.from) + + -- Checking whether room is restricted + local check_restricted = is_restricted(room, who) + if check_restricted ~= nil then + event.allowed = false; + event.stanza.attr.type = 'error'; + return event.origin.send(st.error_reply(event.stanza, "cancel", "forbidden", "You're not allowed to enter this room: " .. check_restricted)); + end +end, 10);