# HG changeset patch # User Kim Alvefur # Date 1448458843 -3600 # Node ID 1a5be0ecc8760feba0a5e03f50b95b7a227f48d2 # Parent 050cd7b6fa96928881716fc55f0ff9f22de5a33b# Parent f719d5e6c6271c0c6af9a447020d15fb72116402 Merge diff -r f719d5e6c627 -r 1a5be0ecc876 mod_alias/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_alias/README.markdown Wed Nov 25 14:40:43 2015 +0100 @@ -0,0 +1,57 @@ +--- +summary: Point alias accounts or domains to correct XMPP user +... + +Introduction +============ + +This module allows you to set up aliases that alert people who try to +contact them or add them to their roster what your actual JID is. This +is useful for changing JIDs, or just in the case where you own both +example.com and example.net, and want people who contact you@example.com +to be alerted to contact you at you@example.net instead. + +This type of aliasing is well supported in the email world, but very hard +to handle with XMPP, this module sidesteps all the hard problems by just +sending the user a helpful message, requiring humans to decide what they +actually want to do. + +This doesn't require any special support on other clients or servers, +just the ability to recieve messages. + +Configuration +============= + +Add the module to the `modules_enabled` list. + + modules_enabled = { + ... + "alias"; + } + +Then set up your list of aliases, aliases can be full or bare JIDs, +or hosts: + + aliases = { + ["old@example.net"] = "new@example.net"; + ["you@example.com"] = "you@example.net"; + ["conference.example.com"] = "conference.example.net"; + } + +You can also set up a custom response, by default it is: + + alias_response = "User $alias can be contacted at $target"; + +A script named mod_alias_postfixadmin.sh is included in this directory to +generate the aliases array directly from a postfixadmin MySQL database. +Instructions for use are included in the script. + +Compatibility +============= + + ------- -------------- + trunk Works + 0.10 Works + 0.9 Unknown + 0.8 Unknown + ------- -------------- diff -r f719d5e6c627 -r 1a5be0ecc876 mod_alias/mod_alias.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_alias/mod_alias.lua Wed Nov 25 14:40:43 2015 +0100 @@ -0,0 +1,43 @@ +-- Copyright (C) 2015 Travis Burtrum +-- This file is MIT/X11 licensed. + +-- set like so in prosody config, works on full or bare jids, or hosts: +--aliases = { +-- ["old@example.net"] = "new@example.net"; +-- ["you@example.com"] = "you@example.net"; +-- ["conference.example.com"] = "conference.example.net"; +--} + +local aliases = module:get_option("aliases", {}); +local alias_response = module:get_option("alias_response", "User $alias can be contacted at $target"); + +local st = require "util.stanza"; + +function handle_alias(event) + + if event.stanza.attr.type ~= "error" then + local alias = event.stanza.attr.to; + local target = aliases[alias]; + if target then + local replacements = { + alias = alias, + target = target + }; + local error_message = alias_response:gsub("%$([%w_]+)", function (v) + return replacements[v] or nil; + end); + local message = st.message{ type = "chat", from = alias, to = event.stanza.attr.from }:tag("body"):text(error_message); + module:send(message); + return event.origin.send(st.error_reply(event.stanza, "cancel", "gone", error_message)); + end + end + +end + +module:hook("message/bare", handle_alias, 300); +module:hook("message/full", handle_alias, 300); +module:hook("message/host", handle_alias, 300); + +module:hook("presence/bare", handle_alias, 300); +module:hook("presence/full", handle_alias, 300); +module:hook("presence/host", handle_alias, 300); diff -r f719d5e6c627 -r 1a5be0ecc876 mod_alias/mod_alias_postfixadmin.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_alias/mod_alias_postfixadmin.sh Wed Nov 25 14:40:43 2015 +0100 @@ -0,0 +1,20 @@ +#!/bin/sh +# Copyright (C) 2015 Travis Burtrum +# This file is MIT/X11 licensed. + +# run like ./mod_alias_postfixadmin.sh "mysql -N -upostfixadmin -ppostfixadmin postfixadmin" > /etc/prosody/aliases.cfg.lua +# then put: +# Include "aliases.cfg.lua" +# in prosody.cfg.lua + +mysql="$1" + +echo "-- alias plugin, generated by mod_alias_postfixadmin.sh" +echo "aliases = {" + +echo "SELECT concat('["'"'"', address, '"'"'"] = "'"'"', goto, '"'"'";') FROM alias WHERE address != goto; +SELECT concat('["'"'"', address, '"'"'"] = "'"'"', goto, '"'"'";') FROM ( + select replace(address, concat('@', target_domain), concat('@', alias_domain)) as address, goto FROM alias JOIN alias_domain ON alias_domain.target_domain = SUBSTRING(alias.address, locate('@',alias.address) + 1, length(alias.address)) +) a WHERE a.address != a.goto;" | $mysql | sort | uniq + +echo "}" diff -r f719d5e6c627 -r 1a5be0ecc876 mod_muc_access_control/mod_muc_access_control.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_muc_access_control/mod_muc_access_control.lua Wed Nov 25 14:40:43 2015 +0100 @@ -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);