mirror of
https://forgejo.ellis.link/continuwuation/continuwuity.git
synced 2026-05-26 20:49:55 +00:00
Compare commits
44 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8c3a0116a | |||
| 379ef5014c | |||
| 2ab177f100 | |||
| a818f51396 | |||
| 09bfe79a44 | |||
| d041adadc8 | |||
| 189ed1c394 | |||
| 36c32938ae | |||
| 915643c965 | |||
| 4063b2c7da | |||
| 943bd81ce9 | |||
| 2942d9133e | |||
| 18a7a85fe4 | |||
| 0fdb1be938 | |||
| 867a3ac376 | |||
| 7a6eff091a | |||
| c278663f65 | |||
| c822c945e7 | |||
| 6eb3dc1f9d | |||
| 789ec71b75 | |||
| 1cfa3ff10b | |||
| 02cf6b5695 | |||
| 4cc4893376 | |||
| 7643b64f60 | |||
| 3d9fd34012 | |||
| 630963d6e1 | |||
| 36da6f5bf3 | |||
| 462ef63945 | |||
| 46bcfe5605 | |||
| 16321cf467 | |||
| 4d59e07006 | |||
| ec5f50c68e | |||
| db1b08532e | |||
| d8f67e3b46 | |||
| 2124fcf325 | |||
| 38b4065270 | |||
| 2e62ca93a8 | |||
| b7a6c819b7 | |||
| eccc878ee9 | |||
| 8b762cf2e6 | |||
| 1ce9ae2cbf | |||
| 6a3370005e | |||
| 675cfb964a | |||
| 09312791a7 |
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
dotenv_if_exists
|
dotenv_if_exists
|
||||||
|
|
||||||
if [ -f /etc/os-release ] && grep -q '^ID=nixos' /etc/os-release; then
|
if command -v nix >/dev/null 2>&1; then
|
||||||
use flake ".#${DIRENV_DEVSHELL:-default}"
|
use flake ".#${DIRENV_DEVSHELL:-default}"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
@@ -16,48 +16,19 @@ jobs:
|
|||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v6
|
- uses: actions/checkout@v6
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
|
||||||
fetch-tags: false
|
|
||||||
fetch-single-branch: true
|
|
||||||
submodules: false
|
|
||||||
persist-credentials: true
|
persist-credentials: true
|
||||||
token: ${{ secrets.FORGEJO_TOKEN }}
|
token: ${{ secrets.FORGEJO_TOKEN }}
|
||||||
|
|
||||||
- uses: https://github.com/cachix/install-nix-action@19effe9fe722874e6d46dd7182e4b8b7a43c4a99 # v31.10.0
|
- name: Install Lix
|
||||||
|
uses: https://github.com/samueldr/lix-gha-installer-action@7b7f14d320d6aacfb65bd1ef761566b3b69e474c
|
||||||
with:
|
with:
|
||||||
nix_path: nixpkgs=channel:nixos-unstable
|
extra_nix_config: experimental-features = nix-command flakes flake-self-attrs
|
||||||
|
|
||||||
# We can skip getting a toolchain hash if this was ran as a dispatch with the intent
|
|
||||||
# to update just the rocksdb hash. If this was ran as a dispatch and the toolchain
|
|
||||||
# files are changed, we still update them, as well as the rocksdb import.
|
|
||||||
- name: Detect changed files
|
|
||||||
id: changes
|
|
||||||
run: |
|
|
||||||
git fetch origin ${{ github.base_ref }} --depth=1 || true
|
|
||||||
if [ -n "${{ github.event.pull_request.base.sha }}" ]; then
|
|
||||||
base=${{ github.event.pull_request.base.sha }}
|
|
||||||
else
|
|
||||||
base=$(git rev-parse HEAD~1)
|
|
||||||
fi
|
|
||||||
echo "Base: $base"
|
|
||||||
echo "HEAD: $(git rev-parse HEAD)"
|
|
||||||
git diff --name-only $base HEAD > changed_files.txt
|
|
||||||
echo "detected changes in $(cat changed_files.txt)"
|
|
||||||
# Join files with commas
|
|
||||||
files=$(paste -sd, changed_files.txt)
|
|
||||||
echo "files=$files" >> $FORGEJO_OUTPUT
|
|
||||||
|
|
||||||
- name: Debug output
|
|
||||||
run: |
|
|
||||||
echo "State of output"
|
|
||||||
echo "Changed files: ${{ steps.changes.outputs.files }}"
|
|
||||||
|
|
||||||
- name: Get new toolchain hash
|
- name: Get new toolchain hash
|
||||||
if: contains(steps.changes.outputs.files, 'Cargo.toml') || contains(steps.changes.outputs.files, 'Cargo.lock') || contains(steps.changes.outputs.files, 'rust-toolchain.toml')
|
|
||||||
run: |
|
run: |
|
||||||
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
||||||
awk '/fromToolchainFile *\{/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/packages/rust.nix > temp.nix
|
awk '/fromToolchainFile *\{/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/rust.nix > temp.nix
|
||||||
mv temp.nix nix/packages/rust.nix
|
mv temp.nix nix/rust.nix
|
||||||
|
|
||||||
# Build continuwuity and filter for the new hash
|
# Build continuwuity and filter for the new hash
|
||||||
# We do `|| true` because we want this to fail without stopping the workflow
|
# We do `|| true` because we want this to fail without stopping the workflow
|
||||||
@@ -65,36 +36,17 @@ jobs:
|
|||||||
|
|
||||||
# Place the new hash in place of the empty hash
|
# Place the new hash in place of the empty hash
|
||||||
new_hash=$(cat new_toolchain_hash.txt)
|
new_hash=$(cat new_toolchain_hash.txt)
|
||||||
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/packages/rust.nix
|
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/rust.nix
|
||||||
|
|
||||||
echo "New hash:"
|
echo "New hash:"
|
||||||
awk -F'"' '/fromToolchainFile/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/packages/rust.nix
|
awk -F'"' '/fromToolchainFile/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/rust.nix
|
||||||
echo "Expected new hash:"
|
echo "Expected new hash:"
|
||||||
cat new_toolchain_hash.txt
|
cat new_toolchain_hash.txt
|
||||||
|
|
||||||
rm new_toolchain_hash.txt
|
rm new_toolchain_hash.txt
|
||||||
|
|
||||||
- name: Get new rocksdb hash
|
- name: Update rocksdb
|
||||||
if: contains(steps.changes.outputs.files, '.nix') || contains(steps.changes.outputs.files, 'flake.lock')
|
run: nix run .#update-rocksdb
|
||||||
run: |
|
|
||||||
# Set the current sha256 to an empty hash to make `nix build` calculate a new one
|
|
||||||
awk '/repo = "rocksdb";/{found=1; print; next} found && /sha256 =/{sub(/sha256 = .*/, "sha256 = lib.fakeSha256;"); found=0} 1' nix/packages/rocksdb/package.nix > temp.nix
|
|
||||||
mv temp.nix nix/packages/rocksdb/package.nix
|
|
||||||
|
|
||||||
# Build continuwuity and filter for the new hash
|
|
||||||
# We do `|| true` because we want this to fail without stopping the workflow
|
|
||||||
nix build .#default 2>&1 | tee >(grep 'got:' | awk '{print $2}' > new_rocksdb_hash.txt) || true
|
|
||||||
|
|
||||||
# Place the new hash in place of the empty hash
|
|
||||||
new_hash=$(cat new_rocksdb_hash.txt)
|
|
||||||
sed -i "s|lib.fakeSha256|\"$new_hash\"|" nix/packages/rocksdb/package.nix
|
|
||||||
|
|
||||||
echo "New hash:"
|
|
||||||
awk -F'"' '/repo = "rocksdb";/{found=1; next} found && /sha256 =/{print $2; found=0}' nix/packages/rocksdb/package.nix
|
|
||||||
echo "Expected new hash:"
|
|
||||||
cat new_rocksdb_hash.txt
|
|
||||||
|
|
||||||
rm new_rocksdb_hash.txt
|
|
||||||
|
|
||||||
- name: Show diff
|
- name: Show diff
|
||||||
run: git diff flake.nix nix
|
run: git diff flake.nix nix
|
||||||
|
|||||||
Generated
+14
-14
@@ -1291,7 +1291,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "continuwuity-admin-api"
|
name = "continuwuity-admin-api"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -1726,7 +1726,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "draupnir-antispam"
|
name = "draupnir-antispam"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -3241,7 +3241,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "meowlnir-antispam"
|
name = "meowlnir-antispam"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
"serde",
|
"serde",
|
||||||
@@ -4545,7 +4545,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma"
|
name = "ruma"
|
||||||
version = "0.10.1"
|
version = "0.10.1"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assign",
|
"assign",
|
||||||
"continuwuity-admin-api",
|
"continuwuity-admin-api",
|
||||||
@@ -4568,7 +4568,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-appservice-api"
|
name = "ruma-appservice-api"
|
||||||
version = "0.10.0"
|
version = "0.10.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -4580,7 +4580,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-client-api"
|
name = "ruma-client-api"
|
||||||
version = "0.18.0"
|
version = "0.18.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"assign",
|
"assign",
|
||||||
@@ -4603,7 +4603,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-common"
|
name = "ruma-common"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
@@ -4635,7 +4635,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-events"
|
name = "ruma-events"
|
||||||
version = "0.28.1"
|
version = "0.28.1"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"as_variant",
|
"as_variant",
|
||||||
"indexmap",
|
"indexmap",
|
||||||
@@ -4660,7 +4660,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-federation-api"
|
name = "ruma-federation-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"headers",
|
"headers",
|
||||||
@@ -4682,7 +4682,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identifiers-validation"
|
name = "ruma-identifiers-validation"
|
||||||
version = "0.9.5"
|
version = "0.9.5"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"thiserror 2.0.18",
|
"thiserror 2.0.18",
|
||||||
@@ -4691,7 +4691,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-identity-service-api"
|
name = "ruma-identity-service-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -4701,7 +4701,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-macros"
|
name = "ruma-macros"
|
||||||
version = "0.13.0"
|
version = "0.13.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"proc-macro-crate",
|
"proc-macro-crate",
|
||||||
@@ -4716,7 +4716,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-push-gateway-api"
|
name = "ruma-push-gateway-api"
|
||||||
version = "0.9.0"
|
version = "0.9.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"js_int",
|
"js_int",
|
||||||
"ruma-common",
|
"ruma-common",
|
||||||
@@ -4728,7 +4728,7 @@ dependencies = [
|
|||||||
[[package]]
|
[[package]]
|
||||||
name = "ruma-signatures"
|
name = "ruma-signatures"
|
||||||
version = "0.15.0"
|
version = "0.15.0"
|
||||||
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=a97b91adcc012ef04991d823b8b5a79c6686ae48#a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
source = "git+https://forgejo.ellis.link/continuwuation/ruwuma?rev=1415caf8a32af4d943580c5ea4e12be1974593c2#1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"base64 0.22.1",
|
"base64 0.22.1",
|
||||||
"ed25519-dalek",
|
"ed25519-dalek",
|
||||||
|
|||||||
+3
-2
@@ -344,7 +344,7 @@ version = "0.1.2"
|
|||||||
[workspace.dependencies.ruma]
|
[workspace.dependencies.ruma]
|
||||||
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
git = "https://forgejo.ellis.link/continuwuation/ruwuma"
|
||||||
#branch = "conduwuit-changes"
|
#branch = "conduwuit-changes"
|
||||||
rev = "a97b91adcc012ef04991d823b8b5a79c6686ae48"
|
rev = "1415caf8a32af4d943580c5ea4e12be1974593c2"
|
||||||
features = [
|
features = [
|
||||||
"compat",
|
"compat",
|
||||||
"rand",
|
"rand",
|
||||||
@@ -383,7 +383,8 @@ features = [
|
|||||||
"unstable-pdu",
|
"unstable-pdu",
|
||||||
"unstable-msc4155",
|
"unstable-msc4155",
|
||||||
"unstable-msc4143", # livekit well_known response
|
"unstable-msc4143", # livekit well_known response
|
||||||
"unstable-msc4284"
|
"unstable-msc4284",
|
||||||
|
"unstable-msc4439", # pgp_key in .well_known/matrix/support
|
||||||
]
|
]
|
||||||
|
|
||||||
[workspace.dependencies.rust-rocksdb]
|
[workspace.dependencies.rust-rocksdb]
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
Added support for requiring users to accept terms and conditions when registering.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Refactored nix package. Breaking, since `all-features` package no longer exists. Continuwuity is now built with jemalloc and liburing by default. Contributed by @Henry-Hiles (QuadRadical).
|
||||||
@@ -0,0 +1,2 @@
|
|||||||
|
Add new config option for [MSC4439](https://github.com/matrix-org/matrix-spec-proposals/pull/4439)
|
||||||
|
PGP key URIs. Contributed by LogN.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed resolving IP of servers that only use SRV delegation. Contributed by @tulir.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed compiler warning in cf_opts.rs when building in release. Contributed by @ezera.
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
Fixed "Sender must be a local user" error for make_join, make_knock, and make_leave federation routes. Contributed by @nex.
|
||||||
@@ -523,6 +523,18 @@
|
|||||||
#
|
#
|
||||||
#recaptcha_private_site_key =
|
#recaptcha_private_site_key =
|
||||||
|
|
||||||
|
# Policy documents, such as terms and conditions or a privacy policy,
|
||||||
|
# which users must agree to when registering an account.
|
||||||
|
#
|
||||||
|
# Example:
|
||||||
|
# ```
|
||||||
|
# [global.registration_terms.privacy_policy]
|
||||||
|
# en = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" }
|
||||||
|
# es = { name = "Política de Privacidad", url = "https://homeserver.example/es/privacy_policy.html" }
|
||||||
|
# ```
|
||||||
|
#
|
||||||
|
#registration_terms = false
|
||||||
|
|
||||||
# Controls whether encrypted rooms and events are allowed.
|
# Controls whether encrypted rooms and events are allowed.
|
||||||
#
|
#
|
||||||
#allow_encryption = true
|
#allow_encryption = true
|
||||||
@@ -1869,6 +1881,11 @@
|
|||||||
#
|
#
|
||||||
#support_mxid =
|
#support_mxid =
|
||||||
|
|
||||||
|
# PGP key URI for server support contacts, to be served as part of the
|
||||||
|
# MSC1929 server support endpoint.
|
||||||
|
#
|
||||||
|
#support_pgp_key =
|
||||||
|
|
||||||
# **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
# **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
||||||
#
|
#
|
||||||
# A list of MatrixRTC foci URLs which will be served as part of the
|
# A list of MatrixRTC foci URLs which will be served as part of the
|
||||||
|
|||||||
+2
-2
@@ -15,13 +15,13 @@ ARG LLVM_VERSION=21
|
|||||||
|
|
||||||
# Install repo tools
|
# Install repo tools
|
||||||
# Line one: compiler tools
|
# Line one: compiler tools
|
||||||
# Line two: curl, for downloading binaries
|
# Line two: curl, for downloading binaries and wget because llvm.sh is broken with curl
|
||||||
# Line three: for xx-verify
|
# Line three: for xx-verify
|
||||||
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \
|
||||||
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
--mount=type=cache,target=/var/lib/apt,sharing=locked \
|
||||||
apt-get update && apt-get install -y \
|
apt-get update && apt-get install -y \
|
||||||
pkg-config make jq \
|
pkg-config make jq \
|
||||||
curl git software-properties-common \
|
wget curl git software-properties-common \
|
||||||
file
|
file
|
||||||
|
|
||||||
# LLVM packages
|
# LLVM packages
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
url = "github:edolstra/flake-compat?ref=master";
|
url = "github:edolstra/flake-compat?ref=master";
|
||||||
flake = false;
|
flake = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
outputs =
|
outputs =
|
||||||
@@ -37,10 +36,10 @@
|
|||||||
flake-parts.lib.mkFlake { inherit inputs; } {
|
flake-parts.lib.mkFlake { inherit inputs; } {
|
||||||
imports = [ ./nix ];
|
imports = [ ./nix ];
|
||||||
systems = [
|
systems = [
|
||||||
# good support
|
|
||||||
"x86_64-linux"
|
"x86_64-linux"
|
||||||
# support untested but theoretically there
|
|
||||||
"aarch64-linux"
|
"aarch64-linux"
|
||||||
|
# support untested but theoretically there
|
||||||
|
"aarch64-darwin"
|
||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,107 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
uwulib = inputs.self.uwulib.init pkgs;
|
|
||||||
|
|
||||||
rocksdbAllFeatures = self'.packages.rocksdb.override {
|
|
||||||
enableJemalloc = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
commonAttrs = (uwulib.build.commonAttrs { }) // {
|
|
||||||
buildInputs = [
|
|
||||||
pkgs.liburing
|
|
||||||
pkgs.rust-jemalloc-sys-unprefixed
|
|
||||||
rocksdbAllFeatures
|
|
||||||
];
|
|
||||||
nativeBuildInputs = [
|
|
||||||
pkgs.pkg-config
|
|
||||||
# bindgen needs the build platform's libclang. Apparently due to "splicing
|
|
||||||
# weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't quite do the
|
|
||||||
# right thing here.
|
|
||||||
pkgs.rustPlatform.bindgenHook
|
|
||||||
];
|
|
||||||
env = {
|
|
||||||
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
|
||||||
LD_LIBRARY_PATH = lib.makeLibraryPath [
|
|
||||||
pkgs.liburing
|
|
||||||
pkgs.rust-jemalloc-sys-unprefixed
|
|
||||||
rocksdbAllFeatures
|
|
||||||
];
|
|
||||||
}
|
|
||||||
// uwulib.environment.buildPackageEnv
|
|
||||||
// {
|
|
||||||
ROCKSDB_INCLUDE_DIR = "${rocksdbAllFeatures}/include";
|
|
||||||
ROCKSDB_LIB_DIR = "${rocksdbAllFeatures}/lib";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
cargoArtifacts = self'.packages.continuwuity-all-features-deps;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# taken from
|
|
||||||
#
|
|
||||||
# https://crane.dev/examples/quick-start.html
|
|
||||||
checks = {
|
|
||||||
continuwuity-all-features-build = self'.packages.continuwuity-all-features-bin;
|
|
||||||
|
|
||||||
continuwuity-all-features-clippy = uwulib.build.craneLibForChecks.cargoClippy (
|
|
||||||
commonAttrs
|
|
||||||
// {
|
|
||||||
inherit cargoArtifacts;
|
|
||||||
cargoClippyExtraArgs = "-- --deny warnings";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
continuwuity-all-features-docs = uwulib.build.craneLibForChecks.cargoDoc (
|
|
||||||
commonAttrs
|
|
||||||
// {
|
|
||||||
inherit cargoArtifacts;
|
|
||||||
# This can be commented out or tweaked as necessary, e.g. set to
|
|
||||||
# `--deny rustdoc::broken-intra-doc-links` to only enforce that lint
|
|
||||||
env.RUSTDOCFLAGS = "--deny warnings";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
# Check formatting
|
|
||||||
continuwuity-all-features-fmt = uwulib.build.craneLibForChecks.cargoFmt {
|
|
||||||
src = uwulib.build.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
continuwuity-all-features-toml-fmt = uwulib.build.craneLibForChecks.taploFmt {
|
|
||||||
src = pkgs.lib.sources.sourceFilesBySuffices uwulib.build.src [ ".toml" ];
|
|
||||||
# taplo arguments can be further customized below as needed
|
|
||||||
taploExtraArgs = "--config ${inputs.self}/taplo.toml";
|
|
||||||
};
|
|
||||||
|
|
||||||
# Audit dependencies
|
|
||||||
continuwuity-all-features-audit = uwulib.build.craneLibForChecks.cargoAudit {
|
|
||||||
inherit (inputs) advisory-db;
|
|
||||||
src = uwulib.build.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Audit licenses
|
|
||||||
continuwuity-all-features-deny = uwulib.build.craneLibForChecks.cargoDeny {
|
|
||||||
src = uwulib.build.src;
|
|
||||||
};
|
|
||||||
|
|
||||||
# Run tests with cargo-nextest
|
|
||||||
# Consider setting `doCheck = false` on `continuwuity-all-features` if you do not want
|
|
||||||
# the tests to run twice
|
|
||||||
continuwuity-all-features-nextest = uwulib.build.craneLibForChecks.cargoNextest (
|
|
||||||
commonAttrs
|
|
||||||
// {
|
|
||||||
inherit cargoArtifacts;
|
|
||||||
partitions = 1;
|
|
||||||
partitionType = "count";
|
|
||||||
cargoNextestPartitionsExtraArgs = "--no-tests=pass";
|
|
||||||
}
|
|
||||||
);
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{ inputs, ... }:
|
||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{
|
||||||
|
pkgs,
|
||||||
|
self',
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
_module.args.craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (
|
||||||
|
pkgs: self'.packages.stable-toolchain
|
||||||
|
);
|
||||||
|
};
|
||||||
|
}
|
||||||
+4
-5
@@ -1,11 +1,10 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
imports = [
|
||||||
./checks
|
./rust.nix
|
||||||
|
./crane.nix
|
||||||
./packages
|
./packages
|
||||||
./shells
|
./devshell.nix
|
||||||
./tests
|
|
||||||
|
|
||||||
./hydra.nix
|
|
||||||
./fmt.nix
|
./fmt.nix
|
||||||
|
./rocksdb-updater.nix
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,42 @@
|
|||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{
|
||||||
|
craneLib,
|
||||||
|
self',
|
||||||
|
lib,
|
||||||
|
pkgs,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
# basic nix shell containing all things necessary to build continuwuity in all flavors manually (on x86_64-linux)
|
||||||
|
devShells.default = craneLib.devShell {
|
||||||
|
packages = [
|
||||||
|
self'.packages.rocksdb
|
||||||
|
pkgs.nodejs
|
||||||
|
pkgs.pkg-config
|
||||||
|
]
|
||||||
|
++ lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
pkgs.liburing
|
||||||
|
pkgs.rust-jemalloc-sys-unprefixed
|
||||||
|
];
|
||||||
|
|
||||||
|
env = {
|
||||||
|
LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
||||||
|
LD_LIBRARY_PATH = lib.makeLibraryPath (
|
||||||
|
[
|
||||||
|
pkgs.stdenv.cc.cc.lib
|
||||||
|
]
|
||||||
|
++ lib.optionals pkgs.stdenv.isLinux [
|
||||||
|
pkgs.liburing
|
||||||
|
pkgs.jemalloc
|
||||||
|
]
|
||||||
|
);
|
||||||
|
}
|
||||||
|
// lib.optionalAttrs pkgs.stdenv.isLinux {
|
||||||
|
PKG_CONFIG_PATH = lib.makeSearchPath "lib/pkgconfig" [
|
||||||
|
pkgs.liburing.dev
|
||||||
|
];
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -1,9 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
let
|
|
||||||
lib = inputs.nixpkgs.lib;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
flake.hydraJobs.packages = builtins.mapAttrs (
|
|
||||||
_name: lib.hydraJob
|
|
||||||
) inputs.self.packages.x86_64-linux;
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,65 @@
|
|||||||
|
{
|
||||||
|
lib,
|
||||||
|
self,
|
||||||
|
stdenv,
|
||||||
|
liburing,
|
||||||
|
craneLib,
|
||||||
|
pkg-config,
|
||||||
|
callPackage,
|
||||||
|
rustPlatform,
|
||||||
|
cargoExtraArgs ? "",
|
||||||
|
rocksdb ? callPackage ./rocksdb.nix { },
|
||||||
|
}:
|
||||||
|
let
|
||||||
|
# see https://crane.dev/API.html#cranelibfiltercargosources
|
||||||
|
# we need to keep the `web` directory which would be filtered out by the regular source filtering function
|
||||||
|
# https://crane.dev/API.html#cranelibcleancargosource
|
||||||
|
isWebTemplate = path: _type: builtins.match ".*(src/(web|service)|docs).*" path != null;
|
||||||
|
isRust = craneLib.filterCargoSources;
|
||||||
|
isNix = path: _type: builtins.match ".+/nix.*" path != null;
|
||||||
|
webOrRustNotNix = p: t: !(isNix p t) && (isWebTemplate p t || isRust p t);
|
||||||
|
|
||||||
|
src = lib.cleanSourceWith {
|
||||||
|
src = self;
|
||||||
|
filter = webOrRustNotNix;
|
||||||
|
name = "source";
|
||||||
|
};
|
||||||
|
|
||||||
|
attrs = {
|
||||||
|
inherit src;
|
||||||
|
nativeBuildInputs = [
|
||||||
|
pkg-config
|
||||||
|
rustPlatform.bindgenHook
|
||||||
|
];
|
||||||
|
buildInputs = lib.optionals stdenv.hostPlatform.isLinux [ liburing ];
|
||||||
|
env = {
|
||||||
|
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
||||||
|
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
in
|
||||||
|
craneLib.buildPackage (
|
||||||
|
lib.recursiveUpdate attrs {
|
||||||
|
inherit cargoExtraArgs;
|
||||||
|
cargoArtifacts = craneLib.buildDepsOnly attrs;
|
||||||
|
|
||||||
|
# Needed to make continuwuity link to rocksdb
|
||||||
|
postFixup = lib.optionalString stdenv.hostPlatform.isLinux ''
|
||||||
|
old_rpath="$(patchelf --print-rpath $out/bin/conduwuit)"
|
||||||
|
extra_rpath="${
|
||||||
|
lib.makeLibraryPath [
|
||||||
|
rocksdb
|
||||||
|
]
|
||||||
|
}"
|
||||||
|
|
||||||
|
patchelf --set-rpath "$old_rpath:$extra_rpath" $out/bin/conduwuit
|
||||||
|
'';
|
||||||
|
|
||||||
|
meta = {
|
||||||
|
description = "A community-driven Matrix homeserver in Rust";
|
||||||
|
mainProgram = "conduwuit";
|
||||||
|
platforms = lib.platforms.all;
|
||||||
|
maintainers = with lib.maintainers; [ quadradical ];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
)
|
||||||
@@ -1,59 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
uwulib = inputs.self.uwulib.init pkgs;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
packages =
|
|
||||||
lib.pipe
|
|
||||||
[
|
|
||||||
# this is the default variant
|
|
||||||
{
|
|
||||||
variantName = "default";
|
|
||||||
commonAttrsArgs.profile = "release";
|
|
||||||
rocksdb = self'.packages.rocksdb;
|
|
||||||
features = { };
|
|
||||||
}
|
|
||||||
# this is the variant with all features enabled (liburing + jemalloc)
|
|
||||||
{
|
|
||||||
variantName = "all-features";
|
|
||||||
commonAttrsArgs.profile = "release";
|
|
||||||
rocksdb = self'.packages.rocksdb.override {
|
|
||||||
enableJemalloc = true;
|
|
||||||
};
|
|
||||||
features = {
|
|
||||||
enabledFeatures = "all";
|
|
||||||
disabledFeatures = uwulib.features.defaultDisabledFeatures ++ [ "bindgen-static" ];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
[
|
|
||||||
(builtins.map (cfg: rec {
|
|
||||||
deps = {
|
|
||||||
name = "continuwuity-${cfg.variantName}-deps";
|
|
||||||
value = uwulib.build.buildDeps {
|
|
||||||
features = uwulib.features.calcFeatures cfg.features;
|
|
||||||
inherit (cfg) commonAttrsArgs rocksdb;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
bin = {
|
|
||||||
name = "continuwuity-${cfg.variantName}-bin";
|
|
||||||
value = uwulib.build.buildPackage {
|
|
||||||
deps = self'.packages.${deps.name};
|
|
||||||
features = uwulib.features.calcFeatures cfg.features;
|
|
||||||
inherit (cfg) commonAttrsArgs rocksdb;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}))
|
|
||||||
(builtins.concatMap builtins.attrValues)
|
|
||||||
builtins.listToAttrs
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,14 +1,18 @@
|
|||||||
{
|
{
|
||||||
imports = [
|
self,
|
||||||
./continuwuity
|
...
|
||||||
./rocksdb
|
}:
|
||||||
./rust.nix
|
{
|
||||||
./uwulib
|
|
||||||
];
|
|
||||||
|
|
||||||
perSystem =
|
perSystem =
|
||||||
{ self', ... }:
|
|
||||||
{
|
{
|
||||||
packages.default = self'.packages.continuwuity-default-bin;
|
pkgs,
|
||||||
|
craneLib,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
{
|
||||||
|
packages = {
|
||||||
|
rocksdb = pkgs.callPackage ./rocksdb.nix { };
|
||||||
|
default = pkgs.callPackage ./continuwuity.nix { inherit self craneLib; };
|
||||||
|
};
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
{
|
||||||
|
stdenv,
|
||||||
|
rocksdb,
|
||||||
|
fetchFromGitea,
|
||||||
|
rust-jemalloc-sys-unprefixed,
|
||||||
|
...
|
||||||
|
}:
|
||||||
|
(rocksdb.override {
|
||||||
|
# rocksdb fails to build with prefixed jemalloc, which is required on
|
||||||
|
# darwin due to [1]. In this case, fall back to building rocksdb with
|
||||||
|
# libc malloc. This should not cause conflicts, because all of the
|
||||||
|
# jemalloc symbols are prefixed.
|
||||||
|
#
|
||||||
|
# [1]: https://github.com/tikv/jemallocator/blob/ab0676d77e81268cd09b059260c75b38dbef2d51/jemalloc-sys/src/env.rs#L17
|
||||||
|
jemalloc = rust-jemalloc-sys-unprefixed;
|
||||||
|
enableJemalloc = stdenv.hostPlatform.isLinux;
|
||||||
|
}).overrideAttrs
|
||||||
|
({
|
||||||
|
version = "continuwuity-v0.5.0-unstable-2026-03-27";
|
||||||
|
src = fetchFromGitea {
|
||||||
|
domain = "forgejo.ellis.link";
|
||||||
|
owner = "continuwuation";
|
||||||
|
repo = "rocksdb";
|
||||||
|
rev = "463f47afceebfe088f6922420265546bd237f249";
|
||||||
|
hash = "sha256-1ef75IDMs5Hba4VWEyXPJb02JyShy5k4gJfzGDhopRk=";
|
||||||
|
};
|
||||||
|
|
||||||
|
# We have this already at https://forgejo.ellis.link/continuwuation/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
||||||
|
# Unsetting `patches` so we don't have to revert it and make this nix exclusive
|
||||||
|
patches = [ ];
|
||||||
|
|
||||||
|
# Unset postPatch, as our version override breaks version-specific sed calls in the original package
|
||||||
|
postPatch = "";
|
||||||
|
})
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
packages = {
|
|
||||||
rocksdb = pkgs.callPackage ./package.nix { };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,87 +0,0 @@
|
|||||||
{
|
|
||||||
lib,
|
|
||||||
stdenv,
|
|
||||||
|
|
||||||
rocksdb,
|
|
||||||
liburing,
|
|
||||||
rust-jemalloc-sys-unprefixed,
|
|
||||||
|
|
||||||
enableJemalloc ? false,
|
|
||||||
|
|
||||||
fetchFromGitea,
|
|
||||||
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
notDarwin = !stdenv.hostPlatform.isDarwin;
|
|
||||||
in
|
|
||||||
(rocksdb.override {
|
|
||||||
# Override the liburing input for the build with our own so
|
|
||||||
# we have it built with the library flag
|
|
||||||
inherit liburing;
|
|
||||||
jemalloc = rust-jemalloc-sys-unprefixed;
|
|
||||||
|
|
||||||
# rocksdb fails to build with prefixed jemalloc, which is required on
|
|
||||||
# darwin due to [1]. In this case, fall back to building rocksdb with
|
|
||||||
# libc malloc. This should not cause conflicts, because all of the
|
|
||||||
# jemalloc symbols are prefixed.
|
|
||||||
#
|
|
||||||
# [1]: https://github.com/tikv/jemallocator/blob/ab0676d77e81268cd09b059260c75b38dbef2d51/jemalloc-sys/src/env.rs#L17
|
|
||||||
enableJemalloc = enableJemalloc && notDarwin;
|
|
||||||
|
|
||||||
# for some reason enableLiburing in nixpkgs rocksdb is default true
|
|
||||||
# which breaks Darwin entirely
|
|
||||||
enableLiburing = notDarwin;
|
|
||||||
}).overrideAttrs
|
|
||||||
(old: {
|
|
||||||
src = fetchFromGitea {
|
|
||||||
domain = "forgejo.ellis.link";
|
|
||||||
owner = "continuwuation";
|
|
||||||
repo = "rocksdb";
|
|
||||||
rev = "10.5.fb";
|
|
||||||
sha256 = "sha256-X4ApGLkHF9ceBtBg77dimEpu720I79ffLoyPa8JMHaU=";
|
|
||||||
};
|
|
||||||
version = "10.5.fb";
|
|
||||||
cmakeFlags =
|
|
||||||
lib.subtractLists (builtins.map (flag: lib.cmakeBool flag true) [
|
|
||||||
# No real reason to have snappy or zlib, no one uses this
|
|
||||||
"WITH_SNAPPY"
|
|
||||||
"ZLIB"
|
|
||||||
"WITH_ZLIB"
|
|
||||||
# We don't need to use ldb or sst_dump (core_tools)
|
|
||||||
"WITH_CORE_TOOLS"
|
|
||||||
# We don't need to build rocksdb tests
|
|
||||||
"WITH_TESTS"
|
|
||||||
# We use rust-rocksdb via C interface and don't need C++ RTTI
|
|
||||||
"USE_RTTI"
|
|
||||||
# This doesn't exist in RocksDB, and USE_SSE is deprecated for
|
|
||||||
# PORTABLE=$(march)
|
|
||||||
"FORCE_SSE42"
|
|
||||||
]) old.cmakeFlags
|
|
||||||
++ (builtins.map (flag: lib.cmakeBool flag false) [
|
|
||||||
# No real reason to have snappy, no one uses this
|
|
||||||
"WITH_SNAPPY"
|
|
||||||
"ZLIB"
|
|
||||||
"WITH_ZLIB"
|
|
||||||
# We don't need to use ldb or sst_dump (core_tools)
|
|
||||||
"WITH_CORE_TOOLS"
|
|
||||||
# We don't need trace tools
|
|
||||||
"WITH_TRACE_TOOLS"
|
|
||||||
# We don't need to build rocksdb tests
|
|
||||||
"WITH_TESTS"
|
|
||||||
# We use rust-rocksdb via C interface and don't need C++ RTTI
|
|
||||||
"USE_RTTI"
|
|
||||||
]);
|
|
||||||
|
|
||||||
enableLiburing = notDarwin;
|
|
||||||
|
|
||||||
# outputs has "tools" which we don't need or use
|
|
||||||
outputs = [ "out" ];
|
|
||||||
|
|
||||||
# preInstall hooks has stuff for messing with ldb/sst_dump which we don't need or use
|
|
||||||
preInstall = "";
|
|
||||||
|
|
||||||
# We have this already at https://forgejo.ellis.link/continuwuation/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
|
||||||
# Unsetting `patches` so we don't have to revert it and make this nix exclusive
|
|
||||||
patches = [ ];
|
|
||||||
})
|
|
||||||
@@ -1,122 +0,0 @@
|
|||||||
args@{ pkgs, inputs, ... }:
|
|
||||||
let
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
uwuenv = import ./environment.nix args;
|
|
||||||
selfpkgs = inputs.self.packages.${pkgs.stdenv.system};
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
# basic, very minimal instance of the crane library with a minimal rust toolchain
|
|
||||||
craneLib = (inputs.crane.mkLib pkgs).overrideToolchain (_: selfpkgs.build-toolchain);
|
|
||||||
# the checks require more rust toolchain components, hence we have this separate instance of the crane library
|
|
||||||
craneLibForChecks = (inputs.crane.mkLib pkgs).overrideToolchain (_: selfpkgs.dev-toolchain);
|
|
||||||
|
|
||||||
# meta information (name, version, etc) of the rust crate based on the Cargo.toml
|
|
||||||
crateInfo = craneLib.crateNameFromCargoToml { cargoToml = "${inputs.self}/Cargo.toml"; };
|
|
||||||
|
|
||||||
src =
|
|
||||||
let
|
|
||||||
# see https://crane.dev/API.html#cranelibfiltercargosources
|
|
||||||
#
|
|
||||||
# we need to keep the `web` directory which would be filtered out by the regular source filtering function
|
|
||||||
#
|
|
||||||
# https://crane.dev/API.html#cranelibcleancargosource
|
|
||||||
isWebTemplate = path: _type: builtins.match ".*(src/(web|service)|docs).*" path != null;
|
|
||||||
isRust = craneLib.filterCargoSources;
|
|
||||||
isNix = path: _type: builtins.match ".+/nix.*" path != null;
|
|
||||||
webOrRustNotNix = p: t: !(isNix p t) && (isWebTemplate p t || isRust p t);
|
|
||||||
in
|
|
||||||
lib.cleanSourceWith {
|
|
||||||
src = inputs.self;
|
|
||||||
filter = webOrRustNotNix;
|
|
||||||
name = "source";
|
|
||||||
};
|
|
||||||
|
|
||||||
# common attrs that are shared between building continuwuity's deps and the package itself
|
|
||||||
commonAttrs =
|
|
||||||
{
|
|
||||||
profile ? "dev",
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
{
|
|
||||||
inherit (crateInfo)
|
|
||||||
pname
|
|
||||||
version
|
|
||||||
;
|
|
||||||
inherit src;
|
|
||||||
|
|
||||||
# this prevents unnecessary rebuilds
|
|
||||||
strictDeps = true;
|
|
||||||
|
|
||||||
dontStrip = profile == "dev" || profile == "test";
|
|
||||||
dontPatchELF = profile == "dev" || profile == "test";
|
|
||||||
|
|
||||||
doCheck = true;
|
|
||||||
|
|
||||||
nativeBuildInputs = [
|
|
||||||
# bindgen needs the build platform's libclang. Apparently due to "splicing
|
|
||||||
# weirdness", pkgs.rustPlatform.bindgenHook on its own doesn't quite do the
|
|
||||||
# right thing here.
|
|
||||||
pkgs.rustPlatform.bindgenHook
|
|
||||||
];
|
|
||||||
};
|
|
||||||
|
|
||||||
makeRocksDBEnv =
|
|
||||||
{ rocksdb }:
|
|
||||||
{
|
|
||||||
ROCKSDB_INCLUDE_DIR = "${rocksdb}/include";
|
|
||||||
ROCKSDB_LIB_DIR = "${rocksdb}/lib";
|
|
||||||
};
|
|
||||||
|
|
||||||
# function that builds the continuwuity dependencies derivation
|
|
||||||
buildDeps =
|
|
||||||
{
|
|
||||||
rocksdb,
|
|
||||||
features,
|
|
||||||
commonAttrsArgs,
|
|
||||||
}:
|
|
||||||
craneLib.buildDepsOnly (
|
|
||||||
(commonAttrs commonAttrsArgs)
|
|
||||||
// {
|
|
||||||
env = uwuenv.buildDepsOnlyEnv
|
|
||||||
// (makeRocksDBEnv { inherit rocksdb; })
|
|
||||||
// {
|
|
||||||
# required since we started using unstable reqwest apparently ... otherwise the all-features build will fail
|
|
||||||
RUSTFLAGS = "--cfg reqwest_unstable";
|
|
||||||
};
|
|
||||||
inherit (features) cargoExtraArgs;
|
|
||||||
}
|
|
||||||
|
|
||||||
);
|
|
||||||
|
|
||||||
# function that builds the continuwuity package
|
|
||||||
buildPackage =
|
|
||||||
{
|
|
||||||
deps,
|
|
||||||
rocksdb,
|
|
||||||
features,
|
|
||||||
commonAttrsArgs,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
rocksdbEnv = makeRocksDBEnv { inherit rocksdb; };
|
|
||||||
in
|
|
||||||
craneLib.buildPackage (
|
|
||||||
(commonAttrs commonAttrsArgs)
|
|
||||||
// {
|
|
||||||
postFixup = ''
|
|
||||||
patchelf --set-rpath "$(${pkgs.patchelf}/bin/patchelf --print-rpath $out/bin/${crateInfo.pname}):${rocksdb}/lib" $out/bin/${crateInfo.pname}
|
|
||||||
'';
|
|
||||||
cargoArtifacts = deps;
|
|
||||||
doCheck = true;
|
|
||||||
env =
|
|
||||||
uwuenv.buildPackageEnv
|
|
||||||
// rocksdbEnv
|
|
||||||
// {
|
|
||||||
# required since we started using unstable reqwest apparently ... otherwise the all-features build will fail
|
|
||||||
RUSTFLAGS = "--cfg reqwest_unstable";
|
|
||||||
};
|
|
||||||
passthru.env = uwuenv.buildPackageEnv // rocksdbEnv;
|
|
||||||
meta.mainProgram = crateInfo.pname;
|
|
||||||
inherit (features) cargoExtraArgs;
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
flake.uwulib = {
|
|
||||||
init = pkgs: {
|
|
||||||
features = import ./features.nix { inherit pkgs inputs; };
|
|
||||||
environment = import ./environment.nix { inherit pkgs inputs; };
|
|
||||||
build = import ./build.nix { inherit pkgs inputs; };
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
args@{ pkgs, inputs, ... }:
|
|
||||||
let
|
|
||||||
uwubuild = import ./build.nix args;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
buildDepsOnlyEnv = {
|
|
||||||
# https://crane.dev/faq/rebuilds-bindgen.html
|
|
||||||
NIX_OUTPATH_USED_AS_RANDOM_SEED = "aaaaaaaaaa";
|
|
||||||
CARGO_PROFILE = "release";
|
|
||||||
}
|
|
||||||
// uwubuild.craneLib.mkCrossToolchainEnv (p: pkgs.clangStdenv);
|
|
||||||
|
|
||||||
buildPackageEnv = {
|
|
||||||
GIT_COMMIT_HASH = inputs.self.rev or inputs.self.dirtyRev or "";
|
|
||||||
GIT_COMMIT_HASH_SHORT = inputs.self.shortRev or inputs.self.dirtyShortRev or "";
|
|
||||||
}
|
|
||||||
// buildDepsOnlyEnv;
|
|
||||||
}
|
|
||||||
@@ -1,77 +0,0 @@
|
|||||||
{ pkgs, inputs, ... }:
|
|
||||||
let
|
|
||||||
inherit (pkgs) lib;
|
|
||||||
in
|
|
||||||
rec {
|
|
||||||
defaultDisabledFeatures = [
|
|
||||||
# dont include experimental features
|
|
||||||
"experimental"
|
|
||||||
# jemalloc profiling/stats features are expensive and shouldn't
|
|
||||||
# be expected on non-debug builds.
|
|
||||||
"jemalloc_prof"
|
|
||||||
"jemalloc_stats"
|
|
||||||
# this is non-functional on nix for some reason
|
|
||||||
"hardened_malloc"
|
|
||||||
# conduwuit_mods is a development-only hot reload feature
|
|
||||||
"conduwuit_mods"
|
|
||||||
# we don't want to enable this feature set by default but be more specific about it
|
|
||||||
"full"
|
|
||||||
];
|
|
||||||
# We perform default-feature unification in nix, because some of the dependencies
|
|
||||||
# on the nix side depend on feature values.
|
|
||||||
calcFeatures =
|
|
||||||
{
|
|
||||||
tomlPath ? "${inputs.self}/src/main",
|
|
||||||
# either a list of feature names or a string "all" which enables all non-default features
|
|
||||||
enabledFeatures ? [ ],
|
|
||||||
disabledFeatures ? defaultDisabledFeatures,
|
|
||||||
default_features ? true,
|
|
||||||
disable_release_max_log_level ? false,
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
# simple helper to get the contents of a Cargo.toml file in a nix format
|
|
||||||
getToml = path: lib.importTOML "${path}/Cargo.toml";
|
|
||||||
|
|
||||||
# get all the features except for the default features
|
|
||||||
allFeatures = lib.pipe tomlPath [
|
|
||||||
getToml
|
|
||||||
(manifest: manifest.features)
|
|
||||||
lib.attrNames
|
|
||||||
(lib.remove "default")
|
|
||||||
];
|
|
||||||
|
|
||||||
# get just the default enabled features
|
|
||||||
allDefaultFeatures = lib.pipe tomlPath [
|
|
||||||
getToml
|
|
||||||
(manifest: manifest.features.default)
|
|
||||||
];
|
|
||||||
|
|
||||||
# depending on the value of enabledFeatures choose just a set or all non-default features
|
|
||||||
#
|
|
||||||
# - [ list of features ] -> choose exactly the features listed
|
|
||||||
# - "all" -> choose all non-default features
|
|
||||||
additionalFeatures = if enabledFeatures == "all" then allFeatures else enabledFeatures;
|
|
||||||
|
|
||||||
# unification with default features (if enabled)
|
|
||||||
features = lib.unique (additionalFeatures ++ lib.optionals default_features allDefaultFeatures);
|
|
||||||
|
|
||||||
# prepare the features that are subtracted from the set
|
|
||||||
disabledFeatures' =
|
|
||||||
disabledFeatures ++ lib.optionals disable_release_max_log_level [ "release_max_log_level" ];
|
|
||||||
|
|
||||||
# construct the final feature set
|
|
||||||
finalFeatures = lib.subtractLists disabledFeatures' features;
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# final feature set, useful for querying it
|
|
||||||
features = finalFeatures;
|
|
||||||
|
|
||||||
# crane flag with the relevant features
|
|
||||||
cargoExtraArgs = builtins.concatStringsSep " " [
|
|
||||||
"--no-default-features"
|
|
||||||
"--locked"
|
|
||||||
(lib.optionalString (finalFeatures != [ ]) "--features")
|
|
||||||
(builtins.concatStringsSep "," finalFeatures)
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
perSystem =
|
||||||
|
{ pkgs, ... }:
|
||||||
|
{
|
||||||
|
apps.update-rocksdb = {
|
||||||
|
type = "app";
|
||||||
|
program = pkgs.writeShellApplication {
|
||||||
|
name = "update-rocksdb";
|
||||||
|
runtimeInputs = [ pkgs.nix-update ];
|
||||||
|
text = "nix-update rocksdb -F --version branch";
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@
|
|||||||
{
|
{
|
||||||
system,
|
system,
|
||||||
lib,
|
lib,
|
||||||
|
pkgs,
|
||||||
...
|
...
|
||||||
}:
|
}:
|
||||||
{
|
{
|
||||||
@@ -11,7 +12,7 @@
|
|||||||
let
|
let
|
||||||
fnx = inputs.fenix.packages.${system};
|
fnx = inputs.fenix.packages.${system};
|
||||||
|
|
||||||
stable = fnx.fromToolchainFile {
|
stable-toolchain = fnx.fromToolchainFile {
|
||||||
file = inputs.self + "/rust-toolchain.toml";
|
file = inputs.self + "/rust-toolchain.toml";
|
||||||
|
|
||||||
# See also `rust-toolchain.toml`
|
# See also `rust-toolchain.toml`
|
||||||
@@ -19,11 +20,10 @@
|
|||||||
};
|
};
|
||||||
in
|
in
|
||||||
{
|
{
|
||||||
# used for building nix stuff (doesn't include rustfmt overhead)
|
inherit stable-toolchain;
|
||||||
build-toolchain = stable;
|
|
||||||
# used for dev shells
|
|
||||||
dev-toolchain = fnx.combine [
|
dev-toolchain = fnx.combine [
|
||||||
stable
|
stable-toolchain
|
||||||
# use the nightly rustfmt because we use nightly features
|
# use the nightly rustfmt because we use nightly features
|
||||||
fnx.complete.rustfmt
|
fnx.complete.rustfmt
|
||||||
];
|
];
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
{ inputs, ... }:
|
|
||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
uwulib = inputs.self.uwulib.init pkgs;
|
|
||||||
rocksdbAllFeatures = self'.packages.rocksdb.override {
|
|
||||||
enableJemalloc = true;
|
|
||||||
};
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# basic nix shell containing all things necessary to build continuwuity in all flavors manually (on x86_64-linux)
|
|
||||||
devShells.default = uwulib.build.craneLib.devShell {
|
|
||||||
packages = [
|
|
||||||
pkgs.nodejs
|
|
||||||
pkgs.pkg-config
|
|
||||||
pkgs.liburing
|
|
||||||
pkgs.rust-jemalloc-sys-unprefixed
|
|
||||||
rocksdbAllFeatures
|
|
||||||
];
|
|
||||||
env.LIBCLANG_PATH = lib.makeLibraryPath [ pkgs.llvmPackages.libclang.lib ];
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -1,150 +0,0 @@
|
|||||||
{
|
|
||||||
perSystem =
|
|
||||||
{
|
|
||||||
self',
|
|
||||||
lib,
|
|
||||||
pkgs,
|
|
||||||
...
|
|
||||||
}:
|
|
||||||
let
|
|
||||||
baseTestScript =
|
|
||||||
pkgs.writers.writePython3Bin "do_test" { libraries = [ pkgs.python3Packages.matrix-nio ]; }
|
|
||||||
''
|
|
||||||
import asyncio
|
|
||||||
import nio
|
|
||||||
|
|
||||||
|
|
||||||
async def main() -> None:
|
|
||||||
# Connect to continuwuity
|
|
||||||
client = nio.AsyncClient("http://continuwuity:6167", "alice")
|
|
||||||
|
|
||||||
# Register as user alice
|
|
||||||
response = await client.register("alice", "my-secret-password")
|
|
||||||
|
|
||||||
# Log in as user alice
|
|
||||||
response = await client.login("my-secret-password")
|
|
||||||
|
|
||||||
# Create a new room
|
|
||||||
response = await client.room_create(federate=False)
|
|
||||||
print("Matrix room create response:", response)
|
|
||||||
assert isinstance(response, nio.RoomCreateResponse)
|
|
||||||
room_id = response.room_id
|
|
||||||
|
|
||||||
# Join the room
|
|
||||||
response = await client.join(room_id)
|
|
||||||
print("Matrix join response:", response)
|
|
||||||
assert isinstance(response, nio.JoinResponse)
|
|
||||||
|
|
||||||
# Send a message to the room
|
|
||||||
response = await client.room_send(
|
|
||||||
room_id=room_id,
|
|
||||||
message_type="m.room.message",
|
|
||||||
content={
|
|
||||||
"msgtype": "m.text",
|
|
||||||
"body": "Hello continuwuity!"
|
|
||||||
}
|
|
||||||
)
|
|
||||||
print("Matrix room send response:", response)
|
|
||||||
assert isinstance(response, nio.RoomSendResponse)
|
|
||||||
|
|
||||||
# Sync responses
|
|
||||||
response = await client.sync(timeout=30000)
|
|
||||||
print("Matrix sync response:", response)
|
|
||||||
assert isinstance(response, nio.SyncResponse)
|
|
||||||
|
|
||||||
# Check the message was received by continuwuity
|
|
||||||
last_message = response.rooms.join[room_id].timeline.events[-1].body
|
|
||||||
assert last_message == "Hello continuwuity!"
|
|
||||||
|
|
||||||
# Leave the room
|
|
||||||
response = await client.room_leave(room_id)
|
|
||||||
print("Matrix room leave response:", response)
|
|
||||||
assert isinstance(response, nio.RoomLeaveResponse)
|
|
||||||
|
|
||||||
# Close the client
|
|
||||||
await client.close()
|
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(main())
|
|
||||||
'';
|
|
||||||
in
|
|
||||||
{
|
|
||||||
# run some nixos tests as checks
|
|
||||||
checks = lib.pipe self'.packages [
|
|
||||||
# we take all packages (names)
|
|
||||||
builtins.attrNames
|
|
||||||
# we filter out all packages that end with `-bin` (which we are interested in for testing)
|
|
||||||
(builtins.filter (lib.hasSuffix "-bin"))
|
|
||||||
# for each of these binaries we built the basic nixos test
|
|
||||||
#
|
|
||||||
# this test was initially yoinked from
|
|
||||||
#
|
|
||||||
# https://github.com/NixOS/nixpkgs/blob/960ce26339661b1b69c6f12b9063ca51b688615f/nixos/tests/matrix/continuwuity.nix
|
|
||||||
(builtins.concatMap (
|
|
||||||
name:
|
|
||||||
builtins.map
|
|
||||||
(
|
|
||||||
{ config, suffix }:
|
|
||||||
{
|
|
||||||
name = "test-${name}-${suffix}";
|
|
||||||
value = pkgs.testers.runNixOSTest {
|
|
||||||
inherit name;
|
|
||||||
|
|
||||||
nodes = {
|
|
||||||
continuwuity = {
|
|
||||||
services.matrix-continuwuity = {
|
|
||||||
enable = true;
|
|
||||||
package = self'.packages.${name};
|
|
||||||
settings = config;
|
|
||||||
extraEnvironment.RUST_BACKTRACE = "yes";
|
|
||||||
};
|
|
||||||
networking.firewall.allowedTCPPorts = [ 6167 ];
|
|
||||||
};
|
|
||||||
client.environment.systemPackages = [ baseTestScript ];
|
|
||||||
};
|
|
||||||
|
|
||||||
testScript = ''
|
|
||||||
start_all()
|
|
||||||
|
|
||||||
with subtest("start continuwuity"):
|
|
||||||
continuwuity.wait_for_unit("continuwuity.service")
|
|
||||||
continuwuity.wait_for_open_port(6167)
|
|
||||||
|
|
||||||
with subtest("ensure messages can be exchanged"):
|
|
||||||
client.succeed("${lib.getExe baseTestScript} >&2")
|
|
||||||
'';
|
|
||||||
|
|
||||||
};
|
|
||||||
}
|
|
||||||
)
|
|
||||||
[
|
|
||||||
{
|
|
||||||
suffix = "base";
|
|
||||||
config = {
|
|
||||||
global = {
|
|
||||||
server_name = name;
|
|
||||||
address = [ "0.0.0.0" ];
|
|
||||||
allow_registration = true;
|
|
||||||
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
{
|
|
||||||
suffix = "with-room-version";
|
|
||||||
config = {
|
|
||||||
global = {
|
|
||||||
server_name = name;
|
|
||||||
address = [ "0.0.0.0" ];
|
|
||||||
allow_registration = true;
|
|
||||||
yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true;
|
|
||||||
default_room_version = "12";
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}
|
|
||||||
]
|
|
||||||
))
|
|
||||||
builtins.listToAttrs
|
|
||||||
];
|
|
||||||
};
|
|
||||||
}
|
|
||||||
@@ -425,7 +425,9 @@ pub async fn full_user_deactivate(
|
|||||||
// TODO: Redact all messages sent by the user in the room
|
// TODO: Redact all messages sent by the user in the room
|
||||||
}
|
}
|
||||||
|
|
||||||
super::update_all_rooms(services, pdu_queue, user_id).await;
|
super::update_all_rooms(services, pdu_queue, user_id)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
for room_id in all_joined_rooms {
|
for room_id in all_joined_rooms {
|
||||||
services.rooms.state_cache.forget(room_id, user_id);
|
services.rooms.state_cache.forget(room_id, user_id);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -462,6 +462,31 @@ async fn create_registration_uiaa_session(
|
|||||||
flows.push(untrusted_flow);
|
flows.push(untrusted_flow);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Require all users to agree to the terms and conditions, if configured
|
||||||
|
let terms = &services.config.registration_terms;
|
||||||
|
if !terms.is_empty() {
|
||||||
|
let mut terms =
|
||||||
|
serde_json::to_value(terms.clone()).expect("failed to serialize terms");
|
||||||
|
|
||||||
|
// Insert a dummy `version` field
|
||||||
|
for (_, documents) in terms.as_object_mut().unwrap() {
|
||||||
|
let documents = documents.as_object_mut().unwrap();
|
||||||
|
|
||||||
|
documents.insert("version".to_owned(), "latest".into());
|
||||||
|
}
|
||||||
|
|
||||||
|
params.insert(
|
||||||
|
AuthType::Terms.as_str().to_owned(),
|
||||||
|
serde_json::json!({
|
||||||
|
"policies": terms,
|
||||||
|
}),
|
||||||
|
);
|
||||||
|
|
||||||
|
for flow in &mut flows {
|
||||||
|
flow.stages.insert(0, AuthType::Terms);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if flows.is_empty() {
|
if flows.is_empty() {
|
||||||
// No flows are configured. Bail out by default
|
// No flows are configured. Bail out by default
|
||||||
// unless open registration was explicitly enabled.
|
// unless open registration was explicitly enabled.
|
||||||
|
|||||||
+56
-25
@@ -1,7 +1,9 @@
|
|||||||
|
use std::iter::once;
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum_client_ip::InsecureClientIp;
|
use axum_client_ip::InsecureClientIp;
|
||||||
use conduwuit::{
|
use conduwuit::{
|
||||||
Err, Event, Result, err, info,
|
Err, Event, Result, RoomVersion, err, info,
|
||||||
utils::{
|
utils::{
|
||||||
TryFutureExtExt,
|
TryFutureExtExt,
|
||||||
math::Expected,
|
math::Expected,
|
||||||
@@ -30,12 +32,14 @@ use ruma::{
|
|||||||
events::{
|
events::{
|
||||||
StateEventType,
|
StateEventType,
|
||||||
room::{
|
room::{
|
||||||
|
create::RoomCreateEventContent,
|
||||||
join_rules::{JoinRule, RoomJoinRulesEventContent},
|
join_rules::{JoinRule, RoomJoinRulesEventContent},
|
||||||
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
|
power_levels::{RoomPowerLevels, RoomPowerLevelsEventContent},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
uint,
|
uint,
|
||||||
};
|
};
|
||||||
|
use tokio::join;
|
||||||
|
|
||||||
use crate::Ruma;
|
use crate::Ruma;
|
||||||
|
|
||||||
@@ -339,36 +343,63 @@ pub(crate) async fn get_public_rooms_filtered_helper(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Check whether the user can publish to the room directory via power levels of
|
/// Checks whether the given user ID is allowed to publish the target room to
|
||||||
/// room history visibility event or room creator
|
/// the server's public room directory. Users are allowed to publish rooms if
|
||||||
|
/// they are server admins, room creators (in v12), or have the power level to
|
||||||
|
/// send `m.room.canonical_alias`.
|
||||||
async fn user_can_publish_room(
|
async fn user_can_publish_room(
|
||||||
services: &Services,
|
services: &Services,
|
||||||
user_id: &UserId,
|
user_id: &UserId,
|
||||||
room_id: &RoomId,
|
room_id: &RoomId,
|
||||||
) -> Result<bool> {
|
) -> Result<bool> {
|
||||||
match services
|
if services.users.is_admin(user_id).await {
|
||||||
.rooms
|
// Server admins can always publish to their own room directory.
|
||||||
.state_accessor
|
return Ok(true);
|
||||||
.room_state_get(room_id, &StateEventType::RoomPowerLevels, "")
|
}
|
||||||
.await
|
let (create_event, room_version, power_levels_content) = join!(
|
||||||
|
services
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.room_state_get(room_id, &StateEventType::RoomCreate, ""),
|
||||||
|
services.rooms.state.get_room_version(room_id),
|
||||||
|
services
|
||||||
|
.rooms
|
||||||
|
.state_accessor
|
||||||
|
.room_state_get_content::<RoomPowerLevelsEventContent>(
|
||||||
|
room_id,
|
||||||
|
&StateEventType::RoomPowerLevels,
|
||||||
|
""
|
||||||
|
)
|
||||||
|
);
|
||||||
|
let room_version = room_version
|
||||||
|
.as_ref()
|
||||||
|
.map_err(|_| err!(Request(NotFound("Unknown room"))))?;
|
||||||
|
let create_event = create_event.map_err(|_| err!(Request(NotFound("Unknown room"))))?;
|
||||||
|
if RoomVersion::new(room_version)
|
||||||
|
.expect("room version must be supported")
|
||||||
|
.explicitly_privilege_room_creators
|
||||||
{
|
{
|
||||||
| Ok(event) => serde_json::from_str(event.content().get())
|
let create_content: RoomCreateEventContent =
|
||||||
.map_err(|_| err!(Database("Invalid event content for m.room.power_levels")))
|
serde_json::from_str(create_event.content().get())
|
||||||
.map(|content: RoomPowerLevelsEventContent| {
|
.map_err(|_| err!(Database("Invalid event content for m.room.create")))?;
|
||||||
RoomPowerLevels::from(content)
|
let is_creator = create_content
|
||||||
.user_can_send_state(user_id, StateEventType::RoomHistoryVisibility)
|
.additional_creators
|
||||||
}),
|
.unwrap_or_default()
|
||||||
| _ => {
|
.into_iter()
|
||||||
match services
|
.chain(once(create_event.sender().to_owned()))
|
||||||
.rooms
|
.any(|sender| sender == user_id);
|
||||||
.state_accessor
|
if is_creator {
|
||||||
.room_state_get(room_id, &StateEventType::RoomCreate, "")
|
return Ok(true);
|
||||||
.await
|
}
|
||||||
{
|
}
|
||||||
| Ok(event) => Ok(event.sender() == user_id),
|
match power_levels_content.map(RoomPowerLevels::from) {
|
||||||
| _ => Err!(Request(Forbidden("User is not allowed to publish this room"))),
|
| Ok(pl) => Ok(pl.user_can_send_state(user_id, StateEventType::RoomCanonicalAlias)),
|
||||||
}
|
| Err(e) =>
|
||||||
},
|
if e.is_not_found() {
|
||||||
|
Ok(create_event.sender() == user_id)
|
||||||
|
} else {
|
||||||
|
Err!(Database("Invalid event content for m.room.power_levels: {e}"))
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -7,7 +7,7 @@ use conduwuit::{
|
|||||||
};
|
};
|
||||||
use conduwuit_service::Services;
|
use conduwuit_service::Services;
|
||||||
use futures::{
|
use futures::{
|
||||||
StreamExt, TryStreamExt,
|
FutureExt, StreamExt, TryStreamExt,
|
||||||
future::{join, join3, join4},
|
future::{join, join3, join4},
|
||||||
};
|
};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
@@ -51,6 +51,7 @@ pub(crate) async fn set_displayname_route(
|
|||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms)
|
update_displayname(&services, &body.user_id, body.displayname.clone(), &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if services.config.allow_local_presence {
|
if services.config.allow_local_presence {
|
||||||
@@ -149,6 +150,7 @@ pub(crate) async fn set_avatar_url_route(
|
|||||||
body.blurhash.clone(),
|
body.blurhash.clone(),
|
||||||
&all_joined_rooms,
|
&all_joined_rooms,
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
if services.config.allow_local_presence {
|
if services.config.allow_local_presence {
|
||||||
@@ -344,7 +346,9 @@ pub async fn update_displayname(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_all_rooms(services, all_joined_rooms, user_id).await;
|
update_all_rooms(services, all_joined_rooms, user_id)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_avatar_url(
|
pub async fn update_avatar_url(
|
||||||
@@ -394,7 +398,9 @@ pub async fn update_avatar_url(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_all_rooms(services, all_joined_rooms, user_id).await;
|
update_all_rooms(services, all_joined_rooms, user_id)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn update_all_rooms(
|
pub async fn update_all_rooms(
|
||||||
|
|||||||
@@ -137,6 +137,7 @@ pub(crate) async fn upgrade_room_route(
|
|||||||
Some(&body.room_id),
|
Some(&body.room_id),
|
||||||
&state_lock,
|
&state_lock,
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await?;
|
.await?;
|
||||||
// Change lock to replacement room
|
// Change lock to replacement room
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
|||||||
@@ -60,6 +60,7 @@ pub(crate) async fn send_state_event_for_key_route(
|
|||||||
None
|
None
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await?,
|
.await?,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ use std::collections::BTreeMap;
|
|||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use axum_client_ip::InsecureClientIp;
|
use axum_client_ip::InsecureClientIp;
|
||||||
use conduwuit::{Err, Result};
|
use conduwuit::{Err, Result};
|
||||||
use futures::StreamExt;
|
use futures::{FutureExt, StreamExt};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
OwnedRoomId,
|
OwnedRoomId,
|
||||||
api::{
|
api::{
|
||||||
@@ -112,6 +112,7 @@ pub(crate) async fn set_profile_key_route(
|
|||||||
Some(display_name.to_owned()),
|
Some(display_name.to_owned()),
|
||||||
&all_joined_rooms,
|
&all_joined_rooms,
|
||||||
)
|
)
|
||||||
|
.boxed()
|
||||||
.await;
|
.await;
|
||||||
} else if body.key_name == "avatar_url" {
|
} else if body.key_name == "avatar_url" {
|
||||||
let Some(avatar_url) = profile_key_value.as_str() else {
|
let Some(avatar_url) = profile_key_value.as_str() else {
|
||||||
@@ -127,7 +128,9 @@ pub(crate) async fn set_profile_key_route(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_avatar_url(&services, &body.user_id, Some(mxc), None, &all_joined_rooms).await;
|
update_avatar_url(&services, &body.user_id, Some(mxc), None, &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
} else {
|
} else {
|
||||||
services.users.set_profile_key(
|
services.users.set_profile_key(
|
||||||
&body.user_id,
|
&body.user_id,
|
||||||
@@ -178,7 +181,9 @@ pub(crate) async fn delete_profile_key_route(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_displayname(&services, &body.user_id, None, &all_joined_rooms).await;
|
update_displayname(&services, &body.user_id, None, &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
} else if body.key_name == "avatar_url" {
|
} else if body.key_name == "avatar_url" {
|
||||||
let all_joined_rooms: Vec<OwnedRoomId> = services
|
let all_joined_rooms: Vec<OwnedRoomId> = services
|
||||||
.rooms
|
.rooms
|
||||||
@@ -188,7 +193,9 @@ pub(crate) async fn delete_profile_key_route(
|
|||||||
.collect()
|
.collect()
|
||||||
.await;
|
.await;
|
||||||
|
|
||||||
update_avatar_url(&services, &body.user_id, None, None, &all_joined_rooms).await;
|
update_avatar_url(&services, &body.user_id, None, None, &all_joined_rooms)
|
||||||
|
.boxed()
|
||||||
|
.await;
|
||||||
} else {
|
} else {
|
||||||
services
|
services
|
||||||
.users
|
.users
|
||||||
|
|||||||
@@ -71,6 +71,7 @@ pub(crate) async fn well_known_support(
|
|||||||
|
|
||||||
let email_address = services.config.well_known.support_email.clone();
|
let email_address = services.config.well_known.support_email.clone();
|
||||||
let matrix_id = services.config.well_known.support_mxid.clone();
|
let matrix_id = services.config.well_known.support_mxid.clone();
|
||||||
|
let pgp_key = services.config.well_known.support_pgp_key.clone();
|
||||||
|
|
||||||
// TODO: support defining multiple contacts in the config
|
// TODO: support defining multiple contacts in the config
|
||||||
let mut contacts: Vec<Contact> = vec![];
|
let mut contacts: Vec<Contact> = vec![];
|
||||||
@@ -88,6 +89,7 @@ pub(crate) async fn well_known_support(
|
|||||||
role: role_value.clone(),
|
role: role_value.clone(),
|
||||||
email_address: email_address.clone(),
|
email_address: email_address.clone(),
|
||||||
matrix_id: matrix_id.clone(),
|
matrix_id: matrix_id.clone(),
|
||||||
|
pgp_key: pgp_key.clone(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -104,6 +106,7 @@ pub(crate) async fn well_known_support(
|
|||||||
role: role_value.clone(),
|
role: role_value.clone(),
|
||||||
email_address: None,
|
email_address: None,
|
||||||
matrix_id: Some(user_id.to_owned()),
|
matrix_id: Some(user_id.to_owned()),
|
||||||
|
pgp_key: None,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,11 +1,13 @@
|
|||||||
use std::borrow::ToOwned;
|
use std::borrow::ToOwned;
|
||||||
|
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Error, Result, debug, debug_info, info, matrix::pdu::PduBuilder, warn};
|
use conduwuit::{
|
||||||
|
Err, Error, Result, debug, debug_info, info, matrix::pdu::PduBuilder, utils, warn,
|
||||||
|
};
|
||||||
use conduwuit_service::Services;
|
use conduwuit_service::Services;
|
||||||
use futures::StreamExt;
|
use futures::StreamExt;
|
||||||
use ruma::{
|
use ruma::{
|
||||||
CanonicalJsonObject, OwnedUserId, RoomId, RoomVersionId, UserId,
|
OwnedUserId, RoomId, RoomVersionId, UserId,
|
||||||
api::{client::error::ErrorKind, federation::membership::prepare_join_event},
|
api::{client::error::ErrorKind, federation::membership::prepare_join_event},
|
||||||
events::{
|
events::{
|
||||||
StateEventType,
|
StateEventType,
|
||||||
@@ -40,6 +42,7 @@ pub(crate) async fn create_join_event_template_route(
|
|||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
origin = body.origin().as_str(),
|
origin = body.origin().as_str(),
|
||||||
|
room_id = %body.room_id,
|
||||||
"Refusing to serve make_join for room we aren't participating in"
|
"Refusing to serve make_join for room we aren't participating in"
|
||||||
);
|
);
|
||||||
return Err!(Request(NotFound("This server is not participating in that room.")));
|
return Err!(Request(NotFound("This server is not participating in that room.")));
|
||||||
@@ -133,10 +136,10 @@ pub(crate) async fn create_join_event_template_route(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_pdu, mut pdu_json) = services
|
let (pdu, _) = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
.create_hash_and_sign_event(
|
.create_event(
|
||||||
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {
|
PduBuilder::state(body.user_id.to_string(), &RoomMemberEventContent {
|
||||||
join_authorized_via_users_server,
|
join_authorized_via_users_server,
|
||||||
..RoomMemberEventContent::new(MembershipState::Join)
|
..RoomMemberEventContent::new(MembershipState::Join)
|
||||||
@@ -147,6 +150,8 @@ pub(crate) async fn create_join_event_template_route(
|
|||||||
)
|
)
|
||||||
.await?;
|
.await?;
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
let mut pdu_json = utils::to_canonical_object(&pdu)
|
||||||
|
.expect("Barebones PDU should be convertible to canonical JSON");
|
||||||
pdu_json.remove("event_id");
|
pdu_json.remove("event_id");
|
||||||
|
|
||||||
Ok(prepare_join_event::v1::Response {
|
Ok(prepare_join_event::v1::Response {
|
||||||
@@ -297,18 +302,3 @@ pub(crate) async fn user_can_perform_restricted_join(
|
|||||||
)))
|
)))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn maybe_strip_event_id(
|
|
||||||
pdu_json: &mut CanonicalJsonObject,
|
|
||||||
room_version_id: &RoomVersionId,
|
|
||||||
) -> Result {
|
|
||||||
use RoomVersionId::*;
|
|
||||||
|
|
||||||
match room_version_id {
|
|
||||||
| V1 | V2 => Ok(()),
|
|
||||||
| _ => {
|
|
||||||
pdu_json.remove("event_id");
|
|
||||||
Ok(())
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use RoomVersionId::*;
|
use RoomVersionId::*;
|
||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Error, Result, debug_warn, info, matrix::pdu::PduBuilder, warn};
|
use conduwuit::{Err, Error, Result, debug_warn, info, matrix::pdu::PduBuilder, utils, warn};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
RoomVersionId,
|
RoomVersionId,
|
||||||
api::{client::error::ErrorKind, federation::knock::create_knock_event_template},
|
api::{client::error::ErrorKind, federation::knock::create_knock_event_template},
|
||||||
@@ -28,6 +28,7 @@ pub(crate) async fn create_knock_event_template_route(
|
|||||||
{
|
{
|
||||||
info!(
|
info!(
|
||||||
origin = body.origin().as_str(),
|
origin = body.origin().as_str(),
|
||||||
|
room_id = %body.room_id,
|
||||||
"Refusing to serve make_knock for room we aren't participating in"
|
"Refusing to serve make_knock for room we aren't participating in"
|
||||||
);
|
);
|
||||||
return Err!(Request(NotFound("This server is not participating in that room.")));
|
return Err!(Request(NotFound("This server is not participating in that room.")));
|
||||||
@@ -98,10 +99,10 @@ pub(crate) async fn create_knock_event_template_route(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let (_pdu, mut pdu_json) = services
|
let (pdu, _) = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
.create_hash_and_sign_event(
|
.create_event(
|
||||||
PduBuilder::state(
|
PduBuilder::state(
|
||||||
body.user_id.to_string(),
|
body.user_id.to_string(),
|
||||||
&RoomMemberEventContent::new(MembershipState::Knock),
|
&RoomMemberEventContent::new(MembershipState::Knock),
|
||||||
@@ -113,9 +114,9 @@ pub(crate) async fn create_knock_event_template_route(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
let mut pdu_json = utils::to_canonical_object(&pdu)
|
||||||
// room v3 and above removed the "event_id" field from remote PDU format
|
.expect("Barebones PDU should be convertible to canonical JSON");
|
||||||
super::maybe_strip_event_id(&mut pdu_json, &room_version_id)?;
|
pdu_json.remove("event_id");
|
||||||
|
|
||||||
Ok(create_knock_event_template::v1::Response {
|
Ok(create_knock_event_template::v1::Response {
|
||||||
room_version: room_version_id,
|
room_version: room_version_id,
|
||||||
|
|||||||
@@ -1,12 +1,11 @@
|
|||||||
use axum::extract::State;
|
use axum::extract::State;
|
||||||
use conduwuit::{Err, Result, info, matrix::pdu::PduBuilder};
|
use conduwuit::{Err, Result, info, matrix::pdu::PduBuilder, utils};
|
||||||
use ruma::{
|
use ruma::{
|
||||||
api::federation::membership::prepare_leave_event,
|
api::federation::membership::prepare_leave_event,
|
||||||
events::room::member::{MembershipState, RoomMemberEventContent},
|
events::room::member::{MembershipState, RoomMemberEventContent},
|
||||||
};
|
};
|
||||||
use serde_json::value::to_raw_value;
|
use serde_json::value::to_raw_value;
|
||||||
|
|
||||||
use super::make_join::maybe_strip_event_id;
|
|
||||||
use crate::Ruma;
|
use crate::Ruma;
|
||||||
|
|
||||||
/// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}`
|
/// # `GET /_matrix/federation/v1/make_leave/{roomId}/{eventId}`
|
||||||
@@ -49,10 +48,10 @@ pub(crate) async fn create_leave_event_template_route(
|
|||||||
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
let room_version_id = services.rooms.state.get_room_version(&body.room_id).await?;
|
||||||
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
let state_lock = services.rooms.state.mutex.lock(&body.room_id).await;
|
||||||
|
|
||||||
let (_pdu, mut pdu_json) = services
|
let (pdu, _) = services
|
||||||
.rooms
|
.rooms
|
||||||
.timeline
|
.timeline
|
||||||
.create_hash_and_sign_event(
|
.create_event(
|
||||||
PduBuilder::state(
|
PduBuilder::state(
|
||||||
body.user_id.to_string(),
|
body.user_id.to_string(),
|
||||||
&RoomMemberEventContent::new(MembershipState::Leave),
|
&RoomMemberEventContent::new(MembershipState::Leave),
|
||||||
@@ -64,9 +63,9 @@ pub(crate) async fn create_leave_event_template_route(
|
|||||||
.await?;
|
.await?;
|
||||||
|
|
||||||
drop(state_lock);
|
drop(state_lock);
|
||||||
|
let mut pdu_json = utils::to_canonical_object(&pdu)
|
||||||
// room v3 and above removed the "event_id" field from remote PDU format
|
.expect("Barebones PDU should be convertible to canonical JSON");
|
||||||
maybe_strip_event_id(&mut pdu_json, &room_version_id)?;
|
pdu_json.remove("event_id");
|
||||||
|
|
||||||
Ok(prepare_leave_event::v1::Response {
|
Ok(prepare_leave_event::v1::Response {
|
||||||
room_version: Some(room_version_id),
|
room_version: Some(room_version_id),
|
||||||
|
|||||||
@@ -71,7 +71,7 @@ async fn create_join_event(
|
|||||||
let room_version_id = services.rooms.state.get_room_version(room_id).await?;
|
let room_version_id = services.rooms.state.get_room_version(room_id).await?;
|
||||||
|
|
||||||
trace!("Generating event ID and converting to canonical json");
|
trace!("Generating event ID and converting to canonical json");
|
||||||
let Ok((event_id, mut value)) = gen_event_id_canonical_json(pdu, &room_version_id) else {
|
let Ok((event_id, value)) = gen_event_id_canonical_json(pdu, &room_version_id) else {
|
||||||
// Event could not be converted to canonical json
|
// Event could not be converted to canonical json
|
||||||
return Err!(Request(BadJson("Could not convert event to canonical json.")));
|
return Err!(Request(BadJson("Could not convert event to canonical json.")));
|
||||||
};
|
};
|
||||||
@@ -189,12 +189,6 @@ async fn create_join_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
trace!("Signing send_join event");
|
|
||||||
services
|
|
||||||
.server_keys
|
|
||||||
.hash_and_sign_event(&mut value, &room_version_id)
|
|
||||||
.map_err(|e| err!(Request(InvalidParam(warn!("Failed to sign send_join event: {e}")))))?;
|
|
||||||
|
|
||||||
let mutex_lock = services
|
let mutex_lock = services
|
||||||
.rooms
|
.rooms
|
||||||
.event_handler
|
.event_handler
|
||||||
|
|||||||
+27
-2
@@ -4,7 +4,7 @@ pub mod manager;
|
|||||||
pub mod proxy;
|
pub mod proxy;
|
||||||
|
|
||||||
use std::{
|
use std::{
|
||||||
collections::{BTreeMap, BTreeSet},
|
collections::{BTreeMap, BTreeSet, HashMap},
|
||||||
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
net::{IpAddr, Ipv4Addr, Ipv6Addr, SocketAddr},
|
||||||
path::PathBuf,
|
path::PathBuf,
|
||||||
};
|
};
|
||||||
@@ -22,7 +22,7 @@ use ruma::{
|
|||||||
OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, RoomVersionId,
|
OwnedRoomId, OwnedRoomOrAliasId, OwnedServerName, OwnedUserId, RoomVersionId,
|
||||||
api::client::discovery::{discover_homeserver::RtcFocusInfo, discover_support::ContactRole},
|
api::client::discovery::{discover_homeserver::RtcFocusInfo, discover_support::ContactRole},
|
||||||
};
|
};
|
||||||
use serde::{Deserialize, de::IgnoredAny};
|
use serde::{Deserialize, Serialize, de::IgnoredAny};
|
||||||
use url::Url;
|
use url::Url;
|
||||||
|
|
||||||
use self::proxy::ProxyConfig;
|
use self::proxy::ProxyConfig;
|
||||||
@@ -655,6 +655,20 @@ pub struct Config {
|
|||||||
/// even if `recaptcha_site_key` is set.
|
/// even if `recaptcha_site_key` is set.
|
||||||
pub recaptcha_private_site_key: Option<String>,
|
pub recaptcha_private_site_key: Option<String>,
|
||||||
|
|
||||||
|
/// Policy documents, such as terms and conditions or a privacy policy,
|
||||||
|
/// which users must agree to when registering an account.
|
||||||
|
///
|
||||||
|
/// Example:
|
||||||
|
/// ```ignore
|
||||||
|
/// [global.registration_terms.privacy_policy]
|
||||||
|
/// en = { name = "Privacy Policy", url = "https://homeserver.example/en/privacy_policy.html" }
|
||||||
|
/// es = { name = "Política de Privacidad", url = "https://homeserver.example/es/privacy_policy.html" }
|
||||||
|
/// ```
|
||||||
|
///
|
||||||
|
/// default: {}
|
||||||
|
#[serde(default)]
|
||||||
|
pub registration_terms: HashMap<String, HashMap<String, TermsDocument>>,
|
||||||
|
|
||||||
/// Controls whether encrypted rooms and events are allowed.
|
/// Controls whether encrypted rooms and events are allowed.
|
||||||
#[serde(default = "true_fn")]
|
#[serde(default = "true_fn")]
|
||||||
pub allow_encryption: bool,
|
pub allow_encryption: bool,
|
||||||
@@ -2191,6 +2205,10 @@ pub struct WellKnownConfig {
|
|||||||
/// listed.
|
/// listed.
|
||||||
pub support_mxid: Option<OwnedUserId>,
|
pub support_mxid: Option<OwnedUserId>,
|
||||||
|
|
||||||
|
/// PGP key URI for server support contacts, to be served as part of the
|
||||||
|
/// MSC1929 server support endpoint.
|
||||||
|
pub support_pgp_key: Option<String>,
|
||||||
|
|
||||||
/// **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
/// **DEPRECATED**: Use `[global.matrix_rtc].foci` instead.
|
||||||
///
|
///
|
||||||
/// A list of MatrixRTC foci URLs which will be served as part of the
|
/// A list of MatrixRTC foci URLs which will be served as part of the
|
||||||
@@ -2494,6 +2512,13 @@ pub struct SmtpConfig {
|
|||||||
pub require_email_for_token_registration: bool,
|
pub require_email_for_token_registration: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// A policy document for use with a m.login.terms stage.
|
||||||
|
#[derive(Clone, Debug, Deserialize, Serialize)]
|
||||||
|
pub struct TermsDocument {
|
||||||
|
pub name: String,
|
||||||
|
pub url: String,
|
||||||
|
}
|
||||||
|
|
||||||
const DEPRECATED_KEYS: &[&str] = &[
|
const DEPRECATED_KEYS: &[&str] = &[
|
||||||
"cache_capacity",
|
"cache_capacity",
|
||||||
"conduit_cache_capacity_modifier",
|
"conduit_cache_capacity_modifier",
|
||||||
|
|||||||
@@ -70,17 +70,19 @@ fn descriptor_cf_options(
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut opts = opts
|
let opts = opts
|
||||||
.get_options_from_string("{{arena_block_size=2097152;}}")
|
.get_options_from_string("{{arena_block_size=2097152;}}")
|
||||||
.map_err(map_err)?;
|
.map_err(map_err)?;
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
let opts = opts
|
let opts = {
|
||||||
.get_options_from_string(
|
let mut opts = opts;
|
||||||
|
opts.get_options_from_string(
|
||||||
"{{paranoid_checks=true;paranoid_file_checks=true;force_consistency_checks=true;\
|
"{{paranoid_checks=true;paranoid_file_checks=true;force_consistency_checks=true;\
|
||||||
verify_sst_unique_id_in_manifest=true;}}",
|
verify_sst_unique_id_in_manifest=true;}}",
|
||||||
)
|
)
|
||||||
.map_err(map_err)?;
|
.map_err(map_err)?
|
||||||
|
};
|
||||||
|
|
||||||
Ok(opts)
|
Ok(opts)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::{
|
|||||||
use askama::Template;
|
use askama::Template;
|
||||||
use async_trait::async_trait;
|
use async_trait::async_trait;
|
||||||
use conduwuit::{Result, info, utils::ReadyExt};
|
use conduwuit::{Result, info, utils::ReadyExt};
|
||||||
use futures::StreamExt;
|
use futures::{FutureExt, StreamExt};
|
||||||
use ruma::{UserId, events::room::message::RoomMessageEventContent};
|
use ruma::{UserId, events::room::message::RoomMessageEventContent};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
@@ -133,7 +133,7 @@ impl Service {
|
|||||||
return Ok(false);
|
return Ok(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.services.admin.make_user_admin(user).await?;
|
self.services.admin.make_user_admin(user).boxed().await?;
|
||||||
|
|
||||||
// Send the welcome message
|
// Send the welcome message
|
||||||
let welcome_message = WelcomeMessage {
|
let welcome_message = WelcomeMessage {
|
||||||
|
|||||||
@@ -72,8 +72,6 @@ impl super::Service {
|
|||||||
if let Some(pos) = dest.as_str().find(':') {
|
if let Some(pos) = dest.as_str().find(':') {
|
||||||
self.actual_dest_2(dest, cache, pos).await?
|
self.actual_dest_2(dest, cache, pos).await?
|
||||||
} else {
|
} else {
|
||||||
self.conditional_query_and_cache(dest.as_str(), 8448, true)
|
|
||||||
.await?;
|
|
||||||
self.services.server.check_running()?;
|
self.services.server.check_running()?;
|
||||||
match self.request_well_known(dest.as_str()).await? {
|
match self.request_well_known(dest.as_str()).await? {
|
||||||
| Some(delegated) =>
|
| Some(delegated) =>
|
||||||
|
|||||||
@@ -56,36 +56,32 @@ pub fn pdu_fits(owned_obj: &mut CanonicalJsonObject) -> bool {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Pulls the room version ID out of the given (create) event.
|
||||||
|
fn room_version_from_event(
|
||||||
|
room_id: OwnedRoomId,
|
||||||
|
event_type: &TimelineEventType,
|
||||||
|
content: &RawValue,
|
||||||
|
) -> Result<RoomVersionId> {
|
||||||
|
if event_type == &TimelineEventType::RoomCreate {
|
||||||
|
let content: RoomCreateEventContent = serde_json::from_str(content.get())?;
|
||||||
|
Ok(content.room_version)
|
||||||
|
} else {
|
||||||
|
Err(Error::InconsistentRoomState(
|
||||||
|
"non-create event for room of unknown version",
|
||||||
|
room_id,
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Creates an event, but does not hash or sign it.
|
||||||
#[implement(super::Service)]
|
#[implement(super::Service)]
|
||||||
pub async fn create_hash_and_sign_event(
|
pub async fn create_event(
|
||||||
&self,
|
&self,
|
||||||
pdu_builder: PduBuilder,
|
pdu_builder: PduBuilder,
|
||||||
sender: &UserId,
|
sender: &UserId,
|
||||||
room_id: Option<&RoomId>,
|
room_id: Option<&RoomId>,
|
||||||
_mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room
|
_mutex_lock: &RoomMutexGuard,
|
||||||
* state mutex */
|
) -> Result<(PduEvent, RoomVersionId)> {
|
||||||
) -> Result<(PduEvent, CanonicalJsonObject)> {
|
|
||||||
#[allow(clippy::boxed_local)]
|
|
||||||
fn from_evt(
|
|
||||||
room_id: OwnedRoomId,
|
|
||||||
event_type: &TimelineEventType,
|
|
||||||
content: &RawValue,
|
|
||||||
) -> Result<RoomVersionId> {
|
|
||||||
if event_type == &TimelineEventType::RoomCreate {
|
|
||||||
let content: RoomCreateEventContent = serde_json::from_str(content.get())?;
|
|
||||||
Ok(content.room_version)
|
|
||||||
} else {
|
|
||||||
Err(Error::InconsistentRoomState(
|
|
||||||
"non-create event for room of unknown version",
|
|
||||||
room_id,
|
|
||||||
))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if !self.services.globals.user_is_local(sender) {
|
|
||||||
return Err!(Request(Forbidden("Sender must be a local user")));
|
|
||||||
}
|
|
||||||
|
|
||||||
let PduBuilder {
|
let PduBuilder {
|
||||||
event_type,
|
event_type,
|
||||||
content,
|
content,
|
||||||
@@ -108,12 +104,16 @@ pub async fn create_hash_and_sign_event(
|
|||||||
.get_room_version(room_id)
|
.get_room_version(room_id)
|
||||||
.await
|
.await
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
from_evt(room_id.to_owned(), &event_type.clone(), &content.clone())
|
room_version_from_event(
|
||||||
|
room_id.to_owned(),
|
||||||
|
&event_type.clone(),
|
||||||
|
&content.clone(),
|
||||||
|
)
|
||||||
})?
|
})?
|
||||||
},
|
},
|
||||||
| None => {
|
| None => {
|
||||||
trace!("No room ID, assuming room creation");
|
trace!("No room ID, assuming room creation");
|
||||||
from_evt(
|
room_version_from_event(
|
||||||
RoomId::new(self.services.globals.server_name()),
|
RoomId::new(self.services.globals.server_name()),
|
||||||
&event_type.clone(),
|
&event_type.clone(),
|
||||||
&content.clone(),
|
&content.clone(),
|
||||||
@@ -186,7 +186,7 @@ pub async fn create_hash_and_sign_event(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut pdu = PduEvent {
|
let pdu = PduEvent {
|
||||||
event_id: ruma::event_id!("$thiswillbefilledinlater").into(),
|
event_id: ruma::event_id!("$thiswillbefilledinlater").into(),
|
||||||
room_id: room_id.map(ToOwned::to_owned),
|
room_id: room_id.map(ToOwned::to_owned),
|
||||||
sender: sender.to_owned(),
|
sender: sender.to_owned(),
|
||||||
@@ -259,19 +259,29 @@ pub async fn create_hash_and_sign_event(
|
|||||||
pdu.event_id,
|
pdu.event_id,
|
||||||
pdu.room_id.as_ref().map_or("None", |id| id.as_str())
|
pdu.room_id.as_ref().map_or("None", |id| id.as_str())
|
||||||
);
|
);
|
||||||
|
Ok((pdu, room_version_id))
|
||||||
|
}
|
||||||
|
|
||||||
|
#[implement(super::Service)]
|
||||||
|
pub async fn create_hash_and_sign_event(
|
||||||
|
&self,
|
||||||
|
pdu_builder: PduBuilder,
|
||||||
|
sender: &UserId,
|
||||||
|
room_id: Option<&RoomId>,
|
||||||
|
mutex_lock: &RoomMutexGuard, /* Take mutex guard to make sure users get the room
|
||||||
|
* state mutex */
|
||||||
|
) -> Result<(PduEvent, CanonicalJsonObject)> {
|
||||||
|
if !self.services.globals.user_is_local(sender) {
|
||||||
|
return Err!(Request(Forbidden("Sender must be a local user")));
|
||||||
|
}
|
||||||
|
let (mut pdu, room_version_id) = self
|
||||||
|
.create_event(pdu_builder, sender, room_id, mutex_lock)
|
||||||
|
.await?;
|
||||||
// Hash and sign
|
// Hash and sign
|
||||||
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
|
let mut pdu_json = utils::to_canonical_object(&pdu).map_err(|e| {
|
||||||
err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}"))))
|
err!(Request(BadJson(warn!("Failed to convert PDU to canonical JSON: {e}"))))
|
||||||
})?;
|
})?;
|
||||||
|
pdu_json.remove("event_id");
|
||||||
// room v3 and above removed the "event_id" field from remote PDU format
|
|
||||||
match room_version_id {
|
|
||||||
| RoomVersionId::V1 | RoomVersionId::V2 => {},
|
|
||||||
| _ => {
|
|
||||||
pdu_json.remove("event_id");
|
|
||||||
},
|
|
||||||
}
|
|
||||||
|
|
||||||
trace!("hashing and signing event {}", pdu.event_id);
|
trace!("hashing and signing event {}", pdu.event_id);
|
||||||
if let Err(e) = self
|
if let Err(e) = self
|
||||||
|
|||||||
@@ -455,6 +455,7 @@ impl Service {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
| AuthData::Terms(_) => Ok(AuthType::Terms),
|
||||||
| _ => Err(StandardErrorBody {
|
| _ => Err(StandardErrorBody {
|
||||||
kind: ErrorKind::Unrecognized,
|
kind: ErrorKind::Unrecognized,
|
||||||
message: "Unsupported stage type".into(),
|
message: "Unsupported stage type".into(),
|
||||||
|
|||||||
Reference in New Issue
Block a user