# HG changeset patch # User Kim Alvefur # Date 1450697061 -3600 # Node ID f263fcf1b0edd3e74679f31407586a0ba101bba7 # Parent 6d7699eda5944e8c290255c4c39b38e7c70075dd# Parent 66aaf7c3cb29cb0b92a8980594648982cb1a7eba Merge with Goffi diff -r 66aaf7c3cb29 -r f263fcf1b0ed README --- a/README Mon Dec 21 11:31:10 2015 +0100 +++ b/README Mon Dec 21 12:24:21 2015 +0100 @@ -34,5 +34,5 @@ prosody-modules for 0.8 are now maintained separately at . -[Prosody]: http://prosody.im/ -[mailing list]: http://prosody.im/discuss +[Prosody]: https://prosody.im/ +[mailing list]: https://prosody.im/discuss diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_alias/README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_alias/README.markdown Mon Dec 21 12:24:21 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 66aaf7c3cb29 -r f263fcf1b0ed mod_alias/mod_alias.lua --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_alias/mod_alias.lua Mon Dec 21 12:24:21 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 66aaf7c3cb29 -r f263fcf1b0ed mod_alias/mod_alias_postfixadmin.sh --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/mod_alias/mod_alias_postfixadmin.sh Mon Dec 21 12:24:21 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 66aaf7c3cb29 -r f263fcf1b0ed mod_auth_ldap/README.markdown --- a/mod_auth_ldap/README.markdown Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_auth_ldap/README.markdown Mon Dec 21 12:24:21 2015 +0100 @@ -37,7 +37,7 @@ ldap\_rootdn The distinguished name to auth against `"" (anonymous)` ldap\_password Password for rootdn `""` ldap\_filter Search filter, with `$user` and `$host` substituded for user- and hostname `"(uid=$user)"` - ldap\_scope Search scope. other values: "base" and "subtree" `"onelevel"` + ldap\_scope Search scope. other values: "base" and "onelevel" `"subtree"` ldap\_tls Enable TLS (StartTLS) to connect to LDAP (can be true or false). The non-standard 'LDAPS' protocol is not supported. `false` ldap\_mode How passwords are validated. `"bind"` diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_auth_ldap/mod_auth_ldap.lua --- a/mod_auth_ldap/mod_auth_ldap.lua Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_auth_ldap/mod_auth_ldap.lua Mon Dec 21 12:24:21 2015 +0100 @@ -9,7 +9,7 @@ local ldap_rootdn = module:get_option_string("ldap_rootdn", ""); local ldap_password = module:get_option_string("ldap_password", ""); local ldap_tls = module:get_option_boolean("ldap_tls"); -local ldap_scope = module:get_option_string("ldap_scope", "onelevel"); +local ldap_scope = module:get_option_string("ldap_scope", "subtree"); local ldap_filter = module:get_option_string("ldap_filter", "(uid=$user)"):gsub("%%s", "$user", 1); local ldap_base = assert(module:get_option_string("ldap_base"), "ldap_base is a required option for ldap"); local ldap_mode = module:get_option_string("ldap_mode", "bind"); diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_http_muc_log/README.markdown --- a/mod_http_muc_log/README.markdown Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_http_muc_log/README.markdown Mon Dec 21 12:24:21 2015 +0100 @@ -8,41 +8,40 @@ ============ This module provides a built-in web interface to view chatroom logs -stored by [mod\_mam\_muc](mod_mam_muc.html). +stored by [mod\_mam\_muc]. Installation ============ -Just copy the folder muc\_log\_http as it is, into the modules folder of -your Prosody installation. +Same as any other module, be sure to include the HTML template +`http_muc_log.html` alongside `mod_http_muc_log.lua`. -Configuration Details -===================== +Configuration +============= -You need to add muc\_log\_http to your global modules\_enabled, and the -configuration options similarly must be put into your global -(server-wide) options section: +For example: - Component "conference.example.com" "muc" - modules_enabled = { - ..... - "mam_muc"; - "http_muc_log"; - ..... - } - storage = { - muc_log = "sql2"; -- for example - } +``` lua +Component "conference.example.com" "muc" +modules_enabled = { + "mam_muc"; + "http_muc_log"; +} +storage = { + muc_log = "sql"; -- for example +} +``` The web interface would then be reachable at the address: http://conference.example.com:5280/muc_log/ -See [the page about Prosodys HTTP server](http://prosody.im/doc/http) -for info about the address. +See [the page about Prosodys HTTP server][doc:http] for info about the +address. Compatibility ============= Requires Prosody 0.10 or above and a storage backend with support for -stanza archives. +stanza archives. See [mod\_storage\_muc\_log] for using legacy data from +[mod\_muc\_log]. diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_http_upload/README.markdown --- a/mod_http_upload/README.markdown Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_http_upload/README.markdown Mon Dec 21 12:24:21 2015 +0100 @@ -58,6 +58,16 @@ http_upload_file_size_limit = 10 * 1024 * 1024 -- this is 10MB in bytes ``` +Path +---- + +By default, uploaded files are put in a sub-directory of the default +Prosody storage path (usually `/var/lib/prosody`). This can be changed: + +``` {.lua} +http_upload_path = "/path/to/uploded/files" +``` + Compatibility ============= diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_http_upload/mod_http_upload.lua --- a/mod_http_upload/mod_http_upload.lua Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_http_upload/mod_http_upload.lua Mon Dec 21 12:24:21 2015 +0100 @@ -11,6 +11,7 @@ local st = require"util.stanza"; local lfs = require"lfs"; local uuid = require"util.uuid".generate; +local urlencode = require"util.http".urlencode; local t_concat = table.concat; local t_insert = table.insert; local s_upper = string.upper; @@ -34,7 +35,7 @@ -- state local pending_slots = module:shared("upload_slots"); -local storage_path = join_path(prosody.paths.data, module.name); +local storage_path = module:get_option_string(module.name .. "_path", join_path(prosody.paths.data, module.name)); lfs.mkdir(storage_path); -- hooks @@ -66,7 +67,7 @@ reply:tag("slot", { xmlns = xmlns_http_upload }); local random = uuid(); pending_slots[random.."/"..filename] = origin.full_jid; - local url = module:http_url() .. "/" .. random .. "/" .. filename; + local url = module:http_url() .. "/" .. random .. "/" .. urlencode(filename); reply:tag("get"):text(url):up(); reply:tag("put"):text(url):up(); origin.send(reply); diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_mam/README.markdown --- a/mod_mam/README.markdown Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_mam/README.markdown Mon Dec 21 12:24:21 2015 +0100 @@ -7,8 +7,7 @@ Introduction ============ -Implementation of [XEP-0313: Message Archive -Management](http://xmpp.org/extensions/xep-0313.html). +Implementation of [XEP-0313: Message Archive Management]. Details ======= @@ -37,15 +36,14 @@ Storage backend --------------- -mod\_mam uses the store "archive2"[^1]. See [Prosodys data storage -documentation](https://prosody.im/doc/storage) for information on how to -configure storage. +mod\_mam uses the store "archive2"[\^1]. See [Prosodys data storage +documentation][doc:storage] for information on how to configure storage. -For example, to use mod\_storage\_sql2[^2]: +For example, to use mod\_storage\_sql: ``` {.lua} storage = { - archive2 = "sql2"; + archive2 = "sql"; } ``` @@ -85,14 +83,12 @@ ------- --------------- trunk Works - 0.10 Works [^3] + 0.10 Works [^2] 0.9 Unsupported 0.8 Does not work ------- --------------- [^1]: Might be changed to "mam" at some point -[^2]: mod\_storage\_sql2 will replace mod\_storage\_sql at some point - -[^3]: requires a storage driver with archive support, eg - mod\_storage\_sql2 in 0.10 +[^2]: requires a storage driver with archive support, eg + mod\_storage\_sql in 0.10 diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_mam/mod_mam.lua --- a/mod_mam/mod_mam.lua Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_mam/mod_mam.lua Mon Dec 21 12:24:21 2015 +0100 @@ -224,7 +224,7 @@ -- Stanza without 'to' are treated as if it was to their own bare jid -- We store chat messages or normal messages that have a body - if not(orig_type == "chat" or orig_type == "normal" and stanza:get_child("body") ) then + if not(orig_type == "chat" or (orig_type == "normal" and stanza:get_child("body")) ) then module:log("debug", "Not archiving stanza: %s (type)", stanza:top_tag()); return; end diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_mam_muc/README.markdown --- a/mod_mam_muc/README.markdown Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_mam_muc/README.markdown Mon Dec 21 12:24:21 2015 +0100 @@ -9,9 +9,8 @@ This module logs the conversation of chatrooms running on the server to Prosody's archive storage. To access them you will need a client with -support for [XEP-0313: Message Archive -Management](http://xmpp.org/extensions/xep-0313.html) or a module such -as [mod\_http\_muc\_log](mod_http_muc_log.html). +support for [XEP-0313: Message Archive Management] or a module such +as [mod\_http\_muc\_log]. Usage ===== @@ -25,16 +24,18 @@ modules_enabled = { "mam_muc", } +``` + +And configure it to use an archive-capable storage module: + +``` {.lua} storage = { - -- This makes mod_mam_muc use the sql2 storage backend (others will use internal) - -- which at the time of this writing is the only one supporting stanza archives - muc_log = "sql2"; + muc_log = "sql"; -- Requires 0.10 or later } ``` -See [Prosodys data storage -documentation](https://prosody.im/doc/storage) for more info on how to -configure storage for different plugins. +See [Prosodys data storage documentation][doc:storage] for more info on +how to configure storage for different plugins. Configuration ============= @@ -57,9 +58,13 @@ Compatibility ============= - ------- --------------- - trunk Works - 0.10 Works + ------- ----------------- + trunk Works best + 0.10 Works partially 0.9 Does not work 0.8 Does not work - ------- --------------- + ------- ----------------- + +Prosody trunk (after April 2014) has a major rewrite of the MUC module, +allowing easier integration. Without this (0.10), some features do not +work, such as correct advertising and join/part logging. diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_mam_muc/mod_mam_muc.lua --- a/mod_mam_muc/mod_mam_muc.lua Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_mam_muc/mod_mam_muc.lua Mon Dec 21 12:24:21 2015 +0100 @@ -3,6 +3,11 @@ -- -- This file is MIT/X11 licensed. +if module:get_host_type() ~= "component" then + module:log("error", "mod_%s should be loaded only on a MUC component, not normal hosts", module.name); + return; +end + local xmlns_mam = "urn:xmpp:mam:0"; local xmlns_delay = "urn:xmpp:delay"; local xmlns_forward = "urn:xmpp:forward:0"; diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_migrate/README.markdown --- a/mod_migrate/README.markdown Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_migrate/README.markdown Mon Dec 21 12:24:21 2015 +0100 @@ -37,7 +37,7 @@ ======== for store in accounts roster private blocklist vcard archive2-archive; do - prosodyctl migrate example.com $store sql2 + prosodyctl migrate example.com $store sql done Compatibility diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_migrate/mod_migrate.lua --- a/mod_migrate/mod_migrate.lua Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_migrate/mod_migrate.lua Mon Dec 21 12:24:21 2015 +0100 @@ -5,55 +5,57 @@ local mm = require"core.modulemanager"; function module.command(arg) - local host, source_store, migrate_to, user = unpack(arg); + local host, source_stores, migrate_to, user = unpack(arg); if not migrate_to then return print("Usage: prosodyctl mod_migrate example.com [-] [users]*"); end sm.initialize_host(host); um.initialize_host(host); local module = module:context(host); - local store_type = source_store:match("%-(%a+)$"); - if store_type then - source_store = source_store:sub(1, -2-#store_type); - end - local storage = module:open_store(source_store, store_type); - local target = assert(sm.load_driver(host, migrate_to)); - target = assert(target:open(source_store, store_type)); + for source_store in source_stores:gmatch("[^,]+") do + local store_type = source_store:match("%-(%a+)$"); + if store_type then + source_store = source_store:sub(1, -2-#store_type); + end + local storage = module:open_store(source_store, store_type); + local target = assert(sm.load_driver(host, migrate_to)); + target = assert(target:open(source_store, store_type)); - local function migrate_user(username) - module:log("info", "Migrating data for %s", username); - local data, err = storage:get(username); - assert(data or err==nil, err); - assert(target:set(username, data)); - end + local function migrate_user(username) + module:log("info", "Migrating data for %s", username); + local data, err = storage:get(username); + assert(data or err==nil, err); + assert(target:set(username, data)); + end - if store_type == "archive" then - function migrate_user(username) - module:log("info", "Migrating archive items for %s", username); - local count, errs = 0, 0; - for id, item, when, with in storage:find(username) do - local ok, err = target:append(username, id, item, when, with); - if ok then - count = count + 1; - else - module:log("warn", "Error: %s", err); - errs = errs + 1; + if store_type == "archive" then + function migrate_user(username) + module:log("info", "Migrating archive items for %s", username); + local count, errs = 0, 0; + for id, item, when, with in storage:find(username) do + local ok, err = target:append(username, id, item, when, with); + if ok then + count = count + 1; + else + module:log("warn", "Error: %s", err); + errs = errs + 1; + end + if ( count + errs ) % 100 == 0 then + module:log("info", "%d items migrated, %d errors", count, errs); + end end - if ( count + errs ) % 100 == 0 then - module:log("info", "%d items migrated, %d errors", count, errs); - end + module:log("info", "%d items migrated, %d errors", count, errs); end - module:log("info", "%d items migrated, %d errors", count, errs); end - end - if arg[4] then - for i = 4, #arg do - migrate_user(arg[i]); - end - else - for user in um.users(host) do - migrate_user(user); + if arg[4] then + for i = 4, #arg do + migrate_user(arg[i]); + end + else + for user in um.users(host) do + migrate_user(user); + end end end end diff -r 66aaf7c3cb29 -r f263fcf1b0ed 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 Mon Dec 21 12:24:21 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); diff -r 66aaf7c3cb29 -r f263fcf1b0ed mod_muc_log_http/muc_log_http/themes/prosody/day_body.html --- a/mod_muc_log_http/muc_log_http/themes/prosody/day_body.html Mon Dec 21 11:31:10 2015 +0100 +++ b/mod_muc_log_http/muc_log_http/themes/prosody/day_body.html Mon Dec 21 12:24:21 2015 +0100 @@ -1,7 +1,7 @@
###DATE###
###JID###
- +