1
0
Fork 0
forked from mirror/prosody

Compare commits

..

3 commits
dev ... invites

Author SHA1 Message Date
Sara Aimée Smiseth
b6af9f8cb5 add tests for new modules 2021-05-07 14:14:40 +02:00
Sara Aimée Smiseth
d1db0837ec set registration_invite_only 2021-05-07 14:14:40 +02:00
Sara Aimée Smiseth
2173f8eff3 first version wip 2021-05-07 14:14:34 +02:00
24 changed files with 218 additions and 405 deletions

View file

@ -11,10 +11,10 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- name: Checkout repository and submodules - uses: actions/checkout@v2
uses: actions/checkout@v2
with: - name: Checkout submodules
submodules: recursive uses: textbook/git-checkout-submodule-action@master
- name: install python3-venv - name: install python3-venv
run: sudo apt-get install python3-venv run: sudo apt-get install python3-venv

View file

@ -2,78 +2,7 @@
## Unreleased ## Unreleased
### Adjust config * Added modules that allow invite-based account registration for Prosody. See also [Great Invitations](https://blog.prosody.im/great-invitations/).
* Replace deprecated legacy_ssl with c2s_direct_tls.
* Removed use_libevent = true. This means the default is now used which is epoll.
### Test
Added a test to check that no deprecated config settings are used.
## v1.3.0
* Updated to Prosody version [0.12.4](https://blog.prosody.im/prosody-0.12.4-released/)
### Breaking Change
Switched from [http_upload](https://modules.prosody.im/mod_http_upload) to [http_file_share](https://prosody.im/doc/modules/mod_http_file_share).
This means that previous uploads will NOT work after upgrading.
ENV variable `HTTP_UPLOAD_FILE_SIZE_LIMIT` was removed.
The new module uses the following variables:
* HTTP_FILE_SHARE_SIZE_LIMIT
* HTTP_FILE_SHARE_DAILY_QUOTA
See [readme.md](readme.md) for explanations and defaults.
## v1.2.10
* Update docker base image to debian bookworm
* [Add LDAP authentication support](https://github.com/SaraSmiseth/prosody/pull/50)
* Add environment variable HTTP_MAX_CONTENT_SIZE for setting http_max_content_size.
* Add environment variable HTTP_UPLOAD_FILE_SIZE_LIMIT for setting http_upload_file_size_limit.
* Add domain_http_upload to disco_items to support http_upload on some clients and if http_upload is not a subdomain.
## v1.2.9
* Update prosody to version 0.12.3
* Update luarocks to version 3.9.2
## v1.2.8
* Updated to Prosody version [0.12.1](https://blog.prosody.im/prosody-0.12.1-released/).
## v1.2.7
* Updated to Prosody version [0.12.0](https://blog.prosody.im/prosody-0.12.0-released/).
* Updated luarocks to version 3.9.0.
## v1.2.6
* Updated to Prosody version [0.11.13](https://blog.prosody.im/prosody-0.11.13-released/).
## v1.2.5
* Updated to Prosody version [0.11.12](https://blog.prosody.im/prosody-0.11.12-released/).
## v1.2.4
* Updated to Prosody version [0.11.11](https://blog.prosody.im/prosody-0.11.11-released/).
* Updated luarocks to version 3.8.0.
## v1.2.3
* Updated to Prosody version [0.11.10](https://blog.prosody.im/prosody-0.11.10-released/).
## v1.2.2
- Update debian from buster-slim to bullseye-slim (#27)
## v1.2.1
* Updated to Prosody version [0.11.9](https://blog.prosody.im/prosody-0.11.9-released/).
## v1.2.0 ## v1.2.0

View file

@ -1,14 +1,14 @@
FROM debian:bookworm-slim FROM debian:buster-slim
ARG BUILD_DATE ARG BUILD_DATE
ARG VCS_REF ARG VCS_REF
ARG VERSION ARG VERSION
ARG LUAROCKS_VERSION=3.11.1 ARG LUAROCKS_VERSION=3.7.0
ARG PROSODY_VERSION=0.12.4 ARG PROSODY_VERSION=0.11.8
ARG LUAROCKS_SHA256="c3fb3d960dffb2b2fe9de7e3cb004dc4d0b34bb3d342578af84f84325c669102" ARG LUAROCKS_SHA256=9255d97fee95cec5b54fc6ac718b11bf5029e45bed7873e053314919cd448551
ARG PROSODY_DOWNLOAD_SHA256="47d712273c2f29558c412f6cdaec073260bbc26b7dda243db580330183d65856" ARG PROSODY_DOWNLOAD_SHA256=830f183b98d5742d81e908d2d8e3258f1b538dad7411f06fda5b2cc5c75068f8
LABEL luarocks.version="${LUAROCKS_VERSION}" LABEL luarocks.version="${LUAROCKS_VERSION}"
LABEL org.opencontainers.image.authors="Sara Smiseth" LABEL org.opencontainers.image.authors="Sara Smiseth"
@ -23,28 +23,30 @@ LABEL org.opencontainers.image.vendor="Sara Smiseth"
LABEL org.opencontainers.image.version="${VERSION}" LABEL org.opencontainers.image.version="${VERSION}"
LABEL prosody.version="${PROSODY_VERSION}" LABEL prosody.version="${PROSODY_VERSION}"
# TODO just for mod_invites, makes the image from 90MB to 150MB, just do it like this?
#libjs-bootstrap4
#libjs-jquery
RUN apt-get update \ RUN apt-get update \
&& DEBIAN_FRONTEND=noninteractive apt-get install -y \ && DEBIAN_FRONTEND=noninteractive apt-get install -y \
libevent-dev `# this is no build dependency, but needed for luaevent` \ libevent-dev `# this is no build dependency, but needed for luaevent` \
libicu72 \ libidn11 \
libidn2-0 \ libjs-bootstrap4 \
libjs-jquery \
libpq-dev \ libpq-dev \
libsqlite3-0 \ libsqlite3-0 \
lua5.2 \ lua5.2 \
lua-bitop \ lua-bitop \
lua-dbi-mysql \ lua-dbi-mysql \
lua-dbi-postgresql \
lua-expat \ lua-expat \
lua-filesystem \ lua-filesystem \
lua-ldap \
lua-socket \ lua-socket \
lua-sec \ lua-sec \
lua-unbound \
wget \ wget \
&& apt-get clean \ && apt-get clean \
&& rm -rf /var/lib/apt/lists/* && rm -rf /var/lib/apt/lists/*
RUN buildDeps='gcc git libc6-dev libidn2-dev liblua5.2-dev libsqlite3-dev libssl-dev libicu-dev make unzip' \ RUN buildDeps='gcc git libc6-dev libidn11-dev liblua5.2-dev libsqlite3-dev libssl-dev make unzip' \
&& set -x \ && set -x \
&& apt-get update && apt-get install -y $buildDeps --no-install-recommends \ && apt-get update && apt-get install -y $buildDeps --no-install-recommends \
&& rm -rf /var/lib/apt/lists/* \ && rm -rf /var/lib/apt/lists/* \
@ -72,6 +74,7 @@ RUN buildDeps='gcc git libc6-dev libidn2-dev liblua5.2-dev libsqlite3-dev libssl
&& luarocks install luaevent \ && luarocks install luaevent \
&& luarocks install luadbi \ && luarocks install luadbi \
`#&& luarocks install luadbi-mysql MYSQL_INCDIR=/usr/include/mariadb/` \ `#&& luarocks install luadbi-mysql MYSQL_INCDIR=/usr/include/mariadb/` \
&& luarocks install luadbi-postgresql POSTGRES_INCDIR=/usr/include/postgresql/ \
&& luarocks install luadbi-sqlite3 \ && luarocks install luadbi-sqlite3 \
&& luarocks install stringy \ && luarocks install stringy \
\ \
@ -99,9 +102,21 @@ COPY *.bash /usr/local/bin/
RUN download-prosody-modules.bash \ RUN download-prosody-modules.bash \
&& docker-prosody-module-install.bash \ && docker-prosody-module-install.bash \
bookmarks `# XEP-0411: Bookmarks Conversion` \
carbons `# message carbons (XEP-0280)` \
cloud_notify `# XEP-0357: Push Notifications` \ cloud_notify `# XEP-0357: Push Notifications` \
csi `# client state indication (XEP-0352)` \
e2e_policy `# require end-2-end encryption` \ e2e_policy `# require end-2-end encryption` \
filter_chatstates `# disable "X is typing" type messages` \ filter_chatstates `# disable "X is typing" type messages` \
http_libjs `# invite-based account registration web dependency` \
http_upload `# file sharing (XEP-0363)` \
invites `# invite-based account registration` \
invites_adhoc \
invites_page \
invites_register \
invites_register_web \
register_apps \
smacks `# stream management (XEP-0198)` \
throttle_presence `# presence throttling in CSI` \ throttle_presence `# presence throttling in CSI` \
vcard_muc `# XEP-0153: vCard-Based Avatar (MUC)` \ vcard_muc `# XEP-0153: vCard-Based Avatar (MUC)` \
&& rm -rf "/usr/src/prosody-modules" && rm -rf "/usr/src/prosody-modules"

View file

@ -24,7 +24,6 @@ modules_enabled = {
"ping"; -- Replies to XMPP pings with pongs "ping"; -- Replies to XMPP pings with pongs
"pep"; -- Enables users to publish their mood, activity, playing music and more "pep"; -- Enables users to publish their mood, activity, playing music and more
"register"; -- Allow users to register on this server using a client and change passwords "register"; -- Allow users to register on this server using a client and change passwords
"turn_external"; -- Allow users to make voice/video calls
--"muc"; -- [Loaded as component, therefore commented here] Multi-user chats (XEP-0045) --"muc"; -- [Loaded as component, therefore commented here] Multi-user chats (XEP-0045)
-- Admin interfaces -- Admin interfaces

View file

@ -1,8 +1,8 @@
default_storage = "sql" default_storage = "sql"
sql = { sql = {
driver = os.getenv("DB_DRIVER") or "SQLite3"; driver = os.getenv("DB_DRIVER");
database = os.getenv("DB_DATABASE") or "prosody.sqlite"; database = os.getenv("DB_DATABASE");
host = os.getenv("DB_HOST"); host = os.getenv("DB_HOST");
port = os.getenv("DB_PORT"); port = os.getenv("DB_PORT");
username = os.getenv("DB_USERNAME"); username = os.getenv("DB_USERNAME");
@ -20,4 +20,3 @@ storage = {
-- https://modules.prosody.im/mod_mam.html -- https://modules.prosody.im/mod_mam.html
archive_expires_after = "1y" archive_expires_after = "1y"
http_max_content_size = os.getenv("HTTP_MAX_CONTENT_SIZE") or 1024 * 1024 * 10 -- Default is 10MB

View file

@ -1,11 +1,8 @@
local stringy = require "stringy" local stringy = require "stringy"
e2e_policy_chat = os.getenv("E2E_POLICY_CHAT") or "required" e2e_policy_chat = os.getenv("E2E_POLICY_CHAT")
e2e_policy_muc = os.getenv("E2E_POLICY_MUC") or "required" e2e_policy_muc = os.getenv("E2E_POLICY_MUC")
e2e_policy_whitelist = stringy.split(os.getenv("E2E_POLICY_WHITELIST"), ", ")
local whitelist = os.getenv("E2E_POLICY_WHITELIST") or ""
e2e_policy_whitelist = stringy.split(whitelist, ", ")
e2e_policy_message_optional_chat = "For security reasons, OMEMO, OTR or PGP encryption is STRONGLY recommended for conversations on this server." e2e_policy_message_optional_chat = "For security reasons, OMEMO, OTR or PGP encryption is STRONGLY recommended for conversations on this server."
e2e_policy_message_required_chat = "For security reasons, OMEMO, OTR or PGP encryption is required for conversations on this server." e2e_policy_message_required_chat = "For security reasons, OMEMO, OTR or PGP encryption is required for conversations on this server."
e2e_policy_message_optional_muc = "For security reasons, OMEMO, OTR or PGP encryption is STRONGLY recommended for MUC on this server." e2e_policy_message_optional_muc = "For security reasons, OMEMO, OTR or PGP encryption is STRONGLY recommended for MUC on this server."

View file

@ -1,18 +1,10 @@
local stringy = require "stringy" local stringy = require "stringy"
local domain = os.getenv("DOMAIN")
local abuse = os.getenv("SERVER_CONTACT_INFO_ABUSE") or "xmpp:abuse@" .. domain
local admin = os.getenv("SERVER_CONTACT_INFO_ADMIN") or "xmpp:admin@" .. domain
local feedback = os.getenv("SERVER_CONTACT_INFO_FEEDBACK") or "xmpp:feedback@" .. domain
local sales = os.getenv("SERVER_CONTACT_INFO_SALES") or "xmpp:sales@" .. domain
local security = os.getenv("SERVER_CONTACT_INFO_SECURITY") or "xmpp:security@" .. domain
local support = os.getenv("SERVER_CONTACT_INFO_SUPPORT") or "xmpp:support@" .. domain
contact_info = { contact_info = {
abuse = stringy.split(abuse, ", "); abuse = stringy.split(os.getenv("SERVER_CONTACT_INFO_ABUSE"), ", ");
admin = stringy.split(admin, ", "); admin = stringy.split(os.getenv("SERVER_CONTACT_INFO_ADMIN"), ", ");
feedback = stringy.split(feedback, ", "); feedback = stringy.split(os.getenv("SERVER_CONTACT_INFO_FEEDBACK"), ", ");
sales = stringy.split(sales, ", "); sales = stringy.split(os.getenv("SERVER_CONTACT_INFO_SALES"), ", ");
security = stringy.split(security, ", "); security = stringy.split(os.getenv("SERVER_CONTACT_INFO_SECURITY"), ", ");
support = stringy.split(support, ", "); support = stringy.split(os.getenv("SERVER_CONTACT_INFO_SUPPORT"), ", ");
} }

View file

@ -1,16 +1,16 @@
local domain = os.getenv("DOMAIN") local domain = os.getenv("DOMAIN")
local domain_http_upload = os.getenv("DOMAIN_HTTP_UPLOAD") or "upload." .. domain local domain_http_upload = os.getenv("DOMAIN_HTTP_UPLOAD")
local domain_muc = os.getenv("DOMAIN_MUC") or "conference." .. domain local domain_muc = os.getenv("DOMAIN_MUC")
local domain_proxy = os.getenv("DOMAIN_PROXY") or "proxy." .. domain local domain_proxy = os.getenv("DOMAIN_PROXY")
local domain_pubsub = os.getenv("DOMAIN_PUBSUB") or "pubsub." .. domain local domain_pubsub = os.getenv("DOMAIN_PUBSUB")
-- XEP-0368: SRV records for XMPP over TLS -- XEP-0368: SRV records for XMPP over TLS
-- https://compliance.conversations.im/test/xep0368/ -- https://compliance.conversations.im/test/xep0368/
c2s_direct_tls_ssl = { legacy_ssl_ssl = {
certificate = "certs/" .. domain .. "/fullchain.pem"; certificate = "certs/" .. domain .. "/fullchain.pem";
key = "certs/" .. domain .. "/privkey.pem"; key = "certs/" .. domain .. "/privkey.pem";
} }
c2s_direct_tls_ports = { 5223 } legacy_ssl_ports = { 5223 }
-- https://prosody.im/doc/certificates#service_certificates -- https://prosody.im/doc/certificates#service_certificates
-- https://prosody.im/doc/ports#ssl_configuration -- https://prosody.im/doc/ports#ssl_configuration
@ -19,22 +19,19 @@ https_ssl = {
key = "certs/" .. domain_http_upload .. "/privkey.pem"; key = "certs/" .. domain_http_upload .. "/privkey.pem";
} }
-- Configure the number of seconds a token is valid for (default 7 days)
-- TODO make configurable
invite_expiry = 86400 * 7
VirtualHost (domain) VirtualHost (domain)
http_paths = {
turn_external_host = os.getenv("TURN_EXTERNAL_HOST") or "turn" .. domain; invites_page = "/invite";
turn_external_port = os.getenv("TURN_EXTERNAL_PORT") or 3478; invites_register_web = "/register";
turn_external_secret = os.getenv("TURN_EXTERNAL_SECRET"); }
disco_items = {
{ domain_http_upload },
}
-- Set up a http file upload because proxy65 is not working in muc -- Set up a http file upload because proxy65 is not working in muc
Component (domain_http_upload) "http_file_share" Component (domain_http_upload) "http_upload"
http_file_share_expires_after = 60 * 60 * 24 * 7 -- a week in seconds http_upload_expire_after = 60 * 60 * 24 * 7 -- a week in seconds
local size_limit = os.getenv("HTTP_FILE_SHARE_SIZE_LIMIT") or 10 * 1024 * 1024 -- Default is 10MB
http_file_share_size_limit = size_limit
http_file_share_daily_quota = os.getenv("HTTP_FILE_SHARE_DAILY_QUOTA") or 10 * size_limit -- Default is 10x the size limit
Component (domain_muc) "muc" Component (domain_muc) "muc"
name = "Prosody Chatrooms" name = "Prosody Chatrooms"
@ -52,6 +49,3 @@ Component (domain_proxy) "proxy65"
-- Implements a XEP-0060 pubsub service. -- Implements a XEP-0060 pubsub service.
Component (domain_pubsub) "pubsub" Component (domain_pubsub) "pubsub"
-- Set TURN server information.

View file

@ -1,6 +1,29 @@
#!/bin/bash #!/bin/bash
set -e set -e
export ALLOW_REGISTRATION=${ALLOW_REGISTRATION:-true}
export REGISTRATION_INVITE_ONLY=${REGISTRATION_INVITE_ONLY:-false}
export DOMAIN_HTTP_UPLOAD=${DOMAIN_HTTP_UPLOAD:-"upload.$DOMAIN"}
export DOMAIN_MUC=${DOMAIN_MUC:-"conference.$DOMAIN"}
export DOMAIN_PROXY=${DOMAIN_PROXY:-"proxy.$DOMAIN"}
export DOMAIN_PUBSUB=${DOMAIN_PUBSUB:-"pubsub.$DOMAIN"}
export DB_DRIVER=${DB_DRIVER:-"SQLite3"}
export DB_DATABASE=${DB_DATABASE:-"prosody.sqlite"}
export E2E_POLICY_CHAT=${E2E_POLICY_CHAT:-"required"}
export E2E_POLICY_MUC=${E2E_POLICY_MUC:-"required"}
export E2E_POLICY_WHITELIST=${E2E_POLICY_WHITELIST:-""}
export LOG_LEVEL=${LOG_LEVEL:-"info"}
export C2S_REQUIRE_ENCRYPTION=${C2S_REQUIRE_ENCRYPTION:-true}
export S2S_REQUIRE_ENCRYPTION=${S2S_REQUIRE_ENCRYPTION:-true}
export S2S_SECURE_AUTH=${S2S_SECURE_AUTH:-true}
export SERVER_CONTACT_INFO_ABUSE=${SERVER_CONTACT_INFO_ABUSE:-"xmpp:abuse@$DOMAIN"}
export SERVER_CONTACT_INFO_ADMIN=${SERVER_CONTACT_INFO_ADMIN:-"xmpp:admin@$DOMAIN"}
export SERVER_CONTACT_INFO_FEEDBACK=${SERVER_CONTACT_INFO_FEEDBACK:-"xmpp:feedback@$DOMAIN"}
export SERVER_CONTACT_INFO_SALES=${SERVER_CONTACT_INFO_SALES:-"xmpp:sales@$DOMAIN"}
export SERVER_CONTACT_INFO_SECURITY=${SERVER_CONTACT_INFO_SECURITY:-"xmpp:security@$DOMAIN"}
export SERVER_CONTACT_INFO_SUPPORT=${SERVER_CONTACT_INFO_SUPPORT:-"xmpp:support@$DOMAIN"}
export PROSODY_ADMINS=${PROSODY_ADMINS:-""}
if [[ "$1" != "prosody" ]]; then if [[ "$1" != "prosody" ]]; then
exec prosodyctl $* exec prosodyctl $*
exit 0; exit 0;

View file

@ -3,31 +3,23 @@
local stringy = require "stringy" local stringy = require "stringy"
local prosody_admins = os.getenv("PROSODY_ADMINS") or ""; admins = stringy.split(os.getenv("PROSODY_ADMINS"), ", ");
admins = stringy.split(prosody_admins, ", ");
pidfile = "/var/run/prosody/prosody.pid" pidfile = "/var/run/prosody/prosody.pid"
allow_registration = os.getenv("ALLOW_REGISTRATION") or "true"; use_libevent = true; -- improves performance
c2s_require_encryption = os.getenv("C2S_REQUIRE_ENCRYPTION") or "true"; allow_registration = os.getenv("ALLOW_REGISTRATION");
s2s_require_encryption = os.getenv("S2S_REQUIRE_ENCRYPTION") or "true"; registration_invite_only = os.getenv("REGISTRATION_INVITE_ONLY");
s2s_secure_auth = os.getenv("S2S_SECURE_AUTH") or "true";
authentication = os.getenv("AUTHENTICATION") or "internal_hashed"; c2s_require_encryption = os.getenv("C2S_REQUIRE_ENCRYPTION");
s2s_require_encryption = os.getenv("S2S_REQUIRE_ENCRYPTION");
s2s_secure_auth = os.getenv("S2S_SECURE_AUTH");
ldap_base = os.getenv("LDAP_BASE"); authentication = "internal_hashed";
ldap_server = os.getenv("LDAP_SERVER") or "localhost";
ldap_rootdn = os.getenv("LDAP_ROOTDN") or "";
ldap_password = os.getenv("LDAP_PASSWORD") or "";
ldap_filter = os.getenv("LDAP_FILTER") or "(uid=$user)";
ldap_scope = os.getenv("LDAP_SCOPE") or "subtree";
ldap_tls = os.getenv("LDAP_TLS") or "false";
ldap_mode = os.getenv("LDAP_MODE") or "bind";
ldap_admin_filter = os.getenv("LDAP_ADMIN_FILTER") or "";
log = { log = {
{levels = {min = os.getenv("LOG_LEVEL") or "info"}, to = "console"}; {levels = {min = os.getenv("LOG_LEVEL")}, to = "console"};
}; };
Include "conf.d/*.cfg.lua"; Include "conf.d/*.cfg.lua";

View file

@ -2,12 +2,14 @@
![Docker](https://github.com/SaraSmiseth/prosody/workflows/Docker/badge.svg?branch=dev) ![Docker](https://github.com/SaraSmiseth/prosody/workflows/Docker/badge.svg?branch=dev)
![Git repository size](https://img.shields.io/github/repo-size/SaraSmiseth/prosody) ![Git repository size](https://img.shields.io/github/repo-size/SaraSmiseth/prosody)
[![Docker image](https://images.microbadger.com/badges/image/sarasmiseth/prosody:latest.svg)](https://microbadger.com/images/sarasmiseth/prosody:latest)
[![Docker version](https://images.microbadger.com/badges/version/sarasmiseth/prosody.svg)](https://microbadger.com/images/sarasmiseth/prosody:latest)
[![Docker pulls](https://img.shields.io/docker/pulls/sarasmiseth/prosody.svg)](https://hub.docker.com/r/sarasmiseth/prosody/) [![Docker pulls](https://img.shields.io/docker/pulls/sarasmiseth/prosody.svg)](https://hub.docker.com/r/sarasmiseth/prosody/)
[![Docker stars](https://img.shields.io/docker/stars/sarasmiseth/prosody.svg)](https://hub.docker.com/r/sarasmiseth/prosody/) [![Docker stars](https://img.shields.io/docker/stars/sarasmiseth/prosody.svg)](https://hub.docker.com/r/sarasmiseth/prosody/)
[![Github open issues](https://img.shields.io/github/issues-raw/SaraSmiseth/prosody)](https://github.com/SaraSmiseth/prosody/issues) [![Github open issues](https://img.shields.io/github/issues-raw/SaraSmiseth/prosody)](https://github.com/SaraSmiseth/prosody/issues)
[![Github open pull requests](https://img.shields.io/github/issues-pr-raw/SaraSmiseth/prosody)](https://github.com/SaraSmiseth/prosody/pulls) [![Github open pull requests](https://img.shields.io/github/issues-pr-raw/SaraSmiseth/prosody)](https://github.com/SaraSmiseth/prosody/pulls)
This docker image provides you with a configured [Prosody](https://prosody.im/) XMPP server. The image is based on `debian:bookworm-slim`. This docker image provides you with a configured [Prosody](https://prosody.im/) XMPP server. The image is based on `debian:buster-slim`.
The server was tested using the Android App [Conversations](https://conversations.im/) and the Desktop client [Gajim](https://gajim.org). The server was tested using the Android App [Conversations](https://conversations.im/) and the Desktop client [Gajim](https://gajim.org).
Multiple [architectures](https://hub.docker.com/r/sarasmiseth/prosody/tags) are supported. I use it on my raspberry pi 4. Multiple [architectures](https://hub.docker.com/r/sarasmiseth/prosody/tags) are supported. I use it on my raspberry pi 4.
@ -36,7 +38,6 @@ While Conversations got everything set-up out-of-the-box, Gajim was used with th
- [Symlinks](#symlinks) - [Symlinks](#symlinks)
- [Permissions](#permissions) - [Permissions](#permissions)
- [Run](#run) - [Run](#run)
- [Volumes permissions](#volumes-permissions)
- [Docker tags](#docker-tags) - [Docker tags](#docker-tags)
- [Configuration](#configuration) - [Configuration](#configuration)
- [Environment variables](#environment-variables) - [Environment variables](#environment-variables)
@ -141,7 +142,6 @@ For example ```cp -L src dest```.
##### Permissions ##### Permissions
See official [documentation](https://prosody.im/doc/certificates#permissions) for more information. See official [documentation](https://prosody.im/doc/certificates#permissions) for more information.
Check [Volumes permissions](#volumes-permissions) as well.
### Run ### Run
@ -152,7 +152,7 @@ version: '3.7'
services: services:
server: server:
image: sarasmiseth/prosody:latest image: sarasmiseth/prosody:v1.0.0
restart: unless-stopped restart: unless-stopped
ports: ports:
- "5000:5000" - "5000:5000"
@ -167,18 +167,9 @@ services:
- ./data:/usr/local/var/lib/prosody - ./data:/usr/local/var/lib/prosody
``` ```
Boot it via: ```docker compose up -d```. Boot it via: ```docker-compose up -d```.
Inspect logs: ```docker compose logs -f```. Inspect logs: ```docker-compose logs -f```.
### Volumes permissions
The prosody user inside the container has the `uid=999` and `gid=999`. If you use the example `docker-compose.yml` from above make sure, that the `./data` folder and the `./certs` folder have the correct permissions.
``` shell
sudo chown 999:999 ./certs
sudo chown 999:999 ./data
```
### Docker tags ### Docker tags
@ -195,50 +186,35 @@ sudo chown 999:999 ./data
#### Environment variables #### Environment variables
| Variable | Description | Type | Default value | | Variable | Description | Type | Default value |
| -------------------------------- | -------------------------------------------------------------------------------------------------------------------- | -------------------------------------------- | -------------------------- | | -------------------------------- | -------------------------------------------------------------------------------------------------------------------- | ------------ | -------------------------- |
| **ALLOW_REGISTRATION** | Whether to allow registration of new accounts via Jabber clients | *optional* | true | | **ALLOW_REGISTRATION** | Whether to allow registration of new accounts via Jabber clients | *optional* | true |
| **DOMAIN** | domain | **required** | null | | **REGISTRATION_INVITE_ONLY** | Require an invitation token for all account registration | *optional* | false |
| **DOMAIN_HTTP_UPLOAD** | Domain which lets clients upload files over HTTP | *optional* | upload.**DOMAIN** | | **DOMAIN** | domain | **required** | null |
| **DOMAIN_MUC** | Domain for Multi-user chat (MUC) for allowing you to create hosted chatrooms/conferences for XMPP users | *optional* | conference.**DOMAIN** | | **DOMAIN_HTTP_UPLOAD** | Domain which lets clients upload files over HTTP | *optional* | upload.**DOMAIN** |
| **DOMAIN_PROXY** | Domain for SOCKS5 bytestream proxy for server-proxied file transfers | *optional* | proxy.**DOMAIN** | | **DOMAIN_MUC** | Domain for Multi-user chat (MUC) for allowing you to create hosted chatrooms/conferences for XMPP users | *optional* | conference.**DOMAIN** |
| **DOMAIN_PUBSUB** | Domain for a XEP-0060 pubsub service | *optional* | pubsub.**DOMAIN** | | **DOMAIN_PROXY** | Domain for SOCKS5 bytestream proxy for server-proxied file transfers | *optional* | proxy.**DOMAIN** |
| **AUTHENTICATION** | authentication | *optional* | "internal_hashed" | | **DOMAIN_PUBSUB** | Domain for a XEP-0060 pubsub service | *optional* | pubsub.**DOMAIN** |
| **LDAP_BASE** | LDAP base directory which stores user accounts | **required** if **AUTHENTICATION** is "ldap" | | | **DB_DRIVER** | May also be "PostgreSQL" or "MySQL" or "SQLite3" (case sensitive!) | *optional* | SQLite3 |
| **LDAP_SERVER** | Space-separated list of hostnames or IPs, optionally with port numbers (e.g. “localhost:8389”) | *optional* | "localhost" | | **DB_DATABASE** | The database name to use. For SQLite3 this the database filename (relative to the data storage directory). | *optional* | prosody.sqlite |
| **LDAP_ROOTDN** | The distinguished name to auth against | *optional* | "" | | **DB_HOST** | The address of the database server | *optional* | |
| **LDAP_PASSWORD** | Password for rootdn | *optional* | "" | | **DB_PORT** | Port on which the database is listening | *optional* | |
| **LDAP_FILTER** | Search filter, with $user and $host substituted for user- and hostname | *optional* | "(uid=$user)" | | **DB_USERNAME** | The username to authenticate to the database | *optional* | |
| **LDAP_SCOPE** | Search scope. other values: “base” and “onelevel” | *optional* | "subtree" | | **DB_PASSWORD** | The password to authenticate to the database | *optional* | |
| **LDAP_TLS** | Enable TLS (StartTLS) to connect to LDAP (can be true or false). The non-standard LDAPS protocol is not supported. | *optional* | "false" | | **E2E_POLICY_CHAT** | Policy for chat messages. Possible values: "none", "optional" and "required". | *optional* | "required" |
| **LDAP_MODE** | How passwords are validated. | *optional* | "bind" | | **E2E_POLICY_MUC** | Policy for MUC messages. Possible values: "none", "optional" and "required". | *optional* | "required" |
| **LDAP_ADMIN_FILTER** | Search filter to match admins, works like ldap_filter | *optional* | "" | | **E2E_POLICY_WHITELIST** | Make this module ignore messages sent to and from this JIDs or MUCs. | *optional* | "" |
| **DB_DRIVER** | May also be "PostgreSQL" or "MySQL" or "SQLite3" (case sensitive!) | *optional* | SQLite3 | | **LOG_LEVEL** | Min log level. Change to debug for more information | *optional* | info |
| **DB_DATABASE** | The database name to use. For SQLite3 this the database filename (relative to the data storage directory). | *optional* | prosody.sqlite | | **C2S_REQUIRE_ENCRYPTION** | Whether to force all client-to-server connections to be encrypted or not | *optional* | true |
| **DB_HOST** | The address of the database server | *optional* | | | **S2S_REQUIRE_ENCRYPTION** | Whether to force all server-to-server connections to be encrypted or not | *optional* | true |
| **DB_PORT** | Port on which the database is listening | *optional* | | | **S2S_SECURE_AUTH** | Require encryption and certificate authentication | *optional* | true |
| **DB_USERNAME** | The username to authenticate to the database | *optional* | | | **SERVER_CONTACT_INFO_ABUSE** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:abuse@**DOMAIN**" |
| **DB_PASSWORD** | The password to authenticate to the database | *optional* | | | **SERVER_CONTACT_INFO_ADMIN** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:admin@**DOMAIN**" |
| **HTTP_MAX_CONTENT_SIZE** | Max http content size in bytes | *optional* | 10485760 | | **SERVER_CONTACT_INFO_FEEDBACK** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:feedback@**DOMAIN**" |
| **HTTP_FILE_SHARE_SIZE_LIMIT** | Max http file share size in bytes | *optional* | 10485760 | | **SERVER_CONTACT_INFO_SALES** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:sales@**DOMAIN**" |
| **HTTP_FILE_SHARE_DAILY_QUOTA** | Daily quota in bytes | *optional* | 10 times share size limit | | **SERVER_CONTACT_INFO_SECURITY** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:security@**DOMAIN**" |
| **E2E_POLICY_CHAT** | Policy for chat messages. Possible values: "none", "optional" and "required". | *optional* | "required" | | **SERVER_CONTACT_INFO_SUPPORT** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:support@**DOMAIN**" |
| **E2E_POLICY_MUC** | Policy for MUC messages. Possible values: "none", "optional" and "required". | *optional* | "required" | | **PROSODY_ADMINS** | Specify who is an administrator. List of adresses. Eg. "me@example.com", "admin@example.net" | *optional* | "" |
| **E2E_POLICY_WHITELIST** | Make this module ignore messages sent to and from this JIDs or MUCs. | *optional* | "" |
| **LOG_LEVEL** | Min log level. Change to debug for more information | *optional* | info |
| **C2S_REQUIRE_ENCRYPTION** | Whether to force all client-to-server connections to be encrypted or not | *optional* | true |
| **S2S_REQUIRE_ENCRYPTION** | Whether to force all server-to-server connections to be encrypted or not | *optional* | true |
| **S2S_SECURE_AUTH** | Require encryption and certificate authentication | *optional* | true |
| **SERVER_CONTACT_INFO_ABUSE** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:abuse@**DOMAIN**" |
| **SERVER_CONTACT_INFO_ADMIN** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:admin@**DOMAIN**" |
| **SERVER_CONTACT_INFO_FEEDBACK** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:feedback@**DOMAIN**" |
| **SERVER_CONTACT_INFO_SALES** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:sales@**DOMAIN**" |
| **SERVER_CONTACT_INFO_SECURITY** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:security@**DOMAIN**" |
| **SERVER_CONTACT_INFO_SUPPORT** | A list of strings. Each string should be an URI. See [here](https://prosody.im/doc/modules/mod_server_contact_info). | *optional* | "xmpp:support@**DOMAIN**" |
| **TURN_EXTERNAL_HOST** | The external hostname for the TURN server. | *optional* | "turn.**DOMAIN**" |
| **TURN_EXTERNAL_PORT** | The external port for the TURN server. | *optional* | "3478" |
| **TURN_EXTERNAL_SECRET** | The external secret for the TURN server. | *optional* | "" |
| **PROSODY_ADMINS** | Specify who is an administrator. List of adresses. Eg. "me@example.com", "admin@example.net" | *optional* | "" |
#### DNS #### DNS
@ -249,7 +225,6 @@ You need these DNS record pointing to your server:
* proxy.domain.tld * proxy.domain.tld
* pubsub.domain.tld * pubsub.domain.tld
* upload.domain.tld * upload.domain.tld
* turn.domain.tld
* A SRV record for _xmpps-client._tcp.domain.tld for port 5223. * A SRV record for _xmpps-client._tcp.domain.tld for port 5223.
where domain.tld is the environment variable DOMAIN. where domain.tld is the environment variable DOMAIN.
@ -269,7 +244,7 @@ If you need additional configuration just overwrite the respective _cfg.lua_ fil
When migrating from prosody 0.10, you need to update the database once: When migrating from prosody 0.10, you need to update the database once:
```bash ```bash
docker compose exec server bash docker-compose exec server bash
prosodyctl mod_storage_sql upgrade prosodyctl mod_storage_sql upgrade
``` ```

@ -1 +1 @@
Subproject commit 397c735212bf1a06cfdd0cb7806c5a6ea79582bf Subproject commit e0de84e9c011223e7f88b7ccf1c929f4327097ba

@ -1 +1 @@
Subproject commit 410dd229a5ed005c68167cc90ed0712ad2a1c909 Subproject commit 49b377a751e6f9379abfdfb3dfa3aafabd8495a1

@ -1 +1 @@
Subproject commit 3c8fadc5097c9acfc96d836dced2bb598e48b009 Subproject commit d140a65044b2d6810381935ae7f0c94c7023c8c3

View file

@ -1,3 +1,5 @@
version: '3.7'
services: services:
prosody: prosody:
image: prosody image: prosody
@ -9,10 +11,10 @@ services:
- "5269:5269" - "5269:5269"
- "5281:5281" - "5281:5281"
environment: environment:
DOMAIN: example.com DOMAIN: localhost
E2E_POLICY_WHITELIST: "admin@example.com, user1@example.com" E2E_POLICY_WHITELIST: "admin@localhost, user1@localhost"
LOG_LEVEL: debug LOG_LEVEL: debug
PROSODY_ADMINS: "admin@example.com, admin2@example.com" PROSODY_ADMINS: "admin@localhost, admin2@localhost"
volumes: volumes:
- ./certs:/usr/local/etc/prosody/certs - ./certs:/usr/local/etc/prosody/certs
@ -26,10 +28,10 @@ services:
- "5269:5269" - "5269:5269"
- "5281:5281" - "5281:5281"
environment: environment:
DOMAIN: example.com DOMAIN: localhost
E2E_POLICY_WHITELIST: "admin@example.com, user1@example.com" E2E_POLICY_WHITELIST: "admin@localhost, user1@localhost"
LOG_LEVEL: debug LOG_LEVEL: debug
PROSODY_ADMINS: "admin@example.com, admin2@example.com" PROSODY_ADMINS: "admin@localhost, admin2@localhost"
#DB_DRIVER: "MySQL" #DB_DRIVER: "MySQL"
DB_DRIVER: "PostgreSQL" DB_DRIVER: "PostgreSQL"
DB_DATABASE: "prosody" DB_DATABASE: "prosody"
@ -43,38 +45,9 @@ services:
- postgres - postgres
postgres: postgres:
image: postgres:16-alpine image: postgres:13-alpine
restart: unless-stopped restart: unless-stopped
environment: environment:
POSTGRES_DB: prosody POSTGRES_DB: prosody
POSTGRES_USER: prosody POSTGRES_USER: prosody
POSTGRES_PASSWORD: prosody POSTGRES_PASSWORD: prosody
prosody_ldap:
image: prosody
restart: unless-stopped
ports:
- "5000:5000"
- "5222:5222"
- "5223:5223"
- "5269:5269"
- "5281:5281"
environment:
DOMAIN: example.com
E2E_POLICY_WHITELIST: "admin@example.com, user1@example.com"
LOG_LEVEL: debug
PROSODY_ADMINS: "admin@example.com, admin2@example.com"
AUTHENTICATION: "ldap"
LDAP_BASE: "dc=example,dc=com"
LDAP_SERVER: "glauth"
LDAP_ROOTDN: "cn=svc,dc=example,dc=com"
LDAP_PASSWORD: "12345678"
volumes:
- ./certs:/usr/local/etc/prosody/certs
depends_on:
- glauth
glauth:
image: glauth/glauth
volumes:
- "./glauth/config.cfg:/app/config/config.cfg"

View file

@ -1,52 +0,0 @@
[ldap]
enabled = true
listen = "0.0.0.0:389"
[ldaps]
enabled = false
[backend]
datastore = "config"
baseDN = "dc=example,dc=com"
[[groups]]
name = "svc"
gidnumber = 5500
[[groups]]
name = "people"
gidnumber = 5501
[[users]]
name = "svc"
uidnumber = 5000
primarygroup = 5500
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users.capabilities]]
action = "search"
object = "*"
[[users]]
name = "admin"
uidnumber = 5001
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users]]
name = "user1"
uidnumber = 5002
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users]]
name = "user2"
uidnumber = 5003
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"
[[users]]
name = "user3"
uidnumber = 5004
primarygroup = 5501
passsha256 = "ef797c8118f02dfb649607dd5d3f8c7623048c9c063d532cc95c5ed7a898a64f"

View file

@ -1,4 +1,3 @@
aioxmpp==0.13.3 aioxmpp==0.12.2
pip-chill==1.0.3 pip-chill==1.0.1
pytest-asyncio==0.21.0 pytest-asyncio==0.15.1
pytz==2023.3

View file

@ -5,7 +5,7 @@ set -e
# generate certs for testing # generate certs for testing
generateCert() { generateCert() {
local DOMAIN="$1" DOMAIN="$1"
if [[ ! -d certs/"$DOMAIN" ]] ; then if [[ ! -d certs/"$DOMAIN" ]] ; then
mkdir -p certs/"$DOMAIN" mkdir -p certs/"$DOMAIN"
cd certs/"$DOMAIN" cd certs/"$DOMAIN"
@ -18,8 +18,7 @@ generateCert() {
registerTestUser() { registerTestUser() {
local userName="$1" local userName="$1"
local containerName="$2" local containerName="$2"
echo "Registering TestUser '$userName' in container '$containerName'" sudo docker exec "$containerName" /bin/bash -c "/entrypoint.bash register $userName localhost 12345678"
sudo docker compose exec "$containerName" /bin/bash -c "prosodyctl register $userName example.com 12345678"
} }
registerTestUsers() { registerTestUsers() {
@ -42,36 +41,31 @@ runTests() {
&& pytest \ && pytest \
&& deactivate \ && deactivate \
&& sleep 5 \ && sleep 5 \
&& sudo docker compose logs "$containerName" \ && sudo docker-compose logs "$containerName" \
&& export batsContainerName="$containerName" \ && export batsContainerName="$containerName" \
&& ./bats/bats-core/bin/bats tests.bats \ && ./bats/bats-core/bin/bats tests.bats \
&& ./bats/bats-core/bin/bats tests-"$containerName".bats && ./bats/bats-core/bin/bats tests-"$containerName".bats
} }
generateCert "example.com" generateCert "localhost"
generateCert "conference.example.com" generateCert "conference.localhost"
generateCert "proxy.example.com" generateCert "proxy.localhost"
generateCert "pubsub.example.com" generateCert "pubsub.localhost"
generateCert "upload.example.com" generateCert "upload.localhost"
# Run tests for first container with postgres # Run tests for first container with postgres
# Start postgres first and wait for 10 seconds before starting prosody. # Start postgres first and wait for 10 seconds before starting prosody.
sudo docker compose down sudo docker-compose down \
sudo docker compose up -d postgres && sudo docker-compose up -d postgres \
sleep 10 && sleep 10 \
sudo docker compose up -d prosody_postgres && sudo docker-compose up -d prosody_postgres
registerTestUsers prosody_postgres registerTestUsers tests_prosody_postgres_1
runTests prosody_postgres runTests prosody_postgres
sudo docker compose down sudo docker-compose down
# Run tests for second container with SQLite # Run tests for second container with SQLite
sudo docker compose up -d prosody sudo docker-compose up -d prosody
registerTestUsers prosody registerTestUsers tests_prosody_1
runTests prosody runTests prosody
sudo docker compose down sudo docker-compose down
# Run tests for prosody with ldap
sudo docker compose up -d prosody_ldap
runTests prosody_ldap
sudo docker compose down

View file

@ -15,7 +15,6 @@ def client(client_username, password):
password, password,
no_verify=True no_verify=True
), ),
override_peer=[("localhost", 5222, aioxmpp.connector.STARTTLSConnector())],
) )
return client return client
@ -40,9 +39,9 @@ def client_with_message_dispatcher(client):
return client return client
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("admin@example.com", "12345678")]) @pytest.mark.parametrize("client_username, password", [("admin@localhost", "12345678")])
async def test_send_message_from_admin_to_user1(client): async def test_send_message_from_admin_to_user1(client):
recipient_jid = aioxmpp.JID.fromstr("user1@example.com") recipient_jid = aioxmpp.JID.fromstr("user1@localhost")
async with client.connected() as stream: async with client.connected() as stream:
msg = aioxmpp.Message( msg = aioxmpp.Message(
to=recipient_jid, to=recipient_jid,
@ -54,9 +53,9 @@ async def test_send_message_from_admin_to_user1(client):
await client.send(msg) await client.send(msg)
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("admin@example.com", "12345678")]) @pytest.mark.parametrize("client_username, password", [("admin@localhost", "12345678")])
async def test_send_message_from_admin_to_user2(client): async def test_send_message_from_admin_to_user2(client):
recipient_jid = aioxmpp.JID.fromstr("user2@example.com") recipient_jid = aioxmpp.JID.fromstr("user2@localhost")
async with client.connected() as stream: async with client.connected() as stream:
msg = aioxmpp.Message( msg = aioxmpp.Message(
to=recipient_jid, to=recipient_jid,
@ -67,9 +66,9 @@ async def test_send_message_from_admin_to_user2(client):
await client.send(msg) await client.send(msg)
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user1@example.com", "12345678")]) @pytest.mark.parametrize("client_username, password", [("user1@localhost", "12345678")])
async def test_send_message_from_user1_to_user2(client): async def test_send_message_from_user1_to_user2(client):
recipient_jid = aioxmpp.JID.fromstr("user2@example.com") recipient_jid = aioxmpp.JID.fromstr("user2@localhost")
async with client.connected() as stream: async with client.connected() as stream:
msg = aioxmpp.Message( msg = aioxmpp.Message(
to=recipient_jid, to=recipient_jid,
@ -80,9 +79,9 @@ async def test_send_message_from_user1_to_user2(client):
await client.send(msg) await client.send(msg)
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user2@example.com", "12345678")]) @pytest.mark.parametrize("client_username, password", [("user2@localhost", "12345678")])
async def test_send_message_from_user2_to_user3(client): async def test_send_message_from_user2_to_user3(client):
recipient_jid = aioxmpp.JID.fromstr("user3@example.com") recipient_jid = aioxmpp.JID.fromstr("user3@localhost")
async with client.connected() as stream: async with client.connected() as stream:
msg = aioxmpp.Message( msg = aioxmpp.Message(
to=recipient_jid, to=recipient_jid,
@ -93,9 +92,9 @@ async def test_send_message_from_user2_to_user3(client):
await client.send(msg) await client.send(msg)
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user2@example.com", "12345678")]) @pytest.mark.parametrize("client_username, password", [("user2@localhost", "12345678")])
async def test_send_message_from_user2_to_nonexisting(client): async def test_send_message_from_user2_to_nonexisting(client):
recipient_jid = aioxmpp.JID.fromstr("nonexisting@example.com") recipient_jid = aioxmpp.JID.fromstr("nonexisting@localhost")
async with client.connected() as stream: async with client.connected() as stream:
msg = aioxmpp.Message( msg = aioxmpp.Message(
to=recipient_jid, to=recipient_jid,
@ -106,10 +105,10 @@ async def test_send_message_from_user2_to_nonexisting(client):
await client.send(msg) await client.send(msg)
@pytest.mark.asyncio @pytest.mark.asyncio
@pytest.mark.parametrize("client_username, password", [("user2@example.com", "wrong password")]) @pytest.mark.parametrize("client_username, password", [("user2@localhost", "wrong password")])
async def test_can_not_log_in_with_wrong_password(client): async def test_can_not_log_in_with_wrong_password(client):
with pytest.raises(aiosasl.AuthenticationFailure): with pytest.raises(aiosasl.AuthenticationFailure):
recipient_jid = aioxmpp.JID.fromstr("nonexisting@example.com") recipient_jid = aioxmpp.JID.fromstr("nonexisting@localhost")
async with client.connected() as stream: async with client.connected() as stream:
msg = aioxmpp.Message( msg = aioxmpp.Message(
to=recipient_jid, to=recipient_jid,

View file

@ -4,7 +4,7 @@ load 'bats/bats-support/load'
load 'bats/bats-assert/load' load 'bats/bats-assert/load'
@test "Should use sqlite" { @test "Should use sqlite" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Connecting to \[SQLite3\] \/usr\/local\/var\/lib\/prosody\/prosody\.sqlite\.\.\.\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Connecting to \[SQLite3\] \/usr\/local\/var\/lib\/prosody\/prosody\.sqlite\.\.\.\""
assert_success assert_success
assert_output assert_output
} }

View file

@ -1,16 +0,0 @@
# For tests with pipes see: https://github.com/sstephenson/bats/issues/10
load 'bats/bats-support/load'
load 'bats/bats-assert/load'
@test "Should use sqlite" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Connecting to \[SQLite3\] \/usr\/local\/var\/lib\/prosody\/prosody\.sqlite\.\.\.\""
assert_success
assert_output
}
@test "Should use ldap" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Host 'example.com' now set to use user provider 'ldap'\""
assert_success
assert_output
}

View file

@ -4,7 +4,7 @@ load 'bats/bats-support/load'
load 'bats/bats-assert/load' load 'bats/bats-assert/load'
@test "Should use postgres" { @test "Should use postgres" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Connecting to \[PostgreSQL\] prosody\.\.\.\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Connecting to \[PostgreSQL\] prosody\.\.\.\""
assert_success assert_success
assert_output assert_output
} }

View file

@ -3,96 +3,111 @@
load 'bats/bats-support/load' load 'bats/bats-support/load'
load 'bats/bats-assert/load' load 'bats/bats-assert/load'
# group alternation in regex because the xml properties switch around. sometimes 'type=...' comes after 'to=...' and sometimes before
@test "Should send 5 messages" { @test "Should send 5 messages" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Received\[c2s\]: <message\" | wc -l" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Received\[c2s\]: <message (type='chat'|to='.*@localhost'|id=':.*') (type='chat'|to='.*@localhost'|id=':.*') (type='chat'|to='.*@localhost'|id=':.*')>\" | wc -l"
assert_success assert_success
assert_output "5" assert_output "5"
} }
@test "Should select certificate for example.com" { @test "Should select certificate for localhost" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \" example.com:tls\" | wc -l" run bash -c "sudo docker-compose logs $batsContainerName | grep \"Selecting certificate /usr/local/etc/prosody/certs/localhost/fullchain.pem with key /usr/local/etc/prosody/certs/localhost/privkey.pem for localhost\" | wc -l"
assert_success assert_success
assert_output "1" assert_output "3"
} }
@test "Should select certificate for conference.example.com" { @test "Should select certificate for conference.localhost" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"conference.example.com:tls\" | wc -l" run bash -c "sudo docker-compose logs $batsContainerName | grep \"Selecting certificate /usr/local/etc/prosody/certs/conference.localhost/fullchain.pem with key /usr/local/etc/prosody/certs/conference.localhost/privkey.pem for conference.localhost\" | wc -l"
assert_success assert_success
assert_output "1" assert_output "3"
} }
@test "Should select certificate for proxy.example.com" { @test "Should select certificate for proxy.localhost" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"proxy.example.com:tls\" | wc -l" run bash -c "sudo docker-compose logs $batsContainerName | grep \"Selecting certificate /usr/local/etc/prosody/certs/proxy.localhost/fullchain.pem with key /usr/local/etc/prosody/certs/proxy.localhost/privkey.pem for proxy.localhost\" | wc -l"
assert_success assert_success
assert_output "1" assert_output "3"
} }
@test "Should select certificate for pubsub.example.com" { @test "Should select certificate for pubsub.localhost" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"pubsub.example.com:tls\" | wc -l" run bash -c "sudo docker-compose logs $batsContainerName | grep \"Selecting certificate /usr/local/etc/prosody/certs/pubsub.localhost/fullchain.pem with key /usr/local/etc/prosody/certs/pubsub.localhost/privkey.pem for pubsub.localhost\" | wc -l"
assert_success assert_success
assert_output "1" assert_output "3"
} }
@test "Should select certificate for upload.example.com" { @test "Should select certificate for upload.localhost" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Certificates loaded\" | grep \"upload.example.com:tls\" | wc -l" run bash -c "sudo docker-compose logs $batsContainerName | grep \"Selecting certificate /usr/local/etc/prosody/certs/upload.localhost/fullchain.pem with key /usr/local/etc/prosody/certs/upload.localhost/privkey.pem for upload.localhost\" | wc -l"
assert_success assert_success
assert_output "1" assert_output "3"
} }
@test "Should log error for user with wrong password" { @test "Should log error for user with wrong password" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Session closed by remote with error: undefined-condition (user intervention: authentication failed: authentication aborted by user)\"" run bash -c "sudo docker-compose logs $batsContainerName | grep \"Session closed by remote with error: undefined-condition (user intervention: authentication failed: authentication aborted by user)\""
assert_success assert_success
assert_output assert_output
} }
@test "Should activate s2s" { @test "Should activate s2s" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 's2s' on (\[::\]:5269|\[\*\]:5269), (\[::\]:5269|\[\*\]:5269)\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Activated service 's2s' on (\[::\]:5269|\[\*\]:5269), (\[::\]:5269|\[\*\]:5269)\""
assert_success assert_success
assert_output assert_output
} }
@test "Should activate c2s" { @test "Should activate c2s" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'c2s' on (\[::\]:5222|\[\*\]:5222), (\[::\]:5222|\[\*\]:5222)\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Activated service 'c2s' on (\[::\]:5222|\[\*\]:5222), (\[::\]:5222|\[\*\]:5222)\""
assert_success assert_success
assert_output assert_output
} }
@test "Should activate c2s_direct_tls" { @test "Should activate legacy_ssl" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'c2s_direct_tls' on (\[::\]:5223|\[\*\]:5223), (\[::\]:5223|\[\*\]:5223)\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Activated service 'legacy_ssl' on (\[::\]:5223|\[\*\]:5223), (\[::\]:5223|\[\*\]:5223)\""
assert_success assert_success
assert_output assert_output
} }
@test "Should activate proxy65" { @test "Should activate proxy65" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'proxy65' on (\[::\]:5000|\[\*\]:5000), (\[::\]:5000|\[\*\]:5000)\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Activated service 'proxy65' on (\[::\]:5000|\[\*\]:5000), (\[::\]:5000|\[\*\]:5000)\""
assert_success
assert_output
}
@test "Should activate http" {
run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Activated service 'http' on (\[::\]:5280|\[\*\]:5280), (\[::\]:5280|\[\*\]:5280)\""
assert_success assert_success
assert_output assert_output
} }
@test "Should activate https" { @test "Should activate https" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"Activated service 'https' on (\[::\]:5281|\[\*\]:5281), (\[::\]:5281|\[\*\]:5281)\"" run bash -c "sudo docker-compose logs $batsContainerName | grep -E \"Activated service 'https' on (\[::\]:5281|\[\*\]:5281), (\[::\]:5281|\[\*\]:5281)\""
assert_success assert_success
assert_output assert_output
} }
@test "Should load module cloud_notify" { @test "Should load module cloud_notify" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"example.com:cloud_notify.*info.*Module loaded\"" run bash -c "sudo docker-compose logs $batsContainerName | grep \"localhost:cloud_notify.*info.*Module loaded\""
assert_success assert_success
assert_output assert_output
} }
@test "Should show upload URL" { @test "Should show upload URL" {
run bash -c "sudo docker compose logs $batsContainerName | grep \"Serving 'file_share' at https:\/\/upload.example.com:5281\/file_share\"" run bash -c "sudo docker-compose logs $batsContainerName | grep \"URL: <https:\/\/upload.localhost:5281\/upload> - Ensure this can be reached by users\""
assert_success assert_success
assert_output assert_output
} }
@test "Should not use deprecated config" { @test "Should serve register_apps" {
run bash -c "sudo docker compose exec $batsContainerName /bin/bash -c \"/entrypoint.bash check\" | grep 'deprecated' -A 3" run bash -c "sudo docker-compose logs | grep \"Serving 'register_apps' at https:\/\/localhost:5281\/register_apps\""
assert_failure assert_success
assert_output
} }
@test "Should not have warnings in log" { @test "Should serve invites_page" {
run bash -c "sudo docker compose logs $batsContainerName | grep -E \"warn\"" run bash -c "sudo docker-compose logs | grep \"Serving 'invites_page' at https:\/\/localhost:5281\/invite\""
assert_failure assert_success
assert_output
}
@test "Should serve invites_register_web" {
run bash -c "sudo docker-compose logs | grep \"Serving 'invites_register_web' at https:\/\/localhost:5281\/register\""
assert_success
assert_output
} }

View file

@ -1,14 +0,0 @@
#!/bin/zsh
update_luarocks() {
# Get latest luarocks version and calculate sha256 hash of the tarball
local LUAROCKS_VER=$(wget -q -O - 'https://api.github.com/repos/luarocks/luarocks/tags' | jq -r ".[0].name")
local LUAROCKS_VER=${LUAROCKS_VER#v}
local LUAROCKS_SHA256_HASH=$(wget -q -O - "https://luarocks.org/releases/luarocks-$LUAROCKS_VER.tar.gz" | sha256sum --zero | perl -lane 'print $F[0]')
# Update Dockerfile
perl -pi -e "s/LUAROCKS_VERSION=\K.*/$LUAROCKS_VER/" Dockerfile
perl -pi -e "s/LUAROCKS_SHA256=\K.*/\"$LUAROCKS_SHA256_HASH\"/" Dockerfile
}
update_luarocks