commit
06ccd71edc
@ -0,0 +1,114 @@
|
|||||||
|
# Setting up draupnir (optional)
|
||||||
|
|
||||||
|
The playbook can install and configure the [draupnir](https://github.com/Gnuxie/Draupnir) moderation bot for you.
|
||||||
|
|
||||||
|
See the project's [documentation](https://github.com/Gnuxie/Draupnir) to learn what it does and why it might be useful to you.
|
||||||
|
|
||||||
|
If your migrating from Mjolnir skip to step 5b.
|
||||||
|
|
||||||
|
## 1. Register the bot account
|
||||||
|
|
||||||
|
The playbook does not automatically create users for you. The bot requires an access token to be able to connect to your homeserver.
|
||||||
|
|
||||||
|
You **need to register the bot user manually** before setting up the bot.
|
||||||
|
|
||||||
|
Choose a strong password for the bot. You can generate a good password with a command like this: `pwgen -s 64 1`.
|
||||||
|
|
||||||
|
You can use the playbook to [register a new user](registering-users.md):
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook -i inventory/hosts setup.yml --extra-vars='username=bot.draupnir password=PASSWORD_FOR_THE_BOT admin=no' --tags=register-user
|
||||||
|
```
|
||||||
|
|
||||||
|
If you would like draupnir to be able to deactivate users, move aliases, shutdown rooms, etc then it must be a server admin so you need to change `admin=no` to `admin=yes` in the command above.
|
||||||
|
|
||||||
|
|
||||||
|
## 2. Get an access token
|
||||||
|
|
||||||
|
Refer to the documentation on [how to obtain an access token](obtaining-access-tokens.md).
|
||||||
|
|
||||||
|
|
||||||
|
## 3. Make sure the account is free from rate limiting
|
||||||
|
|
||||||
|
You will need to prevent Synapse from rate limiting the bot's account. This is not an optional step. If you do not do this step draupnir will crash. This can be done using Synapse's [admin API](https://matrix-org.github.io/synapse/latest/admin_api/user_admin_api.html#override-ratelimiting-for-users). This can also be manually done by editing the Synapse database. Manually editing the Synapse database is rarely a good idea. Please ask for help if you are uncomfortable with these steps.
|
||||||
|
|
||||||
|
1. Copy the statement below into a text editor.
|
||||||
|
|
||||||
|
```
|
||||||
|
INSERT INTO ratelimit_override VALUES ('@bot.draupnir:DOMAIN', 0, 0);
|
||||||
|
```
|
||||||
|
|
||||||
|
1. Change the username (`@bot.draupnir:DOMAIN`) to the username you used when you registered the bot's account. You must change `DOMAIN` to your server's domain.
|
||||||
|
|
||||||
|
1. Get a database terminal by following these steps: [maintenance-postgres.md#getting-a-database-terminal](maintenance-postgres.md#getting-a-database-terminal)
|
||||||
|
|
||||||
|
1. Connect to Synapse's database by typing `\connect synapse` into the database terminal
|
||||||
|
|
||||||
|
1. Paste in the `INSERT INTO` command that you edited and press enter.
|
||||||
|
|
||||||
|
You can run `SELECT * FROM ratelimit_override;` to see if it worked. If the output looks like this:
|
||||||
|
|
||||||
|
```
|
||||||
|
user_id | messages_per_second | burst_count
|
||||||
|
-----------------------+---------------------+-------------
|
||||||
|
@bot.draupnir:raim.ist | 0 | 0`
|
||||||
|
```
|
||||||
|
then you did it correctly.
|
||||||
|
|
||||||
|
|
||||||
|
## 4. Create a management room
|
||||||
|
|
||||||
|
Using your own account, create a new invite only room that you will use to manage the bot. This is the room where you will see the status of the bot and where you will send commands to the bot, such as the command to ban a user from another room. Anyone in this room can control the bot so it is important that you only invite trusted users to this room. The room must be unencrypted since the playbook does not support installing Pantalaimon yet.
|
||||||
|
|
||||||
|
Once you have created the room you need to copy the room ID so you can tell the bot to use that room. In Element you can do this by going to the room's settings, clicking Advanced, and then coping the internal room ID. The room ID will look something like `!QvgVuKq0ha8glOLGMG:DOMAIN`.
|
||||||
|
|
||||||
|
Finally invite the `@bot.draupnir:DOMAIN` account you created earlier into the room.
|
||||||
|
|
||||||
|
|
||||||
|
## 5a. Adjusting the playbook configuration
|
||||||
|
|
||||||
|
Add the following configuration to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file (adapt to your needs):
|
||||||
|
|
||||||
|
You must replace `ACCESS_TOKEN_FROM_STEP_2_GOES_HERE` and `ROOM_ID_FROM_STEP_4_GOES_HERE` with the your own values.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_bot_draupnir_enabled: true
|
||||||
|
|
||||||
|
matrix_bot_draupnir_access_token: "ACCESS_TOKEN_FROM_STEP_2_GOES_HERE"
|
||||||
|
|
||||||
|
matrix_bot_draupnir_management_room: "ROOM_ID_FROM_STEP_4_GOES_HERE"
|
||||||
|
```
|
||||||
|
|
||||||
|
## 5b. Migrating from Mjolnir (Only required if migrating.)
|
||||||
|
|
||||||
|
Replace your matrix_bot_mjolnir config with matrix_bot_draupnir config. Also disable mjolnir if you're doing migration.
|
||||||
|
That is all you need to do due to that Draupnir can complete migration on its own.
|
||||||
|
|
||||||
|
## 6. Installing
|
||||||
|
|
||||||
|
After configuring the playbook, run the [installation](installing.md) command:
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook -i inventory/hosts setup.yml --tags=setup-all,start
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
You can refer to the upstream [documentation](https://github.com/Gnuxie/Draupnir) for additional ways to use and configure draupnir. Check out their [quickstart guide](https://github.com/matrix-org/draupnir/blob/main/docs/moderators.md#quick-usage) for some basic commands you can give to the bot.
|
||||||
|
|
||||||
|
You can configure additional options by adding the `matrix_bot_draupnir_configuration_extension_yaml` variable to your `inventory/host_vars/matrix.DOMAIN/vars.yml` file.
|
||||||
|
|
||||||
|
For example to change draupnir's `recordIgnoredInvites` option to `true` you would add the following to your `vars.yml` file.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_bot_draupnir_configuration_extension_yaml: |
|
||||||
|
# Your custom YAML configuration goes here.
|
||||||
|
# This configuration extends the default starting configuration (`matrix_bot_draupnir_configuration_yaml`).
|
||||||
|
#
|
||||||
|
# You can override individual variables from the default configuration, or introduce new ones.
|
||||||
|
#
|
||||||
|
# If you need something more special, you can take full control by
|
||||||
|
# completely redefining `matrix_bot_draupnir_configuration_yaml`.
|
||||||
|
recordIgnoredInvites: true
|
||||||
|
```
|
@ -0,0 +1,125 @@
|
|||||||
|
# Setting up Matrix User Verification Service (optional)
|
||||||
|
|
||||||
|
**[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) (hereafter: UVS) can only be installed after Matrix services are installed and running.**
|
||||||
|
If you're just installing Matrix services for the first time, please continue with the [Configuration](configuring-playbook.md) / [Installation](installing.md) flow and come back here later.
|
||||||
|
|
||||||
|
Currently, the main purpose of this role is to allow Jitsi to authenticate matrix users and check if they are authorized to join a conference. Please refer to the documentation of the [Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) to understand how it works.
|
||||||
|
|
||||||
|
**Note**: enabling Matrix User Verification Service, means that the `openid` API endpoints will be exposed on the Matrix Federation port (usually `8448`), even if [federation](configuring-playbook-federation.md) is disabled.
|
||||||
|
|
||||||
|
If the Jitsi server is also configured by this playbook, all plugging of variables and secrets is handled in `group_vars/matrix_servers`.
|
||||||
|
|
||||||
|
__Some general concepts of UVS may be helpful to understand the rest, so here they are:__
|
||||||
|
|
||||||
|
UVS can be used to verify two claims:
|
||||||
|
|
||||||
|
* (A) Whether a given OpenID token is valid for a given server and
|
||||||
|
* (B) whether a user is member of a given room and the corresponding PowerLevel
|
||||||
|
|
||||||
|
Verifying an OpenID token id done by finding the corresponding Homeserver via '.well-known/matrix/server' for the given domain.
|
||||||
|
The configured `matrix_user_verification_service_uvs_homeserver_url` does **not** factor into this.
|
||||||
|
By default, this playbook only checks against `matrix_server_fqn_matrix`.
|
||||||
|
Therefore, the request will be made against the public openid API for `matrix_server_fqn_matrix`.
|
||||||
|
|
||||||
|
Verifying RoomMembership and PowerLevel is done against `matrix_user_verification_service_uvs_homeserver_url` which is by default done via the docker network.
|
||||||
|
UVS will verify the validity of the token beforehand though.
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
In order to use UVS, an admin token for the configured homeserver must be supplied. For now this means configuring Synapse and creating the token before installing UVS.
|
||||||
|
|
||||||
|
## Enable
|
||||||
|
|
||||||
|
[Matrix User Verification Service](https://github.com/matrix-org/matrix-user-verification-service) installation is disabled by default.
|
||||||
|
You can enable it in your configuration file (`inventory/host_vars/matrix.<your-domain>/vars.yml`):
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_user_verification_service_enabled: true
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
The only required configuration variable is `matrix_user_verification_service_uvs_access_token` (see below).
|
||||||
|
|
||||||
|
For a list of all configuration options see the role defaults [`roles/matrix-user-verification-service/defaults/main.yml`](../roles/custom/matrix-user-verification-service/defaults/main.yml).
|
||||||
|
But be aware of all the plugging happening in `group_vars/matrix_servers`.
|
||||||
|
|
||||||
|
In the default configuration, the UVS Server is only reachable via the docker network, which is fine if e.g. Jitsi is also running in a container on the host.
|
||||||
|
However, it is possible to expose UVS via setting `matrix_user_verification_service_container_http_host_bind_port`.
|
||||||
|
|
||||||
|
### Access token
|
||||||
|
|
||||||
|
The Synapse Access Token is used to verify RoomMembership and PowerLevel against `matrix_user_verification_service_uvs_homeserver_url`.
|
||||||
|
|
||||||
|
We recommend that you create a dedicated Matrix user for uvs (`uvs` is a good username).
|
||||||
|
Follow our [Registering users](registering-users.md) guide to register a user with administration privileges.
|
||||||
|
|
||||||
|
You are required to specify an access token (belonging to this new user) for UVS to work.
|
||||||
|
To get an access token for the UVS user, you can follow the documentation on [how to do obtain an access token](obtaining-access-tokens.md).
|
||||||
|
|
||||||
|
**Access tokens are sensitive information. Do not include them in any bug reports, messages, or logs. Do not share the access token with anyone.**
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_user_verification_service_uvs_access_token: "YOUR ACCESS TOKEN HERE"
|
||||||
|
```
|
||||||
|
|
||||||
|
### (Optional) Custom Auth Token
|
||||||
|
|
||||||
|
It is possible to set an API Auth Token to restrict access to the UVS. If this is enabled, anyone making a request to UVS must provide it via the header "Authorization: Bearer TOKEN"
|
||||||
|
|
||||||
|
By default, the token will be derived from `matrix_homeserver_generic_secret_key` in `group_vars/matrix_servers`.
|
||||||
|
To set your own Token, simply put the following in your host_vars.
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_user_verification_service_uvs_auth_token: "TOKEN"
|
||||||
|
```
|
||||||
|
|
||||||
|
In case Jitsi is also managed by this playbook and 'matrix' authentication in Jitsi is enabled, this collection will automatically configure Jitsi to use the configured auth token.
|
||||||
|
|
||||||
|
### (Optional) Disable Auth
|
||||||
|
Authorization is enabled by default. To disable set
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_user_verification_service_uvs_require_auth: false
|
||||||
|
```
|
||||||
|
|
||||||
|
in your host_vars.
|
||||||
|
|
||||||
|
### (Optional) Federation
|
||||||
|
|
||||||
|
In theory (however currently untested), UVS can handle federation. Simply set:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
matrix_user_verification_service_uvs_pin_openid_verify_server_name: false
|
||||||
|
```
|
||||||
|
|
||||||
|
in your host_vars.
|
||||||
|
|
||||||
|
This will instruct UVS to verify the OpenID token against any domain given in a request.
|
||||||
|
Homeserver discovery is done via '.well-known/matrix/server' of the given domain.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
After these variables have been set, please run the following command to re-run setup and to restart UVS:
|
||||||
|
|
||||||
|
```
|
||||||
|
ansible-playbook -i inventory/hosts setup.yml --tags=setup-matrix-user-verification-service,start
|
||||||
|
```
|
||||||
|
|
||||||
|
## Logging
|
||||||
|
|
||||||
|
The configuration variable `UVS_LOG_LEVEL` can be set to:
|
||||||
|
- warning
|
||||||
|
- info
|
||||||
|
- debug
|
||||||
|
|
||||||
|
## TLS Certificate Checking
|
||||||
|
If the matrix Homeserver does not provide a valid TLS certificate, UVS will fail with the following error message:
|
||||||
|
|
||||||
|
> message: 'No response received: [object Object]',
|
||||||
|
|
||||||
|
This also applies to self-signed and let's encrypt staging certificates.
|
||||||
|
|
||||||
|
To disable certificate validation altogether (INSECURE! Not suitable for production use!) set: `NODE_TLS_REJECT_UNAUTHORIZED=0`
|
||||||
|
|
||||||
|
Alternatively, it is possible to inject your own CA certificates into the container by mounting a PEM file with additional trusted CAs into the container and pointing the `NODE_EXTRA_CA_CERTS` environment variable to it.
|
@ -0,0 +1,59 @@
|
|||||||
|
---
|
||||||
|
# A moderation tool for Matrix
|
||||||
|
# Project source code URL: https://github.com/Gnuxie/Draupnir
|
||||||
|
|
||||||
|
matrix_bot_draupnir_enabled: true
|
||||||
|
|
||||||
|
matrix_bot_draupnir_version: "v1.80.0-beta.0"
|
||||||
|
|
||||||
|
matrix_bot_draupnir_container_image_self_build: false
|
||||||
|
matrix_bot_draupnir_container_image_self_build_repo: "https://github.com/Gnuxie/Draupnir.git"
|
||||||
|
|
||||||
|
matrix_bot_draupnir_docker_image: "{{ matrix_bot_draupnir_docker_image_name_prefix }}gnuxie/draupnir:{{ matrix_bot_draupnir_version }}"
|
||||||
|
matrix_bot_draupnir_docker_image_name_prefix: "{{ 'localhost/' if matrix_bot_draupnir_container_image_self_build else matrix_container_global_registry_prefix }}"
|
||||||
|
matrix_bot_draupnir_docker_image_force_pull: "{{ matrix_bot_draupnir_docker_image.endswith(':latest') }}"
|
||||||
|
|
||||||
|
matrix_bot_draupnir_base_path: "{{ matrix_base_data_path }}/draupnir"
|
||||||
|
matrix_bot_draupnir_config_path: "{{ matrix_bot_draupnir_base_path }}/config"
|
||||||
|
matrix_bot_draupnir_data_path: "{{ matrix_bot_draupnir_base_path }}/data"
|
||||||
|
matrix_bot_draupnir_docker_src_files_path: "{{ matrix_bot_draupnir_base_path }}/docker-src"
|
||||||
|
|
||||||
|
# A list of extra arguments to pass to the container
|
||||||
|
matrix_bot_draupnir_container_extra_arguments: []
|
||||||
|
|
||||||
|
# List of systemd services that matrix-bot-draupnir.service depends on
|
||||||
|
matrix_bot_draupnir_systemd_required_services_list: ['docker.service']
|
||||||
|
|
||||||
|
# List of systemd services that matrix-bot-draupnir.service wants
|
||||||
|
matrix_bot_draupnir_systemd_wanted_services_list: []
|
||||||
|
|
||||||
|
# The access token for the bot user
|
||||||
|
matrix_bot_draupnir_access_token: ""
|
||||||
|
|
||||||
|
# The room ID where people can use the bot. The bot has no access controls, so
|
||||||
|
# anyone in this room can use the bot - secure your room!
|
||||||
|
# This should be a room alias or room ID - not a matrix.to URL.
|
||||||
|
# Note: draupnir is fairly verbose - expect a lot of messages from it.
|
||||||
|
matrix_bot_draupnir_management_room: ""
|
||||||
|
|
||||||
|
# Default configuration template which covers the generic use case.
|
||||||
|
# You can customize it by controlling the various variables inside it.
|
||||||
|
#
|
||||||
|
# For a more advanced customization, you can extend the default (see `matrix_bot_draupnir_configuration_extension_yaml`)
|
||||||
|
# or completely replace this variable with your own template.
|
||||||
|
matrix_bot_draupnir_configuration_yaml: "{{ lookup('template', 'templates/production.yaml.j2') }}"
|
||||||
|
|
||||||
|
matrix_bot_draupnir_configuration_extension_yaml: |
|
||||||
|
# Your custom YAML configuration goes here.
|
||||||
|
# This configuration extends the default starting configuration (`matrix_bot_draupnir_configuration_yaml`).
|
||||||
|
#
|
||||||
|
# You can override individual variables from the default configuration, or introduce new ones.
|
||||||
|
#
|
||||||
|
# If you need something more special, you can take full control by
|
||||||
|
# completely redefining `matrix_bot_draupnir_configuration_yaml`.
|
||||||
|
|
||||||
|
matrix_bot_draupnir_configuration_extension: "{{ matrix_bot_draupnir_configuration_extension_yaml | from_yaml if matrix_bot_draupnir_configuration_extension_yaml | from_yaml is mapping else {} }}"
|
||||||
|
|
||||||
|
# Holds the final configuration (a combination of the default and its extension).
|
||||||
|
# You most likely don't need to touch this variable. Instead, see `matrix_bot_draupnir_configuration_yaml`.
|
||||||
|
matrix_bot_draupnir_configuration: "{{ matrix_bot_draupnir_configuration_yaml | from_yaml | combine(matrix_bot_draupnir_configuration_extension, recursive=True) }}"
|
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- when: matrix_bot_draupnir_enabled | bool
|
||||||
|
ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml"
|
||||||
|
|
||||||
|
- when: matrix_bot_draupnir_enabled | bool
|
||||||
|
ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml"
|
||||||
|
tags:
|
||||||
|
- setup-all
|
||||||
|
- setup-bot-draupnir
|
||||||
|
- install-all
|
||||||
|
- install-bot-draupnir
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- when: not matrix_bot_draupnir_enabled | bool
|
||||||
|
ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
|
||||||
|
tags:
|
||||||
|
- setup-all
|
||||||
|
- setup-bot-draupnir
|
@ -0,0 +1,74 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- ansible.builtin.set_fact:
|
||||||
|
matrix_bot_draupnir_requires_restart: false
|
||||||
|
|
||||||
|
- name: Ensure matrix-bot-draupnir paths exist
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
mode: 0750
|
||||||
|
owner: "{{ matrix_user_username }}"
|
||||||
|
group: "{{ matrix_user_groupname }}"
|
||||||
|
with_items:
|
||||||
|
- {path: "{{ matrix_bot_draupnir_base_path }}", when: true}
|
||||||
|
- {path: "{{ matrix_bot_draupnir_config_path }}", when: true}
|
||||||
|
- {path: "{{ matrix_bot_draupnir_data_path }}", when: true}
|
||||||
|
- {path: "{{ matrix_bot_draupnir_docker_src_files_path }}", when: "{{ matrix_bot_draupnir_container_image_self_build }}"}
|
||||||
|
when: "item.when | bool"
|
||||||
|
|
||||||
|
- name: Ensure draupnir Docker image is pulled
|
||||||
|
community.docker.docker_image:
|
||||||
|
name: "{{ matrix_bot_draupnir_docker_image }}"
|
||||||
|
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
|
||||||
|
force_source: "{{ matrix_bot_draupnir_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
|
||||||
|
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_bot_draupnir_docker_image_force_pull }}"
|
||||||
|
when: "not matrix_bot_draupnir_container_image_self_build | bool"
|
||||||
|
register: result
|
||||||
|
retries: "{{ devture_playbook_help_container_retries_count }}"
|
||||||
|
delay: "{{ devture_playbook_help_container_retries_delay }}"
|
||||||
|
until: result is not failed
|
||||||
|
|
||||||
|
- name: Ensure draupnir repository is present on self-build
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "{{ matrix_bot_draupnir_container_image_self_build_repo }}"
|
||||||
|
dest: "{{ matrix_bot_draupnir_docker_src_files_path }}"
|
||||||
|
version: "{{ matrix_bot_draupnir_docker_image.split(':')[1] }}"
|
||||||
|
force: "yes"
|
||||||
|
become: true
|
||||||
|
become_user: "{{ matrix_user_username }}"
|
||||||
|
register: matrix_bot_draupnir_git_pull_results
|
||||||
|
when: "matrix_bot_draupnir_container_image_self_build | bool"
|
||||||
|
|
||||||
|
- name: Ensure draupnir Docker image is built
|
||||||
|
community.docker.docker_image:
|
||||||
|
name: "{{ matrix_bot_draupnir_docker_image }}"
|
||||||
|
source: build
|
||||||
|
force_source: "{{ matrix_bot_draupnir_git_pull_results.changed }}"
|
||||||
|
build:
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
path: "{{ matrix_bot_draupnir_docker_src_files_path }}"
|
||||||
|
pull: true
|
||||||
|
when: "matrix_bot_draupnir_container_image_self_build | bool"
|
||||||
|
|
||||||
|
- name: Ensure matrix-bot-draupnir config installed
|
||||||
|
ansible.builtin.copy:
|
||||||
|
content: "{{ matrix_bot_draupnir_configuration | to_nice_yaml(indent=2, width=999999) }}"
|
||||||
|
dest: "{{ matrix_bot_draupnir_config_path }}/production.yaml"
|
||||||
|
mode: 0644
|
||||||
|
owner: "{{ matrix_user_username }}"
|
||||||
|
group: "{{ matrix_user_groupname }}"
|
||||||
|
|
||||||
|
- name: Ensure matrix-bot-draupnir.service installed
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ role_path }}/templates/systemd/matrix-bot-draupnir.service.j2"
|
||||||
|
dest: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-draupnir.service"
|
||||||
|
mode: 0644
|
||||||
|
register: matrix_bot_draupnir_systemd_service_result
|
||||||
|
|
||||||
|
- name: Ensure matrix-bot-draupnir.service restarted, if necessary
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: "matrix-bot-draupnir.service"
|
||||||
|
state: restarted
|
||||||
|
daemon_reload: true
|
||||||
|
when: "matrix_bot_draupnir_requires_restart | bool"
|
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Check existence of matrix-bot-draupnir service
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-draupnir.service"
|
||||||
|
register: matrix_bot_draupnir_service_stat
|
||||||
|
|
||||||
|
- when: matrix_bot_draupnir_service_stat.stat.exists | bool
|
||||||
|
block:
|
||||||
|
- name: Ensure matrix-bot-draupnir is stopped
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: matrix-bot-draupnir
|
||||||
|
state: stopped
|
||||||
|
enabled: false
|
||||||
|
daemon_reload: true
|
||||||
|
|
||||||
|
- name: Ensure matrix-bot-draupnir.service doesn't exist
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ devture_systemd_docker_base_systemd_path }}/matrix-bot-draupnir.service"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure matrix-bot-draupnir paths don't exist
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ matrix_bot_draupnir_base_path }}"
|
||||||
|
state: absent
|
@ -0,0 +1,9 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Fail if required variables are undefined
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: "The `{{ item }}` variable must be defined and have a non-null value."
|
||||||
|
with_items:
|
||||||
|
- "matrix_bot_draupnir_access_token"
|
||||||
|
- "matrix_bot_draupnir_management_room"
|
||||||
|
when: "vars[item] == '' or vars[item] is none"
|
@ -0,0 +1,247 @@
|
|||||||
|
# Endpoint URL that draupnir uses to interact with the matrix homeserver (client-server API),
|
||||||
|
# set this to the pantalaimon URL if you're using that.
|
||||||
|
homeserverUrl: "{{ matrix_homeserver_url }}"
|
||||||
|
|
||||||
|
# Endpoint URL that draupnir could use to fetch events related to reports (client-server API and /_synapse/),
|
||||||
|
# only set this to the public-internet homeserver client API URL, do NOT set this to the pantalaimon URL.
|
||||||
|
rawHomeserverUrl: "{{ matrix_homeserver_url }}"
|
||||||
|
|
||||||
|
# Matrix Access Token to use, draupnir will only use this if pantalaimon.use is false.
|
||||||
|
accessToken: "{{ matrix_bot_draupnir_access_token }}"
|
||||||
|
|
||||||
|
# Options related to Pantalaimon (https://github.com/matrix-org/pantalaimon)
|
||||||
|
#pantalaimon:
|
||||||
|
# # Whether or not draupnir will use pantalaimon to access the matrix homeserver,
|
||||||
|
# # set to `true` if you're using pantalaimon.
|
||||||
|
# #
|
||||||
|
# # Be sure to point homeserverUrl to the pantalaimon instance.
|
||||||
|
# #
|
||||||
|
# # draupnir will log in using the given username and password once,
|
||||||
|
# # then store the resulting access token in a file under dataPath.
|
||||||
|
# use: false
|
||||||
|
#
|
||||||
|
# # The username to login with.
|
||||||
|
# username: draupnir
|
||||||
|
#
|
||||||
|
# # The password draupnir will login with.
|
||||||
|
# #
|
||||||
|
# # After successfully logging in once, this will be ignored, so this value can be blanked after first startup.
|
||||||
|
# password: your_password
|
||||||
|
|
||||||
|
# The path draupnir will store its state/data in, leave default ("/data/storage") when using containers.
|
||||||
|
dataPath: "/data"
|
||||||
|
|
||||||
|
# If true (the default), draupnir will only accept invites from users present in managementRoom.
|
||||||
|
autojoinOnlyIfManager: true
|
||||||
|
|
||||||
|
# If `autojoinOnlyIfManager` is false, only the members in this space can invite
|
||||||
|
# the bot to new rooms.
|
||||||
|
#acceptInvitesFromSpace: "!example:example.org"
|
||||||
|
|
||||||
|
# Whether draupnir should report ignored invites to the management room (if autojoinOnlyIfManager is true).
|
||||||
|
recordIgnoredInvites: false
|
||||||
|
|
||||||
|
# The room ID (or room alias) of the management room, anyone in this room can issue commands to draupnir.
|
||||||
|
#
|
||||||
|
# draupnir has no more granular access controls other than this, be sure you trust everyone in this room - secure it!
|
||||||
|
#
|
||||||
|
# This should be a room alias or room ID - not a matrix.to URL.
|
||||||
|
#
|
||||||
|
# Note: By default, draupnir is fairly verbose - expect a lot of messages in this room.
|
||||||
|
# (see verboseLogging to adjust this a bit.)
|
||||||
|
managementRoom: "{{ matrix_bot_draupnir_management_room }}"
|
||||||
|
|
||||||
|
# Whether draupnir should log a lot more messages in the room,
|
||||||
|
# mainly involves "all-OK" messages, and debugging messages for when draupnir checks bans in a room.
|
||||||
|
verboseLogging: false
|
||||||
|
|
||||||
|
# The log level of terminal (or container) output,
|
||||||
|
# can be one of DEBUG, INFO, WARN and ERROR, in increasing order of importance and severity.
|
||||||
|
#
|
||||||
|
# This should be at INFO or DEBUG in order to get support for draupnir problems.
|
||||||
|
logLevel: "INFO"
|
||||||
|
|
||||||
|
# Whether or not draupnir should synchronize policy lists immediately after startup.
|
||||||
|
# Equivalent to running '!draupnir sync'.
|
||||||
|
syncOnStartup: true
|
||||||
|
|
||||||
|
# Whether or not draupnir should check moderation permissions in all protected rooms on startup.
|
||||||
|
# Equivalent to running `!draupnir verify`.
|
||||||
|
verifyPermissionsOnStartup: true
|
||||||
|
|
||||||
|
# Whether or not draupnir should actually apply bans and policy lists,
|
||||||
|
# turn on to trial some untrusted configuration or lists.
|
||||||
|
noop: false
|
||||||
|
|
||||||
|
# Whether draupnir should check member lists quicker (by using a different endpoint),
|
||||||
|
# keep in mind that enabling this will miss invited (but not joined) users.
|
||||||
|
#
|
||||||
|
# Turn on if your bot is in (very) large rooms, or in large amounts of rooms.
|
||||||
|
fasterMembershipChecks: false
|
||||||
|
|
||||||
|
# A case-insensitive list of ban reasons to have the bot also automatically redact the user's messages for.
|
||||||
|
#
|
||||||
|
# If the bot sees you ban a user with a reason that is an (exact case-insensitive) match to this list,
|
||||||
|
# it will also remove the user's messages automatically.
|
||||||
|
#
|
||||||
|
# Typically this is useful to avoid having to give two commands to the bot.
|
||||||
|
# Advanced: Use asterisks to have the reason match using "globs"
|
||||||
|
# (f.e. "spam*testing" would match "spam for testing" as well as "spamtesting").
|
||||||
|
#
|
||||||
|
# See here for more info: https://www.digitalocean.com/community/tools/glob
|
||||||
|
# Note: Keep in mind that glob is NOT regex!
|
||||||
|
automaticallyRedactForReasons:
|
||||||
|
- "spam"
|
||||||
|
- "advertising"
|
||||||
|
|
||||||
|
# A list of rooms to protect. draupnir will add this to the list it knows from its account data.
|
||||||
|
#
|
||||||
|
# It won't, however, add it to the account data.
|
||||||
|
# Manually add the room via '!draupnir rooms add' to have it stay protected regardless if this config value changes.
|
||||||
|
#
|
||||||
|
# Note: These must be matrix.to URLs
|
||||||
|
#protectedRooms:
|
||||||
|
# - "https://matrix.to/#/#yourroom:example.org"
|
||||||
|
|
||||||
|
# Whether or not to add all joined rooms to the "protected rooms" list
|
||||||
|
# (excluding the management room and watched policy list rooms, see below).
|
||||||
|
#
|
||||||
|
# Note that this effectively makes the protectedRooms and associated commands useless
|
||||||
|
# for regular rooms.
|
||||||
|
#
|
||||||
|
# Note: the management room is *excluded* from this condition.
|
||||||
|
# Explicitly add it as a protected room to protect it.
|
||||||
|
#
|
||||||
|
# Note: Ban list rooms the bot is watching but didn't create will not be protected.
|
||||||
|
# Explicitly add these rooms as a protected room list if you want them protected.
|
||||||
|
protectAllJoinedRooms: false
|
||||||
|
|
||||||
|
# Increase this delay to have Mjölnir wait longer between two consecutive backgrounded
|
||||||
|
# operations. The total duration of operations will be longer, but the homeserver won't
|
||||||
|
# be affected as much. Conversely, decrease this delay to have Mjölnir chain operations
|
||||||
|
# faster. The total duration of operations will generally be shorter, but the performance
|
||||||
|
# of the homeserver may be more impacted.
|
||||||
|
backgroundDelayMS: 500
|
||||||
|
|
||||||
|
# Server administration commands, these commands will only work if draupnir is
|
||||||
|
# a global server administrator, and the bot's server is a Synapse instance.
|
||||||
|
#admin:
|
||||||
|
# # Whether or not draupnir can temporarily take control of any eligible account from the local homeserver who's in the room
|
||||||
|
# # (with enough permissions) to "make" a user an admin.
|
||||||
|
# #
|
||||||
|
# # This only works if a local user with enough admin permissions is present in the room.
|
||||||
|
# enableMakeRoomAdminCommand: false
|
||||||
|
|
||||||
|
# Misc options for command handling and commands
|
||||||
|
commands:
|
||||||
|
# Whether or not the `!draupnir` prefix is necessary to submit commands.
|
||||||
|
#
|
||||||
|
# If `true`, will allow commands like `!ban`, `!help`, etc.
|
||||||
|
#
|
||||||
|
# Note: draupnir can also be pinged by display name instead of having to use
|
||||||
|
# the !draupnir prefix. For example, "my_moderator_bot: ban @spammer:example.org"
|
||||||
|
# will address only my_moderator_bot.
|
||||||
|
allowNoPrefix: false
|
||||||
|
|
||||||
|
# Any additional bot prefixes that draupnir will listen to. i.e. adding `mod` will allow `!mod help`.
|
||||||
|
additionalPrefixes:
|
||||||
|
- "draupnir_bot"
|
||||||
|
- "draupnir"
|
||||||
|
|
||||||
|
# Whether or not commands with a wildcard (*) will require an additional `--force` argument
|
||||||
|
# in the command to be able to be submitted.
|
||||||
|
confirmWildcardBan: true
|
||||||
|
|
||||||
|
# Configuration specific to certain toggle-able protections
|
||||||
|
#protections:
|
||||||
|
# # Configuration for the wordlist plugin, which can ban users based if they say certain
|
||||||
|
# # blocked words shortly after joining.
|
||||||
|
# wordlist:
|
||||||
|
# # A list of case-insensitive keywords that the WordList protection will watch for from new users.
|
||||||
|
# #
|
||||||
|
# # WordList will ban users who use these words when first joining a room, so take caution when selecting them.
|
||||||
|
# #
|
||||||
|
# # For advanced usage, regex can also be used, see the following links for more information;
|
||||||
|
# # - https://www.digitalocean.com/community/tutorials/an-introduction-to-regular-expressions
|
||||||
|
# # - https://regexr.com/
|
||||||
|
# # - https://regexone.com/
|
||||||
|
# words:
|
||||||
|
# - "LoReM"
|
||||||
|
# - "IpSuM"
|
||||||
|
# - "DoLoR"
|
||||||
|
# - "aMeT"
|
||||||
|
#
|
||||||
|
# # For how long (in minutes) the user is "new" to the WordList plugin.
|
||||||
|
# #
|
||||||
|
# # After this time, the user will no longer be banned for using a word in the above wordlist.
|
||||||
|
# #
|
||||||
|
# # Set to zero to disable the timeout and make users *always* appear "new".
|
||||||
|
# # (users will always be banned if they say a bad word)
|
||||||
|
# minutesBeforeTrusting: 20
|
||||||
|
|
||||||
|
# Options for advanced monitoring of the health of the bot.
|
||||||
|
health:
|
||||||
|
# healthz options. These options are best for use in container environments
|
||||||
|
# like Kubernetes to detect how healthy the service is. The bot will report
|
||||||
|
# that it is unhealthy until it is able to process user requests. Typically
|
||||||
|
# this means that it'll flag itself as unhealthy for a number of minutes
|
||||||
|
# before saying "Now monitoring rooms" and flagging itself healthy.
|
||||||
|
#
|
||||||
|
# Health is flagged through HTTP status codes, defined below.
|
||||||
|
healthz:
|
||||||
|
# Whether the healthz integration should be enabled (default false)
|
||||||
|
enabled: false
|
||||||
|
|
||||||
|
# The port to expose the webserver on. Defaults to 8080.
|
||||||
|
port: 8080
|
||||||
|
|
||||||
|
# The address to listen for requests on. Defaults to all addresses.
|
||||||
|
address: "0.0.0.0"
|
||||||
|
|
||||||
|
# The path to expose the monitoring endpoint at. Defaults to `/healthz`
|
||||||
|
endpoint: "/healthz"
|
||||||
|
|
||||||
|
# The HTTP status code which reports that the bot is healthy/ready to
|
||||||
|
# process requests. Typically this should not be changed. Defaults to
|
||||||
|
# 200.
|
||||||
|
healthyStatus: 200
|
||||||
|
|
||||||
|
# The HTTP status code which reports that the bot is not healthy/ready.
|
||||||
|
# Defaults to 418.
|
||||||
|
unhealthyStatus: 418
|
||||||
|
|
||||||
|
# Options for exposing web APIs.
|
||||||
|
#web:
|
||||||
|
# # Whether to enable web APIs.
|
||||||
|
# enabled: false
|
||||||
|
#
|
||||||
|
# # The port to expose the webserver on. Defaults to 8080.
|
||||||
|
# port: 8080
|
||||||
|
#
|
||||||
|
# # The address to listen for requests on. Defaults to only the current
|
||||||
|
# # computer.
|
||||||
|
# address: localhost
|
||||||
|
#
|
||||||
|
# # Alternative setting to open to the entire web. Be careful,
|
||||||
|
# # as this will increase your security perimeter:
|
||||||
|
# #
|
||||||
|
# # address: "0.0.0.0"
|
||||||
|
#
|
||||||
|
# # A web API designed to intercept Matrix API
|
||||||
|
# # POST /_matrix/client/r0/rooms/{roomId}/report/{eventId}
|
||||||
|
# # and display readable abuse reports in the moderation room.
|
||||||
|
# #
|
||||||
|
# # If you wish to take advantage of this feature, you will need
|
||||||
|
# # to configure a reverse proxy, see e.g. test/nginx.conf
|
||||||
|
# abuseReporting:
|
||||||
|
# # Whether to enable this feature.
|
||||||
|
# enabled: false
|
||||||
|
|
||||||
|
# Whether or not to actively poll synapse for abuse reports, to be used
|
||||||
|
# instead of intercepting client calls to synapse's abuse endpoint, when that
|
||||||
|
# isn't possible/practical.
|
||||||
|
pollReports: false
|
||||||
|
|
||||||
|
# Whether or not new reports, received either by webapi or polling,
|
||||||
|
# should be printed to our managementRoom.
|
||||||
|
displayReports: false
|
@ -0,0 +1,42 @@
|
|||||||
|
#jinja2: lstrip_blocks: "True"
|
||||||
|
[Unit]
|
||||||
|
Description=Matrix Draupnir bot
|
||||||
|
{% for service in matrix_bot_draupnir_systemd_required_services_list %}
|
||||||
|
Requires={{ service }}
|
||||||
|
After={{ service }}
|
||||||
|
{% endfor %}
|
||||||
|
{% for service in matrix_bot_draupnir_systemd_required_services_list %}
|
||||||
|
Wants={{ service }}
|
||||||
|
{% endfor %}
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}"
|
||||||
|
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill matrix-bot-draupnir 2>/dev/null || true'
|
||||||
|
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-draupnir 2>/dev/null || true'
|
||||||
|
|
||||||
|
# Intentional delay, so that the homeserver (we likely depend on) can manage to start.
|
||||||
|
ExecStartPre={{ matrix_host_command_sleep }} 5
|
||||||
|
|
||||||
|
ExecStart={{ devture_systemd_docker_base_host_command_docker }} run --rm --name matrix-bot-draupnir \
|
||||||
|
--log-driver=none \
|
||||||
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--network={{ matrix_docker_network }} \
|
||||||
|
--mount type=bind,src={{ matrix_bot_draupnir_config_path }},dst=/data/config,ro \
|
||||||
|
--mount type=bind,src={{ matrix_bot_draupnir_data_path }},dst=/data \
|
||||||
|
{% for arg in matrix_bot_draupnir_container_extra_arguments %}
|
||||||
|
{{ arg }} \
|
||||||
|
{% endfor %}
|
||||||
|
{{ matrix_bot_draupnir_docker_image }}
|
||||||
|
|
||||||
|
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill matrix-bot-draupnir 2>/dev/null || true'
|
||||||
|
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm matrix-bot-draupnir 2>/dev/null || true'
|
||||||
|
Restart=always
|
||||||
|
RestartSec=30
|
||||||
|
SyslogIdentifier=matrix-bot-draupnir
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
@ -0,0 +1,63 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- ansible.builtin.set_fact:
|
||||||
|
matrix_jitsi_prosody_self_check_uvs_health_url: "{{ matrix_jitsi_prosody_auth_matrix_uvs_location }}/health"
|
||||||
|
matrix_jitsi_element_jitsi_well_known_url: "{{ matrix_jitsi_web_public_url }}/.well-known/element/jitsi"
|
||||||
|
|
||||||
|
- name: Check if jitsi serves the .well-known/element/jitsi
|
||||||
|
ansible.builtin.uri:
|
||||||
|
url: "{{ matrix_jitsi_element_jitsi_well_known_url }}"
|
||||||
|
follow_redirects: none
|
||||||
|
return_content: true
|
||||||
|
validate_certs: "{{ matrix_jitsi_self_check_validate_certificates }}"
|
||||||
|
headers:
|
||||||
|
Origin: example.com
|
||||||
|
check_mode: false
|
||||||
|
register: result_well_known_jitsi_element_jitsi
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Fail if .well-known not working
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: |
|
||||||
|
Failed checking that the Jitsi well-known file for Element auth is configured at `{{ matrix_jitsi_element_jitsi_well_known_url }}`
|
||||||
|
Full error: {{ result_well_known_jitsi_element_jitsi }}
|
||||||
|
when: "result_well_known_jitsi_element_jitsi.failed"
|
||||||
|
|
||||||
|
- name: Parse JSON for well-known payload at the matrix hostname
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
well_known_matrix_payload: "{{ result_well_known_jitsi_element_jitsi.content | from_json }}"
|
||||||
|
|
||||||
|
- name: Fail if .well-known not CORS-aware
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: "The well-known file on `{{ matrix_jitsi_element_jitsi_well_known_url }}` is not CORS-aware. The file needs to be served with an Access-Control-Allow-Origin header set."
|
||||||
|
when: "'access_control_allow_origin' not in result_well_known_jitsi_element_jitsi"
|
||||||
|
|
||||||
|
- name: Report working .well-known
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "well-known is configured correctly at `{{ matrix_jitsi_element_jitsi_well_known_url }}`"
|
||||||
|
|
||||||
|
- name: Check if we can reach the user verification service and if it's healthy
|
||||||
|
ansible.builtin.command:
|
||||||
|
argv:
|
||||||
|
- "docker"
|
||||||
|
- "exec"
|
||||||
|
- "matrix-jitsi-prosody"
|
||||||
|
- "wget"
|
||||||
|
- "-O"
|
||||||
|
- "-"
|
||||||
|
- "--quiet"
|
||||||
|
- "{{ matrix_jitsi_prosody_self_check_uvs_health_url | quote }}"
|
||||||
|
register: matrix_jitsi_prosody_self_check_uvs_result
|
||||||
|
changed_when: false
|
||||||
|
ignore_errors: true
|
||||||
|
|
||||||
|
- name: Fail if user verification service is not (reachable and healthy)
|
||||||
|
ansible.builtin.fail:
|
||||||
|
msg: |
|
||||||
|
Failed checking user verification service is up (checked endpoint: `{{ matrix_jitsi_prosody_self_check_uvs_health_url }}`).
|
||||||
|
Full error: {{ matrix_jitsi_prosody_self_check_uvs_result }}
|
||||||
|
when: "matrix_jitsi_prosody_self_check_uvs_result.failed"
|
||||||
|
|
||||||
|
- name: Report healthy user verification service
|
||||||
|
ansible.builtin.debug:
|
||||||
|
msg: "User verification service is working (checked endpoint: `{{ matrix_jitsi_prosody_self_check_uvs_health_url }}`)"
|
@ -0,0 +1,17 @@
|
|||||||
|
---
|
||||||
|
#
|
||||||
|
# Tasks related to configuring Jitsi internal authentication on a running prosody instance.
|
||||||
|
#
|
||||||
|
|
||||||
|
- name: Ensure Jitsi internal authentication users are configured
|
||||||
|
ansible.builtin.shell: "{{ devture_systemd_docker_base_host_command_docker }} exec matrix-jitsi-prosody prosodyctl --config /config/prosody.cfg.lua register {{ item.username | quote }} meet.jitsi {{ item.password | quote }}"
|
||||||
|
with_items: "{{ matrix_jitsi_prosody_auth_internal_accounts }}"
|
||||||
|
when:
|
||||||
|
- matrix_jitsi_prosody_auth_internal_accounts|length > 0
|
||||||
|
register: matrix_jitsi_user_configuration_result
|
||||||
|
changed_when: matrix_jitsi_user_configuration_result.rc == 0
|
||||||
|
no_log: true
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tasks related to clean up after configuring internal authentication.
|
||||||
|
#
|
@ -1,42 +0,0 @@
|
|||||||
---
|
|
||||||
#
|
|
||||||
# Start Necessary Services
|
|
||||||
#
|
|
||||||
|
|
||||||
- name: Ensure matrix-jitsi-prosody container is running
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
state: started
|
|
||||||
name: matrix-jitsi-prosody
|
|
||||||
register: matrix_jitsi_prosody_start_result
|
|
||||||
|
|
||||||
|
|
||||||
#
|
|
||||||
# Tasks related to configuring Jitsi internal authentication
|
|
||||||
#
|
|
||||||
|
|
||||||
- name: Ensure Jitsi internal authentication users are configured
|
|
||||||
ansible.builtin.shell: "{{ devture_systemd_docker_base_host_command_docker }} exec matrix-jitsi-prosody prosodyctl --config /config/prosody.cfg.lua register {{ item.username | quote }} meet.jitsi {{ item.password | quote }}"
|
|
||||||
with_items: "{{ matrix_jitsi_prosody_auth_internal_accounts }}"
|
|
||||||
when:
|
|
||||||
- matrix_jitsi_auth_type == "internal"
|
|
||||||
- matrix_jitsi_prosody_auth_internal_accounts|length > 0
|
|
||||||
register: matrix_jitsi_user_configuration_result
|
|
||||||
changed_when: matrix_jitsi_user_configuration_result.rc == 0
|
|
||||||
no_log: true
|
|
||||||
|
|
||||||
#
|
|
||||||
# Tasks related to configuring other Jitsi authentication mechanisms
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Tasks related to cleaning after Jitsi authentication configuration
|
|
||||||
#
|
|
||||||
|
|
||||||
#
|
|
||||||
# Stop Necessary Services
|
|
||||||
#
|
|
||||||
- name: Ensure matrix-jitsi-prosody container is stopped if necessary
|
|
||||||
ansible.builtin.systemd:
|
|
||||||
state: stopped
|
|
||||||
name: matrix-jitsi-prosody
|
|
||||||
when: matrix_jitsi_prosody_start_result.changed | bool
|
|
@ -0,0 +1,15 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Checkout Prosody Auth Matrix User Verification Plugin Repo
|
||||||
|
ansible.builtin.git:
|
||||||
|
repo: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_location }}"
|
||||||
|
dest: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_target }}"
|
||||||
|
version: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_version }}"
|
||||||
|
|
||||||
|
- name: Install Prosody Auth Matrix User Verification Plugin
|
||||||
|
ansible.builtin.copy:
|
||||||
|
remote_src: true
|
||||||
|
src: "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_target }}/{{ item.path }}"
|
||||||
|
dest: "{{ matrix_jitsi_prosody_plugins_path }}/{{ item.path }}"
|
||||||
|
with_items: "{{ matrix_jitsi_prosody_auth_matrix_files }}"
|
||||||
|
when: item.when | bool
|
@ -0,0 +1,20 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Remove all files regarding prosody mod auth_matrix_user_verification and .well-known/element/jitsi
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item }}"
|
||||||
|
state: absent
|
||||||
|
with_flattened:
|
||||||
|
- "{{ matrix_static_files_base_path }}/.well-known/element/jitsi"
|
||||||
|
- "{{ matrix_jitsi_prosody_auth_matrix_user_verification_repo_target }}"
|
||||||
|
- "{{ matrix_jitsi_prosody_auth_matrix_files | map(attribute='path') | map('regex_replace', '^', matrix_jitsi_prosody_plugins_path+'/') | list }}"
|
||||||
|
register: matrix_jitsi_prosody_auth_matrix_user_verification_uninstalled
|
||||||
|
|
||||||
|
- when: matrix_jitsi_prosody_auth_matrix_user_verification_uninstalled.changed
|
||||||
|
block:
|
||||||
|
- name: Populate service facts
|
||||||
|
ansible.builtin.service_facts:
|
||||||
|
|
||||||
|
- name: Ensure prosody is restarted later on if currently running
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
matrix_jitsi_prosody_require_restart: "{{ true if ansible_facts.services['matrix-jitsi-prosody.service']['state'] == 'running' else false }}"
|
@ -0,0 +1,49 @@
|
|||||||
|
---
|
||||||
|
#####
|
||||||
|
#
|
||||||
|
# This tasks file starts and stops (if state before was stopped) a prosody container during setup to run commands,
|
||||||
|
# that require a running prosody container.
|
||||||
|
# The task is called in ../setup_jitsi_prosody_install.yml.
|
||||||
|
#
|
||||||
|
# Important: The task is called conditionally, as to only start if really needed.
|
||||||
|
# So if you add or change anything - remember to also change the 'when' in: ../setup_jitsi_prosody_install.yml
|
||||||
|
#
|
||||||
|
#####
|
||||||
|
|
||||||
|
#
|
||||||
|
# Start Necessary Services
|
||||||
|
#
|
||||||
|
|
||||||
|
- name: Ensure matrix-jitsi-prosody container is running
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
state: "{{ 'restarted' if matrix_jitsi_prosody_require_restart | default(false) | bool else 'started' }}"
|
||||||
|
name: matrix-jitsi-prosody
|
||||||
|
register: matrix_jitsi_prosody_start_result
|
||||||
|
|
||||||
|
# If the flag was set, we can safely disable now.
|
||||||
|
- name: Disable require restart flag
|
||||||
|
ansible.builtin.set_fact:
|
||||||
|
matrix_jitsi_prosody_require_restart: false
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tasks related to configuring Jitsi internal authentication
|
||||||
|
#
|
||||||
|
|
||||||
|
- name: Ensure internal authentication is properly configured
|
||||||
|
ansible.builtin.include_tasks:
|
||||||
|
file: "{{ role_path }}/tasks/util/prosody_post_setup_hooks/setup_jitsi_auth_internal.yml"
|
||||||
|
when: matrix_jitsi_enable_auth | bool and matrix_jitsi_auth_type == "internal"
|
||||||
|
|
||||||
|
#
|
||||||
|
# Tasks related to ...
|
||||||
|
#
|
||||||
|
|
||||||
|
|
||||||
|
#
|
||||||
|
# Stop Necessary Services
|
||||||
|
#
|
||||||
|
- name: Ensure matrix-jitsi-prosody container is stopped if necessary
|
||||||
|
ansible.builtin.systemd:
|
||||||
|
state: stopped
|
||||||
|
name: matrix-jitsi-prosody
|
||||||
|
when: matrix_jitsi_prosody_start_result.changed | bool
|
@ -0,0 +1,61 @@
|
|||||||
|
---
|
||||||
|
# Set this to the display name for ansible used in Output e.g. fail_msg
|
||||||
|
matrix_user_verification_service_ansible_name: "Matrix User Verification Service"
|
||||||
|
|
||||||
|
# Enable by default. This is overwritten in provided group vars.
|
||||||
|
matrix_user_verification_service_enabled: true
|
||||||
|
|
||||||
|
# Fix version tag
|
||||||
|
matrix_user_verification_service_version: "v2.0.0"
|
||||||
|
|
||||||
|
# Paths
|
||||||
|
matrix_user_verification_service_base_path: "{{ matrix_base_data_path }}/user-verification-service"
|
||||||
|
matrix_user_verification_service_config_path: "{{ matrix_user_verification_service_base_path }}/config"
|
||||||
|
matrix_user_verification_service_config_env_file: "{{ matrix_user_verification_service_config_path }}/.env"
|
||||||
|
|
||||||
|
# Docker
|
||||||
|
matrix_user_verification_service_docker_image_name_prefix: "{{ matrix_container_global_registry_prefix }}"
|
||||||
|
matrix_user_verification_service_docker_image: "{{ matrix_user_verification_service_docker_image_name_prefix }}matrixdotorg/matrix-user-verification-service:{{ matrix_user_verification_service_version }}"
|
||||||
|
matrix_user_verification_service_docker_image_force_pull: "{{ matrix_user_verification_service_docker_image.endswith(':latest') }}"
|
||||||
|
|
||||||
|
matrix_user_verification_service_container_name: "matrix-user-verification-service"
|
||||||
|
# This will be set in group vars
|
||||||
|
matrix_user_verification_service_container_http_host_bind_port: ''
|
||||||
|
matrix_user_verification_service_container_extra_arguments: []
|
||||||
|
# Systemd
|
||||||
|
matrix_user_verification_service_systemd_required_services_list: []
|
||||||
|
matrix_user_verification_service_systemd_wanted_services_list: []
|
||||||
|
matrix_user_verification_service_systemd_service_basename: "matrix-user-verification-service"
|
||||||
|
matrix_user_verification_service_systemd_service_name: "{{ matrix_user_verification_service_systemd_service_basename }}.service"
|
||||||
|
|
||||||
|
# Matrix User Verification Service Configuration
|
||||||
|
## REQUIRED
|
||||||
|
|
||||||
|
# Homeserver client API admin token (synapse only)- Required for the service to verify room membership
|
||||||
|
# matrix_user_verification_service_uvs_access_token:
|
||||||
|
|
||||||
|
# homeserver client api url
|
||||||
|
matrix_user_verification_service_uvs_homeserver_url: "{{ matrix_homeserver_container_url }}"
|
||||||
|
# disable check for non private ip range of homeserver. e.g. set to `true` if your homeserver domain resolves to a private ip.
|
||||||
|
matrix_user_verification_service_uvs_disable_ip_blacklist: false
|
||||||
|
|
||||||
|
## OPTIONAL
|
||||||
|
|
||||||
|
# Require an Auth-Token with API calls. If set to false, UVS will reply to any API call.
|
||||||
|
# The Auth-Token is defined via: matrix_user_verification_service_uvs_auth_token
|
||||||
|
matrix_user_verification_service_uvs_require_auth: true
|
||||||
|
# Auth token to protect the API
|
||||||
|
# If enabled any calls to the provided API endpoints need have the header "Authorization: Bearer TOKEN".
|
||||||
|
# A Token will be derived from matrix_homeserver_generic_secret_key in group_vars/matrix_servers
|
||||||
|
matrix_user_verification_service_uvs_auth_token: ''
|
||||||
|
|
||||||
|
# Pin UVS to only check openId Tokens for the matrix_server_name configured by this playbook.
|
||||||
|
matrix_user_verification_service_uvs_pin_openid_verify_server_name: true
|
||||||
|
# Matrix server name to verify OpenID tokens against.
|
||||||
|
# This is not the homeserverURL, but rather the domain in the matrix "user ID"
|
||||||
|
# UVS can also be instructed to verify against the Matrix server name passed in the token, to enable set to ""
|
||||||
|
matrix_user_verification_service_uvs_openid_verify_server_name: "{{ matrix_domain }}"
|
||||||
|
|
||||||
|
# Log level
|
||||||
|
# See choices here: https://github.com/winstonjs/winston#logging-levels
|
||||||
|
matrix_user_verification_service_uvs_log_level: info
|
@ -0,0 +1,19 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- when: matrix_jitsi_enabled | bool
|
||||||
|
ansible.builtin.include_tasks: "{{ role_path }}/tasks/validate_config.yml"
|
||||||
|
- when: run_setup | bool and matrix_user_verification_service_enabled | bool
|
||||||
|
ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_install.yml"
|
||||||
|
tags:
|
||||||
|
- setup-all
|
||||||
|
- setup-user-verification-service
|
||||||
|
- install-all
|
||||||
|
- install-user-verification-service
|
||||||
|
|
||||||
|
- block:
|
||||||
|
- when: run_setup | bool and not matrix_user_verification_service_enabled | bool
|
||||||
|
ansible.builtin.include_tasks: "{{ role_path }}/tasks/setup_uninstall.yml"
|
||||||
|
tags:
|
||||||
|
- setup-all
|
||||||
|
- setup-user-verification-service
|
@ -0,0 +1,37 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: "Ensure Matrix User Verification Service paths exist"
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ item.path }}"
|
||||||
|
state: directory
|
||||||
|
mode: 0750
|
||||||
|
owner: "{{ matrix_user_username }}"
|
||||||
|
group: "{{ matrix_user_groupname }}"
|
||||||
|
with_items:
|
||||||
|
- {path: "{{ matrix_user_verification_service_config_path }}", when: true}
|
||||||
|
when: item.when | bool
|
||||||
|
|
||||||
|
- name: Ensure Matrix User Verification Service image is pulled
|
||||||
|
community.docker.docker_image:
|
||||||
|
name: "{{ matrix_user_verification_service_docker_image }}"
|
||||||
|
source: "{{ 'pull' if ansible_version.major > 2 or ansible_version.minor > 7 else omit }}"
|
||||||
|
force_source: "{{ matrix_user_verification_service_docker_image_force_pull if ansible_version.major > 2 or ansible_version.minor >= 8 else omit }}"
|
||||||
|
force: "{{ omit if ansible_version.major > 2 or ansible_version.minor >= 8 else matrix_user_verification_service_docker_image_force_pull }}"
|
||||||
|
register: result
|
||||||
|
retries: "{{ devture_playbook_help_container_retries_count }}"
|
||||||
|
delay: "{{ devture_playbook_help_container_retries_delay }}"
|
||||||
|
until: result is not failed
|
||||||
|
|
||||||
|
- name: Ensure Matrix User Verification Service env file installed
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ role_path }}/templates/.env.j2"
|
||||||
|
dest: "{{ matrix_user_verification_service_config_env_file }}"
|
||||||
|
owner: "{{ matrix_user_username }}"
|
||||||
|
group: "{{ matrix_user_groupname }}"
|
||||||
|
mode: 0644
|
||||||
|
|
||||||
|
- name: Ensure matrix-user-verification-service.service installed
|
||||||
|
ansible.builtin.template:
|
||||||
|
src: "{{ role_path }}/templates/systemd/matrix-user-verification-service.service.j2"
|
||||||
|
dest: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_user_verification_service_systemd_service_name }}"
|
||||||
|
mode: 0644
|
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Check existence of matrix-user-verification-service service
|
||||||
|
ansible.builtin.stat:
|
||||||
|
path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_user_verification_service_systemd_service_name }}"
|
||||||
|
register: matrix_user_verification_service_service_stat
|
||||||
|
|
||||||
|
- when: matrix_user_verification_service_service_stat.stat.exists | bool
|
||||||
|
block:
|
||||||
|
- name: Ensure matrix-user-verification-service is stopped
|
||||||
|
ansible.builtin.service:
|
||||||
|
name: "{{ matrix_user_verification_service_systemd_service_basename }}"
|
||||||
|
state: stopped
|
||||||
|
daemon_reload: true
|
||||||
|
register: stopping_result
|
||||||
|
|
||||||
|
- name: Ensure matrix-user-verification-service.service doesn't exist
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ devture_systemd_docker_base_systemd_path }}/{{ matrix_user_verification_service_systemd_service_name }}"
|
||||||
|
state: absent
|
||||||
|
|
||||||
|
- name: Ensure Matrix user-verification-service paths don't exist
|
||||||
|
ansible.builtin.file:
|
||||||
|
path: "{{ matrix_user_verification_service_base_path }}"
|
||||||
|
state: absent
|
@ -0,0 +1,25 @@
|
|||||||
|
---
|
||||||
|
|
||||||
|
- name: Verify homeserver_url is not empty
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- matrix_user_verification_service_uvs_homeserver_url|length > 0
|
||||||
|
fail_msg: "Missing variable in {{ matrix_user_verification_service_ansible_name }} role"
|
||||||
|
|
||||||
|
- name: Verify Auth is configured properly or disabled
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- matrix_user_verification_service_uvs_access_token|length > 0 or not matrix_user_verification_service_uvs_require_auth|bool
|
||||||
|
fail_msg: "If Auth is enabled, a valid (non empty) TOKEN must be given in 'matrix_user_verification_service_uvs_access_token'."
|
||||||
|
|
||||||
|
- name: Verify server_name for openid verification is given, if pinning a single server_name is enabled.
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- matrix_user_verification_service_uvs_openid_verify_server_name|length > 0 or not matrix_user_verification_service_uvs_pin_openid_verify_server_name|bool
|
||||||
|
fail_msg: "If pinning a single server_name is enabled, a valid (non empty) server_name must be given in 'matrix_user_verification_service_uvs_openid_verify_server_name'."
|
||||||
|
|
||||||
|
- name: Verify the homeserver implementation is synapse
|
||||||
|
ansible.builtin.assert:
|
||||||
|
that:
|
||||||
|
- matrix_homeserver_implementation == 'synapse'
|
||||||
|
fail_msg: "The User-Verification-Service requires Synapse as homeserver implementation"
|
@ -0,0 +1,11 @@
|
|||||||
|
UVS_ACCESS_TOKEN={{ matrix_user_verification_service_uvs_access_token }}
|
||||||
|
UVS_HOMESERVER_URL={{ matrix_user_verification_service_uvs_homeserver_url }}
|
||||||
|
UVS_DISABLE_IP_BLACKLIST={{ matrix_user_verification_service_uvs_disable_ip_blacklist }}
|
||||||
|
UVS_LOG_LEVEL={{ matrix_user_verification_service_uvs_log_level }}
|
||||||
|
{% if matrix_user_verification_service_uvs_require_auth | bool %}
|
||||||
|
UVS_AUTH_TOKEN={{ matrix_user_verification_service_uvs_auth_token }}
|
||||||
|
{% endif %}
|
||||||
|
{% if matrix_user_verification_service_uvs_pin_openid_verify_server_name | bool %}
|
||||||
|
UVS_OPENID_VERIFY_SERVER_NAME={{ matrix_user_verification_service_uvs_openid_verify_server_name }}
|
||||||
|
{% endif %}
|
||||||
|
|
@ -0,0 +1,42 @@
|
|||||||
|
#jinja2: lstrip_blocks: "True"
|
||||||
|
[Unit]
|
||||||
|
Description={{ matrix_user_verification_service_ansible_name }}
|
||||||
|
{% for service in matrix_user_verification_service_systemd_required_services_list %}
|
||||||
|
Requires={{ service }}
|
||||||
|
After={{ service }}
|
||||||
|
{% endfor %}
|
||||||
|
{% for service in matrix_user_verification_service_systemd_wanted_services_list %}
|
||||||
|
Wants={{ service }}
|
||||||
|
{% endfor %}
|
||||||
|
DefaultDependencies=no
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
Environment="HOME={{ devture_systemd_docker_base_systemd_unit_home_path }}"
|
||||||
|
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill {{ matrix_user_verification_service_container_name }} 2>/dev/null'
|
||||||
|
ExecStartPre=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_user_verification_service_container_name }} 2>/dev/null'
|
||||||
|
|
||||||
|
|
||||||
|
ExecStart={{ devture_systemd_docker_base_host_command_docker }} run --rm --name {{ matrix_user_verification_service_container_name }}\
|
||||||
|
--log-driver=none \
|
||||||
|
--user={{ matrix_user_uid }}:{{ matrix_user_gid }} \
|
||||||
|
--cap-drop=ALL \
|
||||||
|
--read-only \
|
||||||
|
--network={{ matrix_docker_network }} \
|
||||||
|
{% if matrix_user_verification_service_container_http_host_bind_port %}
|
||||||
|
-p {{ matrix_user_verification_service_container_http_host_bind_port }}:3000 \
|
||||||
|
{% endif %}
|
||||||
|
--mount type=bind,src={{ matrix_user_verification_service_config_env_file }},dst=/app/.env,ro \
|
||||||
|
{% for arg in matrix_user_verification_service_container_extra_arguments %}
|
||||||
|
{{ arg }} \
|
||||||
|
{% endfor %}
|
||||||
|
{{ matrix_user_verification_service_docker_image }}
|
||||||
|
|
||||||
|
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} kill {{ matrix_user_verification_service_container_name }} 2>/dev/null'
|
||||||
|
ExecStop=-{{ devture_systemd_docker_base_host_command_sh }} -c '{{ devture_systemd_docker_base_host_command_docker }} rm {{ matrix_user_verification_service_container_name }} 2>/dev/null'
|
||||||
|
Restart=always
|
||||||
|
RestartSec=30
|
||||||
|
SyslogIdentifier={{ matrix_user_verification_service_systemd_service_basename }}
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
Loading…
Reference in new issue