Compare commits
57 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 4d43444865 | |||
| 04fc87ad07 | |||
| dc573f4562 | |||
| 74826dcb94 | |||
| b20c4e0539 | |||
| fb8a2846df | |||
| 04971d0430 | |||
| f098532b09 | |||
| 60927c1c72 | |||
| 03296412ab | |||
| 934ab6a4fe | |||
| 1378399f9d | |||
| 09680f653f | |||
| 39f19c483a | |||
| 39c0f4ea3d | |||
| 405167fc3f | |||
| b13ea4ff45 | |||
| 100fc5e0f7 | |||
| 96f9d64111 | |||
| 30ad5da5f1 | |||
| ce0ca96df4 | |||
| 4851ad26e2 | |||
| 328759a60f | |||
| 463fa4fd53 | |||
| db494e0d68 | |||
| 4788040458 | |||
| 06531993f6 | |||
| c29197b3f4 | |||
| 739eab46d5 | |||
| 923a98eb66 | |||
| 4430e4dee0 | |||
| d67f19a55d | |||
| b903b46d16 | |||
| 167559bb27 | |||
| 838e4b9d8d | |||
| 038b71fc9d | |||
| 720fbd09c2 | |||
| c42cb90dd3 | |||
| 5950355348 | |||
| f79bd2ac72 | |||
| 80ec0e31b1 | |||
| bda44b16b1 | |||
| e2280aa1a5 | |||
| bdf2de076a | |||
| 1797fec3c9 | |||
| 188fa5a073 | |||
| f0c63c539b | |||
| 649e9da1f8 | |||
| df28359a19 | |||
| 9370e93a8d | |||
| bdd5845490 | |||
| bacffd6174 | |||
| a1bfd7a018 | |||
| 7009f56a7a | |||
| 2c0bfac43e | |||
| fcb6c8a113 | |||
| 1ab77aeb91 |
+252
-14
@@ -27,6 +27,16 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
env:
|
||||
# sccache
|
||||
SCCACHE_GHA_ENABLED: "true"
|
||||
RUSTC_WRAPPER: "sccache"
|
||||
SCCACHE_BUCKET: "sccache"
|
||||
SCCACHE_S3_USE_SSL: ${{ vars.SCCACHE_S3_USE_SSL }}
|
||||
SCCACHE_REGION: ${{ vars.SCCACHE_REGION }}
|
||||
SCCACHE_ENDPOINT: ${{ vars.SCCACHE_ENDPOINT }}
|
||||
SCCACHE_CACHE_MULTIARCH: ${{ vars.SCCACHE_CACHE_MULTIARCH }}
|
||||
AWS_ACCESS_KEY_ID: ${{ secrets.AWS_ACCESS_KEY_ID }}
|
||||
AWS_SECRET_ACCESS_KEY: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
|
||||
# Required to make some things output color
|
||||
TERM: ansi
|
||||
# Publishing to my nix binary cache
|
||||
@@ -38,8 +48,11 @@ env:
|
||||
# Custom nix binary cache if fork is being used
|
||||
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
|
||||
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
|
||||
# Get error output from nix that we can actually use
|
||||
NIX_CONFIG: show-trace = true
|
||||
# Get error output from nix that we can actually use, and use our binary caches for the earlier CI steps
|
||||
NIX_CONFIG: |
|
||||
show-trace = true
|
||||
extra-substituters = https://attic.kennel.juneis.dog/conduit https://attic.kennel.juneis.dog/conduwuit https://cache.lix.systems https://conduwuit.cachix.org
|
||||
extra-trusted-public-keys = conduit:eEKoUwlQGDdYmAI/Q/0slVlegqh/QmAvQd7HBSm21Wk= conduwuit:BbycGUgTISsltcmH0qNjFR9dbrQNYgdIAcmViSGoVTE= cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o= conduwuit.cachix.org-1:MFRm6jcnfTf0jSAbmvLfhO3KBMt4px+1xaereWXp8Xg=
|
||||
|
||||
permissions:
|
||||
packages: write
|
||||
@@ -49,6 +62,8 @@ jobs:
|
||||
tests:
|
||||
name: Test
|
||||
runs-on: ubuntu-latest
|
||||
env:
|
||||
CARGO_PROFILE: "test"
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
@@ -57,7 +72,7 @@ jobs:
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Tag comparison check
|
||||
if: startsWith(github.ref, 'refs/tags/v')
|
||||
if: ${{ startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') }}
|
||||
run: |
|
||||
# Tag mismatch with latest repo tag check to prevent potential downgrades
|
||||
LATEST_TAG=$(git describe --tags `git rev-list --tags --max-count=1`)
|
||||
@@ -115,15 +130,38 @@ jobs:
|
||||
- name: Prepare build environment
|
||||
run: |
|
||||
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
||||
nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||
nix profile install --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||
direnv allow
|
||||
nix develop .#all-features --command true
|
||||
|
||||
- name: Cache CI dependencies
|
||||
run: |
|
||||
bin/nix-build-and-cache ci
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache ci
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# use sccache for Rust
|
||||
- name: Run sccache-cache
|
||||
uses: mozilla-actions/sccache-action@main
|
||||
|
||||
# use rust-cache
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
cache-all-crates: "true"
|
||||
|
||||
- name: Run CI tests
|
||||
run: |
|
||||
@@ -177,6 +215,10 @@ jobs:
|
||||
echo '```' >> $GITHUB_STEP_SUMMARY
|
||||
fi
|
||||
|
||||
- name: Run cargo clean test artifacts
|
||||
run: |
|
||||
cargo clean --profile test
|
||||
|
||||
build:
|
||||
name: Build
|
||||
runs-on: ubuntu-latest
|
||||
@@ -187,6 +229,9 @@ jobs:
|
||||
- target: aarch64-unknown-linux-musl
|
||||
- target: x86_64-unknown-linux-musl
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
|
||||
- name: Sync repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -237,16 +282,42 @@ jobs:
|
||||
- name: Prepare build environment
|
||||
run: |
|
||||
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
||||
nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||
nix profile install --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||
direnv allow
|
||||
nix develop .#all-features --command true
|
||||
|
||||
# use sccache for Rust
|
||||
- name: Run sccache-cache
|
||||
uses: mozilla-actions/sccache-action@main
|
||||
|
||||
# use rust-cache
|
||||
- uses: Swatinem/rust-cache@v2
|
||||
with:
|
||||
cache-all-crates: "true"
|
||||
|
||||
- name: Build static ${{ matrix.target }}
|
||||
run: |
|
||||
CARGO_DEB_TARGET_TUPLE=$(echo ${{ matrix.target }} | grep -o -E '^([^-]*-){3}[^-]*')
|
||||
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
|
||||
bin/nix-build-and-cache just .#static-${{ matrix.target }}-all-features
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache just .#static-${{ matrix.target }}-all-features
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
mkdir -v -p target/release/
|
||||
mkdir -v -p target/$CARGO_DEB_TARGET_TUPLE/release/
|
||||
cp -v -f result/bin/conduit target/release/conduwuit
|
||||
@@ -256,6 +327,66 @@ jobs:
|
||||
mv -v target/release/conduwuit static-${{ matrix.target }}
|
||||
mv -v target/release/${{ matrix.target }}.deb ${{ matrix.target }}.deb
|
||||
|
||||
# quick smoke test of the x86_64 static release binary
|
||||
- name: Run x86_64 static release binary
|
||||
run: |
|
||||
# GH actions default runners are x86_64 only
|
||||
if file result/bin/conduit | grep x86-64; then
|
||||
result/bin/conduit --version
|
||||
fi
|
||||
|
||||
- name: Build static debug ${{ matrix.target }}
|
||||
run: |
|
||||
CARGO_DEB_TARGET_TUPLE=$(echo ${{ matrix.target }} | grep -o -E '^([^-]*-){3}[^-]*')
|
||||
SOURCE_DATE_EPOCH=$(git log -1 --pretty=%ct)
|
||||
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache just .#static-${{ matrix.target }}-all-features-debug
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# > warning: dev profile is not supported and will be a hard error in the future. cargo-deb is for making releases, and it doesn't make sense to use it with dev profiles.
|
||||
# so we need to coerce cargo-deb into thinking this is a release binary
|
||||
mkdir -v -p target/release/
|
||||
mkdir -v -p target/$CARGO_DEB_TARGET_TUPLE/release/
|
||||
cp -v -f result/bin/conduit target/release/conduwuit
|
||||
cp -v -f result/bin/conduit target/$CARGO_DEB_TARGET_TUPLE/release/conduwuit
|
||||
# -p conduit is the main crate name
|
||||
direnv exec . cargo deb --verbose --no-build --no-strip -p conduit --target=$CARGO_DEB_TARGET_TUPLE --output target/release/${{ matrix.target }}-debug.deb
|
||||
mv -v target/release/conduwuit static-${{ matrix.target }}-debug
|
||||
mv -v target/release/${{ matrix.target }}-debug.deb ${{ matrix.target }}-debug.deb
|
||||
|
||||
# quick smoke test of the x86_64 static debug binary
|
||||
- name: Run x86_64 static debug binary
|
||||
run: |
|
||||
# GH actions default runners are x86_64 only
|
||||
if file result/bin/conduit | grep x86-64; then
|
||||
result/bin/conduit --version
|
||||
fi
|
||||
|
||||
# check validity of produced deb package, invalid debs will error on these commands
|
||||
- name: Validate produced deb package
|
||||
run: |
|
||||
# List contents
|
||||
dpkg-deb --contents ${{ matrix.target }}.deb
|
||||
dpkg-deb --contents ${{ matrix.target }}-debug.deb
|
||||
# List info
|
||||
dpkg-deb --info ${{ matrix.target }}.deb
|
||||
dpkg-deb --info ${{ matrix.target }}-debug.deb
|
||||
|
||||
- name: Upload static-${{ matrix.target }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -271,11 +402,65 @@ jobs:
|
||||
if-no-files-found: error
|
||||
compression-level: 0
|
||||
|
||||
- name: Upload static-${{ matrix.target }}-debug
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: static-${{ matrix.target }}-debug
|
||||
path: static-${{ matrix.target }}-debug
|
||||
if-no-files-found: error
|
||||
|
||||
- name: Upload deb ${{ matrix.target }}-debug
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: deb-${{ matrix.target }}-debug
|
||||
path: ${{ matrix.target }}-debug.deb
|
||||
if-no-files-found: error
|
||||
compression-level: 0
|
||||
|
||||
- name: Build OCI image ${{ matrix.target }}
|
||||
run: |
|
||||
bin/nix-build-and-cache just .#oci-image-${{ matrix.target }}-all-features
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache just .#oci-image-${{ matrix.target }}-all-features
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -v -f result oci-image-${{ matrix.target }}.tar.gz
|
||||
|
||||
- name: Build debug OCI image ${{ matrix.target }}
|
||||
run: |
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache just .#oci-image-${{ matrix.target }}-all-features-debug
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -v -f result oci-image-${{ matrix.target }}-debug.tar.gz
|
||||
|
||||
- name: Upload OCI image ${{ matrix.target }}
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
@@ -284,6 +469,14 @@ jobs:
|
||||
if-no-files-found: error
|
||||
compression-level: 0
|
||||
|
||||
- name: Upload OCI image ${{ matrix.target }}-debug
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: oci-image-${{ matrix.target }}-debug
|
||||
path: oci-image-${{ matrix.target }}-debug.tar.gz
|
||||
if-no-files-found: error
|
||||
compression-level: 0
|
||||
|
||||
docker:
|
||||
name: Docker publish
|
||||
runs-on: ubuntu-latest
|
||||
@@ -293,15 +486,15 @@ jobs:
|
||||
DOCKER_ARM64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||
DOCKER_AMD64: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||
DOCKER_TAG: docker.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
||||
DOCKER_BRANCH: docker.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||
DOCKER_BRANCH: docker.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||
GHCR_ARM64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||
GHCR_AMD64: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||
GHCR_TAG: ghcr.io/${{ github.repository }}:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
||||
GHCR_BRANCH: ghcr.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||
GHCR_BRANCH: ghcr.io/${{ github.repository }}:${{ (startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||
GLCR_ARM64: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-arm64v8
|
||||
GLCR_AMD64: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}-amd64
|
||||
GLCR_TAG: registry.gitlab.com/conduwuit/conduwuit:${{ (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}-${{ github.sha }}
|
||||
GLCR_BRANCH: registry.gitlab.com/conduwuit/conduwuit:${{ (startsWith(github.ref, 'refs/tags/v') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||
GLCR_BRANCH: registry.gitlab.com/conduwuit/conduwuit:${{ (startsWith(github.ref, 'refs/tags/v') && !endsWith(github.ref, '-rc') && 'latest') || (github.head_ref != '' && format('merge-{0}-{1}', github.event.number, github.event.pull_request.user.login)) || github.ref_name }}
|
||||
|
||||
DOCKERHUB_TOKEN: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }}
|
||||
@@ -334,8 +527,10 @@ jobs:
|
||||
|
||||
- name: Move OCI images into position
|
||||
run: |
|
||||
mv -v oci-image-x86_64-*/*.tar.gz oci-image-amd64.tar.gz
|
||||
mv -v oci-image-aarch64-*/*.tar.gz oci-image-arm64v8.tar.gz
|
||||
mv -v oci-image-x86_64-unknown-linux-musl/*.tar.gz oci-image-amd64.tar.gz
|
||||
mv -v oci-image-aarch64-unknown-linux-musl/*.tar.gz oci-image-arm64v8.tar.gz
|
||||
mv -v oci-image-x86_64-unknown-linux-musl-debug/*.tar.gz oci-image-amd64-debug.tar.gz
|
||||
mv -v oci-image-aarch64-unknown-linux-musl-debug/*.tar.gz oci-image-arm64v8-debug.tar.gz
|
||||
|
||||
- name: Load and push amd64 image
|
||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||
@@ -359,6 +554,28 @@ jobs:
|
||||
docker push ${{ env.GHCR_ARM64 }}
|
||||
docker push ${{ env.GLCR_ARM64 }}
|
||||
|
||||
- name: Load and push amd64 debug image
|
||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||
run: |
|
||||
docker load -i oci-image-amd64-debug.tar.gz
|
||||
docker tag $(docker images -q conduit:main) ${{ env.DOCKER_AMD64 }}-debug
|
||||
docker tag $(docker images -q conduit:main) ${{ env.GHCR_AMD64 }}-debug
|
||||
docker tag $(docker images -q conduit:main) ${{ env.GLCR_AMD64 }}-debug
|
||||
docker push ${{ env.DOCKER_AMD64 }}-debug
|
||||
docker push ${{ env.GHCR_AMD64 }}-debug
|
||||
docker push ${{ env.GLCR_AMD64 }}-debug
|
||||
|
||||
- name: Load and push arm64 debug image
|
||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||
run: |
|
||||
docker load -i oci-image-arm64v8-debug.tar.gz
|
||||
docker tag $(docker images -q conduit:main) ${{ env.DOCKER_ARM64 }}-debug
|
||||
docker tag $(docker images -q conduit:main) ${{ env.GHCR_ARM64 }}-debug
|
||||
docker tag $(docker images -q conduit:main) ${{ env.GLCR_ARM64 }}-debug
|
||||
docker push ${{ env.DOCKER_ARM64 }}-debug
|
||||
docker push ${{ env.GHCR_ARM64 }}-debug
|
||||
docker push ${{ env.GLCR_ARM64 }}-debug
|
||||
|
||||
- name: Create Docker combined manifests
|
||||
run: |
|
||||
# Dockerhub Container Registry
|
||||
@@ -368,9 +585,21 @@ jobs:
|
||||
docker manifest create ${{ env.GHCR_TAG }} --amend ${{ env.GHCR_ARM64 }} --amend ${{ env.GHCR_AMD64 }}
|
||||
docker manifest create ${{ env.GHCR_BRANCH }} --amend ${{ env.GHCR_ARM64 }} --amend ${{ env.GHCR_AMD64 }}
|
||||
# GitLab Container Registry
|
||||
docker manifest create ${{ env.GLCR_TAG }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GCCR_AMD64 }}
|
||||
docker manifest create ${{ env.GLCR_TAG }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GLCR_AMD64 }}
|
||||
docker manifest create ${{ env.GLCR_BRANCH }} --amend ${{ env.GLCR_ARM64 }} --amend ${{ env.GLCR_AMD64 }}
|
||||
|
||||
- name: Create Docker combined debug manifests
|
||||
run: |
|
||||
# Dockerhub Container Registry
|
||||
docker manifest create ${{ env.DOCKER_TAG }}-debug --amend ${{ env.DOCKER_ARM64 }}-debug --amend ${{ env.DOCKER_AMD64 }}-debug
|
||||
docker manifest create ${{ env.DOCKER_BRANCH }}-debug --amend ${{ env.DOCKER_ARM64 }}-debug --amend ${{ env.DOCKER_AMD64 }}-debug
|
||||
# GitHub Container Registry
|
||||
docker manifest create ${{ env.GHCR_TAG }}-debug --amend ${{ env.GHCR_ARM64 }}-debug --amend ${{ env.GHCR_AMD64 }}-debug
|
||||
docker manifest create ${{ env.GHCR_BRANCH }}-debug --amend ${{ env.GHCR_ARM64 }}-debug --amend ${{ env.GHCR_AMD64 }}-debug
|
||||
# GitLab Container Registry
|
||||
docker manifest create ${{ env.GLCR_TAG }}-debug --amend ${{ env.GLCR_ARM64 }}-debug --amend ${{ env.GLCR_AMD64 }}-debug
|
||||
docker manifest create ${{ env.GLCR_BRANCH }}-debug --amend ${{ env.GLCR_ARM64 }}-debug --amend ${{ env.GLCR_AMD64 }}-debug
|
||||
|
||||
- name: Push manifests to Docker registries
|
||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||
run: |
|
||||
@@ -380,6 +609,12 @@ jobs:
|
||||
docker manifest push ${{ env.GHCR_BRANCH }}
|
||||
docker manifest push ${{ env.GLCR_TAG }}
|
||||
docker manifest push ${{ env.GLCR_BRANCH }}
|
||||
docker manifest push ${{ env.DOCKER_TAG }}-debug
|
||||
docker manifest push ${{ env.DOCKER_BRANCH }}-debug
|
||||
docker manifest push ${{ env.GHCR_TAG }}-debug
|
||||
docker manifest push ${{ env.GHCR_BRANCH }}-debug
|
||||
docker manifest push ${{ env.GLCR_TAG }}-debug
|
||||
docker manifest push ${{ env.GLCR_BRANCH }}-debug
|
||||
|
||||
- name: Add Image Links to Job Summary
|
||||
if: ${{ (vars.DOCKER_USERNAME != '') && (env.DOCKERHUB_TOKEN != '') }}
|
||||
@@ -387,3 +622,6 @@ jobs:
|
||||
echo "- \`docker pull ${{ env.DOCKER_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`docker pull ${{ env.GHCR_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`docker pull ${{ env.GLCR_TAG }}\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`docker pull ${{ env.DOCKER_TAG }}-debug\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`docker pull ${{ env.GHCR_TAG }}-debug\`" >> $GITHUB_STEP_SUMMARY
|
||||
echo "- \`docker pull ${{ env.GLCR_TAG }}-debug\`" >> $GITHUB_STEP_SUMMARY
|
||||
|
||||
@@ -21,8 +21,11 @@ env:
|
||||
# Custom nix binary cache if fork is being used
|
||||
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
|
||||
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
|
||||
# Get error output from nix that we can actually use
|
||||
NIX_CONFIG: show-trace = true
|
||||
# Get error output from nix that we can actually use, and use our binary caches for the earlier CI steps
|
||||
NIX_CONFIG: |
|
||||
show-trace = true
|
||||
extra-substituters = https://attic.kennel.juneis.dog/conduit https://attic.kennel.juneis.dog/conduwuit https://cache.lix.systems https://conduwuit.cachix.org
|
||||
extra-trusted-public-keys = conduit:eEKoUwlQGDdYmAI/Q/0slVlegqh/QmAvQd7HBSm21Wk= conduwuit:BbycGUgTISsltcmH0qNjFR9dbrQNYgdIAcmViSGoVTE= cache.lix.systems:aBnZUw8zA7H35Cz2RyKFVs3H4PlGTLawyY5KRbvJR8o= conduwuit.cachix.org-1:MFRm6jcnfTf0jSAbmvLfhO3KBMt4px+1xaereWXp8Xg=
|
||||
|
||||
# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
|
||||
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
|
||||
@@ -44,6 +47,9 @@ jobs:
|
||||
url: ${{ steps.deployment.outputs.page_url }}
|
||||
|
||||
steps:
|
||||
- name: Free Disk Space (Ubuntu)
|
||||
uses: jlumbroso/free-disk-space@main
|
||||
|
||||
- name: Sync repository
|
||||
uses: actions/checkout@v4
|
||||
|
||||
@@ -98,13 +104,29 @@ jobs:
|
||||
- name: Prepare build environment
|
||||
run: |
|
||||
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
|
||||
nix profile install --impure --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||
nix profile install --inputs-from . nixpkgs#direnv nixpkgs#nix-direnv
|
||||
direnv allow
|
||||
nix develop --command true
|
||||
|
||||
- name: Cache CI dependencies
|
||||
run: |
|
||||
bin/nix-build-and-cache ci
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache ci
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
- name: Run lychee and markdownlint
|
||||
run: |
|
||||
@@ -113,8 +135,26 @@ jobs:
|
||||
|
||||
- name: Build documentation (book)
|
||||
run: |
|
||||
./bin/nix-build-and-cache just .#book
|
||||
cp -r --dereference result public
|
||||
# attic nix binary cache server is very, very terribly flakey. nothing i can do to fix it other than retry multiple times here
|
||||
ATTEMPTS=3
|
||||
SUCCESS=false
|
||||
while (( ATTEMPTS-- > 0 ))
|
||||
do
|
||||
bin/nix-build-and-cache just .#book
|
||||
if [[ $? == 0 ]]; then
|
||||
SUCCESS=true
|
||||
break
|
||||
else
|
||||
sleep 3
|
||||
fi
|
||||
done
|
||||
|
||||
if [[ $SUCCESS == "false" ]]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
cp -r --dereference result public
|
||||
|
||||
- name: Upload generated documentation (book) as normal artifact
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
|
||||
@@ -39,6 +39,7 @@ The following binaries are used in [`engage.toml`][engage.toml]:
|
||||
- [`cargo-deb`][cargo-deb]
|
||||
- [`lychee`][lychee]
|
||||
- [`markdownlint-cli`][markdownlint-cli]
|
||||
- `dpkg`
|
||||
|
||||
### Matrix tests
|
||||
|
||||
|
||||
Generated
+122
-116
@@ -85,9 +85,9 @@ checksum = "5f093eed78becd229346bf859eec0aa4dd7ddde0757287b2b4107a1f09c80002"
|
||||
|
||||
[[package]]
|
||||
name = "async-compression"
|
||||
version = "0.4.11"
|
||||
version = "0.4.12"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "cd066d0b4ef8ecb03a55319dc13aa6910616d0f44008a045bb1835af830abff5"
|
||||
checksum = "fec134f64e2bc57411226dfc4e52dec859ddfc7e711fc5e07b612584f000e4aa"
|
||||
dependencies = [
|
||||
"brotli",
|
||||
"flate2",
|
||||
@@ -118,7 +118,7 @@ checksum = "16e62a023e7c117e27523144c5d2459f4397fcc3cab0085af8e2224f643a0193"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -129,7 +129,7 @@ checksum = "6e0c28dcc82d7c8ead5cb13beb15405b57b8546e93215673ff8ca0349a028107"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -377,7 +377,7 @@ dependencies = [
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -474,13 +474,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "cc"
|
||||
version = "1.1.3"
|
||||
version = "1.1.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "18e2d530f35b40a84124146478cd16f34225306a8441998836466a2e2961c950"
|
||||
checksum = "2aba8f4e9906c7ce3c73463f62a7f0c65183ada1a2d47e397cc8810827f9694f"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"once_cell",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -562,7 +561,7 @@ dependencies = [
|
||||
"heck 0.5.0",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -579,7 +578,7 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b"
|
||||
|
||||
[[package]]
|
||||
name = "conduit"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"conduit_admin",
|
||||
@@ -608,7 +607,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "conduit_admin"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"clap",
|
||||
"conduit_api",
|
||||
@@ -627,7 +626,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "conduit_api"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"axum 0.7.5",
|
||||
"axum-client-ip",
|
||||
@@ -661,7 +660,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "conduit_core"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"argon2",
|
||||
"axum 0.7.5",
|
||||
@@ -703,7 +702,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "conduit_database"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"conduit_core",
|
||||
"const-str",
|
||||
@@ -715,7 +714,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "conduit_router"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"axum 0.7.5",
|
||||
"axum-client-ip",
|
||||
@@ -746,7 +745,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "conduit_service"
|
||||
version = "0.4.5"
|
||||
version = "0.4.6"
|
||||
dependencies = [
|
||||
"async-trait",
|
||||
"base64 0.22.1",
|
||||
@@ -769,7 +768,6 @@ dependencies = [
|
||||
"regex",
|
||||
"reqwest",
|
||||
"ruma",
|
||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=fd686e77950680462377c9105dfb4136dd49c7a0)",
|
||||
"rustyline-async",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -972,7 +970,7 @@ dependencies = [
|
||||
"crossterm_winapi",
|
||||
"futures-core",
|
||||
"libc",
|
||||
"mio",
|
||||
"mio 0.8.11",
|
||||
"parking_lot",
|
||||
"signal-hook",
|
||||
"signal-hook-mio",
|
||||
@@ -1022,7 +1020,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1126,7 +1124,7 @@ dependencies = [
|
||||
"heck 0.4.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1262,7 +1260,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1543,7 +1541,7 @@ dependencies = [
|
||||
"markup5ever",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1747,12 +1745,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "image"
|
||||
version = "0.25.1"
|
||||
version = "0.25.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fd54d660e773627692c524beaad361aca785a4f9f5730ce91f42aabe5bce3d11"
|
||||
checksum = "99314c8a2152b8ddb211f924cdae532d8c5e4c8bb54728e12fff1b0cd5963a10"
|
||||
dependencies = [
|
||||
"bytemuck",
|
||||
"byteorder",
|
||||
"byteorder-lite",
|
||||
"color_quant",
|
||||
"gif",
|
||||
"image-webp",
|
||||
@@ -1764,12 +1762,12 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "image-webp"
|
||||
version = "0.1.2"
|
||||
version = "0.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d730b085583c4d789dfd07fdcf185be59501666a90c97c40162b37e4fdad272d"
|
||||
checksum = "f79afb8cbee2ef20f59ccd477a218c12a93943d075b492015ecb1bb81f8ee904"
|
||||
dependencies = [
|
||||
"byteorder-lite",
|
||||
"thiserror",
|
||||
"quick-error 2.0.1",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1952,7 +1950,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1975,9 +1973,9 @@ checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.4"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e310b3a6b5907f99202fcdb4960ff45b93735d7c7d96b760fcff8db2dc0e103d"
|
||||
checksum = "4979f22fdb869068da03c9f7528f8297c6fd2606bc3a4affe42e6a823fdb8da4"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets 0.52.6",
|
||||
@@ -2033,9 +2031,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "lz4-sys"
|
||||
version = "1.9.5"
|
||||
version = "1.10.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e9764018d143cc854c9f17f0b907de70f14393b1f502da6375dce70f00514eb3"
|
||||
checksum = "109de74d5d2353660401699a4174a4ff23fcc649caf553df71933c7fb45ad868"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"libc",
|
||||
@@ -2149,6 +2147,18 @@ dependencies = [
|
||||
"windows-sys 0.48.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "mio"
|
||||
version = "1.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4569e456d394deccd22ce1c1913e6ea0e54519f577285001215d33557431afe4"
|
||||
dependencies = [
|
||||
"hermit-abi",
|
||||
"libc",
|
||||
"wasi",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "new_debug_unreachable"
|
||||
version = "1.0.6"
|
||||
@@ -2461,7 +2471,7 @@ dependencies = [
|
||||
"proc-macro2",
|
||||
"proc-macro2-diagnostics",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2554,7 +2564,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2642,7 +2652,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"version_check",
|
||||
"yansi",
|
||||
]
|
||||
@@ -2667,7 +2677,7 @@ dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2703,6 +2713,12 @@ version = "1.2.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0"
|
||||
|
||||
[[package]]
|
||||
name = "quick-error"
|
||||
version = "2.0.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3"
|
||||
|
||||
[[package]]
|
||||
name = "quinn"
|
||||
version = "0.11.2"
|
||||
@@ -2739,14 +2755,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "quinn-udp"
|
||||
version = "0.5.2"
|
||||
version = "0.5.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9096629c45860fc7fb143e125eb826b5e721e10be3263160c7d60ca832cf8c46"
|
||||
checksum = "8bffec3605b73c6f1754535084a85229fa8a30f86014e6c81aeec4abb68b0285"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"once_cell",
|
||||
"socket2",
|
||||
"tracing",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
@@ -2791,9 +2806,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.5.2"
|
||||
version = "0.5.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c82cf8cff14456045f55ec4241383baeff27af886adb72ffb2162f99911de0fd"
|
||||
checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
]
|
||||
@@ -2898,7 +2913,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "52e44394d2086d010551b14b53b1f24e31647570cd1deb0379e2c21b329aba00"
|
||||
dependencies = [
|
||||
"hostname 0.3.1",
|
||||
"quick-error",
|
||||
"quick-error 1.2.3",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -2919,7 +2934,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma"
|
||||
version = "0.10.1"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"assign",
|
||||
"js_int",
|
||||
@@ -2929,6 +2944,7 @@ dependencies = [
|
||||
"ruma-common",
|
||||
"ruma-events",
|
||||
"ruma-federation-api",
|
||||
"ruma-identifiers-validation",
|
||||
"ruma-identity-service-api",
|
||||
"ruma-push-gateway-api",
|
||||
"ruma-server-util",
|
||||
@@ -2940,7 +2956,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-appservice-api"
|
||||
version = "0.10.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -2952,7 +2968,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-client-api"
|
||||
version = "0.18.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"assign",
|
||||
@@ -2975,7 +2991,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-common"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"base64 0.22.1",
|
||||
@@ -2988,7 +3004,7 @@ dependencies = [
|
||||
"percent-encoding",
|
||||
"rand",
|
||||
"regex",
|
||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5)",
|
||||
"ruma-identifiers-validation",
|
||||
"ruma-macros",
|
||||
"serde",
|
||||
"serde_html_form",
|
||||
@@ -3005,7 +3021,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-events"
|
||||
version = "0.28.1"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"as_variant",
|
||||
"indexmap 2.2.6",
|
||||
@@ -3015,7 +3031,7 @@ dependencies = [
|
||||
"pulldown-cmark",
|
||||
"regex",
|
||||
"ruma-common",
|
||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5)",
|
||||
"ruma-identifiers-validation",
|
||||
"ruma-macros",
|
||||
"serde",
|
||||
"serde_json",
|
||||
@@ -3028,7 +3044,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-federation-api"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -3040,16 +3056,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-identifiers-validation"
|
||||
version = "0.9.5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"thiserror",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruma-identifiers-validation"
|
||||
version = "0.9.5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=fd686e77950680462377c9105dfb4136dd49c7a0#fd686e77950680462377c9105dfb4136dd49c7a0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"thiserror",
|
||||
@@ -3058,7 +3065,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-identity-service-api"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -3068,22 +3075,22 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-macros"
|
||||
version = "0.13.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro-crate",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"ruma-identifiers-validation 0.9.5 (git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5)",
|
||||
"ruma-identifiers-validation",
|
||||
"serde",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"toml",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "ruma-push-gateway-api"
|
||||
version = "0.9.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"js_int",
|
||||
"ruma-common",
|
||||
@@ -3095,7 +3102,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-server-util"
|
||||
version = "0.3.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"headers",
|
||||
"http 1.1.0",
|
||||
@@ -3108,7 +3115,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-signatures"
|
||||
version = "0.15.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"base64 0.22.1",
|
||||
"ed25519-dalek",
|
||||
@@ -3124,7 +3131,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "ruma-state-res"
|
||||
version = "0.11.0"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c51ccb2c68d2e3557eb12b1a49036531711ec0e5#c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
source = "git+https://github.com/girlbossceo/ruwuma?rev=c76e2873c1593a3308d4ba3e0e4a1db65acf8536#c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
dependencies = [
|
||||
"itertools 0.12.1",
|
||||
"js_int",
|
||||
@@ -3138,8 +3145,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rust-librocksdb-sys"
|
||||
version = "0.23.1+9.3.1"
|
||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=db1ba33c2b78ad228e2525e8902d059c24fc81a1#db1ba33c2b78ad228e2525e8902d059c24fc81a1"
|
||||
version = "0.24.0+9.4.0"
|
||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=4056a3b0f823013fec49f6d0b3e5698856e6476a#4056a3b0f823013fec49f6d0b3e5698856e6476a"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"bzip2-sys",
|
||||
@@ -3155,8 +3162,8 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rust-rocksdb"
|
||||
version = "0.27.1"
|
||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=db1ba33c2b78ad228e2525e8902d059c24fc81a1#db1ba33c2b78ad228e2525e8902d059c24fc81a1"
|
||||
version = "0.28.0"
|
||||
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=4056a3b0f823013fec49f6d0b3e5698856e6476a#4056a3b0f823013fec49f6d0b3e5698856e6476a"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"rust-librocksdb-sys",
|
||||
@@ -3212,7 +3219,7 @@ dependencies = [
|
||||
"log",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki 0.102.5",
|
||||
"rustls-webpki 0.102.6",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -3227,7 +3234,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
"rustls-webpki 0.102.5",
|
||||
"rustls-webpki 0.102.6",
|
||||
"subtle",
|
||||
"zeroize",
|
||||
]
|
||||
@@ -3273,9 +3280,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "rustls-webpki"
|
||||
version = "0.102.5"
|
||||
version = "0.102.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f9a6fccd794a42c2c105b513a2f62bc3fd8f3ba57a4593677ceb0bd035164d78"
|
||||
checksum = "8e6b52d4fda176fd835fdc55a835d4a89b8499cad995885a21149d5ad62f852e"
|
||||
dependencies = [
|
||||
"ring",
|
||||
"rustls-pki-types",
|
||||
@@ -3352,9 +3359,9 @@ checksum = "4646d6f919800cd25c50edb49438a1381e2cd4833c027e75e8897981c50b8b5e"
|
||||
|
||||
[[package]]
|
||||
name = "security-framework"
|
||||
version = "2.11.0"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c627723fd09706bacdb5cf41499e95098555af3c3c29d014dc3c458ef6be11c0"
|
||||
checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"core-foundation",
|
||||
@@ -3365,9 +3372,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "security-framework-sys"
|
||||
version = "2.11.0"
|
||||
version = "2.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "317936bbbd05227752583946b9e66d7ce3b489f84e11a94a510b4437fef407d7"
|
||||
checksum = "75da29fe9b9b08fe9d6b22b5b4bcbc75d8db3aa31e639aa56bb62e9d46bfceaf"
|
||||
dependencies = [
|
||||
"core-foundation-sys",
|
||||
"libc",
|
||||
@@ -3531,7 +3538,7 @@ checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -3677,7 +3684,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "29ad2e15f37ec9a6cc544097b78a1ec90001e9f71b81338ca39f430adaca99af"
|
||||
dependencies = [
|
||||
"libc",
|
||||
"mio",
|
||||
"mio 0.8.11",
|
||||
"signal-hook",
|
||||
]
|
||||
|
||||
@@ -3824,9 +3831,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.71"
|
||||
version = "2.0.72"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b146dcf730474b4bcd16c311627b31ede9ab149045db4d6088b3becaea046462"
|
||||
checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
@@ -3884,22 +3891,22 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "thiserror"
|
||||
version = "1.0.62"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "f2675633b1499176c2dff06b0856a27976a8f9d436737b4cf4f312d4d91d8bbb"
|
||||
checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724"
|
||||
dependencies = [
|
||||
"thiserror-impl",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "thiserror-impl"
|
||||
version = "1.0.62"
|
||||
version = "1.0.63"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d20468752b09f49e909e55a5d338caa8bedf615594e9d80bc4c565d30faf798c"
|
||||
checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4013,21 +4020,20 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20"
|
||||
|
||||
[[package]]
|
||||
name = "tokio"
|
||||
version = "1.38.0"
|
||||
version = "1.39.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a"
|
||||
checksum = "d040ac2b29ab03b09d4129c2f5bbd012a3ac2f79d38ff506a4bf8dd34b0eac8a"
|
||||
dependencies = [
|
||||
"backtrace",
|
||||
"bytes",
|
||||
"libc",
|
||||
"mio",
|
||||
"num_cpus",
|
||||
"mio 1.0.1",
|
||||
"pin-project-lite",
|
||||
"signal-hook-registry",
|
||||
"socket2",
|
||||
"tokio-macros",
|
||||
"tracing",
|
||||
"windows-sys 0.48.0",
|
||||
"windows-sys 0.52.0",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4042,13 +4048,13 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "tokio-macros"
|
||||
version = "2.3.0"
|
||||
version = "2.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a"
|
||||
checksum = "693d596312e88961bc67d7f1f97af8a70227d9f90c31bba5806eec004978d752"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4122,14 +4128,14 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml"
|
||||
version = "0.8.14"
|
||||
version = "0.8.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6f49eb2ab21d2f26bd6db7bf383edc527a7ebaee412d17af4d40fdccd442f335"
|
||||
checksum = "ac2caab0bf757388c6c0ae23b3293fdb463fee59434529014f85e3263b995c28"
|
||||
dependencies = [
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"toml_edit 0.22.15",
|
||||
"toml_edit 0.22.16",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4154,15 +4160,15 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "toml_edit"
|
||||
version = "0.22.15"
|
||||
version = "0.22.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d59a3a72298453f564e2b111fa896f8d07fabb36f51f06d7e875fc5e0b5a3ef1"
|
||||
checksum = "278f3d518e152219c994ce877758516bca5e118eaed6996192a774fb9fbf0788"
|
||||
dependencies = [
|
||||
"indexmap 2.2.6",
|
||||
"serde",
|
||||
"serde_spanned",
|
||||
"toml_datetime",
|
||||
"winnow 0.6.13",
|
||||
"winnow 0.6.15",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -4250,7 +4256,7 @@ checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52"
|
||||
[[package]]
|
||||
name = "tracing"
|
||||
version = "0.1.40"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
dependencies = [
|
||||
"log",
|
||||
"pin-project-lite",
|
||||
@@ -4261,17 +4267,17 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tracing-attributes"
|
||||
version = "0.1.27"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "tracing-core"
|
||||
version = "0.1.32"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
dependencies = [
|
||||
"once_cell",
|
||||
"valuable",
|
||||
@@ -4291,7 +4297,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tracing-log"
|
||||
version = "0.2.0"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
dependencies = [
|
||||
"log",
|
||||
"once_cell",
|
||||
@@ -4319,7 +4325,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "tracing-subscriber"
|
||||
version = "0.3.18"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=b348dca742af641c47bc390261f60711c2af573c#b348dca742af641c47bc390261f60711c2af573c"
|
||||
source = "git+https://github.com/girlbossceo/tracing?rev=4d78a14a5e03f539b8c6b475aefa08bb14e4de91#4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
dependencies = [
|
||||
"matchers",
|
||||
"nu-ansi-term",
|
||||
@@ -4535,7 +4541,7 @@ dependencies = [
|
||||
"once_cell",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
|
||||
@@ -4569,7 +4575,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"syn 2.0.71",
|
||||
"syn 2.0.72",
|
||||
"wasm-bindgen-backend",
|
||||
"wasm-bindgen-shared",
|
||||
]
|
||||
@@ -4840,9 +4846,9 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "winnow"
|
||||
version = "0.6.13"
|
||||
version = "0.6.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "59b5e5f6c299a3c7890b876a2a587f3115162487e704907d9b6cd29473052ba1"
|
||||
checksum = "557404e450152cd6795bb558bca69e43c585055f4606e3bcae5894fc6dac9ba0"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
@@ -4926,9 +4932,9 @@ checksum = "3f423a2c17029964870cfaabb1f13dfab7d092a62a29a89264f4d36990ca414a"
|
||||
|
||||
[[package]]
|
||||
name = "zune-jpeg"
|
||||
version = "0.4.11"
|
||||
version = "0.4.13"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "ec866b44a2a1fd6133d363f073ca1b179f438f99e7e5bfb1e33f7181facfe448"
|
||||
checksum = "16099418600b4d8f028622f73ff6e3deaabdff330fb9a2a131dea781ee8b0768"
|
||||
dependencies = [
|
||||
"zune-core",
|
||||
]
|
||||
|
||||
+42
-29
@@ -14,13 +14,13 @@ categories = ["network-programming"]
|
||||
description = "a very cool fork of Conduit, a Matrix homeserver written in Rust"
|
||||
edition = "2021"
|
||||
homepage = "https://conduwuit.puppyirl.gay/"
|
||||
keywords = ["chat", "matrix", "server"]
|
||||
keywords = ["chat", "matrix", "server", "uwu"]
|
||||
license = "Apache-2.0"
|
||||
# See also `rust-toolchain.toml`
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/girlbossceo/conduwuit"
|
||||
rust-version = "1.77.0"
|
||||
version = "0.4.5"
|
||||
rust-version = "1.80.0"
|
||||
version = "0.4.6"
|
||||
|
||||
[workspace.metadata.crane]
|
||||
name = "conduit"
|
||||
@@ -188,7 +188,7 @@ version = "0.3.30"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.tokio]
|
||||
version = "1.38.0"
|
||||
version = "1.39.1"
|
||||
features = [
|
||||
"fs",
|
||||
"net",
|
||||
@@ -204,7 +204,7 @@ features = [
|
||||
version = "0.3.1"
|
||||
|
||||
[workspace.dependencies.libloading]
|
||||
version = "0.8.3"
|
||||
version = "0.8.5"
|
||||
|
||||
# Validating urls in config, was already a transitive dependency
|
||||
[workspace.dependencies.url]
|
||||
@@ -218,7 +218,7 @@ features = ["alloc", "std"]
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.hyper]
|
||||
version = "1.4.0"
|
||||
version = "1.4.1"
|
||||
features = [
|
||||
"server",
|
||||
"http1",
|
||||
@@ -251,7 +251,7 @@ default-features = false
|
||||
|
||||
# Used for conduit::Error type
|
||||
[workspace.dependencies.thiserror]
|
||||
version = "1.0.62"
|
||||
version = "1.0.63"
|
||||
|
||||
# Used when hashing the state
|
||||
[workspace.dependencies.ring]
|
||||
@@ -280,7 +280,7 @@ version = "0.1.2"
|
||||
[workspace.dependencies.ruma]
|
||||
git = "https://github.com/girlbossceo/ruwuma"
|
||||
#branch = "conduwuit-changes"
|
||||
rev = "c51ccb2c68d2e3557eb12b1a49036531711ec0e5"
|
||||
rev = "c76e2873c1593a3308d4ba3e0e4a1db65acf8536"
|
||||
features = [
|
||||
"compat",
|
||||
"rand",
|
||||
@@ -293,6 +293,7 @@ features = [
|
||||
"server-util",
|
||||
"unstable-exhaustive-types",
|
||||
"ring-compat",
|
||||
"identifiers-validation",
|
||||
"unstable-unspecified",
|
||||
"unstable-msc2448",
|
||||
"unstable-msc2666",
|
||||
@@ -307,10 +308,6 @@ features = [
|
||||
"unstable-extensible-events",
|
||||
]
|
||||
|
||||
[workspace.dependencies.ruma-identifiers-validation]
|
||||
git = "https://github.com/girlbossceo/ruwuma"
|
||||
rev = "fd686e77950680462377c9105dfb4136dd49c7a0"
|
||||
|
||||
[workspace.dependencies.rust-rocksdb]
|
||||
path = "deps/rust-rocksdb"
|
||||
package = "rust-rocksdb-uwu"
|
||||
@@ -372,16 +369,17 @@ version = "0.34.0"
|
||||
version = "0.34.0"
|
||||
|
||||
# jemalloc usage
|
||||
# locked to 0.5.4 due to static binary linking breakage
|
||||
[workspace.dependencies.tikv-jemalloc-sys]
|
||||
version = "0.5.4"
|
||||
version = "=0.5.4"
|
||||
default-features = false
|
||||
features = ["stats", "unprefixed_malloc_on_supported_platforms"]
|
||||
[workspace.dependencies.tikv-jemallocator]
|
||||
version = "0.5.4"
|
||||
version = "=0.6.0"
|
||||
default-features = false
|
||||
features = ["stats", "unprefixed_malloc_on_supported_platforms"]
|
||||
[workspace.dependencies.tikv-jemalloc-ctl]
|
||||
version = "0.5.4"
|
||||
version = "=0.5.4"
|
||||
default-features = false
|
||||
features = ["use_std"]
|
||||
|
||||
@@ -405,8 +403,8 @@ features = [
|
||||
]
|
||||
|
||||
[workspace.dependencies.rustyline-async]
|
||||
git = "https://github.com/girlbossceo/rustyline-async"
|
||||
rev = "de26100b0db03e419a3d8e1dd26895d170d1fe50"
|
||||
version = "0.4.2"
|
||||
default-features = false
|
||||
|
||||
[workspace.dependencies.termimad]
|
||||
version = "0.29.4"
|
||||
@@ -425,16 +423,16 @@ version = "0.1"
|
||||
# https://github.com/girlbossceo/tracing/commit/b348dca742af641c47bc390261f60711c2af573c
|
||||
[patch.crates-io.tracing-subscriber]
|
||||
git = "https://github.com/girlbossceo/tracing"
|
||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
||||
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
[patch.crates-io.tracing]
|
||||
git = "https://github.com/girlbossceo/tracing"
|
||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
||||
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
[patch.crates-io.tracing-core]
|
||||
git = "https://github.com/girlbossceo/tracing"
|
||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
||||
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
[patch.crates-io.tracing-log]
|
||||
git = "https://github.com/girlbossceo/tracing"
|
||||
rev = "b348dca742af641c47bc390261f60711c2af573c"
|
||||
rev = "4d78a14a5e03f539b8c6b475aefa08bb14e4de91"
|
||||
|
||||
# fixes hyper graceful shutdowns [https://github.com/programatik29/axum-server/issues/114]
|
||||
# https://github.com/girlbossceo/axum-server/commit/8e3368d899079818934e61cc9c839abcbbcada8a
|
||||
@@ -442,6 +440,12 @@ rev = "b348dca742af641c47bc390261f60711c2af573c"
|
||||
git = "https://github.com/girlbossceo/axum-server"
|
||||
rev = "8e3368d899079818934e61cc9c839abcbbcada8a"
|
||||
|
||||
# adds a tab completion callback: https://github.com/girlbossceo/rustyline-async/commit/de26100b0db03e419a3d8e1dd26895d170d1fe50
|
||||
# adds event for CTRL+\: https://github.com/girlbossceo/rustyline-async/commit/67d8c49aeac03a5ef4e818f663eaa94dd7bf339b
|
||||
[patch.crates-io.rustyline-async]
|
||||
git = "https://github.com/girlbossceo/rustyline-async"
|
||||
rev = "de26100b0db03e419a3d8e1dd26895d170d1fe50"
|
||||
|
||||
#
|
||||
# Our crates
|
||||
#
|
||||
@@ -653,7 +657,16 @@ opt-level = 'z'
|
||||
# '-Clink-arg=-Wl,-z,nodelete',
|
||||
#]
|
||||
|
||||
# primarily used for CI
|
||||
[profile.test]
|
||||
inherits = "dev"
|
||||
codegen-units = 16
|
||||
incremental = false
|
||||
|
||||
[profile.test.package.'*']
|
||||
inherits = "dev"
|
||||
debug = 0
|
||||
codegen-units = 16
|
||||
incremental = false
|
||||
|
||||
###############################################################################
|
||||
@@ -715,19 +728,19 @@ variant_size_differences = "allow"
|
||||
[workspace.lints.clippy]
|
||||
|
||||
###################
|
||||
cargo = "warn"
|
||||
cargo = { level = "warn", priority = -1 }
|
||||
|
||||
## some sadness
|
||||
multiple_crate_versions = { level = "allow", priority = 1 }
|
||||
|
||||
###################
|
||||
complexity = "warn"
|
||||
complexity = { level = "warn", priority = -1 }
|
||||
|
||||
###################
|
||||
correctness = "warn"
|
||||
correctness = { level = "warn", priority = -1 }
|
||||
|
||||
###################
|
||||
nursery = "warn"
|
||||
nursery = { level = "warn", priority = -1 }
|
||||
|
||||
## some sadness
|
||||
missing_const_for_fn = { level = "allow", priority = 1 } # TODO
|
||||
@@ -737,7 +750,7 @@ significant_drop_in_scrutinee = { level = "allow", priority = 1 } # TODO
|
||||
significant_drop_tightening = { level = "allow", priority = 1 } # TODO
|
||||
|
||||
###################
|
||||
pedantic = "warn"
|
||||
pedantic = { level = "warn", priority = -1 }
|
||||
|
||||
## some sadness
|
||||
doc_markdown = { level = "allow", priority = 1 }
|
||||
@@ -756,7 +769,7 @@ unnecessary_wraps = { level = "allow", priority = 1 }
|
||||
unused_async = { level = "allow", priority = 1 }
|
||||
|
||||
###################
|
||||
perf = "warn"
|
||||
perf = { level = "warn", priority = -1 }
|
||||
|
||||
###################
|
||||
#restriction = "warn"
|
||||
@@ -806,14 +819,14 @@ unseparated_literal_suffix = "warn"
|
||||
verbose_file_reads = "warn"
|
||||
|
||||
###################
|
||||
style = "warn"
|
||||
style = { level = "warn", priority = -1 }
|
||||
|
||||
## some sadness
|
||||
# trivial assertions are quite alright
|
||||
assertions_on_constants = { level = "allow", priority = 1 }
|
||||
|
||||
###################
|
||||
suspicious = "warn"
|
||||
suspicious = { level = "warn", priority = -1 }
|
||||
|
||||
## some sadness
|
||||
let_underscore_future = { level = "allow", priority = 1 }
|
||||
|
||||
@@ -52,9 +52,10 @@
|
||||
|
||||
# Performance monitoring/tracing sample rate for Sentry.io
|
||||
#
|
||||
# Note that too high values may impact performance, and can be disabled by setting it to 0.0
|
||||
# Note that too high values may impact performance, and can be disabled by setting it to 0.0 (0%)
|
||||
# This value is read as a percentage to Sentry, represented as a decimal
|
||||
#
|
||||
# Defaults to 0.15
|
||||
# Defaults to 15% of traces (0.15)
|
||||
#sentry_traces_sample_rate = 0.15
|
||||
|
||||
# Whether to attach a stacktrace to Sentry reports.
|
||||
@@ -401,7 +402,7 @@ allow_profile_lookup_federation_requests = true
|
||||
# setting this to false may reduce startup time.
|
||||
#
|
||||
# Enabled by default.
|
||||
#media_statup_check = true
|
||||
#media_startup_check = true
|
||||
|
||||
# OpenID token expiration/TTL in seconds
|
||||
#
|
||||
@@ -421,8 +422,11 @@ allow_profile_lookup_federation_requests = true
|
||||
|
||||
# Set this to any float value to multiply conduwuit's in-memory LRU caches with.
|
||||
# May be useful if you have significant memory to spare to increase performance.
|
||||
#
|
||||
# This was previously called `conduit_cache_capacity_modifier`
|
||||
#
|
||||
# Defaults to 1.0.
|
||||
#conduit_cache_capacity_modifier = 1.0
|
||||
#cache_capacity_modifier = 1.0
|
||||
|
||||
# Set this to any float value in megabytes for conduwuit to tell the database engine that this much memory is available for database-related caches.
|
||||
# May be useful if you have significant memory to spare to increase performance.
|
||||
|
||||
Vendored
+1
-1
@@ -27,7 +27,7 @@ malloc-usable-size = ["rust-rocksdb/malloc-usable-size"]
|
||||
|
||||
[dependencies.rust-rocksdb]
|
||||
git = "https://github.com/zaidoon1/rust-rocksdb"
|
||||
rev = "db1ba33c2b78ad228e2525e8902d059c24fc81a1"
|
||||
rev = "4056a3b0f823013fec49f6d0b3e5698856e6476a"
|
||||
#branch = "master"
|
||||
default-features = false
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ Otherwise, follow standard Rust project build guides (installing git and cloning
|
||||
While conduwuit can run as any user it is better to use dedicated users for different services. This also allows
|
||||
you to make sure that the file permissions are correctly set up.
|
||||
|
||||
In Debian or RHEL, you can use this command to create a conduwuit user:
|
||||
In Debian or Fedora/RHEL, you can use this command to create a conduwuit user:
|
||||
|
||||
```bash
|
||||
sudo adduser --system conduwuit --group --disabled-login --no-create-home
|
||||
@@ -53,13 +53,11 @@ RocksDB is the only supported database backend.
|
||||
|
||||
## Setting the correct file permissions
|
||||
|
||||
If you are using a dedicated user for conduwuit, you will need to allow it to read the config. To do that you can run this command on
|
||||
|
||||
Debian or RHEL:
|
||||
If you are using a dedicated user for conduwuit, you will need to allow it to read the config. To do that you can run this:
|
||||
|
||||
```bash
|
||||
sudo chown -R root:root /etc/conduwuit
|
||||
sudo chmod 755 /etc/conduwuit
|
||||
sudo chmod -R 755 /etc/conduwuit
|
||||
```
|
||||
|
||||
If you use the default database path you also need to run this:
|
||||
|
||||
+22
-3
@@ -60,6 +60,11 @@ name = "markdownlint"
|
||||
group = "versions"
|
||||
script = "markdownlint --version"
|
||||
|
||||
[[task]]
|
||||
name = "dpkg"
|
||||
group = "versions"
|
||||
script = "dpkg --version"
|
||||
|
||||
[[task]]
|
||||
name = "cargo-audit"
|
||||
group = "security"
|
||||
@@ -68,7 +73,9 @@ script = "cargo audit -D warnings -D unmaintained -D unsound -D yanked"
|
||||
[[task]]
|
||||
name = "cargo-fmt"
|
||||
group = "lints"
|
||||
script = "cargo fmt --check -- --color=always"
|
||||
script = """
|
||||
cargo fmt --check -- --color=always
|
||||
"""
|
||||
|
||||
[[task]]
|
||||
name = "cargo-doc"
|
||||
@@ -79,6 +86,7 @@ env DIRENV_DEVSHELL=all-features \
|
||||
direnv exec . \
|
||||
cargo doc \
|
||||
--workspace \
|
||||
--profile test \
|
||||
--all-features \
|
||||
--no-deps \
|
||||
--document-private-items \
|
||||
@@ -91,6 +99,7 @@ group = "lints"
|
||||
script = """
|
||||
cargo clippy \
|
||||
--workspace \
|
||||
--profile test \
|
||||
--all-targets \
|
||||
--color=always \
|
||||
-- \
|
||||
@@ -105,6 +114,7 @@ env DIRENV_DEVSHELL=all-features \
|
||||
direnv exec . \
|
||||
cargo clippy \
|
||||
--workspace \
|
||||
--profile test \
|
||||
--all-targets \
|
||||
--all-features \
|
||||
--color=always \
|
||||
@@ -118,6 +128,7 @@ group = "lints"
|
||||
script = """
|
||||
cargo clippy \
|
||||
--workspace \
|
||||
--profile test \
|
||||
--features jemalloc \
|
||||
--all-targets \
|
||||
--color=always \
|
||||
@@ -156,6 +167,7 @@ env DIRENV_DEVSHELL=all-features \
|
||||
direnv exec . \
|
||||
cargo test \
|
||||
--workspace \
|
||||
--profile test \
|
||||
--all-targets \
|
||||
--all-features \
|
||||
--color=always \
|
||||
@@ -169,6 +181,7 @@ group = "tests"
|
||||
script = """
|
||||
cargo test \
|
||||
--workspace \
|
||||
--profile test \
|
||||
--all-targets \
|
||||
--color=always \
|
||||
-- \
|
||||
@@ -184,6 +197,12 @@ cargo test \
|
||||
name = "nix-default"
|
||||
group = "tests"
|
||||
script = """
|
||||
bin/nix-build-and-cache just .#default
|
||||
nix run -L .#default -- --help
|
||||
env DIRENV_DEVSHELL=dynamic \
|
||||
CARGO_PROFILE="test" \
|
||||
direnv exec . \
|
||||
bin/nix-build-and-cache just .#default-test
|
||||
env DIRENV_DEVSHELL=dynamic \
|
||||
CARGO_PROFILE="test" \
|
||||
direnv exec . \
|
||||
nix run -L .#default-test -- --help && nix run -L .#default-test -- --version
|
||||
"""
|
||||
|
||||
Generated
+25
-25
@@ -9,11 +9,11 @@
|
||||
"nixpkgs-stable": "nixpkgs-stable"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1717279440,
|
||||
"narHash": "sha256-kH04ReTjxOpQumgWnqy40vvQLSnLGxWP6RF3nq5Esrk=",
|
||||
"lastModified": 1720542474,
|
||||
"narHash": "sha256-aKjJ/4l2I9+wNGTaOGRsuS3M1+IoTibqgEMPDikXm04=",
|
||||
"owner": "zhaofengli",
|
||||
"repo": "attic",
|
||||
"rev": "717cc95983cdc357bc347d70be20ced21f935843",
|
||||
"rev": "6139576a3ce6bb992e0f6c3022528ec233e45f00",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -81,11 +81,11 @@
|
||||
"complement": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1719903368,
|
||||
"narHash": "sha256-PPzgxM4Bir+Zh9FUV/v+RBxEYeJxYVmi/BYo3uqt268=",
|
||||
"lastModified": 1720637557,
|
||||
"narHash": "sha256-oZz6nCmFmdJZpC+K1iOG2KkzTI6rlAmndxANPDVU7X0=",
|
||||
"owner": "matrix-org",
|
||||
"repo": "complement",
|
||||
"rev": "bc97f1ddc1cd7485faf80c8935ee2641f3e1b57c",
|
||||
"rev": "0d14432e010482ea9e13a6f7c47c1533c0c9d62f",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -123,11 +123,11 @@
|
||||
]
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720226507,
|
||||
"narHash": "sha256-yHVvNsgrpyNTXZBEokL8uyB2J6gB1wEx0KOJzoeZi1A=",
|
||||
"lastModified": 1720546058,
|
||||
"narHash": "sha256-iU2yVaPIZm5vMGdlT0+57vdB/aPq/V5oZFBRwYw+HBM=",
|
||||
"owner": "ipetkov",
|
||||
"repo": "crane",
|
||||
"rev": "0aed560c5c0a61c9385bddff471a13036203e11c",
|
||||
"rev": "2d83156f23c43598cf44e152c33a59d3892f8b29",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -209,11 +209,11 @@
|
||||
"rust-analyzer-src": "rust-analyzer-src"
|
||||
},
|
||||
"locked": {
|
||||
"lastModified": 1720420198,
|
||||
"narHash": "sha256-OIuDb6pHDyGpo7YMFyuRzMLcHm7mRvlYOz0Ht7ps2sU=",
|
||||
"lastModified": 1720852044,
|
||||
"narHash": "sha256-3NBYz8VuXuKU+8ONd9NFafCNjPEGHIZQ2Mdoam1a4mY=",
|
||||
"owner": "nix-community",
|
||||
"repo": "fenix",
|
||||
"rev": "abc0549e3560189462a7d394cc9d50af4608d103",
|
||||
"rev": "5087b12a595ee73131a944d922f24d81dae05725",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -381,11 +381,11 @@
|
||||
"liburing": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1719025212,
|
||||
"narHash": "sha256-kD0yhjNStqC6uFqC1AxBwUpc/HlSFtiKrV+gwDyroDc=",
|
||||
"lastModified": 1720798442,
|
||||
"narHash": "sha256-gtPppAoksMLW4GuruQ36nf4EAqIA1Bs6V9Xcx8dBxrQ=",
|
||||
"owner": "axboe",
|
||||
"repo": "liburing",
|
||||
"rev": "7b3245583069bd481190c9da18f22e9fc8c3a805",
|
||||
"rev": "1d674f83b7d0f07553ac44d99a401b05853d9dbe",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -606,11 +606,11 @@
|
||||
},
|
||||
"nixpkgs_4": {
|
||||
"locked": {
|
||||
"lastModified": 1720418205,
|
||||
"narHash": "sha256-cPJoFPXU44GlhWg4pUk9oUPqurPlCFZ11ZQPk21GTPU=",
|
||||
"lastModified": 1720768451,
|
||||
"narHash": "sha256-EYekUHJE2gxeo2pM/zM9Wlqw1Uw2XTJXOSAO79ksc4Y=",
|
||||
"owner": "NixOS",
|
||||
"repo": "nixpkgs",
|
||||
"rev": "655a58a72a6601292512670343087c2d75d859c1",
|
||||
"rev": "7e7c39ea35c5cdd002cd4588b03a3fb9ece6fad9",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
@@ -673,16 +673,16 @@
|
||||
"rocksdb": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1719949653,
|
||||
"narHash": "sha256-DYx7XHH2GEh17GukKhXs6laM6l+eugCmRkF0adpi9wk=",
|
||||
"lastModified": 1720900786,
|
||||
"narHash": "sha256-Vta9Um/RRuWwZ46BjXftV06iWLm/j/9MX39emXUvSAY=",
|
||||
"owner": "girlbossceo",
|
||||
"repo": "rocksdb",
|
||||
"rev": "a935c0273e1ba44eacf88ce3685a9b9831486155",
|
||||
"rev": "911f4243e69c2e320a7a209bf1f5f3ff5f825495",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
"owner": "girlbossceo",
|
||||
"ref": "v9.3.1",
|
||||
"ref": "v9.4.0",
|
||||
"repo": "rocksdb",
|
||||
"type": "github"
|
||||
}
|
||||
@@ -705,11 +705,11 @@
|
||||
"rust-analyzer-src": {
|
||||
"flake": false,
|
||||
"locked": {
|
||||
"lastModified": 1720344064,
|
||||
"narHash": "sha256-STmaV9Zu74QtkGGrbr9uMhskwagfCjJqOAYapXabiuk=",
|
||||
"lastModified": 1720717809,
|
||||
"narHash": "sha256-6I+fm+nTLF/iaj7ffiFGlSY7POmubwUaPA/Wq0Bm53M=",
|
||||
"owner": "rust-lang",
|
||||
"repo": "rust-analyzer",
|
||||
"rev": "a5b21ea0aa644dffd7cf958b43f11f221d53404e",
|
||||
"rev": "ffbc5ad993d5cd2f3b8bcf9a511165470944ab91",
|
||||
"type": "github"
|
||||
},
|
||||
"original": {
|
||||
|
||||
@@ -9,8 +9,7 @@
|
||||
flake-utils.url = "github:numtide/flake-utils?ref=main";
|
||||
nix-filter.url = "github:numtide/nix-filter?ref=main";
|
||||
nixpkgs.url = "github:NixOS/nixpkgs?ref=nixos-unstable";
|
||||
# https://github.com/girlbossceo/rocksdb/commit/db6df0b185774778457dabfcbd822cb81760cade
|
||||
rocksdb = { url = "github:girlbossceo/rocksdb?ref=v9.3.1"; flake = false; };
|
||||
rocksdb = { url = "github:girlbossceo/rocksdb?ref=v9.4.0"; flake = false; };
|
||||
liburing = { url = "github:axboe/liburing?ref=master"; flake = false; };
|
||||
};
|
||||
|
||||
@@ -25,7 +24,7 @@
|
||||
file = ./rust-toolchain.toml;
|
||||
|
||||
# See also `rust-toolchain.toml`
|
||||
sha256 = "sha256-+syqAd2kX8KVa8/U2gz3blIQTTsYYt3U63xBWaGOSc8";
|
||||
sha256 = "sha256-6eN/GKzjVSjEhGO9FhWObkRFaE1Jf+uqMSdQnb8lcB4=";
|
||||
};
|
||||
|
||||
mkScope = pkgs: pkgs.lib.makeScope pkgs.newScope (self: {
|
||||
@@ -45,10 +44,34 @@
|
||||
# we have this already at https://github.com/girlbossceo/rocksdb/commit/a935c0273e1ba44eacf88ce3685a9b9831486155
|
||||
# unsetting this so i don't have to revert it and make this nix exclusive
|
||||
patches = [];
|
||||
# no real reason to have snappy, no one uses this
|
||||
cmakeFlags = pkgs.lib.subtractLists
|
||||
[ "-DWITH_SNAPPY=1" ]
|
||||
old.cmakeFlags;
|
||||
[
|
||||
# no real reason to have snappy, no one uses this
|
||||
"-DWITH_SNAPPY=1"
|
||||
# we dont need to use ldb or sst_dump (core_tools)
|
||||
"-DWITH_CORE_TOOLS=1"
|
||||
# we dont need to build rocksdb tests
|
||||
"-DWITH_TESTS=1"
|
||||
# we use rust-rocksdb via C interface and dont need C++ RTTI
|
||||
"-DUSE_RTTI=1"
|
||||
]
|
||||
old.cmakeFlags
|
||||
++ [
|
||||
# we dont need to use ldb or sst_dump (core_tools)
|
||||
"-DWITH_CORE_TOOLS=0"
|
||||
# we dont need trace tools
|
||||
"-DWITH_TRACE_TOOLS=0"
|
||||
# we dont need to build rocksdb tests
|
||||
"-DWITH_TESTS=0"
|
||||
# we use rust-rocksdb via C interface and dont need C++ RTTI
|
||||
"-DUSE_RTTI=0"
|
||||
];
|
||||
|
||||
# outputs has "tools" which we dont need or use
|
||||
outputs = [ "out" ];
|
||||
|
||||
# preInstall hooks has stuff for messing with ldb/sst_dump which we dont need or use
|
||||
preInstall = "";
|
||||
});
|
||||
# TODO: remove once https://github.com/NixOS/nixpkgs/pull/314945 is available
|
||||
liburing = pkgs.liburing.overrideAttrs (old: {
|
||||
@@ -96,6 +119,9 @@
|
||||
# Needed for producing Debian packages
|
||||
cargo-deb
|
||||
|
||||
# Needed for CI to check validity of produced Debian packages (dpkg-deb)
|
||||
dpkg
|
||||
|
||||
# Needed for Complement
|
||||
go
|
||||
|
||||
@@ -110,6 +136,8 @@
|
||||
|
||||
# Useful for editing the book locally
|
||||
mdbook
|
||||
|
||||
sccache
|
||||
])
|
||||
++ scope.main.buildInputs
|
||||
++ scope.main.propagatedBuildInputs
|
||||
@@ -121,10 +149,35 @@
|
||||
{
|
||||
packages = {
|
||||
default = scopeHost.main;
|
||||
default-debug = scopeHost.main.override {
|
||||
profile = "dev";
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
};
|
||||
default-test = scopeHost.main.override {
|
||||
profile = "test";
|
||||
disable_release_max_log_level = true;
|
||||
};
|
||||
all-features = scopeHost.main.override {
|
||||
all_features = true;
|
||||
# this is non-functional on nix for some reason
|
||||
disable_features = ["hardened_malloc"];
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
all-features-debug = scopeHost.main.override {
|
||||
profile = "dev";
|
||||
all_features = true;
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
hmalloc = scopeHost.main.override { features = ["hardened_malloc"]; };
|
||||
|
||||
@@ -132,8 +185,26 @@
|
||||
oci-image-all-features = scopeHost.oci-image.override {
|
||||
main = scopeHost.main.override {
|
||||
all_features = true;
|
||||
# this is non-functional on nix for some reason
|
||||
disable_features = ["hardened_malloc"];
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
};
|
||||
oci-image-all-features-debug = scopeHost.oci-image.override {
|
||||
main = scopeHost.main.override {
|
||||
profile = "dev";
|
||||
all_features = true;
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
};
|
||||
oci-image-hmalloc = scopeHost.oci-image.override {
|
||||
@@ -170,13 +241,54 @@
|
||||
value = scopeCrossStatic.main;
|
||||
}
|
||||
|
||||
# An output for a statically-linked unstripped debug ("dev") binary
|
||||
{
|
||||
name = "${binaryName}-debug";
|
||||
value = scopeCrossStatic.main.override {
|
||||
profile = "dev";
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
};
|
||||
}
|
||||
|
||||
# An output for a statically-linked unstripped debug binary with the
|
||||
# "test" profile (for CI usage only)
|
||||
{
|
||||
name = "${binaryName}-test";
|
||||
value = scopeCrossStatic.main.override {
|
||||
profile = "test";
|
||||
disable_release_max_log_level = true;
|
||||
};
|
||||
}
|
||||
|
||||
# An output for a statically-linked binary with `--all-features`
|
||||
{
|
||||
name = "${binaryName}-all-features";
|
||||
value = scopeCrossStatic.main.override {
|
||||
all_features = true;
|
||||
# this is non-functional on nix for some reason
|
||||
disable_features = ["hardened_malloc"];
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
# An output for a statically-linked unstripped debug ("dev") binary with `--all-features`
|
||||
{
|
||||
name = "${binaryName}-all-features-debug";
|
||||
value = scopeCrossStatic.main.override {
|
||||
profile = "dev";
|
||||
all_features = true;
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
}
|
||||
|
||||
@@ -194,14 +306,49 @@
|
||||
value = scopeCrossStatic.oci-image;
|
||||
}
|
||||
|
||||
# An output for an OCI image based on that unstripped debug ("dev") binary
|
||||
{
|
||||
name = "oci-image-${crossSystem}-debug";
|
||||
value = scopeCrossStatic.oci-image.override {
|
||||
main = scopeCrossStatic.main.override {
|
||||
profile = "dev";
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
# An output for an OCI image based on that binary with `--all-features`
|
||||
{
|
||||
name = "oci-image-${crossSystem}-all-features";
|
||||
value = scopeCrossStatic.oci-image.override {
|
||||
main = scopeCrossStatic.main.override {
|
||||
all_features = true;
|
||||
# this is non-functional on nix for some reason
|
||||
disable_features = ["hardened_malloc"];
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
|
||||
# An output for an OCI image based on that unstripped debug ("dev") binary with `--all-features`
|
||||
{
|
||||
name = "oci-image-${crossSystem}-all-features-debug";
|
||||
value = scopeCrossStatic.oci-image.override {
|
||||
main = scopeCrossStatic.main.override {
|
||||
profile = "dev";
|
||||
all_features = true;
|
||||
# debug build users expect full logs
|
||||
disable_release_max_log_level = true;
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
};
|
||||
}
|
||||
@@ -229,8 +376,12 @@
|
||||
(scopeHostStatic.overrideScope (final: prev: {
|
||||
main = prev.main.override {
|
||||
all_features = true;
|
||||
# this is non-functional on nix for some reason
|
||||
disable_features = ["hardened_malloc"];
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
}));
|
||||
devShells.no-features = mkDevShell
|
||||
|
||||
@@ -14,7 +14,7 @@ yes_i_am_very_very_sure_i_want_an_open_registration_server_prone_to_abuse = true
|
||||
ip_range_denylist = []
|
||||
url_preview_domain_contains_allowlist = ["*"]
|
||||
media_compat_file_link = false
|
||||
media_statup_check = false
|
||||
media_startup_check = false
|
||||
rocksdb_direct_io = false
|
||||
|
||||
[global.tls]
|
||||
|
||||
@@ -14,8 +14,15 @@
|
||||
|
||||
let
|
||||
main' = main.override {
|
||||
profile = "dev";
|
||||
features = ["axum_dual_protocol"];
|
||||
profile = "test";
|
||||
all_features = true;
|
||||
disable_release_max_log_level = true;
|
||||
disable_features = [
|
||||
# this is non-functional on nix for some reason
|
||||
"hardened_malloc"
|
||||
# dont include experimental features
|
||||
"experimental"
|
||||
];
|
||||
};
|
||||
|
||||
start = writeShellScriptBin "start" ''
|
||||
|
||||
@@ -13,6 +13,12 @@ lib.optionalAttrs stdenv.hostPlatform.isStatic {
|
||||
lib.concatStringsSep
|
||||
" "
|
||||
([]
|
||||
++ lib.optionals
|
||||
stdenv.targetPlatform.isx86_64
|
||||
[ "-C" "target-cpu=x86-64-v2" ]
|
||||
++ lib.optionals
|
||||
stdenv.targetPlatform.isAarch64
|
||||
[ "-C" "target-cpu=cortex-a55" ] # cortex-a55 == ARMv8.2-a
|
||||
# This disables PIE for static builds, which isn't great in terms
|
||||
# of security. Unfortunately, my hand is forced because nixpkgs'
|
||||
# `libstdc++.a` is built without `-fPIE`, which precludes us from
|
||||
|
||||
@@ -51,6 +51,10 @@ rust-jemalloc-sys' = (rust-jemalloc-sys.override {
|
||||
unprefixed = true;
|
||||
}).overrideAttrs (old: {
|
||||
configureFlags = old.configureFlags ++
|
||||
# we dont need docs
|
||||
[ "--disable-doc" ] ++
|
||||
# we dont need cxx/C++ integration
|
||||
[ "--disable-cxx" ] ++
|
||||
# tikv-jemalloc-sys/profiling feature
|
||||
lib.optional (featureEnabled "jemalloc_prof") "--enable-prof";
|
||||
});
|
||||
@@ -71,10 +75,29 @@ buildDepsOnlyEnv =
|
||||
# which breaks Darwin entirely
|
||||
enableLiburing = enableLiburing;
|
||||
}).overrideAttrs (old: {
|
||||
# TODO: static rocksdb fails to build on darwin
|
||||
# TODO: static rocksdb fails to build on darwin, also see <https://github.com/NixOS/nixpkgs/issues/320448>
|
||||
# build log at <https://girlboss.ceo/~strawberry/pb/JjGH>
|
||||
meta.broken = stdenv.hostPlatform.isStatic && stdenv.isDarwin;
|
||||
|
||||
enableLiburing = enableLiburing;
|
||||
|
||||
sse42Support = stdenv.targetPlatform.isx86_64;
|
||||
|
||||
cmakeFlags = if stdenv.targetPlatform.isx86_64
|
||||
then lib.subtractLists [ "-DPORTABLE=1" ] old.cmakeFlags
|
||||
++ lib.optionals stdenv.targetPlatform.isx86_64 [
|
||||
"-DPORTABLE=x86-64-v2"
|
||||
"-DUSE_SSE=1"
|
||||
"-DHAVE_SSE=1"
|
||||
"-DHAVE_SSE42=1"
|
||||
]
|
||||
else if stdenv.targetPlatform.isAarch64
|
||||
then lib.subtractLists [ "-DPORTABLE=1" ] old.cmakeFlags
|
||||
++ lib.optionals stdenv.targetPlatform.isAarch64 [
|
||||
# cortex-a55 == ARMv8.2-a
|
||||
"-DPORTABLE=armv8.2-a"
|
||||
]
|
||||
else old.cmakeFlags;
|
||||
});
|
||||
in
|
||||
{
|
||||
@@ -101,7 +124,11 @@ buildPackageEnv = {
|
||||
# Only needed in static stdenv because these are transitive dependencies of rocksdb
|
||||
CARGO_BUILD_RUSTFLAGS = buildDepsOnlyEnv.CARGO_BUILD_RUSTFLAGS
|
||||
+ lib.optionalString (enableLiburing && stdenv.hostPlatform.isStatic)
|
||||
" -L${lib.getLib liburing}/lib -luring";
|
||||
" -L${lib.getLib liburing}/lib -luring"
|
||||
+ lib.optionalString stdenv.targetPlatform.isx86_64
|
||||
" -Ctarget-cpu=x86-64-v2"
|
||||
+ lib.optionalString stdenv.targetPlatform.isAarch64
|
||||
" -Ctarget-cpu=cortex-a55"; # cortex-a55 == ARMv8.2-a
|
||||
};
|
||||
|
||||
|
||||
@@ -126,6 +153,8 @@ commonAttrs = {
|
||||
];
|
||||
};
|
||||
|
||||
dontStrip = profile == "dev" || profile == "test";
|
||||
|
||||
buildInputs = lib.optional (featureEnabled "jemalloc") rust-jemalloc-sys';
|
||||
|
||||
nativeBuildInputs = [
|
||||
|
||||
+1
-1
@@ -11,7 +11,7 @@
|
||||
# If you're having trouble making the relevant changes, bug a maintainer.
|
||||
|
||||
[toolchain]
|
||||
channel = "1.77.0"
|
||||
channel = "1.80.0"
|
||||
components = [
|
||||
# For rust-analyzer
|
||||
"rust-src",
|
||||
|
||||
@@ -64,6 +64,6 @@ async fn view_room_topic(_body: Vec<&str>, room_id: Box<RoomId>) -> Result<RoomM
|
||||
};
|
||||
|
||||
Ok(RoomMessageEventContent::notice_markdown(format!(
|
||||
"Room topic:\n\n```{room_topic}\n```"
|
||||
"Room topic:\n```\n{room_topic}\n```"
|
||||
)))
|
||||
}
|
||||
|
||||
@@ -42,6 +42,12 @@ pub(super) async fn create(
|
||||
return Ok(RoomMessageEventContent::text_plain(format!("Userid {user_id} already exists")));
|
||||
}
|
||||
|
||||
if user_id.is_historical() {
|
||||
return Ok(RoomMessageEventContent::text_plain(format!(
|
||||
"User ID {user_id} does not conform to new Matrix identifier spec"
|
||||
)));
|
||||
}
|
||||
|
||||
let password = password.unwrap_or_else(|| utils::random_string(AUTO_GEN_PASSWORD_LENGTH));
|
||||
|
||||
// Create user
|
||||
|
||||
@@ -117,7 +117,12 @@ pub(crate) async fn set_room_visibility_route(
|
||||
return Err(Error::BadRequest(ErrorKind::NotFound, "Room not found"));
|
||||
}
|
||||
|
||||
user_can_publish_room(sender_user, &body.room_id)?;
|
||||
if !user_can_publish_room(sender_user, &body.room_id)? {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::forbidden(),
|
||||
"User is not allowed to publish this room",
|
||||
));
|
||||
}
|
||||
|
||||
match &body.visibility {
|
||||
room::Visibility::Public => {
|
||||
@@ -377,8 +382,8 @@ fn user_can_publish_room(user_id: &UserId, room_id: &RoomId) -> Result<bool> {
|
||||
Ok(event.sender == user_id)
|
||||
} else {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::Unauthorized,
|
||||
"You are not allowed to publish this room to the room directory",
|
||||
ErrorKind::forbidden(),
|
||||
"User is not allowed to publish this room",
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,12 +200,13 @@ pub(crate) async fn get_content_route(
|
||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||
|
||||
if let Some(FileMeta {
|
||||
content,
|
||||
content_type,
|
||||
file,
|
||||
content_disposition,
|
||||
}) = services().media.get(&mxc).await?
|
||||
{
|
||||
let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
|
||||
let file = content.expect("content");
|
||||
|
||||
Ok(get_content::v3::Response {
|
||||
file,
|
||||
@@ -282,8 +283,8 @@ pub(crate) async fn get_content_as_filename_route(
|
||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||
|
||||
if let Some(FileMeta {
|
||||
content,
|
||||
content_type,
|
||||
file,
|
||||
content_disposition,
|
||||
}) = services().media.get(&mxc).await?
|
||||
{
|
||||
@@ -293,6 +294,7 @@ pub(crate) async fn get_content_as_filename_route(
|
||||
Some(body.filename.clone()),
|
||||
));
|
||||
|
||||
let file = content.expect("content");
|
||||
Ok(get_content_as_filename::v3::Response {
|
||||
file,
|
||||
content_type,
|
||||
@@ -371,8 +373,8 @@ pub(crate) async fn get_content_thumbnail_route(
|
||||
let mxc = format!("mxc://{}/{}", body.server_name, body.media_id);
|
||||
|
||||
if let Some(FileMeta {
|
||||
content,
|
||||
content_type,
|
||||
file,
|
||||
content_disposition,
|
||||
}) = services()
|
||||
.media
|
||||
@@ -388,6 +390,7 @@ pub(crate) async fn get_content_thumbnail_route(
|
||||
.await?
|
||||
{
|
||||
let content_disposition = Some(make_content_disposition(&content_type, content_disposition, None));
|
||||
let file = content.expect("content");
|
||||
|
||||
Ok(get_content_thumbnail::v3::Response {
|
||||
file,
|
||||
|
||||
@@ -16,6 +16,14 @@ pub(crate) async fn set_presence_route(body: Ruma<set_presence::v3::Request>) ->
|
||||
}
|
||||
|
||||
let sender_user = body.sender_user.as_ref().expect("user is authenticated");
|
||||
|
||||
if sender_user != &body.user_id && body.appservice_info.is_none() {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::InvalidParam,
|
||||
"Not allowed to set presence of other users",
|
||||
));
|
||||
}
|
||||
|
||||
services()
|
||||
.presence
|
||||
.set_presence(sender_user, &body.presence, None, None, body.status_msg.clone())?;
|
||||
|
||||
+5
-5
@@ -1,15 +1,15 @@
|
||||
pub mod client;
|
||||
mod router;
|
||||
pub mod routes;
|
||||
pub mod router;
|
||||
pub mod server;
|
||||
|
||||
extern crate conduit_core as conduit;
|
||||
extern crate conduit_service as service;
|
||||
|
||||
pub(crate) use conduit::{debug_info, debug_warn, utils, Error, Result};
|
||||
pub(crate) use service::{pdu::PduEvent, services, user_is_local};
|
||||
pub(crate) use conduit::{debug_info, debug_warn, pdu::PduEvent, utils, Error, Result};
|
||||
pub(crate) use service::{services, user_is_local};
|
||||
|
||||
pub(crate) use self::router::{Ruma, RumaResponse};
|
||||
pub use crate::router::State;
|
||||
pub(crate) use crate::router::{Ruma, RumaResponse};
|
||||
|
||||
conduit::mod_ctor! {}
|
||||
conduit::mod_dtor! {}
|
||||
|
||||
@@ -1,15 +1,24 @@
|
||||
mod args;
|
||||
mod auth;
|
||||
mod handler;
|
||||
mod request;
|
||||
mod response;
|
||||
|
||||
use axum::{
|
||||
response::IntoResponse,
|
||||
routing::{any, get, post},
|
||||
Router,
|
||||
};
|
||||
use conduit::{err, Error, Server};
|
||||
use conduit::{err, Server};
|
||||
use http::Uri;
|
||||
use ruma::api::client::error::ErrorKind;
|
||||
|
||||
use crate::{client, router::RouterExt, server};
|
||||
use self::handler::RouterExt;
|
||||
pub(super) use self::{args::Args as Ruma, response::RumaResponse};
|
||||
use crate::{client, server};
|
||||
|
||||
pub fn build(router: Router, server: &Server) -> Router {
|
||||
pub type State = &'static service::Services;
|
||||
|
||||
pub fn build(router: Router<State>, server: &Server) -> Router<State> {
|
||||
let config = &server.config;
|
||||
let router = router
|
||||
.ruma_route(client::get_supported_versions_route)
|
||||
@@ -95,7 +104,7 @@ pub fn build(router: Router, server: &Server) -> Router {
|
||||
.ruma_route(client::get_member_events_route)
|
||||
.ruma_route(client::get_protocols_route)
|
||||
.route("/_matrix/client/unstable/thirdparty/protocols",
|
||||
get(client::get_protocols_route_unstable))
|
||||
get(client::get_protocols_route_unstable))
|
||||
.ruma_route(client::send_message_event_route)
|
||||
.ruma_route(client::send_state_event_for_key_route)
|
||||
.ruma_route(client::get_state_events_route)
|
||||
@@ -180,15 +189,15 @@ pub fn build(router: Router, server: &Server) -> Router {
|
||||
.ruma_route(client::get_relating_events_with_rel_type_route)
|
||||
.ruma_route(client::get_relating_events_route)
|
||||
.ruma_route(client::get_hierarchy_route)
|
||||
.ruma_route(client::get_mutual_rooms_route)
|
||||
.ruma_route(client::get_room_summary)
|
||||
.route(
|
||||
"/_matrix/client/unstable/im.nheko.summary/rooms/:room_id_or_alias/summary",
|
||||
get(client::get_room_summary_legacy)
|
||||
)
|
||||
.ruma_route(client::well_known_support)
|
||||
.ruma_route(client::well_known_client)
|
||||
.route("/_conduwuit/server_version", get(client::conduwuit_server_version))
|
||||
.ruma_route(client::get_mutual_rooms_route)
|
||||
.ruma_route(client::get_room_summary)
|
||||
.route(
|
||||
"/_matrix/client/unstable/im.nheko.summary/rooms/:room_id_or_alias/summary",
|
||||
get(client::get_room_summary_legacy)
|
||||
)
|
||||
.ruma_route(client::well_known_support)
|
||||
.ruma_route(client::well_known_client)
|
||||
.route("/_conduwuit/server_version", get(client::conduwuit_server_version))
|
||||
.route("/_matrix/client/r0/rooms/:room_id/initialSync", get(initial_sync))
|
||||
.route("/_matrix/client/v3/rooms/:room_id/initialSync", get(initial_sync))
|
||||
.route("/client/server.json", get(client::syncv3_client_server_json));
|
||||
@@ -233,7 +242,7 @@ pub fn build(router: Router, server: &Server) -> Router {
|
||||
}
|
||||
|
||||
async fn initial_sync(_uri: Uri) -> impl IntoResponse {
|
||||
Error::BadRequest(ErrorKind::GuestAccessForbidden, "Guest access not implemented")
|
||||
err!(Request(GuestAccessForbidden("Guest access not implemented")))
|
||||
}
|
||||
|
||||
async fn federation_disabled() -> impl IntoResponse { err!(Config("allow_federation", "Federation is disabled.")) }
|
||||
@@ -1,24 +1,15 @@
|
||||
mod auth;
|
||||
mod handler;
|
||||
mod request;
|
||||
mod response;
|
||||
|
||||
use std::{mem, ops::Deref};
|
||||
|
||||
use axum::{async_trait, body::Body, extract::FromRequest};
|
||||
use bytes::{BufMut, BytesMut};
|
||||
use conduit::{debug, debug_warn, trace, warn};
|
||||
use ruma::{
|
||||
api::{client::error::ErrorKind, IncomingRequest},
|
||||
CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId,
|
||||
};
|
||||
use conduit::{debug, err, trace, Error, Result};
|
||||
use ruma::{api::IncomingRequest, CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId};
|
||||
|
||||
use self::{auth::Auth, request::Request};
|
||||
pub(super) use self::{handler::RouterExt, response::RumaResponse};
|
||||
use crate::{service::appservice::RegistrationInfo, services, Error, Result};
|
||||
use super::{auth, auth::Auth, request, request::Request};
|
||||
use crate::{service::appservice::RegistrationInfo, services};
|
||||
|
||||
/// Extractor for Ruma request structs
|
||||
pub(crate) struct Ruma<T> {
|
||||
pub(crate) struct Args<T> {
|
||||
/// Request struct body
|
||||
pub(crate) body: T,
|
||||
|
||||
@@ -44,7 +35,7 @@ pub(crate) struct Ruma<T> {
|
||||
}
|
||||
|
||||
#[async_trait]
|
||||
impl<T, S> FromRequest<S, Body> for Ruma<T>
|
||||
impl<T, S> FromRequest<S, Body> for Args<T>
|
||||
where
|
||||
T: IncomingRequest,
|
||||
{
|
||||
@@ -65,7 +56,7 @@ where
|
||||
}
|
||||
}
|
||||
|
||||
impl<T> Deref for Ruma<T> {
|
||||
impl<T> Deref for Args<T> {
|
||||
type Target = T;
|
||||
|
||||
fn deref(&self) -> &Self::Target { &self.body }
|
||||
@@ -109,21 +100,14 @@ where
|
||||
let mut http_request = hyper::Request::builder()
|
||||
.uri(request.parts.uri.clone())
|
||||
.method(request.parts.method.clone());
|
||||
*http_request.headers_mut().unwrap() = request.parts.headers.clone();
|
||||
let http_request = http_request.body(body).unwrap();
|
||||
debug!(
|
||||
"{:?} {:?} {:?}",
|
||||
http_request.method(),
|
||||
http_request.uri(),
|
||||
http_request.headers()
|
||||
);
|
||||
*http_request.headers_mut().expect("mutable http headers") = request.parts.headers.clone();
|
||||
let http_request = http_request.body(body).expect("http request body");
|
||||
|
||||
trace!("{:?} {:?} {:?}", http_request.method(), http_request.uri(), json_body);
|
||||
let body = T::try_from_http_request(http_request, &request.path).map_err(|e| {
|
||||
warn!("try_from_http_request failed: {e:?}",);
|
||||
debug_warn!("JSON body: {:?}", json_body);
|
||||
Error::BadRequest(ErrorKind::BadJson, "Failed to deserialize request.")
|
||||
})?;
|
||||
let headers = http_request.headers();
|
||||
let method = http_request.method();
|
||||
let uri = http_request.uri();
|
||||
debug!("{method:?} {uri:?} {headers:?}");
|
||||
trace!("{method:?} {uri:?} {json_body:?}");
|
||||
|
||||
Ok(body)
|
||||
T::try_from_http_request(http_request, &request.path).map_err(|e| err!(Request(BadJson(debug_warn!("{e}")))))
|
||||
}
|
||||
@@ -10,7 +10,7 @@ use conduit::Result;
|
||||
use http::Method;
|
||||
use ruma::api::IncomingRequest;
|
||||
|
||||
use super::{Ruma, RumaResponse};
|
||||
use super::{Ruma, RumaResponse, State};
|
||||
|
||||
pub(in super::super) trait RouterExt {
|
||||
fn ruma_route<H, T>(self, handler: H) -> Self
|
||||
@@ -18,7 +18,7 @@ pub(in super::super) trait RouterExt {
|
||||
H: RumaHandler<T>;
|
||||
}
|
||||
|
||||
impl RouterExt for Router {
|
||||
impl RouterExt for Router<State> {
|
||||
fn ruma_route<H, T>(self, handler: H) -> Self
|
||||
where
|
||||
H: RumaHandler<T>,
|
||||
@@ -28,9 +28,9 @@ impl RouterExt for Router {
|
||||
}
|
||||
|
||||
pub(in super::super) trait RumaHandler<T> {
|
||||
fn add_routes(&self, router: Router) -> Router;
|
||||
fn add_routes(&self, router: Router<State>) -> Router<State>;
|
||||
|
||||
fn add_route(&self, router: Router, path: &str) -> Router;
|
||||
fn add_route(&self, router: Router<State>, path: &str) -> Router<State>;
|
||||
}
|
||||
|
||||
macro_rules! ruma_handler {
|
||||
@@ -41,17 +41,17 @@ macro_rules! ruma_handler {
|
||||
Req: IncomingRequest + Send + 'static,
|
||||
Ret: IntoResponse,
|
||||
Fut: Future<Output = Result<Req::OutgoingResponse, Ret>> + Send,
|
||||
Fun: FnOnce($($tx,)* Ruma<Req>) -> Fut + Clone + Send + Sync + 'static,
|
||||
$( $tx: FromRequestParts<()> + Send + 'static, )*
|
||||
Fun: FnOnce($($tx,)* Ruma<Req>,) -> Fut + Clone + Send + Sync + 'static,
|
||||
$( $tx: FromRequestParts<State> + Send + 'static, )*
|
||||
{
|
||||
fn add_routes(&self, router: Router) -> Router {
|
||||
fn add_routes(&self, router: Router<State>) -> Router<State> {
|
||||
Req::METADATA
|
||||
.history
|
||||
.all_paths()
|
||||
.fold(router, |router, path| self.add_route(router, path))
|
||||
}
|
||||
|
||||
fn add_route(&self, router: Router, path: &str) -> Router {
|
||||
fn add_route(&self, router: Router<State>, path: &str) -> Router<State> {
|
||||
let handle = self.clone();
|
||||
let method = method_to_filter(&Req::METADATA.method);
|
||||
let action = |$($tx,)* req| async { handle($($tx,)* req).await.map(RumaResponse) };
|
||||
|
||||
@@ -2,11 +2,11 @@ use std::str;
|
||||
|
||||
use axum::{extract::Path, RequestExt, RequestPartsExt};
|
||||
use bytes::Bytes;
|
||||
use conduit::err;
|
||||
use http::request::Parts;
|
||||
use ruma::api::client::error::ErrorKind;
|
||||
use serde::Deserialize;
|
||||
|
||||
use crate::{services, Error, Result};
|
||||
use crate::{services, Result};
|
||||
|
||||
#[derive(Deserialize)]
|
||||
pub(super) struct QueryParams {
|
||||
@@ -26,14 +26,15 @@ pub(super) async fn from(request: hyper::Request<axum::body::Body>) -> Result<Re
|
||||
let (mut parts, body) = limited.into_parts();
|
||||
|
||||
let path: Path<Vec<String>> = parts.extract().await?;
|
||||
let query = serde_html_form::from_str(parts.uri.query().unwrap_or_default())
|
||||
.map_err(|_| Error::BadRequest(ErrorKind::Unknown, "Failed to read query parameters"))?;
|
||||
let query = parts.uri.query().unwrap_or_default();
|
||||
let query =
|
||||
serde_html_form::from_str(query).map_err(|e| err!(Request(Unknown("Failed to read query parameters: {e}"))))?;
|
||||
|
||||
let max_body_size = services().globals.config.max_request_size;
|
||||
|
||||
let body = axum::body::to_bytes(body, max_body_size)
|
||||
.await
|
||||
.map_err(|_| Error::BadRequest(ErrorKind::TooLarge, "Request body too large"))?;
|
||||
.map_err(|e| err!(Request(TooLarge("Request body too large: {e}"))))?;
|
||||
|
||||
Ok(Request {
|
||||
path,
|
||||
|
||||
+59
-59
@@ -1,7 +1,8 @@
|
||||
use std::{collections::BTreeMap, net::IpAddr, time::Instant};
|
||||
|
||||
use axum::extract::State;
|
||||
use axum_client_ip::InsecureClientIp;
|
||||
use conduit::debug_warn;
|
||||
use conduit::{debug, debug_warn, err, trace, warn, Err};
|
||||
use ruma::{
|
||||
api::{
|
||||
client::error::ErrorKind,
|
||||
@@ -18,11 +19,10 @@ use ruma::{
|
||||
OwnedEventId, ServerName,
|
||||
};
|
||||
use tokio::sync::RwLock;
|
||||
use tracing::{debug, error, trace, warn};
|
||||
|
||||
use crate::{
|
||||
service::rooms::event_handler::parse_incoming_pdu,
|
||||
services,
|
||||
services::Services,
|
||||
utils::{self},
|
||||
Error, Result, Ruma,
|
||||
};
|
||||
@@ -34,29 +34,23 @@ type ResolvedMap = BTreeMap<OwnedEventId, Result<(), Error>>;
|
||||
/// Push EDUs and PDUs to this server.
|
||||
#[tracing::instrument(skip_all, fields(%client), name = "send")]
|
||||
pub(crate) async fn send_transaction_message_route(
|
||||
InsecureClientIp(client): InsecureClientIp, body: Ruma<send_transaction_message::v1::Request>,
|
||||
State(services): State<&Services>, InsecureClientIp(client): InsecureClientIp,
|
||||
body: Ruma<send_transaction_message::v1::Request>,
|
||||
) -> Result<send_transaction_message::v1::Response> {
|
||||
let origin = body.origin.as_ref().expect("server is authenticated");
|
||||
|
||||
if *origin != body.body.origin {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::forbidden(),
|
||||
"Not allowed to send transactions on behalf of other servers",
|
||||
));
|
||||
return Err!(Request(Forbidden(
|
||||
"Not allowed to send transactions on behalf of other servers"
|
||||
)));
|
||||
}
|
||||
|
||||
if body.pdus.len() > 50_usize {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::forbidden(),
|
||||
"Not allowed to send more than 50 PDUs in one transaction",
|
||||
));
|
||||
return Err!(Request(Forbidden("Not allowed to send more than 50 PDUs in one transaction")));
|
||||
}
|
||||
|
||||
if body.edus.len() > 100_usize {
|
||||
return Err(Error::BadRequest(
|
||||
ErrorKind::forbidden(),
|
||||
"Not allowed to send more than 100 EDUs in one transaction",
|
||||
));
|
||||
return Err!(Request(Forbidden("Not allowed to send more than 100 EDUs in one transaction")));
|
||||
}
|
||||
|
||||
let txn_start_time = Instant::now();
|
||||
@@ -69,8 +63,8 @@ pub(crate) async fn send_transaction_message_route(
|
||||
"Starting txn",
|
||||
);
|
||||
|
||||
let resolved_map = handle_pdus(&client, &body, origin, &txn_start_time).await?;
|
||||
handle_edus(&client, &body, origin).await?;
|
||||
let resolved_map = handle_pdus(services, &client, &body, origin, &txn_start_time).await?;
|
||||
handle_edus(services, &client, &body, origin).await?;
|
||||
|
||||
debug!(
|
||||
pdus = ?body.pdus.len(),
|
||||
@@ -90,7 +84,8 @@ pub(crate) async fn send_transaction_message_route(
|
||||
}
|
||||
|
||||
async fn handle_pdus(
|
||||
_client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName, txn_start_time: &Instant,
|
||||
services: &Services, _client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName,
|
||||
txn_start_time: &Instant,
|
||||
) -> Result<ResolvedMap> {
|
||||
let mut parsed_pdus = Vec::with_capacity(body.pdus.len());
|
||||
for pdu in &body.pdus {
|
||||
@@ -110,7 +105,7 @@ async fn handle_pdus(
|
||||
// corresponding signing keys
|
||||
let pub_key_map = RwLock::new(BTreeMap::new());
|
||||
if !parsed_pdus.is_empty() {
|
||||
services()
|
||||
services
|
||||
.rooms
|
||||
.event_handler
|
||||
.fetch_required_signing_keys(parsed_pdus.iter().map(|(_event_id, event, _room_id)| event), &pub_key_map)
|
||||
@@ -126,7 +121,7 @@ async fn handle_pdus(
|
||||
let mut resolved_map = BTreeMap::new();
|
||||
for (event_id, value, room_id) in parsed_pdus {
|
||||
let pdu_start_time = Instant::now();
|
||||
let mutex_lock = services()
|
||||
let mutex_lock = services
|
||||
.rooms
|
||||
.event_handler
|
||||
.mutex_federation
|
||||
@@ -134,7 +129,7 @@ async fn handle_pdus(
|
||||
.await;
|
||||
resolved_map.insert(
|
||||
event_id.clone(),
|
||||
services()
|
||||
services
|
||||
.rooms
|
||||
.event_handler
|
||||
.handle_incoming_pdu(origin, &room_id, &event_id, value, true, &pub_key_map)
|
||||
@@ -162,7 +157,7 @@ async fn handle_pdus(
|
||||
}
|
||||
|
||||
async fn handle_edus(
|
||||
client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName,
|
||||
services: &Services, client: &IpAddr, body: &Ruma<send_transaction_message::v1::Request>, origin: &ServerName,
|
||||
) -> Result<()> {
|
||||
for edu in body
|
||||
.edus
|
||||
@@ -170,12 +165,12 @@ async fn handle_edus(
|
||||
.filter_map(|edu| serde_json::from_str::<Edu>(edu.json().get()).ok())
|
||||
{
|
||||
match edu {
|
||||
Edu::Presence(presence) => handle_edu_presence(client, origin, presence).await?,
|
||||
Edu::Receipt(receipt) => handle_edu_receipt(client, origin, receipt).await?,
|
||||
Edu::Typing(typing) => handle_edu_typing(client, origin, typing).await?,
|
||||
Edu::DeviceListUpdate(content) => handle_edu_device_list_update(client, origin, content).await?,
|
||||
Edu::DirectToDevice(content) => handle_edu_direct_to_device(client, origin, content).await?,
|
||||
Edu::SigningKeyUpdate(content) => handle_edu_signing_key_update(client, origin, content).await?,
|
||||
Edu::Presence(presence) => handle_edu_presence(services, client, origin, presence).await?,
|
||||
Edu::Receipt(receipt) => handle_edu_receipt(services, client, origin, receipt).await?,
|
||||
Edu::Typing(typing) => handle_edu_typing(services, client, origin, typing).await?,
|
||||
Edu::DeviceListUpdate(content) => handle_edu_device_list_update(services, client, origin, content).await?,
|
||||
Edu::DirectToDevice(content) => handle_edu_direct_to_device(services, client, origin, content).await?,
|
||||
Edu::SigningKeyUpdate(content) => handle_edu_signing_key_update(services, client, origin, content).await?,
|
||||
Edu::_Custom(ref _custom) => {
|
||||
debug_warn!(?body.edus, "received custom/unknown EDU");
|
||||
},
|
||||
@@ -185,8 +180,10 @@ async fn handle_edus(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_edu_presence(_client: &IpAddr, origin: &ServerName, presence: PresenceContent) -> Result<()> {
|
||||
if !services().globals.allow_incoming_presence() {
|
||||
async fn handle_edu_presence(
|
||||
services: &Services, _client: &IpAddr, origin: &ServerName, presence: PresenceContent,
|
||||
) -> Result<()> {
|
||||
if !services.globals.allow_incoming_presence() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -199,7 +196,7 @@ async fn handle_edu_presence(_client: &IpAddr, origin: &ServerName, presence: Pr
|
||||
continue;
|
||||
}
|
||||
|
||||
services().presence.set_presence(
|
||||
services.presence.set_presence(
|
||||
&update.user_id,
|
||||
&update.presence,
|
||||
Some(update.currently_active),
|
||||
@@ -211,13 +208,15 @@ async fn handle_edu_presence(_client: &IpAddr, origin: &ServerName, presence: Pr
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: ReceiptContent) -> Result<()> {
|
||||
if !services().globals.allow_incoming_read_receipts() {
|
||||
async fn handle_edu_receipt(
|
||||
services: &Services, _client: &IpAddr, origin: &ServerName, receipt: ReceiptContent,
|
||||
) -> Result<()> {
|
||||
if !services.globals.allow_incoming_read_receipts() {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
for (room_id, room_updates) in receipt.receipts {
|
||||
if services()
|
||||
if services
|
||||
.rooms
|
||||
.event_handler
|
||||
.acl_check(origin, &room_id)
|
||||
@@ -239,7 +238,7 @@ async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: Rece
|
||||
continue;
|
||||
}
|
||||
|
||||
if services()
|
||||
if services
|
||||
.rooms
|
||||
.state_cache
|
||||
.room_members(&room_id)
|
||||
@@ -255,7 +254,7 @@ async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: Rece
|
||||
room_id: room_id.clone(),
|
||||
};
|
||||
|
||||
services()
|
||||
services
|
||||
.rooms
|
||||
.read_receipt
|
||||
.readreceipt_update(&user_id, &room_id, &event)?;
|
||||
@@ -273,8 +272,10 @@ async fn handle_edu_receipt(_client: &IpAddr, origin: &ServerName, receipt: Rece
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: TypingContent) -> Result<()> {
|
||||
if !services().globals.config.allow_incoming_typing {
|
||||
async fn handle_edu_typing(
|
||||
services: &Services, _client: &IpAddr, origin: &ServerName, typing: TypingContent,
|
||||
) -> Result<()> {
|
||||
if !services.globals.config.allow_incoming_typing {
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
@@ -286,7 +287,7 @@ async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: Typing
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if services()
|
||||
if services
|
||||
.rooms
|
||||
.event_handler
|
||||
.acl_check(typing.user_id.server_name(), &typing.room_id)
|
||||
@@ -299,26 +300,26 @@ async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: Typing
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if services()
|
||||
if services
|
||||
.rooms
|
||||
.state_cache
|
||||
.is_joined(&typing.user_id, &typing.room_id)?
|
||||
{
|
||||
if typing.typing {
|
||||
let timeout = utils::millis_since_unix_epoch().saturating_add(
|
||||
services()
|
||||
services
|
||||
.globals
|
||||
.config
|
||||
.typing_federation_timeout_s
|
||||
.saturating_mul(1000),
|
||||
);
|
||||
services()
|
||||
services
|
||||
.rooms
|
||||
.typing
|
||||
.typing_add(&typing.user_id, &typing.room_id, timeout)
|
||||
.await?;
|
||||
} else {
|
||||
services()
|
||||
services
|
||||
.rooms
|
||||
.typing
|
||||
.typing_remove(&typing.user_id, &typing.room_id)
|
||||
@@ -336,7 +337,7 @@ async fn handle_edu_typing(_client: &IpAddr, origin: &ServerName, typing: Typing
|
||||
}
|
||||
|
||||
async fn handle_edu_device_list_update(
|
||||
_client: &IpAddr, origin: &ServerName, content: DeviceListUpdateContent,
|
||||
services: &Services, _client: &IpAddr, origin: &ServerName, content: DeviceListUpdateContent,
|
||||
) -> Result<()> {
|
||||
let DeviceListUpdateContent {
|
||||
user_id,
|
||||
@@ -351,13 +352,13 @@ async fn handle_edu_device_list_update(
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
services().users.mark_device_key_update(&user_id)?;
|
||||
services.users.mark_device_key_update(&user_id)?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn handle_edu_direct_to_device(
|
||||
_client: &IpAddr, origin: &ServerName, content: DirectDeviceContent,
|
||||
services: &Services, _client: &IpAddr, origin: &ServerName, content: DirectDeviceContent,
|
||||
) -> Result<()> {
|
||||
let DirectDeviceContent {
|
||||
sender,
|
||||
@@ -375,7 +376,7 @@ async fn handle_edu_direct_to_device(
|
||||
}
|
||||
|
||||
// Check if this is a new transaction id
|
||||
if services()
|
||||
if services
|
||||
.transaction_ids
|
||||
.existing_txnid(&sender, None, &message_id)?
|
||||
.is_some()
|
||||
@@ -387,28 +388,27 @@ async fn handle_edu_direct_to_device(
|
||||
for (target_device_id_maybe, event) in map {
|
||||
match target_device_id_maybe {
|
||||
DeviceIdOrAllDevices::DeviceId(target_device_id) => {
|
||||
services().users.add_to_device_event(
|
||||
services.users.add_to_device_event(
|
||||
&sender,
|
||||
target_user_id,
|
||||
target_device_id,
|
||||
&ev_type.to_string(),
|
||||
event.deserialize_as().map_err(|e| {
|
||||
error!("To-Device event is invalid: {event:?} {e}");
|
||||
Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid")
|
||||
})?,
|
||||
event
|
||||
.deserialize_as()
|
||||
.map_err(|e| err!(Request(InvalidParam(error!("To-Device event is invalid: {e}")))))?,
|
||||
)?;
|
||||
},
|
||||
|
||||
DeviceIdOrAllDevices::AllDevices => {
|
||||
for target_device_id in services().users.all_device_ids(target_user_id) {
|
||||
services().users.add_to_device_event(
|
||||
for target_device_id in services.users.all_device_ids(target_user_id) {
|
||||
services.users.add_to_device_event(
|
||||
&sender,
|
||||
target_user_id,
|
||||
&target_device_id?,
|
||||
&ev_type.to_string(),
|
||||
event
|
||||
.deserialize_as()
|
||||
.map_err(|_| Error::BadRequest(ErrorKind::InvalidParam, "Event is invalid"))?,
|
||||
.map_err(|e| err!(Request(InvalidParam("Event is invalid: {e}"))))?,
|
||||
)?;
|
||||
}
|
||||
},
|
||||
@@ -417,7 +417,7 @@ async fn handle_edu_direct_to_device(
|
||||
}
|
||||
|
||||
// Save transaction id with empty data
|
||||
services()
|
||||
services
|
||||
.transaction_ids
|
||||
.add_txnid(&sender, None, &message_id, &[])?;
|
||||
|
||||
@@ -425,7 +425,7 @@ async fn handle_edu_direct_to_device(
|
||||
}
|
||||
|
||||
async fn handle_edu_signing_key_update(
|
||||
_client: &IpAddr, origin: &ServerName, content: SigningKeyUpdateContent,
|
||||
services: &Services, _client: &IpAddr, origin: &ServerName, content: SigningKeyUpdateContent,
|
||||
) -> Result<()> {
|
||||
let SigningKeyUpdateContent {
|
||||
user_id,
|
||||
@@ -442,7 +442,7 @@ async fn handle_edu_signing_key_update(
|
||||
}
|
||||
|
||||
if let Some(master_key) = master_key {
|
||||
services()
|
||||
services
|
||||
.users
|
||||
.add_cross_signing_keys(&user_id, &master_key, &self_signing_key, &None, true)?;
|
||||
}
|
||||
|
||||
@@ -58,8 +58,8 @@ pub struct Config {
|
||||
|
||||
#[serde(default = "default_pdu_cache_capacity")]
|
||||
pub pdu_cache_capacity: u32,
|
||||
#[serde(default = "default_conduit_cache_capacity_modifier")]
|
||||
pub conduit_cache_capacity_modifier: f64,
|
||||
#[serde(default = "default_cache_capacity_modifier", alias = "conduit_cache_capacity_modifier")]
|
||||
pub cache_capacity_modifier: f64,
|
||||
#[serde(default = "default_auth_chain_cache_capacity")]
|
||||
pub auth_chain_cache_capacity: u32,
|
||||
#[serde(default = "default_shorteventid_cache_capacity")]
|
||||
@@ -391,8 +391,9 @@ struct ListeningAddr {
|
||||
addrs: Either<IpAddr, Vec<IpAddr>>,
|
||||
}
|
||||
|
||||
const DEPRECATED_KEYS: &[&str] = &[
|
||||
const DEPRECATED_KEYS: &[&str; 9] = &[
|
||||
"cache_capacity",
|
||||
"conduit_cache_capacity_modifier",
|
||||
"max_concurrent_requests",
|
||||
"well_known_client",
|
||||
"well_known_server",
|
||||
@@ -484,7 +485,7 @@ impl fmt::Display for Config {
|
||||
);
|
||||
line("Database backups to keep", &self.database_backups_to_keep.to_string());
|
||||
line("Database cache capacity (MB)", &self.db_cache_capacity_mb.to_string());
|
||||
line("Cache capacity modifier", &self.conduit_cache_capacity_modifier.to_string());
|
||||
line("Cache capacity modifier", &self.cache_capacity_modifier.to_string());
|
||||
line("PDU cache capacity", &self.pdu_cache_capacity.to_string());
|
||||
line("Auth chain cache capacity", &self.auth_chain_cache_capacity.to_string());
|
||||
line("Short eventid cache capacity", &self.shorteventid_cache_capacity.to_string());
|
||||
@@ -847,7 +848,7 @@ fn default_db_cache_capacity_mb() -> f64 { 256.0 }
|
||||
|
||||
fn default_pdu_cache_capacity() -> u32 { 150_000 }
|
||||
|
||||
fn default_conduit_cache_capacity_modifier() -> f64 { 1.0 }
|
||||
fn default_cache_capacity_modifier() -> f64 { 1.0 }
|
||||
|
||||
fn default_auth_chain_cache_capacity() -> u32 { 100_000 }
|
||||
|
||||
|
||||
@@ -31,6 +31,7 @@
|
||||
//! Err(Database(error!("problem with db: {msg}")))` logs the error at the
|
||||
//! callsite and then returns the error with the same string. Caller has the
|
||||
//! option of replacing `error!` with `debug_error!`.
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! Err {
|
||||
($($args:tt)*) => {
|
||||
@@ -49,14 +50,16 @@ macro_rules! err {
|
||||
$crate::$level!($($args),*);
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::forbidden(),
|
||||
$crate::format_maybe!($($args),*)
|
||||
$crate::format_maybe!($($args),*),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
}};
|
||||
|
||||
(Request(Forbidden($($args:expr),*))) => {
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::forbidden(),
|
||||
$crate::format_maybe!($($args),*)
|
||||
$crate::format_maybe!($($args),*),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
};
|
||||
|
||||
@@ -64,14 +67,16 @@ macro_rules! err {
|
||||
$crate::$level!($($args),*);
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::$variant,
|
||||
$crate::format_maybe!($($args),*)
|
||||
$crate::format_maybe!($($args),*),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
}};
|
||||
|
||||
(Request($variant:ident($($args:expr),*))) => {
|
||||
$crate::error::Error::Request(
|
||||
::ruma::api::client::error::ErrorKind::$variant,
|
||||
$crate::format_maybe!($($args),*)
|
||||
$crate::format_maybe!($($args),*),
|
||||
::http::StatusCode::BAD_REQUEST
|
||||
)
|
||||
};
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ pub enum Error {
|
||||
#[error("{0}: {1}")]
|
||||
BadRequest(ruma::api::client::error::ErrorKind, &'static str), //TODO: remove
|
||||
#[error("{0}: {1}")]
|
||||
Request(ruma::api::client::error::ErrorKind, Cow<'static, str>),
|
||||
Request(ruma::api::client::error::ErrorKind, Cow<'static, str>, http::StatusCode),
|
||||
#[error("from {0}: {1}")]
|
||||
Redaction(ruma::OwnedServerName, ruma::canonical_json::RedactionError),
|
||||
#[error("Remote server {0} responded with: {1}")]
|
||||
@@ -78,7 +78,7 @@ pub enum Error {
|
||||
|
||||
// conduwuit
|
||||
#[error("Arithmetic operation failed: {0}")]
|
||||
Arithmetic(&'static str),
|
||||
Arithmetic(Cow<'static, str>),
|
||||
#[error("There was a problem with the '{0}' directive in your configuration: {1}")]
|
||||
Config(&'static str, Cow<'static, str>),
|
||||
#[error("{0}")]
|
||||
@@ -120,7 +120,7 @@ impl Error {
|
||||
|
||||
match self {
|
||||
Self::Federation(_, error) => response::ruma_error_kind(error).clone(),
|
||||
Self::BadRequest(kind, _) | Self::Request(kind, _) => kind.clone(),
|
||||
Self::BadRequest(kind, ..) | Self::Request(kind, ..) => kind.clone(),
|
||||
_ => Unknown,
|
||||
}
|
||||
}
|
||||
@@ -128,7 +128,8 @@ impl Error {
|
||||
pub fn status_code(&self) -> http::StatusCode {
|
||||
match self {
|
||||
Self::Federation(_, ref error) | Self::RumaError(ref error) => error.status_code,
|
||||
Self::BadRequest(ref kind, _) | Self::Request(ref kind, _) => response::bad_request_code(kind),
|
||||
Self::Request(ref kind, _, code) => response::status_code(kind, *code),
|
||||
Self::BadRequest(ref kind, ..) => response::bad_request_code(kind),
|
||||
Self::Conflict(_) => http::StatusCode::CONFLICT,
|
||||
_ => http::StatusCode::INTERNAL_SERVER_ERROR,
|
||||
}
|
||||
|
||||
+38
-16
@@ -1,7 +1,13 @@
|
||||
use bytes::BytesMut;
|
||||
use http::StatusCode;
|
||||
use http_body_util::Full;
|
||||
use ruma::api::{client::uiaa::UiaaResponse, OutgoingResponse};
|
||||
use ruma::api::{
|
||||
client::{
|
||||
error::{ErrorBody, ErrorKind},
|
||||
uiaa::UiaaResponse,
|
||||
},
|
||||
OutgoingResponse,
|
||||
};
|
||||
|
||||
use super::Error;
|
||||
use crate::error;
|
||||
@@ -25,7 +31,7 @@ impl From<Error> for UiaaResponse {
|
||||
return Self::AuthResponse(uiaainfo);
|
||||
}
|
||||
|
||||
let body = ruma::api::client::error::ErrorBody::Standard {
|
||||
let body = ErrorBody::Standard {
|
||||
kind: error.kind(),
|
||||
message: error.message(),
|
||||
};
|
||||
@@ -37,10 +43,33 @@ impl From<Error> for UiaaResponse {
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn bad_request_code(kind: &ruma::api::client::error::ErrorKind) -> StatusCode {
|
||||
use ruma::api::client::error::ErrorKind::*;
|
||||
pub(super) fn status_code(kind: &ErrorKind, hint: StatusCode) -> StatusCode {
|
||||
if hint == StatusCode::BAD_REQUEST {
|
||||
bad_request_code(kind)
|
||||
} else {
|
||||
hint
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn bad_request_code(kind: &ErrorKind) -> StatusCode {
|
||||
use ErrorKind::*;
|
||||
|
||||
match kind {
|
||||
// 429
|
||||
LimitExceeded {
|
||||
..
|
||||
} => StatusCode::TOO_MANY_REQUESTS,
|
||||
|
||||
// 413
|
||||
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
||||
|
||||
// 405
|
||||
Unrecognized => StatusCode::METHOD_NOT_ALLOWED,
|
||||
|
||||
// 404
|
||||
NotFound => StatusCode::NOT_FOUND,
|
||||
|
||||
// 403
|
||||
GuestAccessForbidden
|
||||
| ThreepidAuthFailed
|
||||
| UserDeactivated
|
||||
@@ -52,26 +81,20 @@ pub(super) fn bad_request_code(kind: &ruma::api::client::error::ErrorKind) -> St
|
||||
..
|
||||
} => StatusCode::FORBIDDEN,
|
||||
|
||||
// 401
|
||||
UnknownToken {
|
||||
..
|
||||
}
|
||||
| MissingToken
|
||||
| Unauthorized => StatusCode::UNAUTHORIZED,
|
||||
|
||||
LimitExceeded {
|
||||
..
|
||||
} => StatusCode::TOO_MANY_REQUESTS,
|
||||
|
||||
TooLarge => StatusCode::PAYLOAD_TOO_LARGE,
|
||||
|
||||
NotFound | Unrecognized => StatusCode::NOT_FOUND,
|
||||
|
||||
// 400
|
||||
_ => StatusCode::BAD_REQUEST,
|
||||
}
|
||||
}
|
||||
|
||||
pub(super) fn ruma_error_message(error: &ruma::api::client::error::Error) -> String {
|
||||
if let ruma::api::client::error::ErrorBody::Standard {
|
||||
if let ErrorBody::Standard {
|
||||
message,
|
||||
..
|
||||
} = &error.body
|
||||
@@ -82,7 +105,6 @@ pub(super) fn ruma_error_message(error: &ruma::api::client::error::Error) -> Str
|
||||
format!("{error}")
|
||||
}
|
||||
|
||||
pub(super) fn ruma_error_kind(e: &ruma::api::client::error::Error) -> &ruma::api::client::error::ErrorKind {
|
||||
e.error_kind()
|
||||
.unwrap_or(&ruma::api::client::error::ErrorKind::Unknown)
|
||||
pub(super) fn ruma_error_kind(e: &ruma::api::client::error::Error) -> &ErrorKind {
|
||||
e.error_kind().unwrap_or(&ErrorKind::Unknown)
|
||||
}
|
||||
|
||||
+6
-1
@@ -116,7 +116,12 @@ impl PduEvent {
|
||||
.map_or_else(|| Ok(BTreeMap::new()), |u| serde_json::from_str(u.get()))
|
||||
.map_err(|_| Error::bad_database("Invalid unsigned in pdu event"))?;
|
||||
|
||||
unsigned.insert("age".to_owned(), to_raw_value(&1).unwrap());
|
||||
// deliberately allowing for the possibility of negative age
|
||||
let now: i128 = MilliSecondsSinceUnixEpoch::now().get().into();
|
||||
let then: i128 = self.origin_server_ts.into();
|
||||
let this_age: i128 = now.saturating_sub(then);
|
||||
|
||||
unsigned.insert("age".to_owned(), to_raw_value(&this_age).unwrap());
|
||||
self.unsigned = Some(to_raw_value(&unsigned).expect("unsigned is valid"));
|
||||
|
||||
Ok(())
|
||||
|
||||
@@ -2,14 +2,14 @@ use std::{cmp, time::Duration};
|
||||
|
||||
pub use checked_ops::checked_ops;
|
||||
|
||||
use crate::{Error, Result};
|
||||
use crate::{Err, Error, Result};
|
||||
|
||||
/// Checked arithmetic expression. Returns a Result<R, Error::Arithmetic>
|
||||
#[macro_export]
|
||||
macro_rules! checked {
|
||||
($($input:tt)*) => {
|
||||
$crate::utils::math::checked_ops!($($input)*)
|
||||
.ok_or_else(|| $crate::Error::Arithmetic("operation overflowed or result invalid"))
|
||||
.ok_or_else(|| $crate::err!(Arithmetic("operation overflowed or result invalid")))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,7 +21,7 @@ macro_rules! validated {
|
||||
($($input:tt)*) => {
|
||||
//#[allow(clippy::arithmetic_side_effects)] {
|
||||
//Some($($input)*)
|
||||
// .ok_or_else(|| $crate::Error::Arithmetic("this error should never been seen"))
|
||||
// .ok_or_else(|| $crate::err!(Arithmetic("this error should never been seen")))
|
||||
//}
|
||||
|
||||
//NOTE: remove me when stmt_expr_attributes is stable
|
||||
@@ -57,7 +57,7 @@ pub fn continue_exponential_backoff(min: Duration, max: Duration, elapsed: Durat
|
||||
#[allow(clippy::as_conversions)]
|
||||
pub fn usize_from_f64(val: f64) -> Result<usize, Error> {
|
||||
if val < 0.0 {
|
||||
return Err(Error::Arithmetic("Converting negative float to unsigned integer"));
|
||||
return Err!(Arithmetic("Converting negative float to unsigned integer"));
|
||||
}
|
||||
|
||||
//SAFETY: <https://doc.rust-lang.org/std/primitive.f64.html#method.to_int_unchecked>
|
||||
|
||||
@@ -310,7 +310,7 @@ fn set_table_with_shared_cache(
|
||||
}
|
||||
|
||||
fn cache_size(config: &Config, base_size: u32, entity_size: usize) -> usize {
|
||||
let ents = f64::from(base_size) * config.conduit_cache_capacity_modifier;
|
||||
let ents = f64::from(base_size) * config.cache_capacity_modifier;
|
||||
|
||||
#[allow(clippy::as_conversions, clippy::cast_sign_loss, clippy::cast_possible_truncation)]
|
||||
(ents as usize)
|
||||
|
||||
@@ -5,7 +5,7 @@ use axum::{
|
||||
Router,
|
||||
};
|
||||
use axum_client_ip::SecureClientIpSource;
|
||||
use conduit::{Result, Server};
|
||||
use conduit::{error, Result, Server};
|
||||
use http::{
|
||||
header::{self, HeaderName},
|
||||
HeaderValue, Method, StatusCode,
|
||||
@@ -149,7 +149,7 @@ fn cors_layer(_server: &Server) -> CorsLayer {
|
||||
fn body_limit_layer(server: &Server) -> DefaultBodyLimit { DefaultBodyLimit::max(server.config.max_request_size) }
|
||||
|
||||
#[allow(clippy::needless_pass_by_value)]
|
||||
#[tracing::instrument(skip_all)]
|
||||
#[tracing::instrument(skip_all, name = "panic")]
|
||||
fn catch_panic(err: Box<dyn Any + Send + 'static>) -> http::Response<http_body_util::Full<bytes::Bytes>> {
|
||||
conduit_service::services()
|
||||
.server
|
||||
@@ -165,17 +165,17 @@ fn catch_panic(err: Box<dyn Any + Send + 'static>) -> http::Response<http_body_u
|
||||
"Unknown internal server error occurred.".to_owned()
|
||||
};
|
||||
|
||||
error!("{details:#}");
|
||||
let body = serde_json::json!({
|
||||
"errcode": "M_UNKNOWN",
|
||||
"error": "M_UNKNOWN: Internal server error occurred",
|
||||
"details": details,
|
||||
})
|
||||
.to_string();
|
||||
});
|
||||
|
||||
http::Response::builder()
|
||||
.status(StatusCode::INTERNAL_SERVER_ERROR)
|
||||
.header(header::CONTENT_TYPE, "application/json")
|
||||
.body(http_body_util::Full::from(body))
|
||||
.body(http_body_util::Full::from(body.to_string()))
|
||||
.expect("Failed to create response for our panic catcher?")
|
||||
}
|
||||
|
||||
|
||||
+8
-23
@@ -4,9 +4,8 @@ use axum::{
|
||||
extract::State,
|
||||
response::{IntoResponse, Response},
|
||||
};
|
||||
use conduit::{debug, debug_error, debug_warn, defer, error, trace, Error, Result, Server};
|
||||
use conduit::{debug, debug_error, debug_warn, defer, err, error, trace, Result, Server};
|
||||
use http::{Method, StatusCode, Uri};
|
||||
use ruma::api::client::error::{Error as RumaError, ErrorBody, ErrorKind};
|
||||
|
||||
#[tracing::instrument(skip_all, level = "debug")]
|
||||
pub(crate) async fn spawn(
|
||||
@@ -58,33 +57,13 @@ pub(crate) async fn handle(
|
||||
trace!(active, finished, "leave");
|
||||
}};
|
||||
|
||||
let method = req.method().clone();
|
||||
let uri = req.uri().clone();
|
||||
let method = req.method().clone();
|
||||
let result = next.run(req).await;
|
||||
handle_result(&method, &uri, result)
|
||||
}
|
||||
|
||||
fn handle_result(method: &Method, uri: &Uri, result: Response) -> Result<Response, StatusCode> {
|
||||
handle_result_log(method, uri, &result);
|
||||
match result.status() {
|
||||
StatusCode::METHOD_NOT_ALLOWED => handle_result_405(method, uri, &result),
|
||||
_ => Ok(result),
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_result_405(_method: &Method, _uri: &Uri, result: &Response) -> Result<Response, StatusCode> {
|
||||
let error = Error::RumaError(RumaError {
|
||||
status_code: result.status(),
|
||||
body: ErrorBody::Standard {
|
||||
kind: ErrorKind::Unrecognized,
|
||||
message: "M_UNRECOGNIZED: Method not allowed for endpoint".to_owned(),
|
||||
},
|
||||
});
|
||||
|
||||
Ok(error.into_response())
|
||||
}
|
||||
|
||||
fn handle_result_log(method: &Method, uri: &Uri, result: &Response) {
|
||||
let status = result.status();
|
||||
let reason = status.canonical_reason().unwrap_or("Unknown Reason");
|
||||
let code = status.as_u16();
|
||||
@@ -97,4 +76,10 @@ fn handle_result_log(method: &Method, uri: &Uri, result: &Response) {
|
||||
} else {
|
||||
trace!(method = ?method, uri = ?uri, "{code} {reason}");
|
||||
}
|
||||
|
||||
if status == StatusCode::METHOD_NOT_ALLOWED {
|
||||
return Ok(err!(Request(Unrecognized("Method Not Allowed"))).into_response());
|
||||
}
|
||||
|
||||
Ok(result)
|
||||
}
|
||||
|
||||
@@ -2,24 +2,23 @@ use std::sync::Arc;
|
||||
|
||||
use axum::{response::IntoResponse, routing::get, Router};
|
||||
use conduit::{Error, Server};
|
||||
use conduit_service as service;
|
||||
use http::Uri;
|
||||
use http::{StatusCode, Uri};
|
||||
use ruma::api::client::error::ErrorKind;
|
||||
|
||||
extern crate conduit_api as api;
|
||||
extern crate conduit_service as service;
|
||||
|
||||
pub(crate) fn build(server: &Arc<Server>) -> Router {
|
||||
let state = service::services();
|
||||
let router = Router::new()
|
||||
let router = Router::<api::State>::new();
|
||||
|
||||
api::router::build(router, server)
|
||||
.route("/", get(it_works))
|
||||
.fallback(not_found)
|
||||
.with_state(state);
|
||||
|
||||
api::routes::build(router, server)
|
||||
.with_state(service::services())
|
||||
}
|
||||
|
||||
async fn not_found(_uri: Uri) -> impl IntoResponse {
|
||||
Error::BadRequest(ErrorKind::Unrecognized, "Unrecognized request")
|
||||
Error::Request(ErrorKind::Unrecognized, "Not Found".into(), StatusCode::NOT_FOUND)
|
||||
}
|
||||
|
||||
async fn it_works() -> &'static str { "hewwo from conduwuit woof!" }
|
||||
|
||||
@@ -127,8 +127,8 @@ async fn fini(server: &Arc<Server>, listener: UnixListener, mut tasks: JoinSet<(
|
||||
debug!("Waiting for requests to finish...");
|
||||
while server.metrics.requests_spawn_active.load(Ordering::Relaxed) > 0 {
|
||||
tokio::select! {
|
||||
_ = tasks.join_next() => {}
|
||||
() = sleep(FINI_POLL_INTERVAL) => {}
|
||||
task = tasks.join_next() => if task.is_none() { break; },
|
||||
() = sleep(FINI_POLL_INTERVAL) => {},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -57,7 +57,6 @@ lru-cache.workspace = true
|
||||
rand.workspace = true
|
||||
regex.workspace = true
|
||||
reqwest.workspace = true
|
||||
ruma-identifiers-validation.workspace = true
|
||||
ruma.workspace = true
|
||||
rustyline-async.workspace = true
|
||||
rustyline-async.optional = true
|
||||
|
||||
@@ -9,7 +9,7 @@ use std::{
|
||||
};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use conduit::{debug, error, Error, Result};
|
||||
use conduit::{debug, error, error::default_log, Error, Result};
|
||||
pub use create::create_admin_room;
|
||||
pub use grant::make_user_admin;
|
||||
use loole::{Receiver, Sender};
|
||||
@@ -239,9 +239,9 @@ async fn respond_to_room(content: RoomMessageEventContent, room_id: &RoomId, use
|
||||
.build_and_append_pdu(response_pdu, user_id, room_id, &state_lock)
|
||||
.await
|
||||
{
|
||||
if let Err(e) = handle_response_error(e, room_id, user_id, &state_lock).await {
|
||||
error!("{e}");
|
||||
}
|
||||
handle_response_error(e, room_id, user_id, &state_lock)
|
||||
.await
|
||||
.unwrap_or_else(default_log);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -39,7 +39,6 @@ pub struct Service {
|
||||
pub stable_room_versions: Vec<RoomVersionId>,
|
||||
pub unstable_room_versions: Vec<RoomVersionId>,
|
||||
pub bad_event_ratelimiter: Arc<RwLock<HashMap<OwnedEventId, RateLimitState>>>,
|
||||
pub bad_signature_ratelimiter: Arc<RwLock<HashMap<Vec<String>, RateLimitState>>>,
|
||||
pub bad_query_ratelimiter: Arc<RwLock<HashMap<OwnedServerName, RateLimitState>>>,
|
||||
pub stateres_mutex: Arc<Mutex<()>>,
|
||||
pub server_user: OwnedUserId,
|
||||
@@ -101,7 +100,6 @@ impl crate::Service for Service {
|
||||
stable_room_versions,
|
||||
unstable_room_versions,
|
||||
bad_event_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
||||
bad_signature_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
||||
bad_query_ratelimiter: Arc::new(RwLock::new(HashMap::new())),
|
||||
stateres_mutex: Arc::new(Mutex::new(())),
|
||||
admin_alias: RoomAliasId::parse(format!("#admins:{}", &config.server_name))
|
||||
@@ -144,13 +142,6 @@ impl crate::Service for Service {
|
||||
.len();
|
||||
writeln!(out, "bad_query_ratelimiter: {bad_query_ratelimiter}")?;
|
||||
|
||||
let bad_signature_ratelimiter = self
|
||||
.bad_signature_ratelimiter
|
||||
.read()
|
||||
.expect("locked for reading")
|
||||
.len();
|
||||
writeln!(out, "bad_signature_ratelimiter: {bad_signature_ratelimiter}")?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -166,11 +157,6 @@ impl crate::Service for Service {
|
||||
.write()
|
||||
.expect("locked for writing")
|
||||
.clear();
|
||||
|
||||
self.bad_signature_ratelimiter
|
||||
.write()
|
||||
.expect("locked for writing")
|
||||
.clear();
|
||||
}
|
||||
|
||||
fn name(&self) -> &str { crate::service::make_name(std::module_path!()) }
|
||||
|
||||
@@ -12,6 +12,13 @@ pub(crate) struct Data {
|
||||
url_previews: Arc<Map>,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
pub(super) struct Metadata {
|
||||
pub(super) content_disposition: Option<String>,
|
||||
pub(super) content_type: Option<String>,
|
||||
pub(super) key: Vec<u8>,
|
||||
}
|
||||
|
||||
impl Data {
|
||||
pub(super) fn new(db: &Arc<Database>) -> Self {
|
||||
Self {
|
||||
@@ -104,9 +111,7 @@ impl Data {
|
||||
Ok(keys)
|
||||
}
|
||||
|
||||
pub(super) fn search_file_metadata(
|
||||
&self, mxc: &str, width: u32, height: u32,
|
||||
) -> Result<(Option<String>, Option<String>, Vec<u8>)> {
|
||||
pub(super) fn search_file_metadata(&self, mxc: &str, width: u32, height: u32) -> Result<Metadata> {
|
||||
let mut prefix = mxc.as_bytes().to_vec();
|
||||
prefix.push(0xFF);
|
||||
prefix.extend_from_slice(&width.to_be_bytes());
|
||||
@@ -141,7 +146,12 @@ impl Data {
|
||||
.map_err(|_| Error::bad_database("Content Disposition in mediaid_file is invalid unicode."))?,
|
||||
)
|
||||
};
|
||||
Ok((content_disposition, content_type, key))
|
||||
|
||||
Ok(Metadata {
|
||||
content_disposition,
|
||||
content_type,
|
||||
key,
|
||||
})
|
||||
}
|
||||
|
||||
/// Gets all the media keys in our database (this includes all the metadata
|
||||
|
||||
+33
-183
@@ -1,13 +1,13 @@
|
||||
mod data;
|
||||
mod tests;
|
||||
mod thumbnail;
|
||||
|
||||
use std::{collections::HashMap, io::Cursor, num::Saturating as Sat, path::PathBuf, sync::Arc, time::SystemTime};
|
||||
use std::{collections::HashMap, path::PathBuf, sync::Arc, time::SystemTime};
|
||||
|
||||
use async_trait::async_trait;
|
||||
use base64::{engine::general_purpose, Engine as _};
|
||||
use conduit::{checked, debug, debug_error, error, utils, Error, Result, Server};
|
||||
use data::Data;
|
||||
use image::imageops::FilterType;
|
||||
use conduit::{debug, debug_error, err, error, utils, Err, Result, Server};
|
||||
use data::{Data, Metadata};
|
||||
use ruma::{OwnedMxcUri, OwnedUserId};
|
||||
use serde::Serialize;
|
||||
use tokio::{
|
||||
@@ -20,10 +20,9 @@ use crate::services;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct FileMeta {
|
||||
#[allow(dead_code)]
|
||||
pub content_disposition: Option<String>,
|
||||
pub content: Option<Vec<u8>>,
|
||||
pub content_type: Option<String>,
|
||||
pub file: Vec<u8>,
|
||||
pub content_disposition: Option<String>,
|
||||
}
|
||||
|
||||
#[derive(Serialize, Default)]
|
||||
@@ -101,47 +100,30 @@ impl Service {
|
||||
|
||||
Ok(())
|
||||
} else {
|
||||
error!("Failed to find any media keys for MXC \"{mxc}\" in our database (MXC does not exist)");
|
||||
Err(Error::bad_database(
|
||||
"Failed to find any media keys for the provided MXC in our database (MXC does not exist)",
|
||||
))
|
||||
Err!(Database(error!(
|
||||
"Failed to find any media keys for MXC {mxc:?} in our database."
|
||||
)))
|
||||
}
|
||||
}
|
||||
|
||||
/// Uploads or replaces a file thumbnail.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn upload_thumbnail(
|
||||
&self, sender_user: Option<OwnedUserId>, mxc: &str, content_disposition: Option<&str>,
|
||||
content_type: Option<&str>, width: u32, height: u32, file: &[u8],
|
||||
) -> Result<()> {
|
||||
let key = if let Some(user) = sender_user {
|
||||
self.db
|
||||
.create_file_metadata(Some(user.as_str()), mxc, width, height, content_disposition, content_type)?
|
||||
} else {
|
||||
self.db
|
||||
.create_file_metadata(None, mxc, width, height, content_disposition, content_type)?
|
||||
};
|
||||
|
||||
//TODO: Dangling metadata in database if creation fails
|
||||
let mut f = self.create_media_file(&key).await?;
|
||||
f.write_all(file).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Downloads a file.
|
||||
pub async fn get(&self, mxc: &str) -> Result<Option<FileMeta>> {
|
||||
if let Ok((content_disposition, content_type, key)) = self.db.search_file_metadata(mxc, 0, 0) {
|
||||
let mut file = Vec::new();
|
||||
if let Ok(Metadata {
|
||||
content_disposition,
|
||||
content_type,
|
||||
key,
|
||||
}) = self.db.search_file_metadata(mxc, 0, 0)
|
||||
{
|
||||
let mut content = Vec::new();
|
||||
let path = self.get_media_file(&key);
|
||||
BufReader::new(fs::File::open(path).await?)
|
||||
.read_to_end(&mut file)
|
||||
.read_to_end(&mut content)
|
||||
.await?;
|
||||
|
||||
Ok(Some(FileMeta {
|
||||
content_disposition,
|
||||
content: Some(content),
|
||||
content_type,
|
||||
file,
|
||||
content_disposition,
|
||||
}))
|
||||
} else {
|
||||
Ok(None)
|
||||
@@ -154,23 +136,16 @@ impl Service {
|
||||
let all_keys = self.db.get_all_media_keys();
|
||||
|
||||
let user_duration: SystemTime = match cyborgtime::parse_duration(&time) {
|
||||
Ok(duration) => {
|
||||
debug!("Parsed duration: {:?}", duration);
|
||||
debug!("System time now: {:?}", SystemTime::now());
|
||||
SystemTime::now().checked_sub(duration).ok_or_else(|| {
|
||||
Error::bad_database("Duration specified is not valid against the current system time")
|
||||
})?
|
||||
},
|
||||
Err(e) => {
|
||||
error!("Failed to parse user-specified time duration: {}", e);
|
||||
return Err(Error::bad_database("Failed to parse user-specified time duration."));
|
||||
},
|
||||
Err(e) => return Err!(Database(error!("Failed to parse specified time duration: {e}"))),
|
||||
Ok(duration) => SystemTime::now()
|
||||
.checked_sub(duration)
|
||||
.ok_or(err!(Arithmetic("Duration {duration:?} is too large")))?,
|
||||
};
|
||||
|
||||
let mut remote_mxcs: Vec<String> = vec![];
|
||||
|
||||
for key in all_keys {
|
||||
debug!("Full MXC key from database: {:?}", key);
|
||||
debug!("Full MXC key from database: {key:?}");
|
||||
|
||||
// we need to get the MXC URL from the first part of the key (the first 0xff /
|
||||
// 255 push). this is all necessary because of conduit using magic keys for
|
||||
@@ -179,24 +154,19 @@ impl Service {
|
||||
let mxc = parts
|
||||
.next()
|
||||
.map(|bytes| {
|
||||
utils::string_from_bytes(bytes).map_err(|e| {
|
||||
error!("Failed to parse MXC unicode bytes from our database: {}", e);
|
||||
Error::bad_database("Failed to parse MXC unicode bytes from our database")
|
||||
})
|
||||
utils::string_from_bytes(bytes)
|
||||
.map_err(|e| err!(Database(error!("Failed to parse MXC unicode bytes from our database: {e}"))))
|
||||
})
|
||||
.transpose()?;
|
||||
|
||||
let Some(mxc_s) = mxc else {
|
||||
return Err(Error::bad_database(
|
||||
"Parsed MXC URL unicode bytes from database but still is None",
|
||||
));
|
||||
return Err!(Database("Parsed MXC URL unicode bytes from database but still is None"));
|
||||
};
|
||||
|
||||
debug!("Parsed MXC key to URL: {}", mxc_s);
|
||||
|
||||
debug!("Parsed MXC key to URL: {mxc_s}");
|
||||
let mxc = OwnedMxcUri::from(mxc_s);
|
||||
if mxc.server_name() == Ok(services().globals.server_name()) {
|
||||
debug!("Ignoring local media MXC: {}", mxc);
|
||||
debug!("Ignoring local media MXC: {mxc}");
|
||||
// ignore our own MXC URLs as this would be local media.
|
||||
continue;
|
||||
}
|
||||
@@ -215,14 +185,14 @@ impl Service {
|
||||
},
|
||||
Err(err) => {
|
||||
if force {
|
||||
error!("Could not delete MXC path {:?}: {:?}. Skipping...", path, err);
|
||||
error!("Could not delete MXC path {path:?}: {err:?}. Skipping...");
|
||||
continue;
|
||||
}
|
||||
return Err(err.into());
|
||||
},
|
||||
};
|
||||
debug!("File created at: {:?}", file_created_at);
|
||||
|
||||
debug!("File created at: {file_created_at:?}");
|
||||
if file_created_at <= user_duration {
|
||||
debug!("File is within user duration, pushing to list of file paths and keys to delete.");
|
||||
remote_mxcs.push(mxc.to_string());
|
||||
@@ -232,15 +202,12 @@ impl Service {
|
||||
debug!(
|
||||
"Finished going through all our media in database for eligible keys to delete, checking if these are empty"
|
||||
);
|
||||
|
||||
if remote_mxcs.is_empty() {
|
||||
return Err(Error::bad_database("Did not found any eligible MXCs to delete."));
|
||||
return Err!(Database("Did not found any eligible MXCs to delete."));
|
||||
}
|
||||
|
||||
debug!("Deleting media now in the past \"{:?}\".", user_duration);
|
||||
|
||||
debug!("Deleting media now in the past {user_duration:?}.");
|
||||
let mut deletion_count: usize = 0;
|
||||
|
||||
for mxc in remote_mxcs {
|
||||
debug!("Deleting MXC {mxc} from database and filesystem");
|
||||
self.delete(&mxc).await?;
|
||||
@@ -250,123 +217,6 @@ impl Service {
|
||||
Ok(deletion_count)
|
||||
}
|
||||
|
||||
/// Returns width, height of the thumbnail and whether it should be cropped.
|
||||
/// Returns None when the server should send the original file.
|
||||
pub fn thumbnail_properties(&self, width: u32, height: u32) -> Option<(u32, u32, bool)> {
|
||||
match (width, height) {
|
||||
(0..=32, 0..=32) => Some((32, 32, true)),
|
||||
(0..=96, 0..=96) => Some((96, 96, true)),
|
||||
(0..=320, 0..=240) => Some((320, 240, false)),
|
||||
(0..=640, 0..=480) => Some((640, 480, false)),
|
||||
(0..=800, 0..=600) => Some((800, 600, false)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
/// Downloads a file's thumbnail.
|
||||
///
|
||||
/// Here's an example on how it works:
|
||||
///
|
||||
/// - Client requests an image with width=567, height=567
|
||||
/// - Server rounds that up to (800, 600), so it doesn't have to save too
|
||||
/// many thumbnails
|
||||
/// - Server rounds that up again to (958, 600) to fix the aspect ratio
|
||||
/// (only for width,height>96)
|
||||
/// - Server creates the thumbnail and sends it to the user
|
||||
///
|
||||
/// For width,height <= 96 the server uses another thumbnailing algorithm
|
||||
/// which crops the image afterwards.
|
||||
pub async fn get_thumbnail(&self, mxc: &str, width: u32, height: u32) -> Result<Option<FileMeta>> {
|
||||
let (width, height, crop) = self
|
||||
.thumbnail_properties(width, height)
|
||||
.unwrap_or((0, 0, false)); // 0, 0 because that's the original file
|
||||
|
||||
if let Ok((content_disposition, content_type, key)) = self.db.search_file_metadata(mxc, width, height) {
|
||||
// Using saved thumbnail
|
||||
let mut file = Vec::new();
|
||||
let path = self.get_media_file(&key);
|
||||
fs::File::open(path).await?.read_to_end(&mut file).await?;
|
||||
|
||||
Ok(Some(FileMeta {
|
||||
content_disposition,
|
||||
content_type,
|
||||
file: file.clone(),
|
||||
}))
|
||||
} else if let Ok((content_disposition, content_type, key)) = self.db.search_file_metadata(mxc, 0, 0) {
|
||||
// Generate a thumbnail
|
||||
let mut file = Vec::new();
|
||||
let path = self.get_media_file(&key);
|
||||
fs::File::open(path).await?.read_to_end(&mut file).await?;
|
||||
|
||||
if let Ok(image) = image::load_from_memory(&file) {
|
||||
let original_width = image.width();
|
||||
let original_height = image.height();
|
||||
if width > original_width || height > original_height {
|
||||
return Ok(Some(FileMeta {
|
||||
content_disposition,
|
||||
content_type,
|
||||
file: file.clone(),
|
||||
}));
|
||||
}
|
||||
|
||||
let thumbnail = if crop {
|
||||
image.resize_to_fill(width, height, FilterType::CatmullRom)
|
||||
} else {
|
||||
let (exact_width, exact_height) = {
|
||||
let ratio = Sat(original_width) * Sat(height);
|
||||
let nratio = Sat(width) * Sat(original_height);
|
||||
|
||||
let use_width = nratio <= ratio;
|
||||
let intermediate = if use_width {
|
||||
Sat(original_height) * Sat(checked!(width / original_width)?)
|
||||
} else {
|
||||
Sat(original_width) * Sat(checked!(height / original_height)?)
|
||||
};
|
||||
|
||||
if use_width {
|
||||
(width, intermediate.0)
|
||||
} else {
|
||||
(intermediate.0, height)
|
||||
}
|
||||
};
|
||||
|
||||
image.thumbnail_exact(exact_width, exact_height)
|
||||
};
|
||||
|
||||
let mut thumbnail_bytes = Vec::new();
|
||||
thumbnail.write_to(&mut Cursor::new(&mut thumbnail_bytes), image::ImageFormat::Png)?;
|
||||
|
||||
// Save thumbnail in database so we don't have to generate it again next time
|
||||
let thumbnail_key = self.db.create_file_metadata(
|
||||
None,
|
||||
mxc,
|
||||
width,
|
||||
height,
|
||||
content_disposition.as_deref(),
|
||||
content_type.as_deref(),
|
||||
)?;
|
||||
|
||||
let mut f = self.create_media_file(&thumbnail_key).await?;
|
||||
f.write_all(&thumbnail_bytes).await?;
|
||||
|
||||
Ok(Some(FileMeta {
|
||||
content_disposition,
|
||||
content_type,
|
||||
file: thumbnail_bytes.clone(),
|
||||
}))
|
||||
} else {
|
||||
// Couldn't parse file to generate thumbnail, send original
|
||||
Ok(Some(FileMeta {
|
||||
content_disposition,
|
||||
content_type,
|
||||
file: file.clone(),
|
||||
}))
|
||||
}
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
pub async fn get_url_preview(&self, url: &str) -> Option<UrlPreviewData> { self.db.get_url_preview(url) }
|
||||
|
||||
/// TODO: use this?
|
||||
|
||||
@@ -0,0 +1,174 @@
|
||||
use std::{cmp, io::Cursor, num::Saturating as Sat};
|
||||
|
||||
use conduit::{checked, Result};
|
||||
use image::{imageops::FilterType, DynamicImage};
|
||||
use ruma::OwnedUserId;
|
||||
use tokio::{
|
||||
fs,
|
||||
io::{AsyncReadExt, AsyncWriteExt},
|
||||
};
|
||||
|
||||
use super::{data::Metadata, FileMeta};
|
||||
|
||||
impl super::Service {
|
||||
/// Uploads or replaces a file thumbnail.
|
||||
#[allow(clippy::too_many_arguments)]
|
||||
pub async fn upload_thumbnail(
|
||||
&self, sender_user: Option<OwnedUserId>, mxc: &str, content_disposition: Option<&str>,
|
||||
content_type: Option<&str>, width: u32, height: u32, file: &[u8],
|
||||
) -> Result<()> {
|
||||
let key = if let Some(user) = sender_user {
|
||||
self.db
|
||||
.create_file_metadata(Some(user.as_str()), mxc, width, height, content_disposition, content_type)?
|
||||
} else {
|
||||
self.db
|
||||
.create_file_metadata(None, mxc, width, height, content_disposition, content_type)?
|
||||
};
|
||||
|
||||
//TODO: Dangling metadata in database if creation fails
|
||||
let mut f = self.create_media_file(&key).await?;
|
||||
f.write_all(file).await?;
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Downloads a file's thumbnail.
|
||||
///
|
||||
/// Here's an example on how it works:
|
||||
///
|
||||
/// - Client requests an image with width=567, height=567
|
||||
/// - Server rounds that up to (800, 600), so it doesn't have to save too
|
||||
/// many thumbnails
|
||||
/// - Server rounds that up again to (958, 600) to fix the aspect ratio
|
||||
/// (only for width,height>96)
|
||||
/// - Server creates the thumbnail and sends it to the user
|
||||
///
|
||||
/// For width,height <= 96 the server uses another thumbnailing algorithm
|
||||
/// which crops the image afterwards.
|
||||
#[tracing::instrument(skip(self), name = "thumbnail", level = "debug")]
|
||||
pub async fn get_thumbnail(&self, mxc: &str, width: u32, height: u32) -> Result<Option<FileMeta>> {
|
||||
// 0, 0 because that's the original file
|
||||
let (width, height, crop) = thumbnail_properties(width, height).unwrap_or((0, 0, false));
|
||||
|
||||
if let Ok(metadata) = self.db.search_file_metadata(mxc, width, height) {
|
||||
self.get_thumbnail_saved(metadata).await
|
||||
} else if let Ok(metadata) = self.db.search_file_metadata(mxc, 0, 0) {
|
||||
self.get_thumbnail_generate(mxc, width, height, crop, metadata)
|
||||
.await
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Using saved thumbnail
|
||||
#[tracing::instrument(skip(self), name = "saved", level = "debug")]
|
||||
async fn get_thumbnail_saved(&self, data: Metadata) -> Result<Option<FileMeta>> {
|
||||
let mut content = Vec::new();
|
||||
let path = self.get_media_file(&data.key);
|
||||
fs::File::open(path)
|
||||
.await?
|
||||
.read_to_end(&mut content)
|
||||
.await?;
|
||||
|
||||
Ok(Some(into_filemeta(data, content)))
|
||||
}
|
||||
|
||||
/// Generate a thumbnail
|
||||
#[tracing::instrument(skip(self), name = "generate", level = "debug")]
|
||||
async fn get_thumbnail_generate(
|
||||
&self, mxc: &str, width: u32, height: u32, crop: bool, data: Metadata,
|
||||
) -> Result<Option<FileMeta>> {
|
||||
let mut content = Vec::new();
|
||||
let path = self.get_media_file(&data.key);
|
||||
fs::File::open(path)
|
||||
.await?
|
||||
.read_to_end(&mut content)
|
||||
.await?;
|
||||
|
||||
let Ok(image) = image::load_from_memory(&content) else {
|
||||
// Couldn't parse file to generate thumbnail, send original
|
||||
return Ok(Some(into_filemeta(data, content)));
|
||||
};
|
||||
|
||||
if width > image.width() || height > image.height() {
|
||||
return Ok(Some(into_filemeta(data, content)));
|
||||
}
|
||||
|
||||
let mut thumbnail_bytes = Vec::new();
|
||||
let thumbnail = thumbnail_generate(&image, width, height, crop)?;
|
||||
thumbnail.write_to(&mut Cursor::new(&mut thumbnail_bytes), image::ImageFormat::Png)?;
|
||||
|
||||
// Save thumbnail in database so we don't have to generate it again next time
|
||||
let thumbnail_key = self.db.create_file_metadata(
|
||||
None,
|
||||
mxc,
|
||||
width,
|
||||
height,
|
||||
data.content_disposition.as_deref(),
|
||||
data.content_type.as_deref(),
|
||||
)?;
|
||||
|
||||
let mut f = self.create_media_file(&thumbnail_key).await?;
|
||||
f.write_all(&thumbnail_bytes).await?;
|
||||
|
||||
Ok(Some(into_filemeta(data, thumbnail_bytes)))
|
||||
}
|
||||
}
|
||||
|
||||
fn thumbnail_generate(image: &DynamicImage, width: u32, height: u32, crop: bool) -> Result<DynamicImage> {
|
||||
let thumbnail = if crop {
|
||||
image.resize_to_fill(width, height, FilterType::CatmullRom)
|
||||
} else {
|
||||
let (exact_width, exact_height) = thumbnail_dimension(image, width, height)?;
|
||||
image.thumbnail_exact(exact_width, exact_height)
|
||||
};
|
||||
|
||||
Ok(thumbnail)
|
||||
}
|
||||
|
||||
fn thumbnail_dimension(image: &DynamicImage, width: u32, height: u32) -> Result<(u32, u32)> {
|
||||
let image_width = image.width();
|
||||
let image_height = image.height();
|
||||
|
||||
let width = cmp::min(width, image_width);
|
||||
let height = cmp::min(height, image_height);
|
||||
|
||||
let use_width = Sat(width) * Sat(image_height) < Sat(height) * Sat(image_width);
|
||||
|
||||
let x = if use_width {
|
||||
let dividend = (Sat(height) * Sat(image_width)).0;
|
||||
checked!(dividend / image_height)?
|
||||
} else {
|
||||
width
|
||||
};
|
||||
|
||||
let y = if !use_width {
|
||||
let dividend = (Sat(width) * Sat(image_height)).0;
|
||||
checked!(dividend / image_width)?
|
||||
} else {
|
||||
height
|
||||
};
|
||||
|
||||
Ok((x, y))
|
||||
}
|
||||
|
||||
/// Returns width, height of the thumbnail and whether it should be cropped.
|
||||
/// Returns None when the server should send the original file.
|
||||
fn thumbnail_properties(width: u32, height: u32) -> Option<(u32, u32, bool)> {
|
||||
match (width, height) {
|
||||
(0..=32, 0..=32) => Some((32, 32, true)),
|
||||
(0..=96, 0..=96) => Some((96, 96, true)),
|
||||
(0..=320, 0..=240) => Some((320, 240, false)),
|
||||
(0..=640, 0..=480) => Some((640, 480, false)),
|
||||
(0..=800, 0..=600) => Some((800, 600, false)),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn into_filemeta(data: Metadata, content: Vec<u8>) -> FileMeta {
|
||||
FileMeta {
|
||||
content: Some(content),
|
||||
content_type: data.content_type,
|
||||
content_disposition: data.content_disposition,
|
||||
}
|
||||
}
|
||||
@@ -16,7 +16,7 @@ impl Data {
|
||||
pub(super) fn new(server: &Arc<Server>, db: &Arc<Database>) -> Self {
|
||||
let config = &server.config;
|
||||
let cache_size = f64::from(config.auth_chain_cache_capacity);
|
||||
let cache_size = usize_from_f64(cache_size * config.conduit_cache_capacity_modifier).expect("valid cache size");
|
||||
let cache_size = usize_from_f64(cache_size * config.cache_capacity_modifier).expect("valid cache size");
|
||||
Self {
|
||||
shorteventid_authchain: db["shorteventid_authchain"].clone(),
|
||||
auth_chain_cache: Mutex::new(LruCache::new(cache_size)),
|
||||
|
||||
@@ -161,7 +161,7 @@ impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
let config = &args.server.config;
|
||||
let cache_size = f64::from(config.roomid_spacehierarchy_cache_capacity);
|
||||
let cache_size = cache_size * config.conduit_cache_capacity_modifier;
|
||||
let cache_size = cache_size * config.cache_capacity_modifier;
|
||||
Ok(Arc::new(Self {
|
||||
roomid_spacehierarchy_cache: Mutex::new(LruCache::new(usize_from_f64(cache_size)?)),
|
||||
}))
|
||||
|
||||
@@ -45,9 +45,9 @@ impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
let config = &args.server.config;
|
||||
let server_visibility_cache_capacity =
|
||||
f64::from(config.server_visibility_cache_capacity) * config.conduit_cache_capacity_modifier;
|
||||
f64::from(config.server_visibility_cache_capacity) * config.cache_capacity_modifier;
|
||||
let user_visibility_cache_capacity =
|
||||
f64::from(config.user_visibility_cache_capacity) * config.conduit_cache_capacity_modifier;
|
||||
f64::from(config.user_visibility_cache_capacity) * config.cache_capacity_modifier;
|
||||
|
||||
Ok(Arc::new(Self {
|
||||
db: Data::new(args.db),
|
||||
|
||||
@@ -55,7 +55,7 @@ pub struct Service {
|
||||
impl crate::Service for Service {
|
||||
fn build(args: crate::Args<'_>) -> Result<Arc<Self>> {
|
||||
let config = &args.server.config;
|
||||
let cache_capacity = f64::from(config.stateinfo_cache_capacity) * config.conduit_cache_capacity_modifier;
|
||||
let cache_capacity = f64::from(config.stateinfo_cache_capacity) * config.cache_capacity_modifier;
|
||||
Ok(Arc::new(Self {
|
||||
db: Data::new(args.db),
|
||||
stateinfo_cache: StdMutex::new(LruCache::new(usize_from_f64(cache_capacity)?)),
|
||||
|
||||
@@ -252,7 +252,7 @@ async fn request_well_known(dest: &str) -> Result<Option<String>> {
|
||||
.as_str()
|
||||
.unwrap_or_default();
|
||||
|
||||
if ruma_identifiers_validation::server_name::validate(m_server).is_err() {
|
||||
if ruma::identifiers_validation::server_name::validate(m_server).is_err() {
|
||||
debug_error!("response content missing or invalid");
|
||||
return Ok(None);
|
||||
}
|
||||
@@ -443,7 +443,9 @@ impl crate::globals::resolver::Resolver {
|
||||
impl CachedDest {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
||||
pub fn valid(&self) -> bool { true }
|
||||
|
||||
//pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 18..60 * 60 * 36) }
|
||||
@@ -452,7 +454,9 @@ impl CachedDest {
|
||||
impl CachedOverride {
|
||||
#[inline]
|
||||
#[must_use]
|
||||
pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
||||
pub fn valid(&self) -> bool { true }
|
||||
|
||||
//pub fn valid(&self) -> bool { self.expire > SystemTime::now() }
|
||||
|
||||
#[must_use]
|
||||
pub(crate) fn default_expire() -> SystemTime { rand::timepoint_secs(60 * 60 * 6..60 * 60 * 12) }
|
||||
|
||||
+42
-57
@@ -1,6 +1,6 @@
|
||||
use std::{collections::BTreeMap, mem::size_of, sync::Arc};
|
||||
|
||||
use conduit::{debug_info, utils, warn, Error, Result};
|
||||
use conduit::{debug_info, err, utils, warn, Err, Error, Result};
|
||||
use database::{Database, Map};
|
||||
use ruma::{
|
||||
api::client::{device::Device, error::ErrorKind, filter::FilterDefinition},
|
||||
@@ -87,19 +87,19 @@ impl Data {
|
||||
let mut parts = bytes.split(|&b| b == 0xFF);
|
||||
let user_bytes = parts
|
||||
.next()
|
||||
.ok_or_else(|| Error::bad_database("User ID in token_userdeviceid is invalid."))?;
|
||||
.ok_or_else(|| err!(Database("User ID in token_userdeviceid is invalid.")))?;
|
||||
let device_bytes = parts
|
||||
.next()
|
||||
.ok_or_else(|| Error::bad_database("Device ID in token_userdeviceid is invalid."))?;
|
||||
.ok_or_else(|| err!(Database("Device ID in token_userdeviceid is invalid.")))?;
|
||||
|
||||
Ok(Some((
|
||||
UserId::parse(
|
||||
utils::string_from_bytes(user_bytes)
|
||||
.map_err(|_| Error::bad_database("User ID in token_userdeviceid is invalid unicode."))?,
|
||||
.map_err(|e| err!(Database("User ID in token_userdeviceid is invalid unicode. {e}")))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("User ID in token_userdeviceid is invalid."))?,
|
||||
.map_err(|e| err!(Database("User ID in token_userdeviceid is invalid. {e}")))?,
|
||||
utils::string_from_bytes(device_bytes)
|
||||
.map_err(|_| Error::bad_database("Device ID in token_userdeviceid is invalid."))?,
|
||||
.map_err(|e| err!(Database("Device ID in token_userdeviceid is invalid. {e}")))?,
|
||||
)))
|
||||
})
|
||||
}
|
||||
@@ -109,9 +109,9 @@ impl Data {
|
||||
Box::new(self.userid_password.iter().map(|(bytes, _)| {
|
||||
UserId::parse(
|
||||
utils::string_from_bytes(&bytes)
|
||||
.map_err(|_| Error::bad_database("User ID in userid_password is invalid unicode."))?,
|
||||
.map_err(|e| err!(Database("User ID in userid_password is invalid unicode. {e}")))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("User ID in userid_password is invalid."))
|
||||
.map_err(|e| err!(Database("User ID in userid_password is invalid. {e}")))
|
||||
}))
|
||||
}
|
||||
|
||||
@@ -165,7 +165,7 @@ impl Data {
|
||||
.map_or(Ok(None), |bytes| {
|
||||
Ok(Some(
|
||||
utils::string_from_bytes(&bytes)
|
||||
.map_err(|_| Error::bad_database("Displayname in db is invalid."))?,
|
||||
.map_err(|e| err!(Database("Displayname in db is invalid. {e}")))?,
|
||||
))
|
||||
})
|
||||
}
|
||||
@@ -188,10 +188,8 @@ impl Data {
|
||||
self.userid_avatarurl
|
||||
.get(user_id.as_bytes())?
|
||||
.map(|bytes| {
|
||||
let s_bytes = utils::string_from_bytes(&bytes).map_err(|e| {
|
||||
warn!("Avatar URL in db is invalid: {}", e);
|
||||
Error::bad_database("Avatar URL in db is invalid.")
|
||||
})?;
|
||||
let s_bytes = utils::string_from_bytes(&bytes)
|
||||
.map_err(|e| err!(Database(warn!("Avatar URL in db is invalid: {e}"))))?;
|
||||
let mxc_uri: OwnedMxcUri = s_bytes.into();
|
||||
Ok(mxc_uri)
|
||||
})
|
||||
@@ -215,10 +213,7 @@ impl Data {
|
||||
self.userid_blurhash
|
||||
.get(user_id.as_bytes())?
|
||||
.map(|bytes| {
|
||||
let s = utils::string_from_bytes(&bytes)
|
||||
.map_err(|_| Error::bad_database("Avatar URL in db is invalid."))?;
|
||||
|
||||
Ok(s)
|
||||
utils::string_from_bytes(&bytes).map_err(|e| err!(Database("Avatar URL in db is invalid. {e}")))
|
||||
})
|
||||
.transpose()
|
||||
}
|
||||
@@ -314,9 +309,9 @@ impl Data {
|
||||
bytes
|
||||
.rsplit(|&b| b == 0xFF)
|
||||
.next()
|
||||
.ok_or_else(|| Error::bad_database("UserDevice ID in db is invalid."))?,
|
||||
.ok_or_else(|| err!(Database("UserDevice ID in db is invalid.")))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("Device ID in userdeviceid_metadata is invalid."))?
|
||||
.map_err(|e| err!(Database("Device ID in userdeviceid_metadata is invalid. {e}")))?
|
||||
.into())
|
||||
}),
|
||||
)
|
||||
@@ -330,13 +325,9 @@ impl Data {
|
||||
|
||||
// should not be None, but we shouldn't assert either lol...
|
||||
if self.userdeviceid_metadata.get(&userdeviceid)?.is_none() {
|
||||
warn!(
|
||||
"Called set_token for a non-existent user \"{}\" and/or device ID \"{}\" with no metadata in database",
|
||||
user_id, device_id
|
||||
);
|
||||
return Err(Error::bad_database(
|
||||
"User does not exist or device ID has no metadata in database.",
|
||||
));
|
||||
return Err!(Database(error!(
|
||||
"User {user_id:?} does not exist or device ID {device_id:?} has no metadata."
|
||||
)));
|
||||
}
|
||||
|
||||
// Remove old token
|
||||
@@ -366,14 +357,9 @@ impl Data {
|
||||
// Only existing devices should be able to call this, but we shouldn't assert
|
||||
// either...
|
||||
if self.userdeviceid_metadata.get(&key)?.is_none() {
|
||||
warn!(
|
||||
"Called add_one_time_key for a non-existent user \"{}\" and/or device ID \"{}\" with no metadata in \
|
||||
database",
|
||||
user_id, device_id
|
||||
);
|
||||
return Err(Error::bad_database(
|
||||
"User does not exist or device ID has no metadata in database.",
|
||||
));
|
||||
return Err!(Database(error!(
|
||||
"User {user_id:?} does not exist or device ID {device_id:?} has no metadata."
|
||||
)));
|
||||
}
|
||||
|
||||
key.push(0xFF);
|
||||
@@ -401,7 +387,7 @@ impl Data {
|
||||
.get(user_id.as_bytes())?
|
||||
.map_or(Ok(0), |bytes| {
|
||||
utils::u64_from_bytes(&bytes)
|
||||
.map_err(|_| Error::bad_database("Count in roomid_lastroomactiveupdate is invalid."))
|
||||
.map_err(|e| err!(Database("Count in roomid_lastroomactiveupdate is invalid. {e}")))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -429,11 +415,10 @@ impl Data {
|
||||
serde_json::from_slice(
|
||||
key.rsplit(|&b| b == 0xFF)
|
||||
.next()
|
||||
.ok_or_else(|| Error::bad_database("OneTimeKeyId in db is invalid."))?,
|
||||
.ok_or_else(|| err!(Database("OneTimeKeyId in db is invalid.")))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("OneTimeKeyId in db is invalid."))?,
|
||||
serde_json::from_slice(&value)
|
||||
.map_err(|_| Error::bad_database("OneTimeKeys in db are invalid."))?,
|
||||
.map_err(|e| err!(Database("OneTimeKeyId in db is invalid. {e}")))?,
|
||||
serde_json::from_slice(&value).map_err(|e| err!(Database("OneTimeKeys in db are invalid. {e}")))?,
|
||||
))
|
||||
})
|
||||
.transpose()
|
||||
@@ -457,9 +442,9 @@ impl Data {
|
||||
bytes
|
||||
.rsplit(|&b| b == 0xFF)
|
||||
.next()
|
||||
.ok_or_else(|| Error::bad_database("OneTimeKey ID in db is invalid."))?,
|
||||
.ok_or_else(|| err!(Database("OneTimeKey ID in db is invalid.")))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("DeviceKeyId in db is invalid."))?
|
||||
.map_err(|e| err!(Database("DeviceKeyId in db is invalid. {e}")))?
|
||||
.algorithm(),
|
||||
)
|
||||
}) {
|
||||
@@ -581,19 +566,19 @@ impl Data {
|
||||
.get(&key)?
|
||||
.ok_or(Error::BadRequest(ErrorKind::InvalidParam, "Tried to sign nonexistent key."))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("key in keyid_key is invalid."))?;
|
||||
.map_err(|e| err!(Database("key in keyid_key is invalid. {e}")))?;
|
||||
|
||||
let signatures = cross_signing_key
|
||||
.get_mut("signatures")
|
||||
.ok_or_else(|| Error::bad_database("key in keyid_key has no signatures field."))?
|
||||
.ok_or_else(|| err!(Database("key in keyid_key has no signatures field.")))?
|
||||
.as_object_mut()
|
||||
.ok_or_else(|| Error::bad_database("key in keyid_key has invalid signatures field."))?
|
||||
.ok_or_else(|| err!(Database("key in keyid_key has invalid signatures field.")))?
|
||||
.entry(sender_id.to_string())
|
||||
.or_insert_with(|| serde_json::Map::new().into());
|
||||
|
||||
signatures
|
||||
.as_object_mut()
|
||||
.ok_or_else(|| Error::bad_database("signatures in keyid_key for a user is invalid."))?
|
||||
.ok_or_else(|| err!(Database("signatures in keyid_key for a user is invalid.")))?
|
||||
.insert(signature.0, signature.1.into());
|
||||
|
||||
self.keyid_key.insert(
|
||||
@@ -640,7 +625,7 @@ impl Data {
|
||||
Error::bad_database("User ID in devicekeychangeid_userid is invalid unicode.")
|
||||
})?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("User ID in devicekeychangeid_userid is invalid."))
|
||||
.map_err(|e| err!(Database("User ID in devicekeychangeid_userid is invalid. {e}")))
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -685,7 +670,7 @@ impl Data {
|
||||
|
||||
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
||||
Ok(Some(
|
||||
serde_json::from_slice(&bytes).map_err(|_| Error::bad_database("DeviceKeys in db are invalid."))?,
|
||||
serde_json::from_slice(&bytes).map_err(|e| err!(Database("DeviceKeys in db are invalid. {e}")))?,
|
||||
))
|
||||
})
|
||||
}
|
||||
@@ -719,7 +704,7 @@ impl Data {
|
||||
) -> Result<Option<Raw<CrossSigningKey>>> {
|
||||
self.keyid_key.get(key)?.map_or(Ok(None), |bytes| {
|
||||
let mut cross_signing_key = serde_json::from_slice::<serde_json::Value>(&bytes)
|
||||
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?;
|
||||
.map_err(|e| err!(Database("CrossSigningKey in db is invalid. {e}")))?;
|
||||
clean_signatures(&mut cross_signing_key, sender_user, user_id, allowed_signatures)?;
|
||||
|
||||
Ok(Some(Raw::from_json(
|
||||
@@ -751,7 +736,7 @@ impl Data {
|
||||
self.keyid_key.get(&key)?.map_or(Ok(None), |bytes| {
|
||||
Ok(Some(
|
||||
serde_json::from_slice(&bytes)
|
||||
.map_err(|_| Error::bad_database("CrossSigningKey in db is invalid."))?,
|
||||
.map_err(|e| err!(Database("CrossSigningKey in db is invalid. {e}")))?,
|
||||
))
|
||||
})
|
||||
})
|
||||
@@ -792,7 +777,7 @@ impl Data {
|
||||
for (_, value) in self.todeviceid_events.scan_prefix(prefix) {
|
||||
events.push(
|
||||
serde_json::from_slice(&value)
|
||||
.map_err(|_| Error::bad_database("Event in todeviceid_events is invalid."))?,
|
||||
.map_err(|e| err!(Database("Event in todeviceid_events is invalid. {e}")))?,
|
||||
);
|
||||
}
|
||||
|
||||
@@ -816,7 +801,7 @@ impl Data {
|
||||
Ok::<_, Error>((
|
||||
key.clone(),
|
||||
utils::u64_from_bytes(&key[key.len().saturating_sub(size_of::<u64>())..key.len()])
|
||||
.map_err(|_| Error::bad_database("ToDeviceId has invalid count bytes."))?,
|
||||
.map_err(|e| err!(Database("ToDeviceId has invalid count bytes. {e}")))?,
|
||||
))
|
||||
})
|
||||
.filter_map(Result::ok)
|
||||
@@ -877,7 +862,7 @@ impl Data {
|
||||
.get(user_id.as_bytes())?
|
||||
.map_or(Ok(None), |bytes| {
|
||||
utils::u64_from_bytes(&bytes)
|
||||
.map_err(|_| Error::bad_database("Invalid devicelistversion in db."))
|
||||
.map_err(|e| err!(Database("Invalid devicelistversion in db. {e}")))
|
||||
.map(Some)
|
||||
})
|
||||
}
|
||||
@@ -893,7 +878,7 @@ impl Data {
|
||||
.scan_prefix(key)
|
||||
.map(|(_, bytes)| {
|
||||
serde_json::from_slice::<Device>(&bytes)
|
||||
.map_err(|_| Error::bad_database("Device in userdeviceid_metadata is invalid."))
|
||||
.map_err(|e| err!(Database("Device in userdeviceid_metadata is invalid. {e}")))
|
||||
}),
|
||||
)
|
||||
}
|
||||
@@ -920,7 +905,7 @@ impl Data {
|
||||
let raw = self.userfilterid_filter.get(&key)?;
|
||||
|
||||
if let Some(raw) = raw {
|
||||
serde_json::from_slice(&raw).map_err(|_| Error::bad_database("Invalid filter event in db."))
|
||||
serde_json::from_slice(&raw).map_err(|e| err!(Database("Invalid filter event in db. {e}")))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
@@ -954,7 +939,7 @@ impl Data {
|
||||
let expires_at = u64::from_be_bytes(
|
||||
expires_at_bytes
|
||||
.try_into()
|
||||
.map_err(|_| Error::bad_database("expires_at in openid_userid is invalid u64."))?,
|
||||
.map_err(|e| err!(Database("expires_at in openid_userid is invalid u64. {e}")))?,
|
||||
);
|
||||
|
||||
if expires_at < utils::millis_since_unix_epoch() {
|
||||
@@ -966,9 +951,9 @@ impl Data {
|
||||
|
||||
UserId::parse(
|
||||
utils::string_from_bytes(user_bytes)
|
||||
.map_err(|_| Error::bad_database("User ID in openid_userid is invalid unicode."))?,
|
||||
.map_err(|e| err!(Database("User ID in openid_userid is invalid unicode. {e}")))?,
|
||||
)
|
||||
.map_err(|_| Error::bad_database("User ID in openid_userid is invalid."))
|
||||
.map_err(|e| err!(Database("User ID in openid_userid is invalid. {e}")))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user