Compare commits

..

20 Commits

Author SHA1 Message Date
strawberry 2fad03597a a
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 17:38:59 -04:00
strawberry 7f22f0e3a6 keypair logging adjustments
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 15:09:36 -04:00
strawberry a0161ed7c1 config option to allow incoming remote read receipts
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 12:16:04 -04:00
strawberry 41d9e24c03 ignore deactivated users and remote user profiles wih forbidden_usernames
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 12:11:24 -04:00
strawberry 3ac5368578 bump conduwuit version to 0.1.8
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
Jason Volk d2bb3dc93f add flush suite to sending service; trigger on read receipts.
Signed-off-by: Jason Volk <jason@zemos.net>
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
Jason Volk 3af303e52b complete federation destination caching preempting getaddrinfo(3).
fixed some clippy lints and spacing adjusted

Signed-off-by: Jason Volk <jason@zemos.net>
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
Jason Volk 72c97434b0 add remove_batch with transaction to database abstraction.
adjusted to make building sqlite happy again

Signed-off-by: Jason Volk <jason@zemos.net>
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
Jason Volk 73c42991e9 clear dns and tls-override caches from !admin command.
Signed-off-by: Jason Volk <jason@zemos.net>
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
strawberry e982428f07 bump async-trait and ruma
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
strawberry 70b1bdd655 slight inclusive wording changes
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
strawberry 6d4163d410 track media uploads by user
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
strawberry a33b33cab5 document forbidden room aliases and usernames
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:39 -04:00
Matthias Ahouansou c14b28b408 feat(spaces): hierarchy over federation
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-17 10:50:30 -04:00
strawberry 8972487691 check allow_federation in send_federation_request
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-16 16:07:42 -04:00
Matthias Ahouansou aec63c29e1 refactor: check if federation is disabled inside the authcheck where possible
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-16 16:05:52 -04:00
Matthias Ahouansou 72182f3714 fix: avoid panics when admin room is not available
Co-authored-by: strawberry <strawberry@puppygock.gay>
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-16 14:11:03 -04:00
strawberry 94b4d584a6 admin command to see a room's full state from our database
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-16 13:23:57 -04:00
strawberry 41f27dc949 slight wording updates
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-16 13:23:57 -04:00
strawberry 29f5b58098 remove rocksdb optimize_level_style_compaction
Signed-off-by: strawberry <strawberry@puppygock.gay>
2024-03-16 13:23:57 -04:00
54 changed files with 369 additions and 984 deletions
-7
View File
@@ -6,23 +6,16 @@ on:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
env:
# Required to make some things output color
TERM: ansi
# Publishing to my nix binary cache
ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN }}
# Just in case incremental is still being set to true, speeds up CI
CARGO_INCREMENTAL: 0
# Custom nix binary cache if fork is being used
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
permissions:
packages: write
contents: read
jobs:
ci:
-117
View File
@@ -1,117 +0,0 @@
name: Documentation and GitHub Pages
on:
pull_request:
push:
branches:
- main
# Allows you to run this workflow manually from the Actions tab
workflow_dispatch:
env:
# Required to make some things output color
TERM: ansi
# Publishing to my nix binary cache
ATTIC_TOKEN: ${{ secrets.ATTIC_TOKEN }}
# Custom nix binary cache if fork is being used
ATTIC_ENDPOINT: ${{ vars.ATTIC_ENDPOINT }}
ATTIC_PUBLIC_KEY: ${{ vars.ATTIC_PUBLIC_KEY }}
# 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.
concurrency:
group: "pages"
cancel-in-progress: false
jobs:
docs:
name: Documentation and GitHub Pages
runs-on: ubuntu-latest
permissions:
pages: write
id-token: write
environment:
name: github-pages
url: ${{ steps.deployment.outputs.page_url }}
steps:
- name: Sync repository
uses: actions/checkout@v4
- name: Setup GitHub Pages
if: github.event_name != 'pull_request'
uses: actions/configure-pages@v4
- name: Install Nix (with flakes and nix-command enabled)
uses: cachix/install-nix-action@v26
with:
nix_path: nixpkgs=channel:nixos-unstable
# Add `nix-community`, Crane, upstream Conduit, and conduwuit binary caches
extra_nix_config: |
experimental-features = nix-command flakes
extra-substituters = https://nix-community.cachix.org
extra-trusted-public-keys = nix-community.cachix.org-1:mB9FSh9qf2dCimDSUo8Zy7bkq5CX+/rkCWyvRCYg3Fs=
extra-substituters = https://crane.cachix.org
extra-trusted-public-keys = crane.cachix.org-1:8Scfpmn9w+hGdXH/Q9tTLiYAE/2dnJYRJP7kl80GuRk=
extra-substituters = https://nix.computer.surgery/conduit
extra-trusted-public-keys = conduit:ZGAf6P6LhNvnoJJ3Me3PRg7tlLSrPxcQ2RiE5LIppjo=
extra-substituters = https://attic.kennel.juneis.dog/conduit
extra-trusted-public-keys = conduit:Isq8FGyEC6FOXH6nD+BOeAA+bKp6X6UIbupSlGEPuOg=
extra-substituters = https://attic.kennel.juneis.dog/conduwuit
extra-trusted-public-keys = conduwuit:lYPVh7o1hLu1idH4Xt2QHaRa49WRGSAqzcfFd94aOTw=
- name: Add alternative Nix binary caches if specified
if: ${{ (env.ATTIC_ENDPOINT != '') && (env.ATTIC_PUBLIC_KEY != '') }}
run: |
echo "extra-substituters = ${{ env.ATTIC_ENDPOINT }}" >> /etc/nix/nix.conf
echo "extra-trusted-public-keys = ${{ env.ATTIC_PUBLIC_KEY }}" >> /etc/nix/nix.conf
- name: Pop/push Magic Nix Cache
uses: DeterminateSystems/magic-nix-cache-action@main
- name: Configure `nix-direnv`
run: |
echo 'source $HOME/.nix-profile/share/nix-direnv/direnvrc' > "$HOME/.direnvrc"
- name: Install `direnv` and `nix-direnv`
run: nix-env -f "<nixpkgs>" -iA direnv -iA nix-direnv
# Do this to shorten the logs for the real CI step
- name: Populate `/nix/store`
run: nix develop --command true
- name: Allow direnv
run: direnv allow
- name: Cache x86_64 inputs for devShell
run: |
./bin/nix-build-and-cache .#devShells.x86_64-linux.default.inputDerivation
- name: Build documentation (book)
run: |
./bin/nix-build-and-cache .#book
cp -r --dereference result public
- name: Upload generated documentation (book) as normal artifact
uses: actions/upload-artifact@v4
with:
name: public
path: public
if-no-files-found: error
# don't compress again
compression-level: 0
- name: Upload generated documentation (book) as GitHub Pages artifact
if: github.event_name != 'pull_request'
uses: actions/upload-pages-artifact@v3
with:
path: public
- name: Deploy to GitHub Pages
if: github.event_name != 'pull_request'
id: deployment
uses: actions/deploy-pages@v4
-3
View File
@@ -75,8 +75,5 @@ test-conduit.toml
# Gitlab CI cache
/.gitlab-ci.d
# mdbook output
public/
# macOS
.DS_Store
+2 -19
View File
@@ -105,10 +105,6 @@ artifacts:
- ./bin/nix-build-and-cache .#oci-image-aarch64-unknown-linux-musl
- cp result oci-image-arm64v8.tar.gz
- ./bin/nix-build-and-cache .#book
# We can't just copy the symlink, we need to dereference it https://gitlab.com/gitlab-org/gitlab/-/issues/19746
- cp -r --dereference result public
artifacts:
paths:
- x86_64-unknown-linux-musl
@@ -116,7 +112,6 @@ artifacts:
- x86_64-unknown-linux-musl.deb
- oci-image-amd64.tar.gz
- oci-image-arm64v8.tar.gz
- public
rules:
# CI required for all MRs
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
@@ -129,9 +124,9 @@ artifacts:
.push-oci-image:
stage: publish
image: docker:25.0.5
image: docker:25.0.4
services:
- docker:25.0.5-dind
- docker:25.0.4-dind
variables:
IMAGE_SUFFIX_AMD64: amd64
IMAGE_SUFFIX_ARM64V8: arm64v8
@@ -169,15 +164,3 @@ oci-image:push-gitlab:
IMAGE_NAME: $CI_REGISTRY_IMAGE/conduwuit
before_script:
- docker login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
pages:
stage: publish
dependencies:
- artifacts
only:
- next
script:
- "true"
artifacts:
paths:
- public
-3
View File
@@ -1,3 +0,0 @@
# Docs: Map markdown to html files
- source: /docs/(.+)\.md/
public: '\1.html'
Generated
+101 -111
View File
@@ -102,7 +102,7 @@ checksum = "461abc97219de0eaaf81fe3ef974a540158f3d079c2ab200f891f1a2ef201e85"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -245,7 +245,7 @@ version = "0.69.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a00dc851838a2120612785d195287475a3ac45514741da670b735818822129a0"
dependencies = [
"bitflags 2.5.0",
"bitflags 2.4.2",
"cexpr",
"clang-sys",
"itertools 0.12.1",
@@ -256,7 +256,7 @@ dependencies = [
"regex",
"rustc-hash",
"shlex",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -267,9 +267,9 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "bitflags"
version = "2.5.0"
version = "2.4.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cf4b9d6a944f767f8e5e0db018570623c85f3d925ac718db4e06d0187adb21c1"
checksum = "ed570934406eb16438a4e976b1b4500774099c13b8cb96eec99f620f05090ddf"
[[package]]
name = "blake2"
@@ -355,15 +355,6 @@ version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd16c4719339c4530435d38e511904438d07cce7950afa3718a84ac36c10e89e"
[[package]]
name = "chrono"
version = "0.4.35"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8eaf5903dcbc0a39312feb77df2ff4c76387d591b9fc7b04a238dcf8bb62639a"
dependencies = [
"num-traits",
]
[[package]]
name = "clang-sys"
version = "1.7.0"
@@ -404,7 +395,7 @@ dependencies = [
"heck 0.5.0",
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -430,13 +421,11 @@ dependencies = [
"axum-server-dual-protocol",
"base64 0.22.0",
"bytes",
"chrono",
"clap",
"cyborgtime",
"either",
"figment",
"futures-util",
"hickory-resolver",
"hmac",
"http",
"hyper",
@@ -478,6 +467,7 @@ dependencies = [
"tracing-flame",
"tracing-opentelemetry",
"tracing-subscriber",
"trust-dns-resolver",
"webpage",
]
@@ -577,7 +567,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -674,7 +664,7 @@ dependencies = [
"heck 0.4.1",
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -799,7 +789,7 @@ checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -960,51 +950,6 @@ version = "0.4.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70"
[[package]]
name = "hickory-proto"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "091a6fbccf4860009355e3efc52ff4acf37a63489aad7435372d44ceeb6fbbcf"
dependencies = [
"async-trait",
"cfg-if",
"data-encoding",
"enum-as-inner",
"futures-channel",
"futures-io",
"futures-util",
"idna 0.4.0",
"ipnet",
"once_cell",
"rand",
"thiserror",
"tinyvec",
"tokio",
"tracing",
"url",
]
[[package]]
name = "hickory-resolver"
version = "0.24.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "35b8f021164e6a984c9030023544c57789c51760065cd510572fedcfb04164e8"
dependencies = [
"cfg-if",
"futures-util",
"hickory-proto",
"ipconfig",
"lru-cache",
"once_cell",
"parking_lot",
"rand",
"resolv-conf",
"smallvec",
"thiserror",
"tokio",
"tracing",
]
[[package]]
name = "hmac"
version = "0.12.1"
@@ -1167,9 +1112,9 @@ dependencies = [
[[package]]
name = "image-webp"
version = "0.1.1"
version = "0.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7a84a25dcae3ac487bc24ef280f9e20c79c9b1a3e5e32cbed3041d1c514aa87c"
checksum = "ba6107a25f04af48ceeb4093eebc9b405ee5a1813a0bab5ecf1805d3eabb3337"
dependencies = [
"byteorder",
"thiserror",
@@ -1356,7 +1301,7 @@ dependencies = [
[[package]]
name = "libsqlite3-sys"
version = "0.28.0"
source = "git+https://github.com/rusqlite/rusqlite?branch=master#20487e8c27c483de1a83c33176e47dd998e2a7d1"
source = "git+https://github.com/rusqlite/rusqlite?branch=master#983f08b8d753deb60649661c8a1c3bc3bd4f358a"
dependencies = [
"cc",
"pkg-config",
@@ -1525,7 +1470,7 @@ version = "0.28.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ab2156c4fce2f8df6c499cc1c763e4394b7482525bf2a9701c9d79d215f519e4"
dependencies = [
"bitflags 2.5.0",
"bitflags 2.4.2",
"cfg-if",
"cfg_aliases",
"libc",
@@ -1810,7 +1755,7 @@ dependencies = [
"proc-macro2",
"proc-macro2-diagnostics",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -1884,7 +1829,7 @@ checksum = "2f38a4412a78282e09a2cf38d195ea5420d15ba0602cb375210efbc877243965"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -1979,7 +1924,7 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
"version_check",
"yansi",
]
@@ -2084,9 +2029,9 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f"
[[package]]
name = "reqwest"
version = "0.11.27"
version = "0.11.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "dd67538700a17451e7cba03ac727fb961abb7607553461627b97de0b89cf4a62"
checksum = "78bf93c4af7a8bb7d879d51cebe797356ff10ae8516ace542b5182d9dcac10b2"
dependencies = [
"base64 0.21.7",
"bytes",
@@ -2094,7 +2039,6 @@ dependencies = [
"futures-core",
"futures-util",
"h2",
"hickory-resolver",
"http",
"http-body",
"hyper",
@@ -2118,6 +2062,7 @@ dependencies = [
"tokio-rustls",
"tokio-socks",
"tower-service",
"trust-dns-resolver",
"url",
"wasm-bindgen",
"wasm-bindgen-futures",
@@ -2153,7 +2098,7 @@ dependencies = [
[[package]]
name = "ruma"
version = "0.9.4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"assign",
"js_int",
@@ -2172,7 +2117,7 @@ dependencies = [
[[package]]
name = "ruma-appservice-api"
version = "0.9.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"js_int",
"ruma-common",
@@ -2184,7 +2129,7 @@ dependencies = [
[[package]]
name = "ruma-client-api"
version = "0.17.4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"as_variant",
"assign",
@@ -2203,7 +2148,7 @@ dependencies = [
[[package]]
name = "ruma-common"
version = "0.12.1"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"as_variant",
"base64 0.21.7",
@@ -2222,7 +2167,6 @@ dependencies = [
"serde_html_form",
"serde_json",
"thiserror",
"time",
"tracing",
"url",
"uuid",
@@ -2232,7 +2176,7 @@ dependencies = [
[[package]]
name = "ruma-events"
version = "0.27.11"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"as_variant",
"indexmap",
@@ -2254,7 +2198,7 @@ dependencies = [
[[package]]
name = "ruma-federation-api"
version = "0.8.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"js_int",
"ruma-common",
@@ -2266,7 +2210,7 @@ dependencies = [
[[package]]
name = "ruma-identifiers-validation"
version = "0.9.3"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"js_int",
"thiserror",
@@ -2275,7 +2219,7 @@ dependencies = [
[[package]]
name = "ruma-identity-service-api"
version = "0.8.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"js_int",
"ruma-common",
@@ -2285,7 +2229,7 @@ dependencies = [
[[package]]
name = "ruma-macros"
version = "0.12.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"once_cell",
"proc-macro-crate",
@@ -2293,14 +2237,14 @@ dependencies = [
"quote",
"ruma-identifiers-validation",
"serde",
"syn 2.0.53",
"syn 2.0.52",
"toml",
]
[[package]]
name = "ruma-push-gateway-api"
version = "0.8.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"js_int",
"ruma-common",
@@ -2312,7 +2256,7 @@ dependencies = [
[[package]]
name = "ruma-signatures"
version = "0.14.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"base64 0.21.7",
"ed25519-dalek",
@@ -2328,7 +2272,7 @@ dependencies = [
[[package]]
name = "ruma-state-res"
version = "0.10.0"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#5ab81eef0aff02f75570abc149f147af12417ca4"
source = "git+https://github.com/girlbossceo/ruma?branch=conduwuit-changes#b36cacb4d1e7e8ef0a9afe4b82de4cc5fd9e2b6c"
dependencies = [
"itertools 0.11.0",
"js_int",
@@ -2343,9 +2287,9 @@ dependencies = [
[[package]]
name = "rusqlite"
version = "0.31.0"
source = "git+https://github.com/rusqlite/rusqlite?branch=master#20487e8c27c483de1a83c33176e47dd998e2a7d1"
source = "git+https://github.com/rusqlite/rusqlite?branch=master#983f08b8d753deb60649661c8a1c3bc3bd4f358a"
dependencies = [
"bitflags 2.5.0",
"bitflags 2.4.2",
"fallible-iterator",
"fallible-streaming-iterator",
"hashlink",
@@ -2355,8 +2299,8 @@ dependencies = [
[[package]]
name = "rust-librocksdb-sys"
version = "0.19.0+9.0.0"
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=4b8491b9db45066115435881184902bbb23d3811#4b8491b9db45066115435881184902bbb23d3811"
version = "0.18.1+8.11.3"
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=3e4a0f632a8c0c2839c7d183725c53895110d907#3e4a0f632a8c0c2839c7d183725c53895110d907"
dependencies = [
"bindgen",
"bzip2-sys",
@@ -2371,8 +2315,8 @@ dependencies = [
[[package]]
name = "rust-rocksdb"
version = "0.22.8"
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=4b8491b9db45066115435881184902bbb23d3811#4b8491b9db45066115435881184902bbb23d3811"
version = "0.22.7"
source = "git+https://github.com/zaidoon1/rust-rocksdb?rev=3e4a0f632a8c0c2839c7d183725c53895110d907#3e4a0f632a8c0c2839c7d183725c53895110d907"
dependencies = [
"libc",
"rust-librocksdb-sys",
@@ -2531,7 +2475,7 @@ checksum = "7eb0b34b42edc17f6b7cac84a52a1c5f0e1bb2227e997ca9011ea3dd34e8610b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -2601,9 +2545,9 @@ dependencies = [
[[package]]
name = "serde_yaml"
version = "0.9.33"
version = "0.9.32"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a0623d197252096520c6f2a5e1171ee436e5af99a5d7caa2891e55e61950e6d9"
checksum = "8fd075d994154d4a774f95b51fb96bdc2832b0ea48425c92546073816cda1f2f"
dependencies = [
"indexmap",
"itoa",
@@ -2797,9 +2741,9 @@ dependencies = [
[[package]]
name = "syn"
version = "2.0.53"
version = "2.0.52"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "7383cd0e49fff4b6b90ca5670bfd3e9d6a733b3f90c686605aa7eec8c4996032"
checksum = "b699d15b36d1f02c3e7c69f8ffef53de37aefae075d8488d4ba1a7788d574a07"
dependencies = [
"proc-macro2",
"quote",
@@ -2861,7 +2805,7 @@ checksum = "c61f3ba182994efc43764a46c018c347bc492c79f024e705f46567b418f6d4f7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -2999,7 +2943,7 @@ checksum = "5b8a1e28f2deaa14e508979454cb3a223b10b938b45af148bc0986de36f1923b"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -3105,7 +3049,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "61c5bb1d698276a2443e5ecfabc1008bf15a36c12e6a7176e7bf089ea9131140"
dependencies = [
"async-compression",
"bitflags 2.5.0",
"bitflags 2.4.2",
"bytes",
"futures-core",
"futures-util",
@@ -3153,7 +3097,7 @@ checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
@@ -3224,6 +3168,52 @@ dependencies = [
"tracing-log",
]
[[package]]
name = "trust-dns-proto"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3119112651c157f4488931a01e586aa459736e9d6046d3bd9105ffb69352d374"
dependencies = [
"async-trait",
"cfg-if",
"data-encoding",
"enum-as-inner",
"futures-channel",
"futures-io",
"futures-util",
"idna 0.4.0",
"ipnet",
"once_cell",
"rand",
"smallvec",
"thiserror",
"tinyvec",
"tokio",
"tracing",
"url",
]
[[package]]
name = "trust-dns-resolver"
version = "0.23.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "10a3e6c3aff1718b3c73e395d1f35202ba2ffa847c6a62eea0db8fb4cfe30be6"
dependencies = [
"cfg-if",
"futures-util",
"ipconfig",
"lru-cache",
"once_cell",
"parking_lot",
"rand",
"resolv-conf",
"smallvec",
"thiserror",
"tokio",
"tracing",
"trust-dns-proto",
]
[[package]]
name = "try-lock"
version = "0.2.5"
@@ -3283,9 +3273,9 @@ dependencies = [
[[package]]
name = "unsafe-libyaml"
version = "0.2.11"
version = "0.2.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861"
checksum = "ab4c90930b95a82d00dc9e9ac071b4991924390d46cbd0dfe566148667605e4b"
[[package]]
name = "untrusted"
@@ -3318,9 +3308,9 @@ checksum = "09cc8ee72d2a9becf2f2febe0205bbed8fc6615b7cb429ad062dc7b7ddd036a9"
[[package]]
name = "uuid"
version = "1.8.0"
version = "1.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0"
checksum = "f00cc9702ca12d3c81455259621e676d0f7251cec66a21e98fe2e9a37db93b2a"
dependencies = [
"getrandom",
]
@@ -3379,7 +3369,7 @@ dependencies = [
"once_cell",
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
"wasm-bindgen-shared",
]
@@ -3413,7 +3403,7 @@ checksum = "e94f17b526d0a461a191c78ea52bbce64071ed5c04c9ffe424dcb38f74171bb7"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
"wasm-bindgen-backend",
"wasm-bindgen-shared",
]
@@ -3681,7 +3671,7 @@ checksum = "9ce1b18ccd8e73a9321186f97e46f9f04b778851177567b1975109d26a08d2a6"
dependencies = [
"proc-macro2",
"quote",
"syn 2.0.53",
"syn 2.0.52",
]
[[package]]
+4 -10
View File
@@ -27,7 +27,7 @@ base64 = "0.22.0"
ring = "0.17.8"
# Used when querying the SRV record of other servers
hickory-resolver = "0.24.0"
trust-dns-resolver = "0.23.2"
# Used to find matching events for appservices
regex = "1.10.3"
@@ -67,12 +67,6 @@ cyborgtime = "2.1.1"
bytes = "1.5.0"
http = "0.2.12"
# standard date and time tools
[dependencies.chrono]
version = "0.4.35"
features = ["alloc"]
default-features = false
# Web framework
[dependencies.axum]
version = "0.6.20"
@@ -107,7 +101,7 @@ features = [
]
[dependencies.reqwest]
version = "0.11.27"
version = "0.11.26"
default-features = false
features = [
"rustls-tls-native-roots",
@@ -122,7 +116,7 @@ version = "1.0.197"
features = ["rc"]
# Used for appservice registration files
[dependencies.serde_yaml]
version = "0.9.33"
version = "0.9.32"
# Used for ruma wrapper
[dependencies.serde_json]
version = "1.0.114"
@@ -261,7 +255,7 @@ features = [
[dependencies.rust-rocksdb]
git = "https://github.com/zaidoon1/rust-rocksdb"
#branch = "master"
rev = "4b8491b9db45066115435881184902bbb23d3811"
rev = "3e4a0f632a8c0c2839c7d183725c53895110d907"
optional = true
default-features = true
features = [
+5 -7
View File
@@ -1,6 +1,4 @@
# Simple setup
This is the recommended way to set up Conduit. It is the easiest way to get started and is suitable for most use cases.
# Deploying Conduit
### Please note that this documentation is not fully representative of conduwuit at the moment. Assume majority of it is outdated.
@@ -120,7 +118,7 @@ Now we need to create the Conduit's config file in `/etc/conduwuit/conduwuit.tom
to read it. You need to change at least the server name.**
You can also choose to use a different database backend, but right now only `rocksdb` and `sqlite` are recommended.
See the following example config at [conduwuit-example.toml](../configuration.md)
See the following example config at [conduwuit-example.toml](conduwuit-example.toml)
## Setting the correct file permissions
@@ -284,7 +282,7 @@ $ sudo systemctl enable conduit
## How do I know it works?
You can open [a Matrix client](https://matrix.org/ecosystem/clients), enter your homeserver and try to register.
You can open <https://app.element.io>, enter your homeserver and try to register.
You can also use these commands as a quick health check.
@@ -302,8 +300,8 @@ $ curl https://your.server.name:8448/_matrix/client/versions
## Audio/Video calls
For Audio/Video call functionality see the [TURN Guide](../turn.md).
For Audio/Video call functionality see the [TURN Guide](TURN.md).
## Appservices
If you want to set up an appservice, take a look at the [Appservice Guide](../appservices.md).
If you want to set up an appservice, take a look at the [Appservice Guide](APPSERVICES.md).
-6
View File
@@ -82,9 +82,3 @@
- Admin debug command to fetch a PDU from a remote server and inserts it into our database/timeline
- Update rusqlite/sqlite (not that you should be using it)
- Disable update check by default as it's not useful for conduwuit
- Declare various missing server capabilities at `/_matrix/client/v3/capabilities` which also fixes FluffyChat password resets, and other clients that expose basic features based on this endpoint's response
- Config option to disable incoming remote read receipts if desired
- Extend clear cache admin command to support clearing DNS and TLS name override caches
- Responsive outgoing read receipt EDU support
- Federation destination DNS cache support to call *less* of the thread-blocking `getaddrinfo(3)` significantly less, improving federation ping/latency
- Store the sender user with the MXC URL for all media uploads (`/upload`) (not for thumbnails or media requests which are unauthenticated)
+23 -21
View File
@@ -1,17 +1,9 @@
# conduwuit
### a well maintained fork of [Conduit](https://conduit.rs/)
[![CI and Artifacts](https://github.com/girlbossceo/conduwuit/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/girlbossceo/conduwuit/actions/workflows/ci.yml)
<!-- ANCHOR: catchphrase -->
### a well maintained fork of [Conduit](https://conduit.rs/)
<!-- ANCHOR_END: catchphrase -->
Visit the [Conduwuit documentation](https://conduwuit.puppyirl.gay/) for more information.
Alternatively you can open [docs/introduction.md](docs/introduction.md) in this repository.
<!-- ANCHOR: body -->
#### What is Matrix?
[Matrix](https://matrix.org) is an open network for secure and decentralized
communication. Users from every Matrix homeserver can chat with users from all
other Matrix servers. You can even use bridges (also called Matrix Appservices)
@@ -35,7 +27,11 @@ from time to time.
There are still a few nice to have features missing that some users may notice:
- Outgoing typing indicators (receiving works)
- Outgoing read receipts and typing indicators (receiving works)
#### What's different about your fork than upstream Conduit?
See [DIFFERENCES.md](DIFFERENCES.md)
#### Why does this fork exist? Why don't you contribute back upstream?
@@ -49,9 +45,16 @@ I now intend on contributing back as time and mental energy sees fit, but my for
- Have a **stable** testing ground for some MRs or new features and bug fixes
And various other reasons that may not be listed here.
<!-- ANCHOR_END: body -->
<!-- ANCHOR: footer -->
#### How can I deploy my own?
conduwuit officially supports Linux, macOS, BSD, and Windows.
- Simple install (this was tested the most): [DEPLOY.md](DEPLOY.md)
- Nix/NixOS (and binary cache): [nix/README.md](nix/README.md)
If you want to connect an Appservice to Conduit, take a look at [APPSERVICES.md](APPSERVICES.md).
#### How can I contribute?
1. Look for an issue you would like to work on and make sure it's not assigned
@@ -69,9 +72,9 @@ If you run into any question, feel free to
#### Donate
- Liberapay: <https://liberapay.com/girlbossceo>
- Ko-fi: <https://ko-fi.com/puppygock>
- GitHub Sponsors: <https://github.com/sponsors/girlbossceo>
Liberapay: <https://liberapay.com/girlbossceo>\
Ko-fi: <https://ko-fi.com/puppygock>\
GitHub Sponsors: <https://github.com/sponsors/girlbossceo>
#### Logo
@@ -83,9 +86,8 @@ Both.
#### Mirrors of conduwuit
- GitHub: <https://github.com/girlbossceo/conduwuit>
- GitLab: <https://gitlab.com/girlbossceo/conduwuit>
- git.gay: <https://git.gay/june/conduwuit>
- Codeberg: <https://codeberg.org/girlbossceo/conduwuit>
- sourcehut: <https://git.sr.ht/~girlbossceo/conduwuit>
<!-- ANCHOR_END: footer -->
GitHub: <https://github.com/girlbossceo/conduwuit>\
GitLab: <https://gitlab.com/girlbossceo/conduwuit>\
git.gay: <https://git.gay/june/conduwuit>\
Codeberg: <https://codeberg.org/girlbossceo/conduwuit>\
sourcehut: <https://git.sr.ht/~girlbossceo/conduwuit>
View File
-18
View File
@@ -1,18 +0,0 @@
[book]
title = "conduwuit"
description = "conduwuit, which is a fork of Conduit, is a simple, fast and reliable chat server for the Matrix protocol"
language = "en"
multilingual = false
src = "docs"
[build]
build-dir = "public"
create-missing = true
[output.html]
git-repository-url = "https://github.com/girlbossceo/conduwuit"
edit-url-template = "https://github.com/girlbossceo/conduwuit/edit/main/{path}"
git-repository-icon = "fa-github-square"
[output.html.search]
limit-results = 15
+4 -10
View File
@@ -173,7 +173,7 @@ registration_token = "change this token for something specific to your server"
# This is checked upon room alias creation, custom room ID creation if used, and startup as warnings if any room aliases
# in your database have a forbidden room alias/ID.
# No default.
# forbidden_alias_names = []
# forbidden_room_names = []
# Set this to true to allow your server's public room directory to be federated.
# Set this to false to protect against /publicRooms spiders, but will forbid external users
@@ -263,12 +263,6 @@ url_preview_check_root_domain = false
# Defaults to true as this is the fastest option for federation.
#query_trusted_key_servers_first = true
# List/vector of room **IDs** that conduwuit will make newly registered users join.
# The room IDs specified must be rooms that you have joined at least once on the server, and must be public.
#
# No default.
#auto_join_rooms = []
### Generic database options
@@ -280,8 +274,8 @@ url_preview_check_root_domain = false
# 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.
# Defaults to 256.0
#db_cache_capacity_mb = 256.0
# Defaults to 300.0
#db_cache_capacity_mb = 300.0
# Interval in seconds when conduwuit will run database cleanup operations.
#
@@ -320,7 +314,7 @@ url_preview_check_root_domain = false
# Amount of threads that RocksDB will use for parallelism. Set to 0 to use all your physical cores.
# Conduit eagerly spawns threads mainly for federation, so it may not be desirable to use all your cores / logical threads.
#
# Defaults to your CPU physical core count (not logical threads).
# Defaults to your CPU physical core count (not logical threads) count divided by 2 (half)
#rocksdb_parallelism_threads = 0
# Maximum number of LOG files RocksDB will keep. This must *not* be set to 0. It must be at least 1.
+1 -1
View File
@@ -5,7 +5,7 @@ Installation
------------
Information about downloading, building and deploying the Debian package, see
the "Installing Conduit" section in the Deploying docs.
the "Installing Conduit" section in [DEPLOY.md](../DEPLOY.md).
All following sections until "Setting up the Reverse Proxy" be ignored because
this is handled automatically by the packaging.
@@ -70,7 +70,7 @@ docker run -d -p 8448:6167 \
or you can use [docker-compose](#docker-compose).
The `-d` flag lets the container run in detached mode. You now need to supply a `conduit.toml` config file, an example can be found [here](../configuration.md).
The `-d` flag lets the container run in detached mode. You now need to supply a `conduit.toml` config file, an example can be found [here](../conduwuit-example.toml).
You can pass in different env vars to change config values on the fly. You can even configure Conduit completely by using env vars, but for that you need
to pass `-e CONDUIT_CONFIG=""` into your container. For an overview of possible values, please take a look at the `docker-compose.yml` file.
@@ -89,7 +89,7 @@ When picking the traefik-related compose file, rename it so it matches `docker-c
rename the override file to `docker-compose.override.yml`. Edit the latter with the values you want
for your server.
Additional info about deploying Conduit can be found [here](simple.md).
Additional info about deploying Conduit can be found [here](../DEPLOY.md).
### Build
@@ -131,7 +131,7 @@ So...step by step:
1. Copy [`docker-compose.for-traefik.yml`](docker-compose.for-traefik.yml) (or
[`docker-compose.with-traefik.yml`](docker-compose.with-traefik.yml)) and [`docker-compose.override.yml`](docker-compose.override.yml) from the repository and remove `.for-traefik` (or `.with-traefik`) from the filename.
2. Open both files and modify/adjust them to your needs. Meaning, change the `CONDUIT_SERVER_NAME` and the volume host mappings according to your needs.
3. Create the `conduit.toml` config file, an example can be found [here](../configuration.md), or set `CONDUIT_CONFIG=""` and configure Conduit per env vars.
3. Create the `conduit.toml` config file, an example can be found [here](../conduwuit-example.toml), or set `CONDUIT_CONFIG=""` and configure Conduit per env vars.
4. Uncomment the `element-web` service if you want to host your own Element Web Client and create a `element_config.json`.
5. Create the files needed by the `well-known` service.
-13
View File
@@ -1,13 +0,0 @@
# Summary
- [Introduction](introduction.md)
- [Differences from upstream Conduit](differences.md)
- [Example configuration](configuration.md)
- [Deployment options](deploying.md)
- [Simple (Recommended)](deploying/simple.md)
- [Debian](deploying/debian.md)
- [Docker](deploying/docker.md)
- [Nix](deploying/nix.md)
- [TURN](turn.md)
- [Appservices](appservices.md)
-5
View File
@@ -1,5 +0,0 @@
# Example configuration
``` toml
{{#include ../conduwuit-example.toml}}
```
-8
View File
@@ -1,8 +0,0 @@
# Deployment options
There are several ways to deploy a Conduit server.
- [Simple (Recommended)](deploying/simple.md) - This is the recommended way to set up Conduit.
- [Debian](deploying/debian.md) - If you're using a debian-based system, you may find the `deb` package useful.
- [Docker](deploying/docker.md) - We provide multi-arch OCI images for Conduit.
- [Nix](deploying/nix.md) - Nix flake based setup.
-1
View File
@@ -1 +0,0 @@
{{#include ../../debian/README.md}}
-17
View File
@@ -1,17 +0,0 @@
# Conduit
{{#include ../README.md:catchphrase}}
{{#include ../README.md:body}}
#### What's different about your fork than upstream Conduit?
See [differences.md](differences.md)
#### How can I deploy my own?
- [Deployment options](deploying.md)
If you want to connect an Appservice to Conduit, take a look at the [appservices documentation](appservices.md).
{{#include ../README.md:footer}}
-10
View File
@@ -50,11 +50,6 @@ name = "cargo-deb"
group = "versions"
script = "cargo deb --version"
[[task]]
name = "lychee"
group = "versions"
script = "lychee --version"
[[task]]
name = "cargo-audit"
group = "security"
@@ -82,11 +77,6 @@ name = "cargo-clippy"
group = "lints"
script = "cargo clippy --workspace --all-targets --all-features --color=always -- -D warnings"
[[task]]
name = "lychee"
group = "lints"
script = "lychee --offline docs"
[[task]]
name = "cargo"
group = "tests"
-32
View File
@@ -208,35 +208,6 @@
packages = {
default = package pkgsHost;
oci-image = mkOciImage pkgsHost self.packages.${system}.default;
book =
let
package = self.packages.${system}.default;
in
pkgsHost.stdenv.mkDerivation {
pname = "${package.pname}-book";
version = package.version;
src = nix-filter {
root = ./.;
include = [
"book.toml"
"conduwuit-example.toml"
"README.md"
"debian/README.md"
"docs"
];
};
nativeBuildInputs = (with pkgsHost; [
mdbook
]);
buildPhase = ''
mdbook build
mv public $out
'';
};
}
//
builtins.listToAttrs
@@ -305,9 +276,6 @@
# Needed for our script for Complement
jq
# Needed for finding broken markdown links
lychee
]);
};
});
+2 -34
View File
@@ -12,13 +12,10 @@ use ruma::{
events::{room::message::RoomMessageEventContent, GlobalAccountDataEventType},
push, UserId,
};
use tracing::{error, info, warn};
use tracing::{info, warn};
use super::{DEVICE_ID_LENGTH, SESSION_ID_LENGTH, TOKEN_LENGTH};
use crate::{
api::client_server::{self, join_room_by_id_helper},
services, utils, Error, Result, Ruma,
};
use crate::{api::client_server, services, utils, Error, Result, Ruma};
const RANDOM_USER_ID_LENGTH: usize = 10;
@@ -288,35 +285,6 @@ pub async fn register_route(body: Ruma<register::v3::Request>) -> Result<registe
}
}
if !services().globals.config.auto_join_rooms.is_empty() {
for room in &services().globals.config.auto_join_rooms {
if !services().rooms.state_cache.server_in_room(services().globals.server_name(), room)? {
warn!("Skipping room {room} to automatically join as we have never joined before.");
continue;
}
if let Some(room_id_server_name) = room.server_name() {
match join_room_by_id_helper(
Some(&user_id),
room,
Some("Automatically joining this room upon registration".to_owned()),
&[room_id_server_name.to_owned(), services().globals.server_name().to_owned()],
None,
)
.await
{
Ok(_) => {
info!("Automatically joined room {room} for user {user_id}");
},
Err(e) => {
// don't return this error so we don't fail registrations
error!("Failed to automatically join room {room} for user {user_id}: {e}");
},
};
}
}
}
Ok(register::v3::Response {
access_token: Some(token),
user_id,
+1 -1
View File
@@ -21,7 +21,7 @@ pub async fn create_alias_route(body: Ruma<create_alias::v3::Request>) -> Result
return Err(Error::BadRequest(ErrorKind::InvalidParam, "Alias is from another server."));
}
if services().globals.forbidden_alias_names().is_match(body.room_alias.alias()) {
if services().globals.forbidden_room_names().is_match(body.room_alias.alias()) {
return Err(Error::BadRequest(ErrorKind::Unknown, "Room alias is forbidden."));
}
+2 -20
View File
@@ -1,13 +1,12 @@
use std::collections::BTreeMap;
use ruma::api::client::discovery::get_capabilities::{
self, Capabilities, ChangePasswordCapability, RoomVersionStability, RoomVersionsCapability, SetAvatarUrlCapability,
SetDisplayNameCapability, ThirdPartyIdChangesCapability,
self, Capabilities, RoomVersionStability, RoomVersionsCapability,
};
use crate::{services, Result, Ruma};
/// # `GET /_matrix/client/v3/capabilities`
/// # `GET /_matrix/client/r0/capabilities`
///
/// Get information on the supported feature set and other relevent capabilities
/// of this server.
@@ -28,23 +27,6 @@ pub async fn get_capabilities_route(
available,
};
capabilities.change_password = ChangePasswordCapability {
enabled: true,
};
capabilities.set_avatar_url = SetAvatarUrlCapability {
enabled: true,
};
capabilities.set_displayname = SetDisplayNameCapability {
enabled: true,
};
// conduit does not implement 3PID stuff
capabilities.thirdparty_id_changes = ThirdPartyIdChangesCapability {
enabled: false,
};
Ok(get_capabilities::v3::Response {
capabilities,
})
+2 -2
View File
@@ -313,7 +313,7 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
(
server,
tokio::time::timeout(
Duration::from_secs(90),
Duration::from_secs(50),
services().sending.send_federation_request(
server,
federation::keys::get_keys::v1::Request {
@@ -323,7 +323,7 @@ pub(crate) async fn get_keys_helper<F: Fn(&UserId) -> bool>(
)
.await
.map_err(|e| {
error!("get_keys_helper query took too long: {e}");
error!("get_keys_helper query took too long: {}", e);
Error::BadServerResponse("get_keys_helper query took too long")
}),
)
+1 -1
View File
@@ -474,7 +474,7 @@ pub async fn joined_members_route(body: Ruma<joined_members::v3::Request>) -> Re
})
}
pub(crate) async fn join_room_by_id_helper(
async fn join_room_by_id_helper(
sender_user: Option<&UserId>, room_id: &RoomId, reason: Option<String>, servers: &[OwnedServerName],
_third_party_signed: Option<&ThirdPartySigned>,
) -> Result<join_room_by_id::v3::Response> {
+2 -2
View File
@@ -80,7 +80,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
}
// apply forbidden room alias checks to custom room IDs too
if services().globals.forbidden_alias_names().is_match(&custom_room_id_s) {
if services().globals.forbidden_room_names().is_match(&custom_room_id_s) {
return Err(Error::BadRequest(ErrorKind::Unknown, "Custom room ID is forbidden."));
}
@@ -144,7 +144,7 @@ pub async fn create_room_route(body: Ruma<create_room::v3::Request>) -> Result<c
}
// check if room alias is forbidden
if services().globals.forbidden_alias_names().is_match(localpart) {
if services().globals.forbidden_room_names().is_match(localpart) {
return Err(Error::BadRequest(ErrorKind::Unknown, "Room alias name is forbidden."));
}
+3 -1
View File
@@ -1333,7 +1333,9 @@ pub async fn sync_events_v4_route(
ruma::JsOption::Some(heroes_avatar)
} else {
match services().rooms.state_accessor.get_avatar(room_id)? {
ruma::JsOption::Some(avatar) => ruma::JsOption::from_option(avatar.url),
ruma::JsOption::Some(avatar) => {
avatar.url.map_or(ruma::JsOption::Undefined, ruma::JsOption::Some)
},
ruma::JsOption::Null => ruma::JsOption::Null,
ruma::JsOption::Undefined => ruma::JsOption::Undefined,
}
-1
View File
@@ -38,7 +38,6 @@ pub async fn get_supported_versions_route(
],
unstable_features: BTreeMap::from_iter([
("org.matrix.e2e_cross_signing".to_owned(), true),
//("org.matrix.msc2285.stable".to_owned(), true),
("org.matrix.msc2836".to_owned(), true),
("org.matrix.msc3827".to_owned(), true),
("org.matrix.msc2946".to_owned(), true),
+2 -24
View File
@@ -84,7 +84,8 @@ where
appservice_registration
{
match metadata.authentication {
AuthScheme::AccessToken => {
// TODO: verify if just or'ing `AuthScheme::AppserviceToken` is correct here
AuthScheme::AccessToken | AuthScheme::AccessTokenOptional | AuthScheme::AppserviceToken => {
let user_id = query_params.user_id.map_or_else(
|| {
UserId::parse_with_server_name(
@@ -96,8 +97,6 @@ where
|s| UserId::parse(s).unwrap(),
);
debug!("User ID: {:?}", user_id);
if !services().users.exists(&user_id)? {
return Err(Error::BadRequest(ErrorKind::Forbidden, "User does not exist."));
}
@@ -105,27 +104,6 @@ where
// TODO: Check if appservice is allowed to be that user
(Some(user_id), None, None, true)
},
AuthScheme::AccessTokenOptional | AuthScheme::AppserviceToken => {
let user_id = query_params.user_id.map_or_else(
|| {
UserId::parse_with_server_name(
registration.sender_localpart.as_str(),
services().globals.server_name(),
)
.unwrap()
},
|s| UserId::parse(s).unwrap(),
);
debug!("User ID: {:?}", user_id);
if !services().users.exists(&user_id)? {
(None, None, None, true)
} else {
// TODO: Check if appservice is allowed to be that user
(Some(user_id), None, None, true)
}
},
AuthScheme::ServerSignatures => (None, None, None, true),
AuthScheme::None => (None, None, None, true),
}
+1 -1
View File
@@ -13,7 +13,6 @@ use std::{
use axum::{response::IntoResponse, Json};
use futures_util::future::TryFutureExt;
use get_profile_information::v1::ProfileField;
use hickory_resolver::{error::ResolveError, lookup::SrvLookup};
use http::header::{HeaderValue, AUTHORIZATION};
use ipaddress::IPAddress;
use ruma::{
@@ -54,6 +53,7 @@ use ruma::{
use serde_json::value::{to_raw_value, RawValue as RawJsonValue};
use tokio::sync::RwLock;
use tracing::{debug, error, info, warn};
use trust_dns_resolver::{error::ResolveError, lookup::SrvLookup};
use crate::{
api::client_server::{self, claim_keys_helper, get_keys_helper},
+38 -1
View File
@@ -2,7 +2,7 @@
use std::path::PathBuf;
use clap::Parser;
use clap::{Parser, Subcommand};
/// Commandline arguments
#[derive(Parser, Debug)]
@@ -11,6 +11,43 @@ pub struct Args {
#[arg(short, long)]
/// Optional argument to the path of a conduwuit config TOML file
pub config: Option<PathBuf>,
#[clap(subcommand)]
/// Optional subcommand to export the homeserver signing key and exit
pub signing_key: Option<SigningKey>,
}
#[derive(Debug, Subcommand)]
pub enum SigningKey {
/// Filesystem path to export the homeserver signing key to.
/// The output will be: `ed25519 <version> <keypair base64 encoded>` which
/// is Synapse's format
ExportPath {
path: PathBuf,
},
/// Filesystem path for conduwuit to attempt to read and import the
/// homeserver signing key. The expected format is Synapse's format:
/// `ed25519 <version> <keypair base64 encoded>`
ImportPath {
path: PathBuf,
#[arg(long)]
/// Optional argument to import the key but don't overwrite our signing
/// key, and instead add it to `old_verify_keys`. This field tells other
/// servers that this is our old public key that can still be used to
/// sign old events.
///
/// See https://spec.matrix.org/v1.9/server-server-api/#get_matrixkeyv2server for more details.
add_to_old_public_keys: bool,
#[arg(long)]
/// Timestamp (`expired_ts`) in seconds since UNIX epoch that the old
/// homeserver signing key stopped being used.
///
/// See https://spec.matrix.org/v1.9/server-server-api/#get_matrixkeyv2server for more details.
timestamp: u64,
},
}
/// Parse commandline arguments into structured data
+8 -31
View File
@@ -10,7 +10,7 @@ use either::Either;
use figment::Figment;
use itertools::Itertools;
use regex::RegexSet;
use ruma::{OwnedRoomId, OwnedServerName, RoomVersionId};
use ruma::{OwnedServerName, RoomVersionId};
use serde::{de::IgnoredAny, Deserialize};
use tracing::{debug, error, warn};
@@ -41,10 +41,7 @@ pub struct Config {
pub server_name: OwnedServerName,
#[serde(default = "default_database_backend")]
pub database_backend: String,
pub database_path: PathBuf,
pub database_backup_path: Option<PathBuf>,
#[serde(default = "default_database_backups_to_keep")]
pub database_backups_to_keep: i16,
pub database_path: String,
#[serde(default = "default_db_cache_capacity_mb")]
pub db_cache_capacity_mb: f64,
#[serde(default = "default_new_user_displayname_suffix")]
@@ -110,9 +107,6 @@ pub struct Config {
#[serde(default = "default_turn_ttl")]
pub turn_ttl: u64,
#[serde(default = "Vec::new")]
pub auto_join_rooms: Vec<OwnedRoomId>,
#[serde(default = "default_rocksdb_log_level")]
pub rocksdb_log_level: String,
#[serde(default = "default_rocksdb_max_log_file_size")]
@@ -178,7 +172,7 @@ pub struct Config {
#[serde(default = "RegexSet::empty")]
#[serde(with = "serde_regex")]
pub forbidden_alias_names: RegexSet,
pub forbidden_room_names: RegexSet,
#[serde(default = "RegexSet::empty")]
#[serde(with = "serde_regex")]
@@ -257,15 +251,7 @@ impl fmt::Display for Config {
let lines = [
("Server name", self.server_name.host()),
("Database backend", &self.database_backend),
("Database path", &self.database_path.to_string_lossy()),
(
"Database backup path",
match &self.database_backup_path {
Some(path) => path.to_str().unwrap(),
None => "",
},
),
("Database backups to keep", &self.database_backups_to_keep.to_string()),
("Database path", &self.database_path),
("Database cache capacity (MB)", &self.db_cache_capacity_mb.to_string()),
("Cache capacity modifier", &self.conduit_cache_capacity_modifier.to_string()),
("PDU cache capacity", &self.pdu_cache_capacity.to_string()),
@@ -367,13 +353,6 @@ impl fmt::Display for Config {
}
&lst.join(", ")
}),
("Auto Join Rooms", {
let mut lst = vec![];
for room in &self.auto_join_rooms {
lst.push(room);
}
&lst.into_iter().join(", ")
}),
#[cfg(feature = "compression-zstd")]
("zstd Response Body Compression", &self.zstd_compression.to_string()),
#[cfg(feature = "rocksdb")]
@@ -426,8 +405,8 @@ impl fmt::Display for Config {
("Forbidden usernames", {
&self.forbidden_usernames.patterns().iter().join(", ")
}),
("Forbidden room aliases", {
&self.forbidden_alias_names.patterns().iter().join(", ")
("Forbidden room names", {
&self.forbidden_room_names.patterns().iter().join(", ")
}),
(
"URL preview domain contains allowlist",
@@ -467,11 +446,9 @@ fn default_port() -> ListeningPort {
fn default_unix_socket_perms() -> u32 { 660 }
fn default_database_backups_to_keep() -> i16 { 1 }
fn default_database_backend() -> String { "rocksdb".to_owned() }
fn default_db_cache_capacity_mb() -> f64 { 256.0 }
fn default_db_cache_capacity_mb() -> f64 { 300.0 }
fn default_conduit_cache_capacity_modifier() -> f64 { 1.0 }
@@ -512,7 +489,7 @@ fn default_rocksdb_max_log_file_size() -> usize {
4 * 1024 * 1024
}
fn default_rocksdb_parallelism_threads() -> usize { 0 }
fn default_rocksdb_parallelism_threads() -> usize { num_cpus::get_physical() / 2 }
fn default_rocksdb_compression_algo() -> String { "zstd".to_owned() }
+5 -28
View File
@@ -1,4 +1,4 @@
use std::{error::Error, future::Future, pin::Pin, sync::Arc};
use std::{future::Future, pin::Pin, sync::Arc};
use super::Config;
use crate::Result;
@@ -18,8 +18,6 @@ pub(crate) trait KeyValueDatabaseEngine: Send + Sync {
Self: Sized;
fn open_tree(&self, name: &'static str) -> Result<Arc<dyn KvTree>>;
fn flush(&self) -> Result<()>;
#[allow(dead_code)]
fn sync(&self) -> Result<()> { Ok(()) }
fn cleanup(&self) -> Result<()> { Ok(()) }
fn memory_usage(&self) -> Result<String> {
Ok("Current database engine does not support memory usage reporting.".to_owned())
@@ -27,10 +25,6 @@ pub(crate) trait KeyValueDatabaseEngine: Send + Sync {
#[allow(dead_code)]
fn clear_caches(&self) {}
fn backup(&self) -> Result<(), Box<dyn Error>> { unimplemented!() }
fn backup_list(&self) -> Result<String> { Ok(String::new()) }
}
pub(crate) trait KvTree: Send + Sync {
@@ -45,37 +39,20 @@ pub(crate) trait KvTree: Send + Sync {
}
fn insert(&self, key: &[u8], value: &[u8]) -> Result<()>;
fn insert_batch(&self, iter: &mut dyn Iterator<Item = (Vec<u8>, Vec<u8>)>) -> Result<()> {
for (key, value) in iter {
self.insert(&key, &value)?;
}
Ok(())
}
fn insert_batch(&self, iter: &mut dyn Iterator<Item = (Vec<u8>, Vec<u8>)>) -> Result<()>;
fn remove(&self, key: &[u8]) -> Result<()>;
#[allow(dead_code)]
fn remove_batch(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> {
for key in iter {
self.remove(&key)?;
}
Ok(())
}
#[cfg(feature = "rocksdb")]
fn remove_batch(&self, _iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> { unimplemented!() }
fn iter<'a>(&'a self) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a>;
fn iter_from<'a>(&'a self, from: &[u8], backwards: bool) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a>;
fn increment(&self, key: &[u8]) -> Result<Vec<u8>>;
fn increment_batch(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()> {
for key in iter {
self.increment(&key)?;
}
Ok(())
}
fn increment_batch(&self, iter: &mut dyn Iterator<Item = Vec<u8>>) -> Result<()>;
fn scan_prefix<'a>(&'a self, prefix: Vec<u8>) -> Box<dyn Iterator<Item = (Vec<u8>, Vec<u8>)> + 'a>;
+60 -152
View File
@@ -4,24 +4,19 @@ use std::{
sync::{Arc, RwLock},
};
use chrono::{DateTime, Utc};
use rust_rocksdb::{
backup::{BackupEngine, BackupEngineOptions},
LogLevel::{Debug, Error, Fatal, Info, Warn},
WriteBatchWithTransaction,
};
use tracing::{debug, error, info};
use tracing::{debug, info};
use super::{super::Config, watchers::Watchers, KeyValueDatabaseEngine, KvTree};
use crate::{utils, Result};
pub(crate) struct Engine {
rocks: rust_rocksdb::DBWithThreadMode<rust_rocksdb::MultiThreaded>,
row_cache: rust_rocksdb::Cache,
col_cache: rust_rocksdb::Cache,
cache: rust_rocksdb::Cache,
old_cfs: Vec<String>,
opts: rust_rocksdb::Options,
env: rust_rocksdb::Env,
config: Config,
}
@@ -32,13 +27,24 @@ struct RocksDbEngineTree<'a> {
write_lock: RwLock<()>,
}
fn db_options(
config: &Config, env: &rust_rocksdb::Env, row_cache: &rust_rocksdb::Cache, col_cache: &rust_rocksdb::Cache,
) -> rust_rocksdb::Options {
fn db_options(rocksdb_cache: &rust_rocksdb::Cache, config: &Config) -> rust_rocksdb::Options {
// block-based options: https://docs.rs/rocksdb/latest/rocksdb/struct.BlockBasedOptions.html#
let mut block_based_options = rust_rocksdb::BlockBasedOptions::default();
block_based_options.set_block_cache(rocksdb_cache);
// "Difference of spinning disk"
// https://zhangyuchi.gitbooks.io/rocksdbbook/content/RocksDB-Tuning-Guide.html
block_based_options.set_block_size(64 * 1024);
block_based_options.set_cache_index_and_filter_blocks(true);
block_based_options.set_bloom_filter(10.0, false);
block_based_options.set_pin_l0_filter_and_index_blocks_in_cache(true);
block_based_options.set_optimize_filters_for_memory(true);
// database options: https://docs.rs/rocksdb/latest/rocksdb/struct.Options.html#
let mut db_opts = rust_rocksdb::Options::default();
// Logging
let rocksdb_log_level = match config.rocksdb_log_level.as_ref() {
"debug" => Debug,
"info" => Info,
@@ -46,52 +52,7 @@ fn db_options(
"fatal" => Fatal,
_ => Error,
};
db_opts.set_log_level(rocksdb_log_level);
db_opts.set_max_log_file_size(config.rocksdb_max_log_file_size);
db_opts.set_log_file_time_to_roll(config.rocksdb_log_time_to_roll);
db_opts.set_keep_log_file_num(config.rocksdb_max_log_files);
// Processing
let threads = if config.rocksdb_parallelism_threads == 0 {
num_cpus::get_physical() // max cores if user specified 0
} else {
config.rocksdb_parallelism_threads
};
db_opts.set_max_background_jobs(threads.try_into().unwrap());
db_opts.set_max_subcompactions(threads.try_into().unwrap());
// IO
db_opts.set_use_direct_reads(true);
db_opts.set_use_direct_io_for_flush_and_compaction(true);
if config.rocksdb_optimize_for_spinning_disks {
db_opts.set_skip_stats_update_on_db_open(true); // speeds up opening DB on hard
// drives
}
// Blocks
let mut block_based_options = rust_rocksdb::BlockBasedOptions::default();
block_based_options.set_block_size(4 * 1024);
block_based_options.set_metadata_block_size(4 * 1024);
block_based_options.set_bloom_filter(9.6, true);
block_based_options.set_optimize_filters_for_memory(true);
block_based_options.set_cache_index_and_filter_blocks(true);
block_based_options.set_pin_top_level_index_and_filter(true);
block_based_options.set_block_cache(col_cache);
db_opts.set_row_cache(row_cache);
// Buffers
db_opts.set_write_buffer_size(2 * 1024 * 1024);
db_opts.set_max_write_buffer_number(2);
db_opts.set_min_write_buffer_number(1);
// Files
db_opts.set_level_zero_file_num_compaction_trigger(1);
db_opts.set_target_file_size_base(64 * 1024 * 1024);
db_opts.set_max_bytes_for_level_base(128 * 1024 * 1024);
db_opts.set_ttl(14 * 24 * 60 * 60);
// Compression
let rocksdb_compression_algo = match config.rocksdb_compression_algo.as_ref() {
"zstd" => rust_rocksdb::DBCompressionType::Zstd,
"zlib" => rust_rocksdb::DBCompressionType::Zlib,
@@ -100,6 +61,29 @@ fn db_options(
_ => rust_rocksdb::DBCompressionType::Zstd,
};
let threads = if config.rocksdb_parallelism_threads == 0 {
num_cpus::get_physical() // max cores if user specified 0
} else {
config.rocksdb_parallelism_threads
};
db_opts.set_log_level(rocksdb_log_level);
db_opts.set_max_log_file_size(config.rocksdb_max_log_file_size);
db_opts.set_log_file_time_to_roll(config.rocksdb_log_time_to_roll);
db_opts.set_keep_log_file_num(config.rocksdb_max_log_files);
if config.rocksdb_optimize_for_spinning_disks {
db_opts.set_skip_stats_update_on_db_open(true); // speeds up opening DB on hard drives
db_opts.set_compaction_readahead_size(4 * 1024 * 1024); // "If youre running RocksDB on spinning disks, you should set this to at least
// 2MB. That way RocksDBs compaction is doing sequential instead of random
// reads."
db_opts.set_target_file_size_base(256 * 1024 * 1024);
} else {
db_opts.set_max_bytes_for_level_base(512 * 1024 * 1024);
db_opts.set_use_direct_reads(true);
db_opts.set_use_direct_io_for_flush_and_compaction(true);
}
if config.rocksdb_bottommost_compression {
db_opts.set_bottommost_compression_type(rocksdb_compression_algo);
db_opts.set_bottommost_zstd_max_train_bytes(0, true);
@@ -110,10 +94,18 @@ fn db_options(
// -14 w_bits is only read by zlib.
db_opts.set_compression_options(-14, config.rocksdb_compression_level, 0, 0);
db_opts.set_block_based_table_factory(&block_based_options);
db_opts.create_if_missing(true);
db_opts.increase_parallelism(
threads.try_into().expect("Failed to convert \"rocksdb_parallelism_threads\" usize into i32"),
);
db_opts.set_compression_type(rocksdb_compression_algo);
// Misc
db_opts.create_if_missing(true);
// https://github.com/facebook/rocksdb/wiki/Setup-Options-and-Basic-Tuning
db_opts.set_level_compaction_dynamic_level_bytes(true);
db_opts.set_max_background_jobs(6);
db_opts.set_bytes_per_sync(1_048_576);
// https://github.com/facebook/rocksdb/wiki/WAL-Recovery-Modes#ktoleratecorruptedtailrecords
//
@@ -126,21 +118,15 @@ fn db_options(
let prefix_extractor = rust_rocksdb::SliceTransform::create_fixed_prefix(1);
db_opts.set_prefix_extractor(prefix_extractor);
db_opts.set_block_based_table_factory(&block_based_options);
db_opts.set_env(env);
db_opts
}
impl KeyValueDatabaseEngine for Arc<Engine> {
fn open(config: &Config) -> Result<Self> {
let cache_capacity_bytes = config.db_cache_capacity_mb * 1024.0 * 1024.0;
let row_cache_capacity_bytes = (cache_capacity_bytes * 0.25) as usize;
let col_cache_capacity_bytes = (cache_capacity_bytes * 0.75) as usize;
let cache_capacity_bytes = (config.db_cache_capacity_mb * 1024.0 * 1024.0) as usize;
let rocksdb_cache = rust_rocksdb::Cache::new_lru_cache(cache_capacity_bytes);
let db_env = rust_rocksdb::Env::new()?;
let row_cache = rust_rocksdb::Cache::new_lru_cache(row_cache_capacity_bytes);
let col_cache = rust_rocksdb::Cache::new_lru_cache(col_cache_capacity_bytes);
let db_opts = db_options(config, &db_env, &row_cache, &col_cache);
let db_opts = db_options(&rocksdb_cache, config);
debug!("Listing column families in database");
let cfs =
@@ -152,16 +138,13 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
let db = rust_rocksdb::DBWithThreadMode::<rust_rocksdb::MultiThreaded>::open_cf_descriptors(
&db_opts,
&config.database_path,
cfs.iter().map(|name| rust_rocksdb::ColumnFamilyDescriptor::new(name, db_opts.clone())),
cfs.iter().map(|name| rust_rocksdb::ColumnFamilyDescriptor::new(name, db_options(&rocksdb_cache, config))),
)?;
Ok(Arc::new(Engine {
rocks: db,
row_cache,
col_cache,
cache: rocksdb_cache,
old_cfs: cfs,
opts: db_opts,
env: db_env,
config: config.clone(),
}))
}
@@ -170,7 +153,7 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
if !self.old_cfs.contains(&name.to_owned()) {
// Create if it didn't exist
debug!("Creating new column family in database: {}", name);
let _ = self.rocks.create_cf(name, &self.opts);
let _ = self.rocks.create_cf(name, &db_options(&self.cache, &self.config));
}
Ok(Arc::new(RocksDbEngineTree {
@@ -182,35 +165,23 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
}
fn flush(&self) -> Result<()> {
debug!("Running flush_wal (no sync)");
rust_rocksdb::DBCommon::flush_wal(&self.rocks, false)?;
Ok(())
}
fn sync(&self) -> Result<()> {
rust_rocksdb::DBCommon::flush_wal(&self.rocks, true)?;
Ok(())
}
fn memory_usage(&self) -> Result<String> {
let stats = rust_rocksdb::perf::get_memory_usage_stats(
Some(&[&self.rocks]),
Some(&[&self.row_cache, &self.col_cache]),
)?;
let stats = rust_rocksdb::perf::get_memory_usage_stats(Some(&[&self.rocks]), Some(&[&self.cache]))?;
Ok(format!(
"Approximate memory usage of all the mem-tables: {:.3} MB\nApproximate memory usage of un-flushed \
mem-tables: {:.3} MB\nApproximate memory usage of all the table readers: {:.3} MB\nApproximate memory \
usage by cache: {:.3} MB\nApproximate memory usage by row cache: {:.3} MB pinned: {:.3} MB\nApproximate \
memory usage by column cache: {:.3} MB pinned: {:.3} MB\n",
usage by cache: {:.3} MB\nApproximate memory usage by cache pinned: {:.3} MB\n",
stats.mem_table_total as f64 / 1024.0 / 1024.0,
stats.mem_table_unflushed as f64 / 1024.0 / 1024.0,
stats.mem_table_readers_total as f64 / 1024.0 / 1024.0,
stats.cache_total as f64 / 1024.0 / 1024.0,
self.row_cache.get_usage() as f64 / 1024.0 / 1024.0,
self.row_cache.get_pinned_usage() as f64 / 1024.0 / 1024.0,
self.col_cache.get_usage() as f64 / 1024.0 / 1024.0,
self.col_cache.get_pinned_usage() as f64 / 1024.0 / 1024.0,
self.cache.get_pinned_usage() as f64 / 1024.0 / 1024.0,
))
}
@@ -223,69 +194,6 @@ impl KeyValueDatabaseEngine for Arc<Engine> {
Ok(())
}
fn backup(&self) -> Result<(), Box<dyn std::error::Error>> {
let path = self.config.database_backup_path.as_ref();
if path.is_none() || path.is_some_and(|path| path.as_os_str().is_empty()) {
return Ok(());
}
let options = BackupEngineOptions::new(path.unwrap())?;
let mut engine = BackupEngine::open(&options, &self.env)?;
let ret = if self.config.database_backups_to_keep > 0 {
match engine.create_new_backup_flush(&self.rocks, true) {
Err(e) => return Err(Box::new(e)),
Ok(_) => {
let _info = engine.get_backup_info();
let info = &_info.last().unwrap();
info!(
"Created database backup #{} using {} bytes in {} files",
info.backup_id, info.size, info.num_files,
);
Ok(())
},
}
} else {
Ok(())
};
if self.config.database_backups_to_keep >= 0 {
let keep = u32::try_from(self.config.database_backups_to_keep)?;
if let Err(e) = engine.purge_old_backups(keep.try_into()?) {
error!("Failed to purge old backup: {:?}", e.to_string())
}
}
ret
}
fn backup_list(&self) -> Result<String> {
let path = self.config.database_backup_path.as_ref();
if path.is_none() || path.is_some_and(|path| path.as_os_str().is_empty()) {
return Ok(
"Configure database_backup_path to enable backups, or the path specified is not valid".to_owned(),
);
}
let mut res = String::new();
let options = BackupEngineOptions::new(path.unwrap())?;
let engine = BackupEngine::open(&options, &self.env)?;
for info in engine.get_backup_info() {
std::fmt::write(
&mut res,
format_args!(
"#{} {}: {} bytes, {} files\n",
info.backup_id,
DateTime::<Utc>::from_timestamp(info.timestamp, 0).unwrap_or_default().to_rfc2822(),
info.size,
info.num_files,
),
)
.unwrap();
}
Ok(res)
}
// TODO: figure out if this is needed for rocksdb
#[allow(dead_code)]
fn clear_caches(&self) {}
+9 -6
View File
@@ -8,6 +8,7 @@ use ruma::{
signatures::Ed25519KeyPair,
DeviceId, MilliSecondsSinceUnixEpoch, OwnedServerSigningKeyId, ServerName, UserId,
};
use tracing::debug;
use crate::{database::KeyValueDatabase, service, services, utils, Error, Result};
@@ -185,7 +186,9 @@ lasttimelinecount_cache: {lasttimelinecount_cache}\n"
fn load_keypair(&self) -> Result<Ed25519KeyPair> {
let keypair_bytes = self.global.get(b"keypair")?.map_or_else(
|| {
debug!("No keypair found in database, assuming this is a new deployment and generating one.");
let keypair = utils::generate_keypair();
debug!("Generated keypair bytes: {:?}", keypair);
self.global.insert(b"keypair", &keypair)?;
Ok::<_, Error>(keypair)
},
@@ -200,6 +203,7 @@ lasttimelinecount_cache: {lasttimelinecount_cache}\n"
)
.map_err(|_| Error::bad_database("Invalid version bytes in keypair."))
.and_then(|version| {
debug!("Keypair version: {version}");
// 2. key
parts
.next()
@@ -207,8 +211,11 @@ lasttimelinecount_cache: {lasttimelinecount_cache}\n"
.map(|key| (version, key))
})
.and_then(|(version, key)| {
Ed25519KeyPair::from_der(key, version)
.map_err(|_| Error::bad_database("Private or public keys are invalid."))
debug!("Keypair bytes: {:?}", key);
let keypair = Ed25519KeyPair::from_der(key, version)
.map_err(|_| Error::bad_database("Private or public keys are invalid."));
debug!("Private and public key: {keypair:?}");
keypair
})
}
@@ -272,8 +279,4 @@ lasttimelinecount_cache: {lasttimelinecount_cache}\n"
self.global.insert(b"version", &new_version.to_be_bytes())?;
Ok(())
}
fn backup(&self) -> Result<(), Box<dyn std::error::Error>> { self.db.backup() }
fn backup_list(&self) -> Result<String> { self.db.backup_list() }
}
+3 -26
View File
@@ -1,4 +1,4 @@
use ruma::{api::client::error::ErrorKind, OwnedUserId};
use ruma::api::client::error::ErrorKind;
use tracing::debug;
use crate::{
@@ -25,12 +25,8 @@ impl service::media::Data for KeyValueDatabase {
self.mediaid_file.insert(&key, &[])?;
if let Some(user) = sender_user {
let mut key = mxc.as_bytes().to_vec();
key.push(0xFF);
let mut user = user.as_bytes().to_vec();
user.push(0xFF);
let key = mxc.as_bytes().to_vec();
let user = user.as_bytes().to_vec();
self.mediaid_user.insert(&key, &user)?;
}
@@ -69,8 +65,6 @@ impl service::media::Data for KeyValueDatabase {
let mut prefix = mxc.as_bytes().to_vec();
prefix.push(0xFF);
debug!("AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA prefix: {:?}", prefix);
let mut keys: Vec<Vec<u8>> = vec![];
for (key, _) in self.mediaid_file.scan_prefix(prefix) {
@@ -88,23 +82,6 @@ impl service::media::Data for KeyValueDatabase {
Ok(keys)
}
fn get_all_media_keys_by_user(&self, user_id: OwnedUserId) -> Result<Vec<Vec<u8>>> {
debug!("User ID: {user_id:?}");
let mut user = user_id.as_bytes().to_vec();
user.push(0xFF);
let mut keys: Vec<Vec<u8>> = vec![];
for (key, value) in self.mediaid_user.iter() {
if value == user {
keys.push(key);
}
}
Ok(keys)
}
fn search_file_metadata(
&self, mxc: String, width: u32, height: u32,
) -> Result<(Option<String>, Option<String>, Vec<u8>)> {
+1 -1
View File
@@ -953,7 +953,7 @@ impl KeyValueDatabase {
}
{
let patterns = &services().globals.config.forbidden_alias_names;
let patterns = &services().globals.config.forbidden_room_names;
if !patterns.is_empty() {
for address in services().rooms.metadata.iter_ids() {
let room_id = address?;
+54 -15
View File
@@ -15,8 +15,12 @@ use axum::{
use axum_server::{bind, bind_rustls, tls_rustls::RustlsConfig, Handle as ServerHandle};
#[cfg(feature = "axum_dual_protocol")]
use axum_server_dual_protocol::ServerExt;
use conduit::api::{client_server, server_server};
use base64::{engine::general_purpose, Engine as _};
pub use conduit::*; // Re-export everything from the library crate
use conduit::{
api::{client_server, server_server},
clap::{Args, SigningKey},
};
use either::Either::{Left, Right};
use figment::{
providers::{Env, Format, Toml},
@@ -28,12 +32,15 @@ use http::{
};
#[cfg(unix)]
use hyperlocal::SocketIncoming;
use ruma::api::{
use ruma::{
api::{
client::{
error::{Error as RumaError, ErrorBody, ErrorKind},
uiaa::UiaaResponse,
},
IncomingRequest,
},
serde::Base64,
};
#[cfg(all(not(target_env = "msvc"), feature = "jemalloc"))]
use tikv_jemallocator::Jemalloc;
@@ -73,7 +80,7 @@ async fn main() {
} else if args.config.is_some() {
Figment::new()
.merge(
Toml::file(args.config.expect(
Toml::file(args.config.as_ref().expect(
"conduwuit config commandline argument was specified, but appears to be invalid. This should be \
set to the path of a valid TOML file.",
))
@@ -169,8 +176,16 @@ async fn main() {
let config = &services().globals.config;
/* ad-hoc config validation/checks */
/* homeserver signing keypair subcommand stuff */
if let Some(subcommands) = &args.signing_key {
if signing_key_operations(subcommands).await.is_ok() {
return;
}
}
debug!("Ed25519KeyPair: {:?}", services().globals.keypair());
/* ad-hoc config validation/checks */
if config.unix_socket_path.is_some() && !cfg!(unix) {
error!(
"UNIX socket support is only available on *nix platforms. Please remove \"unix_socket_path\" from your \
@@ -280,7 +295,7 @@ async fn main() {
}
if config.allow_outgoing_presence && !config.allow_local_presence {
error!("Outgoing presence requires allowing local presence. Please enable \"allow_local_presence\".");
error!("Outgoing presence requires allowing local presence. Please enable \"allow_outgoing_presence\".");
return;
}
@@ -535,15 +550,11 @@ async fn unrecognized_method<B: Send + 'static>(
let uri = req.uri().clone();
let inner = next.run(req).await;
if inner.status() == StatusCode::METHOD_NOT_ALLOWED {
if uri.path().contains("_matrix/") {
warn!("Method not allowed: {method} {uri}");
} else {
info!("Method not allowed: {method} {uri}");
}
return Ok(RumaResponse(UiaaResponse::MatrixError(RumaError {
body: ErrorBody::Standard {
kind: ErrorKind::Unrecognized,
message: "M_UNRECOGNIZED: Method not allowed for endpoint".to_owned(),
message: "M_UNRECOGNIZED: Unrecognized request".to_owned(),
},
status_code: StatusCode::METHOD_NOT_ALLOWED,
}))
@@ -810,12 +821,7 @@ async fn shutdown_signal(handle: ServerHandle, tx: Sender<()>) -> Result<()> {
}
async fn not_found(uri: Uri) -> impl IntoResponse {
if uri.path().contains("_matrix/") {
warn!("Not found: {uri}");
} else {
info!("Not found: {uri}");
}
Error::BadRequest(ErrorKind::Unrecognized, "Unrecognized request")
}
@@ -921,3 +927,36 @@ fn maximize_fd_limit() -> Result<(), nix::errno::Errno> {
Ok(())
}
/// Homeserver signing key commands/operations
async fn signing_key_operations(subcommands: &SigningKey) -> Result<()> {
match subcommands {
SigningKey::ExportPath {
path,
} => {
let mut file = tokio::fs::File::create(path).await?;
let mut content = String::new();
content.push_str("ed25519 ");
let version = services().globals.keypair().version();
content.push_str(version);
content.push(' ');
let keypair = services().globals.keypair();
debug!("Ed25519KeyPair: {:?}", keypair);
//let key_base64 = Base64::new(key);
Ok(())
},
SigningKey::ImportPath {
path,
add_to_old_public_keys,
timestamp,
} => {
unimplemented!()
},
}
}
+1 -111
View File
@@ -30,9 +30,7 @@ use tracing::{debug, error, info, warn};
use super::pdu::PduBuilder;
use crate::{
api::{
client_server::{
get_alias_helper, join_room_by_id_helper, leave_all_rooms, leave_room, AUTO_GEN_PASSWORD_LENGTH,
},
client_server::{get_alias_helper, leave_all_rooms, leave_room, AUTO_GEN_PASSWORD_LENGTH},
server_server::parse_incoming_pdu,
},
services,
@@ -94,12 +92,6 @@ enum MediaCommand {
event_id: Option<Box<EventId>>,
},
/// Deletes all **uploaded** local media from the specified user.
DeleteFromUser {
/// User ID to delete all media from
user_id: Box<UserId>,
},
/// - Deletes a codeblock list of MXC URLs from our database and on the
/// filesystem
DeleteList,
@@ -111,13 +103,6 @@ enum MediaCommand {
/// past 5 minutes
duration: String,
},
/// - Lists all **uploaded** local media from the specified user with their
/// MXC URLs.
ListFromUser {
/// User ID to list all media from
user_id: Box<UserId>,
},
}
#[cfg_attr(test, derive(Debug))]
@@ -451,13 +436,6 @@ enum ServerCommand {
ClearServiceCaches {
amount: u32,
},
/// - Performs an online backup of the database (only available for RocksDB
/// at the moment)
BackupDatabase,
/// - List database backups
ListBackups,
}
#[derive(Debug)]
@@ -819,17 +797,6 @@ impl Service {
));
}
},
MediaCommand::DeleteFromUser {
user_id,
} => {
let deleted_count = services().media.delete_from_user(user_id.into()).await?;
debug!("Deleted {deleted_count} total media files.");
return Ok(RoomMessageEventContent::text_plain(format!(
"Deleted {deleted_count} total media files.",
)));
},
MediaCommand::DeleteList => {
if body.len() > 2 && body[0].trim().starts_with("```") && body.last().unwrap().trim() == "```" {
let mxc_list = body.clone().drain(1..body.len() - 1).collect::<Vec<_>>();
@@ -863,25 +830,6 @@ impl Service {
deleted_count
)));
},
MediaCommand::ListFromUser {
user_id,
} => {
let mxc_list = services().media.list_all_media_by_user(user_id.clone().into()).await?;
let output_plain = format!(
"All MXC URLs {user_id} Uploaded:\n{}",
mxc_list.iter().map(ToOwned::to_owned).collect::<Vec<_>>().join("\n")
);
let output_html = format!(
"<table><caption>All MXC URLs {user_id} \
Uploaded</caption>\n<tr><th>URL</th></tr>\n{}</table>",
mxc_list.iter().fold(String::new(), |mut output, mxc| {
writeln!(output, "<tr><td>{}</td></tr>", mxc).unwrap();
output
})
);
RoomMessageEventContent::text_html(output_plain, output_html)
},
}
},
AdminCommand::Users(command) => match command {
@@ -945,35 +893,6 @@ impl Service {
.expect("to json value always works"),
)?;
if !services().globals.config.auto_join_rooms.is_empty() {
for room in &services().globals.config.auto_join_rooms {
if !services().rooms.state_cache.server_in_room(services().globals.server_name(), room)? {
warn!("Skipping room {room} to automatically join as we have never joined before.");
continue;
}
if let Some(room_id_server_name) = room.server_name() {
match join_room_by_id_helper(
Some(&user_id),
room,
Some("Automatically joining this room upon registration".to_owned()),
&[room_id_server_name.to_owned(), services().globals.server_name().to_owned()],
None,
)
.await
{
Ok(_) => {
info!("Automatically joined room {room} for user {user_id}");
},
Err(e) => {
// don't return this error so we don't fail registrations
error!("Failed to automatically join room {room} for user {user_id}: {e}");
},
};
}
}
}
// we dont add a device since we're not the user, just the creator
// Inhibit login does not work for guests
@@ -1947,35 +1866,6 @@ impl Service {
RoomMessageEventContent::text_plain("Done.")
},
ServerCommand::ListBackups => {
let result = services().globals.db.backup_list()?;
if result.is_empty() {
return Ok(RoomMessageEventContent::text_plain("No backups found."));
}
RoomMessageEventContent::text_plain(result)
},
ServerCommand::BackupDatabase => {
if !cfg!(feature = "rocksdb") {
return Ok(RoomMessageEventContent::text_plain(
"Only RocksDB supports online backups in conduwuit.",
));
}
let mut result = tokio::task::spawn_blocking(move || match services().globals.db.backup() {
Ok(_) => String::new(),
Err(e) => (*e).to_string(),
})
.await
.unwrap();
if result.is_empty() {
result = services().globals.db.backup_list()?;
}
RoomMessageEventContent::text_plain(&result)
},
},
AdminCommand::Debug(command) => match command {
DebugCommand::GetAuthChain {
+1 -3
View File
@@ -1,4 +1,4 @@
use std::{collections::BTreeMap, error::Error};
use std::collections::BTreeMap;
use async_trait::async_trait;
use ruma::{
@@ -32,6 +32,4 @@ pub trait Data: Send + Sync {
fn signing_keys_for(&self, origin: &ServerName) -> Result<BTreeMap<OwnedServerSigningKeyId, VerifyKey>>;
fn database_version(&self) -> Result<u64>;
fn bump_database_version(&self, new_version: u64) -> Result<()>;
fn backup(&self) -> Result<(), Box<dyn Error>> { unimplemented!() }
fn backup_list(&self) -> Result<String> { Ok(String::new()) }
}
+8 -11
View File
@@ -17,7 +17,6 @@ use argon2::Argon2;
use base64::{engine::general_purpose, Engine as _};
pub use data::Data;
use futures_util::FutureExt;
use hickory_resolver::TokioAsyncResolver;
use hyper::{
client::connect::dns::{GaiResolver, Name},
service::Service as HyperService,
@@ -35,6 +34,7 @@ use ruma::{
};
use tokio::sync::{broadcast, watch::Receiver, Mutex, RwLock, Semaphore};
use tracing::{error, info};
use trust_dns_resolver::TokioAsyncResolver;
use crate::{api::server_server::FedDest, services, Config, Error, Result};
@@ -152,7 +152,7 @@ impl Service<'_> {
let keypair = match keypair {
Ok(k) => k,
Err(e) => {
error!("Keypair invalid. Deleting...");
error!("Homeserver signing keypair in database is invalid. Deleting...");
db.remove_keypair()?;
return Err(e);
},
@@ -327,8 +327,6 @@ impl Service<'_> {
pub fn turn_secret(&self) -> &String { &self.config.turn_secret }
pub fn auto_join_rooms(&self) -> &[OwnedRoomId] { &self.config.auto_join_rooms }
pub fn notification_push_path(&self) -> &String { &self.config.notification_push_path }
pub fn emergency_password(&self) -> &Option<String> { &self.config.emergency_password }
@@ -347,7 +345,7 @@ impl Service<'_> {
pub fn url_preview_check_root_domain(&self) -> bool { self.config.url_preview_check_root_domain }
pub fn forbidden_alias_names(&self) -> &RegexSet { &self.config.forbidden_alias_names }
pub fn forbidden_room_names(&self) -> &RegexSet { &self.config.forbidden_room_names }
pub fn forbidden_usernames(&self) -> &RegexSet { &self.config.forbidden_usernames }
@@ -499,9 +497,8 @@ fn reqwest_client_builder(config: &Config) -> Result<reqwest::ClientBuilder> {
});
let mut reqwest_client_builder = reqwest::Client::builder()
.hickory_dns(true)
.pool_max_idle_per_host(1)
.pool_idle_timeout(Duration::from_secs(50))
.trust_dns(true)
.pool_max_idle_per_host(0)
.connect_timeout(Duration::from_secs(60))
.timeout(Duration::from_secs(60 * 5))
.redirect(redirect_policy)
@@ -528,10 +525,10 @@ fn url_preview_reqwest_client_builder(config: &Config) -> Result<reqwest::Client
});
let mut reqwest_client_builder = reqwest::Client::builder()
.hickory_dns(true)
.trust_dns(true)
.pool_max_idle_per_host(0)
.connect_timeout(Duration::from_secs(20))
.timeout(Duration::from_secs(30))
.connect_timeout(Duration::from_secs(60))
.timeout(Duration::from_secs(60 * 5))
.redirect(redirect_policy)
.user_agent("Conduwuit".to_owned() + "/" + env!("CARGO_PKG_VERSION"));
-4
View File
@@ -1,5 +1,3 @@
use ruma::OwnedUserId;
use crate::Result;
pub trait Data: Send + Sync {
@@ -17,8 +15,6 @@ pub trait Data: Send + Sync {
fn search_mxc_metadata_prefix(&self, mxc: String) -> Result<Vec<Vec<u8>>>;
fn get_all_media_keys_by_user(&self, user_id: OwnedUserId) -> Result<Vec<Vec<u8>>>;
fn get_all_media_keys(&self) -> Result<Vec<Vec<u8>>>;
fn remove_url_preview(&self, url: &str) -> Result<()>;
+5 -75
View File
@@ -12,7 +12,7 @@ use tokio::{
};
use tracing::{debug, error};
use crate::{services, utils::string_from_bytes, Error, Result};
use crate::{services, utils, Error, Result};
#[derive(Debug)]
pub struct FileMeta {
@@ -110,71 +110,6 @@ impl Service {
}
}
/// Deletes all media in the database and from the media directory by a
/// specific user
pub async fn delete_from_user(&self, user_id: OwnedUserId) -> Result<u32> {
if let Ok(user_keys) = self.db.get_all_media_keys_by_user(user_id.clone()) {
if user_keys.is_empty() {
error!("User \"{user_id}\" has not uploaded any media.");
return Err(Error::bad_database("User has not uploaded any media."));
}
let mut mxc_deletion_count = 0;
for key in user_keys {
let mxc = String::from_utf8_lossy(&key);
let keys = self.db.search_mxc_metadata_prefix(mxc.to_string())?; // the MXC alone does not determine the file path, it is only the prefix
for key in keys {
let mxc = String::from_utf8_lossy(&key);
debug!("Deleting MXC {mxc} from database");
self.delete(mxc.to_string()).await?;
mxc_deletion_count += 1;
}
}
Ok(mxc_deletion_count)
} else {
error!("Failed to find any media keys for user \"{user_id}\" in our database");
Err(Error::bad_database(
"Failed to find any media keys for the provided user in our database",
))
}
}
pub async fn list_all_media_by_user(&self, user_id: OwnedUserId) -> Result<Vec<String>> {
if let Ok(keys) = self.db.get_all_media_keys_by_user(user_id.clone()) {
if keys.is_empty() {
error!("User \"{user_id}\" has not uploaded any media.");
return Err(Error::bad_database("User has not uploaded any media."));
}
let mut mxc_list: Vec<String> = vec![];
for key in keys {
let mxc_string = string_from_bytes(&key).map_err(|e| {
error!("Failed to convert MXC key to string in database for user \"{user_id}\": {e}");
Error::bad_database("Failed to convert MXC key to string in database")
})?;
// TODO: add the file name
mxc_list.push(mxc_string);
}
Ok(mxc_list)
} else {
error!("Failed to find any media keys for user \"{user_id}\" in our database");
Err(Error::bad_database(
"Failed to find any media keys for the provided user in our database",
))
}
}
/// Uploads or replaces a file thumbnail.
#[allow(clippy::too_many_arguments)]
pub async fn upload_thumbnail(
@@ -265,7 +200,7 @@ impl Service {
let mxc = parts
.next()
.map(|bytes| {
string_from_bytes(bytes).map_err(|e| {
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")
})
@@ -547,8 +482,7 @@ mod tests {
impl Data for MockedKVDatabase {
fn create_file_metadata(
&self, _sender_user: Option<&str>, mxc: String, width: u32, height: u32, content_disposition: Option<&str>,
content_type: Option<&str>,
&self, mxc: String, width: u32, height: u32, content_disposition: Option<&str>, content_type: Option<&str>,
) -> Result<Vec<u8>> {
// copied from src/database/key_value/media.rs
let mut key = mxc.as_bytes().to_vec();
@@ -567,8 +501,6 @@ mod tests {
fn search_mxc_metadata_prefix(&self, _mxc: String) -> Result<Vec<Vec<u8>>> { todo!() }
fn get_all_media_keys_by_user(&self, _user_id: OwnedUserId) -> Result<Vec<Vec<u8>>> { todo!() }
fn get_all_media_keys(&self) -> Result<Vec<Vec<u8>>> { todo!() }
fn search_file_metadata(
@@ -600,10 +532,8 @@ mod tests {
let content_disposition = "attachment; filename=\"this is a very long file name with spaces and special \
characters like äöüß and even emoji like 🦀.png\"";
let content_type = "image/png";
let key = media
.db
.create_file_metadata(None, mxc, width, height, Some(content_disposition), Some(content_type))
.unwrap();
let key =
media.db.create_file_metadata(mxc, width, height, Some(content_disposition), Some(content_type)).unwrap();
let mut r = PathBuf::new();
r.push("/tmp");
r.push("media");
+1 -1
View File
@@ -1098,7 +1098,7 @@ mod tests {
fn invalid_pagnation_tokens() {
fn token_is_err(token: &str) {
let token: Result<PagnationToken> = PagnationToken::from_str(token);
token.unwrap_err();
assert!(token.is_err());
}
token_is_err("231_2_noabool");
+4 -3
View File
@@ -230,9 +230,10 @@ impl Service {
pub fn get_name(&self, room_id: &RoomId) -> Result<Option<String>> {
services().rooms.state_accessor.room_state_get(room_id, &StateEventType::RoomName, "")?.map_or(Ok(None), |s| {
Ok(serde_json::from_str(s.content.get())
.map(|c: RoomNameEventContent| Some(c.name))
.unwrap_or_else(|_| None))
serde_json::from_str(s.content.get()).map(|c: RoomNameEventContent| Some(c.name)).map_err(|e| {
error!("Invalid room name event in database for room {}. {}", room_id, e);
Error::bad_database("Invalid room name event in database.")
})
})
}
+5
View File
@@ -11,6 +11,7 @@ use argon2::{password_hash::SaltString, PasswordHasher};
use rand::prelude::*;
use ring::digest;
use ruma::{canonical_json::try_from_json_map, CanonicalJsonError, CanonicalJsonObject, OwnedUserId};
use tracing::debug;
use crate::{services, Error, Result};
@@ -30,8 +31,11 @@ pub(crate) fn increment(old: Option<&[u8]>) -> Option<Vec<u8>> {
Some(number.to_be_bytes().to_vec())
}
/// Generates a new homeserver signing key. First 8 bytes are the version (a
/// random alphanumeric string), the rest are generated by Ed25519KeyPair
pub fn generate_keypair() -> Vec<u8> {
let mut value = random_string(8).as_bytes().to_vec();
debug!("Keypair version bytes: {value:?}");
value.push(0xFF);
value.extend_from_slice(
&ruma::signatures::Ed25519KeyPair::generate().expect("Ed25519KeyPair generation always works (?)"),
@@ -58,6 +62,7 @@ pub fn user_id_from_bytes(bytes: &[u8]) -> Result<OwnedUserId> {
.map_err(|_| Error::bad_database("Failed to parse user id from bytes"))
}
/// Generats a random *alphanumeric* string
pub fn random_string(length: usize) -> String {
thread_rng().sample_iter(&rand::distributions::Alphanumeric).take(length).map(char::from).collect()
}