diff --git a/.envrc b/.envrc index 172993c4..bad73b75 100644 --- a/.envrc +++ b/.envrc @@ -2,8 +2,6 @@ dotenv_if_exists -if [ -f /etc/os-release ] && grep -q '^ID=nixos' /etc/os-release; then - use flake ".#${DIRENV_DEVSHELL:-default}" -fi +# use flake ".#${DIRENV_DEVSHELL:-default}" PATH_add bin diff --git a/.forgejo/actions/prefligit/action.yml b/.forgejo/actions/prefligit/action.yml new file mode 100644 index 00000000..8cbd4500 --- /dev/null +++ b/.forgejo/actions/prefligit/action.yml @@ -0,0 +1,27 @@ +name: prefligit +description: | + Runs prefligit, pre-commit reimplemented in Rust. +inputs: + extra_args: + description: options to pass to pre-commit run + required: false + default: '--all-files' + +runs: + using: composite + steps: + - name: Install uv + uses: https://github.com/astral-sh/setup-uv@v6 + with: + enable-cache: true + ignore-nothing-to-cache: true + - name: Install Prefligit + shell: bash + run: | + curl --proto '=https' --tlsv1.2 -LsSf https://github.com/j178/prefligit/releases/download/v0.0.10/prefligit-installer.sh | sh + - uses: actions/cache@v3 + with: + path: ~/.cache/prefligit + key: prefligit-0|${{ hashFiles('.pre-commit-config.yaml') }} + - run: prefligit run --show-diff-on-failure --color=always -v ${{ inputs.extra_args }} + shell: bash diff --git a/.forgejo/workflows/prefligit-checks.yml b/.forgejo/workflows/prefligit-checks.yml new file mode 100644 index 00000000..cc512496 --- /dev/null +++ b/.forgejo/workflows/prefligit-checks.yml @@ -0,0 +1,22 @@ +name: Checks / Prefligit + +on: + push: + pull_request: +permissions: + contents: read + +jobs: + prefligit: + runs-on: ubuntu-latest + env: + FROM_REF: ${{ github.event.pull_request.base.sha || (!github.event.forced && ( github.event.before != '0000000000000000000000000000000000000000' && github.event.before || github.sha )) || format('{0}~', github.sha) }} + TO_REF: ${{ github.sha }} + steps: + - name: Checkout repository + uses: actions/checkout@v4 + with: + persist-credentials: false + - uses: ./.forgejo/actions/prefligit + with: + extra_args: --all-files --hook-stage manual diff --git a/.forgejo/workflows/prek-checks.yml b/.forgejo/workflows/prek-checks.yml deleted file mode 100644 index ac330ca2..00000000 --- a/.forgejo/workflows/prek-checks.yml +++ /dev/null @@ -1,34 +0,0 @@ -name: Checks / Prek - -on: - push: - pull_request: - -permissions: - contents: read - -jobs: - fast-checks: - name: Pre-commit & Formatting - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - with: - persist-credentials: false - - - name: Install uv - uses: https://github.com/astral-sh/setup-uv@v5 - with: - enable-cache: true - ignore-nothing-to-cache: true - cache-dependency-glob: '' - - - name: Run prek - run: | - uvx prek run \ - --all-files \ - --hook-stage manual \ - --show-diff-on-failure \ - --color=always \ - -v diff --git a/.forgejo/workflows/renovate.yml b/.forgejo/workflows/renovate.yml deleted file mode 100644 index e8522bec..00000000 --- a/.forgejo/workflows/renovate.yml +++ /dev/null @@ -1,62 +0,0 @@ -name: Maintenance / Renovate - -on: - schedule: - # Run at 5am UTC daily to avoid late-night dev - - cron: '0 5 * * *' - - workflow_dispatch: - inputs: - dryRun: - description: 'Dry run mode' - required: false - default: null - type: choice - options: - - null - - 'extract' - - 'lookup' - - 'full' - logLevel: - description: 'Log level' - required: false - default: 'info' - type: choice - options: - - 'info' - - 'warning' - - 'critical' - - push: - branches: - - main - paths: - # Re-run when config changes - - '.forgejo/workflows/renovate.yml' - - 'renovate.json' - -jobs: - renovate: - name: Renovate - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - - name: Self-hosted Renovate - uses: https://github.com/renovatebot/github-action@v40.1.0 - env: - LOG_LEVEL: ${{ inputs.logLevel || 'info' }} - RENOVATE_AUTODISCOVER: 'false' - RENOVATE_BINARY_SOURCE: 'install' - RENOVATE_DRY_RUN: ${{ inputs.dryRun || 'false' }} - RENOVATE_ENDPOINT: ${{ github.server_url }}/api/v1 - RENOVATE_GIT_TIMEOUT: 60000 - RENOVATE_GIT_URL: 'endpoint' - RENOVATE_GITHUB_TOKEN_WARN: 'false' - RENOVATE_ONBOARDING: 'false' - RENOVATE_PLATFORM: 'forgejo' - RENOVATE_PR_COMMITS_PER_RUN_LIMIT: 3 - RENOVATE_REPOSITORIES: '["${{ github.repository }}"]' - RENOVATE_REQUIRE_CONFIG: 'required' - RENOVATE_TOKEN: ${{ secrets.RENOVATE_TOKEN }} diff --git a/.forgejo/workflows/rust-checks.yml b/.forgejo/workflows/rust-checks.yml index c46363a0..0595c053 100644 --- a/.forgejo/workflows/rust-checks.yml +++ b/.forgejo/workflows/rust-checks.yml @@ -73,7 +73,7 @@ jobs: run: | cargo clippy \ --workspace \ - --features full \ + --all-features \ --locked \ --no-deps \ --profile test \ @@ -133,7 +133,7 @@ jobs: run: | cargo test \ --workspace \ - --features full \ + --all-features \ --locked \ --profile test \ --all-targets \ diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 841427b7..fcfaade5 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,4 +1,5 @@ -github: [JadedBlueEyes, nexy7574] +github: [JadedBlueEyes] +# Doesn't support an array, so we can only list nex +ko_fi: nexy7574 custom: - - https://ko-fi.com/nexy7574 - https://ko-fi.com/JadedBlueEyes diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index da594310..68e3a982 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -9,7 +9,7 @@ repos: - repo: https://github.com/pre-commit/pre-commit-hooks rev: v5.0.0 hooks: - - id: fix-byte-order-marker + - id: check-byte-order-marker - id: check-case-conflict - id: check-symlinks - id: destroyed-symlinks diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b5ecf38a..2e11cff4 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -65,11 +65,11 @@ Tests, compilation, and linting can be run with standard Cargo commands: cargo test # Check compilation -cargo check --workspace --features full +cargo check --workspace --all-features # Run lints -cargo clippy --workspace --features full -# Auto-fix: cargo clippy --workspace --features full --fix --allow-staged; +cargo clippy --workspace --all-features +# Auto-fix: cargo clippy --workspace --all-features --fix --allow-staged; # Format code (must use nightly) cargo +nightly fmt diff --git a/Cargo.lock b/Cargo.lock index b38a0961..c85432c9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -52,9 +52,9 @@ dependencies = [ [[package]] name = "anstream" -version = "0.6.19" +version = "0.6.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "301af1932e46185686725e0fad2f8f2aa7da69dd70bf6ecc44d6b703844a3933" +checksum = "8acc5369981196006228e28809f761875c0327210a891e941f4c683b3a99529b" dependencies = [ "anstyle", "anstyle-parse", @@ -73,27 +73,27 @@ checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd" [[package]] name = "anstyle-parse" -version = "0.2.7" +version = "0.2.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4e7644824f0aa2c7b9384579234ef10eb7efb6a0deb83f9630a49594dd9c15c2" +checksum = "3b2d16507662817a6a20a9ea92df6652ee4f94f914589377d69f3b21bc5798a9" dependencies = [ "utf8parse", ] [[package]] name = "anstyle-query" -version = "1.1.3" +version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c8bdeb6047d8983be085bab0ba1472e6dc604e7041dbf6fcd5e71523014fae9" +checksum = "79947af37f4177cfead1110013d678905c37501914fba0efea834c3fe9a8d60c" dependencies = [ "windows-sys 0.59.0", ] [[package]] name = "anstyle-wincon" -version = "3.0.9" +version = "3.0.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "403f75924867bb1033c59fbf0797484329750cfbe3c4325cd33127941fabc882" +checksum = "6680de5231bd6ee4c6191b8a1325daa282b415391ec9d3a37bd34f2060dc73fa" dependencies = [ "anstyle", "once_cell_polyfill", @@ -126,7 +126,7 @@ checksum = "0ae92a5119aa49cdbcf6b9f893fe4e1d98b04ccbf82ee0584ad948a44a734dea" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -183,7 +183,7 @@ dependencies = [ "rustc-hash 2.1.1", "serde", "serde_derive", - "syn 2.0.104", + "syn", ] [[package]] @@ -198,45 +198,6 @@ dependencies = [ "winnow", ] -[[package]] -name = "asn1-rs" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f6fd5ddaf0351dff5b8da21b2fb4ff8e08ddd02857f0bf69c47639106c0fff0" -dependencies = [ - "asn1-rs-derive", - "asn1-rs-impl", - "displaydoc", - "nom", - "num-traits", - "rusticata-macros", - "thiserror 1.0.69", - "time", -] - -[[package]] -name = "asn1-rs-derive" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "726535892e8eae7e70657b4c8ea93d26b8553afb1ce617caee529ef96d7dee6c" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "synstructure 0.12.6", -] - -[[package]] -name = "asn1-rs-impl" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2777730b2039ac0f95f093556e61b6d26cebed5393ca6f152717777cec3a42ed" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "assign" version = "1.1.1" @@ -256,9 +217,9 @@ dependencies = [ [[package]] name = "async-compression" -version = "0.4.27" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ddb939d66e4ae03cee6091612804ba446b12878410cfa17f785f4dd67d4014e8" +checksum = "40f6024f3f856663b45fd0c9b6f2024034a702f453549449e0d84a305900dad4" dependencies = [ "brotli", "flate2", @@ -289,7 +250,7 @@ checksum = "c7c24de15d275a1ecfd47a380fb4d5ec9bfe0933f309ed5e705b775596a3574d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -300,7 +261,7 @@ checksum = "e539d3fca749fcee5236ab05e93a52867dd549cc157c8cb7f99595f3cedffdb5" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -340,18 +301,18 @@ dependencies = [ [[package]] name = "avif-serialize" -version = "0.8.5" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ea8ef51aced2b9191c08197f55450d830876d9933f8f48a429b354f1d496b42" +checksum = "98922d6a4cfbcb08820c69d8eeccc05bb1f29bfa06b4f5b1dbfe9a868bd7608e" dependencies = [ "arrayvec", ] [[package]] name = "aws-lc-rs" -version = "1.13.3" +version = "1.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c953fe1ba023e6b7730c0d4b031d06f267f23a46167dcbd40316644b10a17ba" +checksum = "93fcc8f365936c834db5514fc45aee5b1202d677e6b40e48468aaaa8183ca8c7" dependencies = [ "aws-lc-sys", "zeroize", @@ -359,9 +320,9 @@ dependencies = [ [[package]] name = "aws-lc-sys" -version = "0.30.0" +version = "0.29.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbfd150b5dbdb988bcc8fb1fe787eb6b7ee6180ca24da683b61ea5405f3d43ff" +checksum = "61b1d86e7705efe1be1b569bab41d4fa1e14e220b60a160f78de2db687add079" dependencies = [ "bindgen 0.69.5", "cc", @@ -472,11 +433,11 @@ dependencies = [ "hyper", "hyper-util", "pin-project-lite", - "rustls 0.23.29", - "rustls-pemfile 2.2.0", + "rustls", + "rustls-pemfile", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls", "tower-service", ] @@ -491,9 +452,9 @@ dependencies = [ "http", "http-body-util", "pin-project", - "rustls 0.23.29", + "rustls", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls", "tokio-util", "tower-layer", "tower-service", @@ -560,15 +521,15 @@ dependencies = [ "regex", "rustc-hash 1.1.0", "shlex", - "syn 2.0.104", + "syn", "which", ] [[package]] name = "bindgen" -version = "0.72.0" +version = "0.71.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4f72209734318d0b619a5e0f5129918b848c416e122a3c4ce054e03cb87b726f" +checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3" dependencies = [ "bitflags 2.9.1", "cexpr", @@ -579,7 +540,7 @@ dependencies = [ "regex", "rustc-hash 2.1.1", "shlex", - "syn 2.0.104", + "syn", ] [[package]] @@ -668,9 +629,9 @@ checksum = "f4ad8f11f288f48ca24471bbd51ac257aaeaaa07adae295591266b792902ae64" [[package]] name = "bumpalo" -version = "3.19.0" +version = "3.18.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43" +checksum = "793db76d6187cd04dff33004d8e6c9cc4e05cd330500379d2394209271b4aeee" [[package]] name = "bytemuck" @@ -724,9 +685,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.30" +version = "1.2.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7" +checksum = "d487aa071b5f64da6f19a3e848e3578944b726ee5a4854b82172f02aa876bfdc" dependencies = [ "jobserver", "libc", @@ -795,9 +756,9 @@ dependencies = [ [[package]] name = "clap" -version = "4.5.41" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be92d32e80243a54711e5d7ce823c35c41c9d929dc4ab58e1276f625841aadf9" +checksum = "40b6887a1d8685cebccf115538db5c0efe625ccac9696ad45c409d96566e910f" dependencies = [ "clap_builder", "clap_derive", @@ -814,9 +775,9 @@ dependencies = [ [[package]] name = "clap_builder" -version = "4.5.41" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "707eab41e9622f9139419d573eca0900137718000c517d47da73045f54331c3d" +checksum = "e0c66c08ce9f0c698cbce5c0279d0bb6ac936d8674174fe48f736533b964f59e" dependencies = [ "anstream", "anstyle", @@ -826,14 +787,14 @@ dependencies = [ [[package]] name = "clap_derive" -version = "4.5.41" +version = "4.5.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef4f52386a59ca4c860f7393bcf8abd8dfd91ecccc0f774635ff68e92eeef491" +checksum = "d2c7947ae4cc3d851207c1adb5b5e260ff0cca11446b1d6d1423788e442257ce" dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -844,9 +805,9 @@ checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675" [[package]] name = "clap_mangen" -version = "0.2.28" +version = "0.2.26" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e2fb6d3f935bbb9819391528b0e7cf655e78a0bc7a7c3d227211a1d24fc11db1" +checksum = "724842fa9b144f9b89b3f3d371a89f3455eea660361d13a554f68f8ae5d6c13a" dependencies = [ "clap", "roff", @@ -869,9 +830,9 @@ checksum = "3d7b894f5411737b7867f4827955924d7c254fc9f4d91a6aad6b097804b1018b" [[package]] name = "colorchoice" -version = "1.0.4" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b05b61dc5112cbb17e4b6cd61790d9845d13888356391624cbe7e41efeac1e75" +checksum = "5b63caa9aa9397e2d9480a9b13673856c78d8ac123288526c37d7839f2a86990" [[package]] name = "concurrent-queue" @@ -884,7 +845,7 @@ dependencies = [ [[package]] name = "conduwuit" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "clap", "conduwuit_admin", @@ -914,7 +875,7 @@ dependencies = [ [[package]] name = "conduwuit_admin" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "clap", "conduwuit_api", @@ -935,7 +896,7 @@ dependencies = [ [[package]] name = "conduwuit_api" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "async-trait", "axum", @@ -967,14 +928,14 @@ dependencies = [ [[package]] name = "conduwuit_build_metadata" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "built 0.8.0", ] [[package]] name = "conduwuit_core" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "argon2", "arrayvec", @@ -1011,7 +972,7 @@ dependencies = [ "rand 0.8.5", "regex", "reqwest", - "ring 0.17.14", + "ring", "ruma", "sanitize-filename", "serde", @@ -1035,7 +996,7 @@ dependencies = [ [[package]] name = "conduwuit_database" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "async-channel", "conduwuit_core", @@ -1053,17 +1014,17 @@ dependencies = [ [[package]] name = "conduwuit_macros" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] name = "conduwuit_router" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "axum", "axum-client-ip", @@ -1083,7 +1044,7 @@ dependencies = [ "hyper-util", "log", "ruma", - "rustls 0.23.29", + "rustls", "sd-notify", "sentry", "sentry-tower", @@ -1097,7 +1058,7 @@ dependencies = [ [[package]] name = "conduwuit_service" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "async-trait", "base64 0.22.1", @@ -1113,7 +1074,6 @@ dependencies = [ "image", "ipaddress", "itertools 0.14.0", - "ldap3", "log", "loole", "lru-cache", @@ -1136,7 +1096,7 @@ dependencies = [ [[package]] name = "conduwuit_web" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "askama", "axum", @@ -1195,15 +1155,15 @@ checksum = "c2459377285ad874054d797f3ccebf984978aa39129f6eafde5cdc8315b612f8" [[package]] name = "const-str" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "041fbfcf8e7054df725fb9985297e92422cdc80fcf313665f5ca3d761bb63f4c" +checksum = "9e991226a70654b49d34de5ed064885f0bef0348a8e70018b8ff1ac80aa984a2" [[package]] name = "const_panic" -version = "0.2.13" +version = "0.2.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b98d1483e98c9d67f341ab4b3915cfdc54740bd6f5cccc9226ee0535d86aa8fb" +checksum = "2459fc9262a1aa204eb4b5764ad4f189caec88aea9634389c0a25f8be7f6265e" [[package]] name = "convert_case" @@ -1223,16 +1183,6 @@ dependencies = [ "crossterm", ] -[[package]] -name = "core-foundation" -version = "0.9.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91e195e091a93c46f7102ec7818a2aa394e1e1771c3ab4825963fa03e45afb8f" -dependencies = [ - "core-foundation-sys", - "libc", -] - [[package]] name = "core-foundation" version = "0.10.1" @@ -1270,9 +1220,9 @@ dependencies = [ [[package]] name = "crc32fast" -version = "1.5.0" +version = "1.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9481c1c90cbf2ac953f07c8d4a58aa3945c425b7185c9154d67a65e4230da511" +checksum = "a97769d94ddab943e4510d138150169a2758b5ef3eb191a9ee688de3e23ef7b3" dependencies = [ "cfg-if", ] @@ -1306,7 +1256,7 @@ dependencies = [ "proc-macro2", "quote", "strict", - "syn 2.0.104", + "syn", ] [[package]] @@ -1378,7 +1328,7 @@ dependencies = [ "futures-core", "mio", "parking_lot", - "rustix 1.0.8", + "rustix 1.0.7", "signal-hook", "signal-hook-mio", "winapi", @@ -1395,9 +1345,9 @@ dependencies = [ [[package]] name = "crunchy" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" +checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929" [[package]] name = "crypto-common" @@ -1416,7 +1366,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "32a2785755761f3ddc1492979ce1e48d2c00d09311c39e4466429188f3dd6501" dependencies = [ "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1443,7 +1393,7 @@ checksum = "f46882e17999c6cc590af592290432be3bce0428cb0d5f8b6715e4dc7b383eb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1484,20 +1434,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "der-parser" -version = "8.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dbd676fbbab537128ef0278adb5576cf363cff6aa22a7b24effe97347cfab61e" -dependencies = [ - "asn1-rs", - "displaydoc", - "nom", - "num-bigint", - "num-traits", - "rusticata-macros", -] - [[package]] name = "deranged" version = "0.4.0" @@ -1525,7 +1461,7 @@ dependencies = [ "convert_case", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1547,7 +1483,7 @@ checksum = "97369cbbc041bc366949bc74d34658d6cda5621039731c6310521892a3a20ae0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1577,9 +1513,9 @@ dependencies = [ [[package]] name = "ed25519-dalek" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e796c081cee67dc755e1a36a0a172b897fab85fc3f6bc48307991f64e4eca9" +checksum = "4a3daa8e81a3963a60642bcc1f90a670680bd4a77535faa384e9d1c79d620871" dependencies = [ "curve25519-dalek", "ed25519", @@ -1608,7 +1544,7 @@ dependencies = [ "heck", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1628,7 +1564,7 @@ checksum = "44f23cf4b44bfce11a86ace86f8a73ffdec849c9fd00a386a53d278bd9e81fb3" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1798,7 +1734,6 @@ checksum = "65bc07b1a8bc7c85c5f2e110c476c7389b4554ba72af57d8445ea63a576b0876" dependencies = [ "futures-channel", "futures-core", - "futures-executor", "futures-io", "futures-sink", "futures-task", @@ -1846,7 +1781,7 @@ checksum = "162ee34ebcb7c64a8abebc059ce0fee27c2262618d7b60ed8faf72fef13c3650" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -1932,9 +1867,9 @@ dependencies = [ [[package]] name = "gif" -version = "0.13.3" +version = "0.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4ae047235e33e2829703574b54fdec96bfbad892062d97fed2f76022287de61b" +checksum = "3fb2d69b19215e18bb912fa30f7ce15846e301408695e44e0ef719f1da9e19f2" dependencies = [ "color_quant", "weezl", @@ -1954,9 +1889,9 @@ checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2" [[package]] name = "h2" -version = "0.4.11" +version = "0.4.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "17da50a276f1e01e0ba6c029e47b7100754904ee8a278f886546e98575380785" +checksum = "a9421a676d1b147b16b82c9225157dc629087ef8ec4d5e2960f9437a90dac0a5" dependencies = [ "atomic-waker", "bytes", @@ -1964,7 +1899,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.10.0", + "indexmap 2.9.0", "slab", "tokio", "tokio-util", @@ -2094,8 +2029,8 @@ dependencies = [ "idna", "ipnet", "once_cell", - "rand 0.9.2", - "ring 0.17.14", + "rand 0.9.1", + "ring", "serde", "thiserror 2.0.12", "tinyvec", @@ -2138,7 +2073,7 @@ dependencies = [ "moka", "once_cell", "parking_lot", - "rand 0.9.2", + "rand 0.9.1", "resolv-conf", "serde", "smallvec", @@ -2187,7 +2122,7 @@ dependencies = [ "markup5ever", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -2281,13 +2216,13 @@ dependencies = [ "http", "hyper", "hyper-util", - "rustls 0.23.29", - "rustls-native-certs 0.8.1", + "rustls", + "rustls-native-certs", "rustls-pki-types", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls", "tower-service", - "webpki-roots 1.0.2", + "webpki-roots 1.0.1", ] [[package]] @@ -2480,9 +2415,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.10.0" +version = "2.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fe4cd85333e22411419a0bcae1297d25e58c9443848b11dc6a86fefe8c78a661" +checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e" dependencies = [ "equivalent", "hashbrown 0.15.4", @@ -2509,18 +2444,7 @@ checksum = "c34819042dc3d3971c46c2190835914dfbe0c3c13f61449b2997f4e9722dfa60" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", -] - -[[package]] -name = "io-uring" -version = "0.7.9" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d93587f37623a1a17d94ef2bc9ada592f5465fe7732084ab7beefabe5c77c0c4" -dependencies = [ - "bitflags 2.9.1", - "cfg-if", - "libc", + "syn", ] [[package]] @@ -2606,9 +2530,9 @@ dependencies = [ [[package]] name = "jpeg-decoder" -version = "0.3.2" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "00810f1d8b74be64b13dbf3db89ac67740615d6c891f0e7b6179326533011a07" +checksum = "f5d4a7da358eff58addd2877a45865158f0d78c911d43a5784ceb7bbf52833b0" [[package]] name = "js-sys" @@ -2678,7 +2602,7 @@ dependencies = [ "proc-macro2", "quote", "regex", - "syn 2.0.104", + "syn", ] [[package]] @@ -2693,43 +2617,6 @@ version = "1.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "830d08ce1d1d941e6b30645f1a0eb5643013d835ce3779a5fc208261dbe10f55" -[[package]] -name = "lber" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2df7f9fd9f64cf8f59e1a4a0753fe7d575a5b38d3d7ac5758dcee9357d83ef0a" -dependencies = [ - "bytes", - "nom", -] - -[[package]] -name = "ldap3" -version = "0.11.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "166199a8207874a275144c8a94ff6eed5fcbf5c52303e4d9b4d53a0c7ac76554" -dependencies = [ - "async-trait", - "bytes", - "futures", - "futures-util", - "lazy_static", - "lber", - "log", - "nom", - "percent-encoding", - "ring 0.16.20", - "rustls 0.21.12", - "rustls-native-certs 0.6.3", - "thiserror 1.0.69", - "tokio", - "tokio-rustls 0.24.1", - "tokio-stream", - "tokio-util", - "url", - "x509-parser", -] - [[package]] name = "lebe" version = "0.5.2" @@ -2744,9 +2631,9 @@ checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776" [[package]] name = "libfuzzer-sys" -version = "0.4.10" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5037190e1f70cbeef565bd267599242926f724d3b8a9f510fd7e0b540cfa4404" +checksum = "cf78f52d400cf2d84a3a973a78a592b4adc535739e0a5597a0da6f0c357adc75" dependencies = [ "arbitrary", "cc", @@ -2968,7 +2855,7 @@ checksum = "a9882ef5c56df184b8ffc107fc6c61e33ee3a654b021961d790a78571bb9d67a" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3134,7 +3021,7 @@ checksum = "ed3955f1a9c7c0c15e092f9c887db08b1fc683305fdf6eb6684f22555355e202" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3196,15 +3083,6 @@ dependencies = [ "memchr", ] -[[package]] -name = "oid-registry" -version = "0.6.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9bedf36ffb6ba96c2eb7144ef6270557b52e54b20c0a8e1eb2ff99a6c6959bff" -dependencies = [ - "asn1-rs", -] - [[package]] name = "once_cell" version = "1.21.3" @@ -3235,7 +3113,7 @@ checksum = "1e32339a5dc40459130b3bd269e9892439f55b33e772d2a9d402a789baaf4e8a" dependencies = [ "futures-core", "futures-sink", - "indexmap 2.10.0", + "indexmap 2.9.0", "js-sys", "once_cell", "pin-project-lite", @@ -3395,7 +3273,7 @@ dependencies = [ "proc-macro2", "proc-macro2-diagnostics", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3411,7 +3289,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b4c5cc86750666a3ed20bdaf5ca2a0344f9c67674cae0515bec2da16fbaa47db" dependencies = [ "fixedbitset", - "indexmap 2.10.0", + "indexmap 2.9.0", ] [[package]] @@ -3469,7 +3347,7 @@ checksum = "6e918e4ff8c4549eb882f14b3a4bc8c8bc93de829416eacf579f1207a8fbf861" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3502,12 +3380,12 @@ checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" [[package]] name = "plist" -version = "1.7.4" +version = "1.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3af6b589e163c5a788fab00ce0c0366f6efbb9959c2f9874b224936af7fce7e1" +checksum = "3d77244ce2d584cd84f6a15f86195b8c9b2a0dfbfd817c09e0464244091a58ed" dependencies = [ "base64 0.22.1", - "indexmap 2.10.0", + "indexmap 2.9.0", "quick-xml", "serde", "time", @@ -3564,12 +3442,12 @@ checksum = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c" [[package]] name = "prettyplease" -version = "0.2.36" +version = "0.2.35" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ff24dfcda44452b9816fff4cd4227e1bb73ff5a2f1bc1105aa92fb8565ce44d2" +checksum = "061c1221631e079b26479d25bbf2275bfe5917ae8419cd7e34f13bfc2aa7539a" dependencies = [ "proc-macro2", - "syn 2.0.104", + "syn", ] [[package]] @@ -3598,28 +3476,28 @@ checksum = "af066a9c399a26e020ada66a034357a868728e72cd426f3adcd35f80d88d88c8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", "version_check", "yansi", ] [[package]] name = "profiling" -version = "1.0.17" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3eb8486b569e12e2c32ad3e204dbaba5e4b5b216e9367044f25f1dba42341773" +checksum = "afbdc74edc00b6f6a218ca6a5364d6226a259d4b8ea1af4a0ea063f27e179f4d" dependencies = [ "profiling-procmacros", ] [[package]] name = "profiling-procmacros" -version = "1.0.17" +version = "1.0.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "52717f9a02b6965224f95ca2a81e2e0c5c43baacd28ca057577988930b6c3d5b" +checksum = "a65f2e60fbf1063868558d69c6beacf412dc755f9fc020f514b7955fc914fe30" dependencies = [ "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3642,7 +3520,7 @@ dependencies = [ "itertools 0.14.0", "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -3689,9 +3567,9 @@ checksum = "a993555f31e5a609f617c12db6250dedcac1b0a85076912c436e6fc9b2c8e6a3" [[package]] name = "quick-xml" -version = "0.38.0" +version = "0.37.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8927b0664f5c5a98265138b7e3f90aa19a6b21353182469ace36d4ac527b7b1b" +checksum = "331e97a1af0bf59823e6eadffe373d7b27f485be8748f71471c662c1f269b7fb" dependencies = [ "memchr", ] @@ -3708,7 +3586,7 @@ dependencies = [ "quinn-proto", "quinn-udp", "rustc-hash 2.1.1", - "rustls 0.23.29", + "rustls", "socket2", "thiserror 2.0.12", "tokio", @@ -3725,10 +3603,10 @@ dependencies = [ "bytes", "getrandom 0.3.3", "lru-slab", - "rand 0.9.2", - "ring 0.17.14", + "rand 0.9.1", + "ring", "rustc-hash 2.1.1", - "rustls 0.23.29", + "rustls", "rustls-pki-types", "slab", "thiserror 2.0.12", @@ -3779,9 +3657,9 @@ dependencies = [ [[package]] name = "rand" -version = "0.9.2" +version = "0.9.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +checksum = "9fbfd9d094a40bf3ae768db9361049ace4c0e04a4fd6b359518bd7b73a73dd97" dependencies = [ "rand_chacha 0.9.0", "rand_core 0.9.3", @@ -3862,9 +3740,9 @@ dependencies = [ [[package]] name = "ravif" -version = "0.11.20" +version = "0.11.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5825c26fddd16ab9f515930d49028a630efec172e903483c94796cfe31893e6b" +checksum = "d6a5f31fcf7500f9401fea858ea4ab5525c99f2322cfcee732c0e6c74208c0c6" dependencies = [ "avif-serialize", "imgref", @@ -3908,9 +3786,9 @@ dependencies = [ [[package]] name = "redox_syscall" -version = "0.5.15" +version = "0.5.13" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8af0dde094006011e6a740d4879319439489813bd0bcdc7d821beaeeff48ec" +checksum = "0d04b7d0ee6b4a0207a0a7adb104d23ecb0b47d6beae7152d0fa34b692b29fd6" dependencies = [ "bitflags 2.9.1", ] @@ -3987,16 +3865,16 @@ dependencies = [ "percent-encoding", "pin-project-lite", "quinn", - "rustls 0.23.29", - "rustls-native-certs 0.8.1", - "rustls-pemfile 2.2.0", + "rustls", + "rustls-native-certs", + "rustls-pemfile", "rustls-pki-types", "serde", "serde_json", "serde_urlencoded", "sync_wrapper", "tokio", - "tokio-rustls 0.26.2", + "tokio-rustls", "tokio-socks", "tokio-util", "tower 0.5.2", @@ -4016,24 +3894,9 @@ source = "git+https://forgejo.ellis.link/continuwuation/resolv-conf?rev=56251316 [[package]] name = "rgb" -version = "0.8.52" +version = "0.8.50" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c6a884d2998352bb4daf0183589aec883f16a6da1f4dde84d8e2e9a5409a1ce" - -[[package]] -name = "ring" -version = "0.16.20" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" -dependencies = [ - "cc", - "libc", - "once_cell", - "spin", - "untrusted 0.7.1", - "web-sys", - "winapi", -] +checksum = "57397d16646700483b67d2dd6511d79318f9d057fdbd21a4066aeac8b41d310a" [[package]] name = "ring" @@ -4045,7 +3908,7 @@ dependencies = [ "cfg-if", "getrandom 0.2.16", "libc", - "untrusted 0.9.0", + "untrusted", "windows-sys 0.52.0", ] @@ -4117,7 +3980,7 @@ dependencies = [ "form_urlencoded", "getrandom 0.2.16", "http", - "indexmap 2.10.0", + "indexmap 2.9.0", "js_int", "konst", "percent-encoding", @@ -4143,7 +4006,7 @@ name = "ruma-events" version = "0.28.1" dependencies = [ "as_variant", - "indexmap 2.10.0", + "indexmap 2.9.0", "js_int", "js_option", "percent-encoding", @@ -4210,7 +4073,7 @@ dependencies = [ "quote", "ruma-identifiers-validation", "serde", - "syn 2.0.104", + "syn", "toml", ] @@ -4242,10 +4105,10 @@ dependencies = [ [[package]] name = "rust-librocksdb-sys" -version = "0.38.0+10.4.2" -source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=99b0319416b64830dd6f8943e1f65e15aeef18bc#99b0319416b64830dd6f8943e1f65e15aeef18bc" +version = "0.33.0+9.11.1" +source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=fc9a99ac54a54208f90fdcba33ae6ee8bc3531dd#fc9a99ac54a54208f90fdcba33ae6ee8bc3531dd" dependencies = [ - "bindgen 0.72.0", + "bindgen 0.71.1", "bzip2-sys", "cc", "glob", @@ -4259,8 +4122,8 @@ dependencies = [ [[package]] name = "rust-rocksdb" -version = "0.42.1" -source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=99b0319416b64830dd6f8943e1f65e15aeef18bc#99b0319416b64830dd6f8943e1f65e15aeef18bc" +version = "0.37.0" +source = "git+https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1?rev=fc9a99ac54a54208f90fdcba33ae6ee8bc3531dd#fc9a99ac54a54208f90fdcba33ae6ee8bc3531dd" dependencies = [ "libc", "rust-librocksdb-sys", @@ -4293,15 +4156,6 @@ dependencies = [ "semver", ] -[[package]] -name = "rusticata-macros" -version = "4.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "faf0c4a6ece9950b9abdb62b1cfcf2a68b3b67a10ba445b3bb85be2a293d0632" -dependencies = [ - "nom", -] - [[package]] name = "rustix" version = "0.38.44" @@ -4317,57 +4171,33 @@ dependencies = [ [[package]] name = "rustix" -version = "1.0.8" +version = "1.0.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11181fbabf243db407ef8df94a6ce0b2f9a733bd8be4ad02b4eda9602296cac8" +checksum = "c71e83d6afe7ff64890ec6b71d6a69bb8a610ab78ce364b3352876bb4c801266" dependencies = [ "bitflags 2.9.1", "errno", "libc", "linux-raw-sys 0.9.4", - "windows-sys 0.60.2", + "windows-sys 0.59.0", ] [[package]] name = "rustls" -version = "0.21.12" +version = "0.23.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" -dependencies = [ - "log", - "ring 0.17.14", - "rustls-webpki 0.101.7", - "sct", -] - -[[package]] -name = "rustls" -version = "0.23.29" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2491382039b29b9b11ff08b76ff6c97cf287671dbb74f0be44bda389fffe9bd1" +checksum = "7160e3e10bf4535308537f3c4e1641468cd0e485175d6163087c0393c7d46643" dependencies = [ "aws-lc-rs", "log", "once_cell", - "ring 0.17.14", + "ring", "rustls-pki-types", - "rustls-webpki 0.103.4", + "rustls-webpki", "subtle", "zeroize", ] -[[package]] -name = "rustls-native-certs" -version = "0.6.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a9aace74cb666635c918e9c12bc0d348266037aa8eb599b5cba565709a8dff00" -dependencies = [ - "openssl-probe", - "rustls-pemfile 1.0.4", - "schannel", - "security-framework 2.11.1", -] - [[package]] name = "rustls-native-certs" version = "0.8.1" @@ -4377,16 +4207,7 @@ dependencies = [ "openssl-probe", "rustls-pki-types", "schannel", - "security-framework 3.2.0", -] - -[[package]] -name = "rustls-pemfile" -version = "1.0.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1c74cae0a4cf6ccbbf5f359f08efdf8ee7e1dc532573bf0db71968cb56b1448c" -dependencies = [ - "base64 0.21.7", + "security-framework", ] [[package]] @@ -4410,24 +4231,14 @@ dependencies = [ [[package]] name = "rustls-webpki" -version = "0.101.7" +version = "0.103.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" -dependencies = [ - "ring 0.17.14", - "untrusted 0.9.0", -] - -[[package]] -name = "rustls-webpki" -version = "0.103.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0a17884ae0c1b773f1ccd2bd4a8c72f16da897310a98b0e84bf349ad5ead92fc" +checksum = "e4a72fe2bcf7a6ac6fd7d0b9e5cb68aeb7d4c0a0271730218b3e92d43b4eb435" dependencies = [ "aws-lc-rs", - "ring 0.17.14", + "ring", "rustls-pki-types", - "untrusted 0.9.0", + "untrusted", ] [[package]] @@ -4486,16 +4297,6 @@ version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" -[[package]] -name = "sct" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da046153aa2352493d6cb7da4b6e5c0c057d8a1d0a9aa8560baffdd945acd414" -dependencies = [ - "ring 0.17.14", - "untrusted 0.9.0", -] - [[package]] name = "sd-notify" version = "0.4.5" @@ -4505,19 +4306,6 @@ dependencies = [ "libc", ] -[[package]] -name = "security-framework" -version = "2.11.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "897b2245f0b511c87893af39b033e5ca9cce68824c4d7e7630b5a1d339658d02" -dependencies = [ - "bitflags 2.9.1", - "core-foundation 0.9.4", - "core-foundation-sys", - "libc", - "security-framework-sys", -] - [[package]] name = "security-framework" version = "3.2.0" @@ -4525,7 +4313,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags 2.9.1", - "core-foundation 0.10.1", + "core-foundation", "core-foundation-sys", "libc", "security-framework-sys", @@ -4555,7 +4343,7 @@ checksum = "255914a8e53822abd946e2ce8baa41d4cded6b8e938913b7f7b9da5b7ab44335" dependencies = [ "httpdate", "reqwest", - "rustls 0.23.29", + "rustls", "sentry-backtrace", "sentry-contexts", "sentry-core", @@ -4699,7 +4487,7 @@ checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -4709,7 +4497,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d2de91cf02bbc07cde38891769ccd5d4f073d22a40683aa4bc7a95781aaa2c4" dependencies = [ "form_urlencoded", - "indexmap 2.10.0", + "indexmap 2.9.0", "itoa", "ryu", "serde", @@ -4717,9 +4505,9 @@ dependencies = [ [[package]] name = "serde_json" -version = "1.0.141" +version = "1.0.140" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3" +checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373" dependencies = [ "itoa", "memchr", @@ -4774,7 +4562,7 @@ version = "0.9.34+deprecated" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6a8b1a1a2ebf674015cc02edccce75287f1a0130d394307b36743c2f5d504b47" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.9.0", "itoa", "ryu", "serde", @@ -4913,12 +4701,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "spin" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" - [[package]] name = "spki" version = "0.7.3" @@ -4987,17 +4769,6 @@ version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" -[[package]] -name = "syn" -version = "1.0.109" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" -dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", -] - [[package]] name = "syn" version = "2.0.104" @@ -5018,18 +4789,6 @@ dependencies = [ "futures-core", ] -[[package]] -name = "synstructure" -version = "0.12.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f36bdaa60a83aca3921b5259d5400cbf5e90fc51931376a9bd4a0eb79aa7210f" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", - "unicode-xid", -] - [[package]] name = "synstructure" version = "0.13.2" @@ -5038,7 +4797,7 @@ checksum = "728a70f3dbaf5bab7f0c4b1ac8d7ae5ea60a4b5549c8a5914361c99147a709d2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -5129,7 +4888,7 @@ checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -5140,7 +4899,7 @@ checksum = "7f7cf42b4507d8ea322120659672cf1b9dbb93f8f2d4ecfd6e51350ff5b17a1d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -5281,18 +5040,16 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.46.1" +version = "1.45.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0cc3a2344dafbe23a245241fe8b09735b521110d30fcefbbd5feb1797ca35d17" +checksum = "75ef51a33ef1da925cea3e4eb122833cb377c61439ca401b770f54902b806779" dependencies = [ "backtrace", "bytes", - "io-uring", "libc", "mio", "pin-project-lite", "signal-hook-registry", - "slab", "socket2", "tokio-macros", "tracing", @@ -5307,14 +5064,14 @@ checksum = "6e06d43f1345a3bcd39f6a56dbb7dcab2ba47e68e8ac134855e7e2bdbaf8cab8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] name = "tokio-metrics" -version = "0.4.3" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "23ff82f660c98e4ff60da5eb8fa864a4130f34b56d92d5cd23d6fdfcc14e95fa" +checksum = "7817b32d36c9b94744d7aa3f8fc13526aa0f5112009d7045f3c659413a6e44ac" dependencies = [ "futures-util", "pin-project-lite", @@ -5322,23 +5079,13 @@ dependencies = [ "tokio-stream", ] -[[package]] -name = "tokio-rustls" -version = "0.24.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" -dependencies = [ - "rustls 0.21.12", - "tokio", -] - [[package]] name = "tokio-rustls" version = "0.26.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "8e727b36a1a0e8b74c376ac2211e40c2c8af09fb4013c60d910495810f008e9b" dependencies = [ - "rustls 0.23.29", + "rustls", "tokio", ] @@ -5405,7 +5152,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.10.0", + "indexmap 2.9.0", "serde", "serde_spanned", "toml_datetime", @@ -5536,7 +5283,7 @@ source = "git+https://forgejo.ellis.link/continuwuation/tracing?rev=1e64095a8051 dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -5629,9 +5376,9 @@ checksum = "1dccffe3ce07af9386bfd29e80c0ab1a8205a2fc34e4bcd40364df902cfa8f3f" [[package]] name = "typewit" -version = "1.12.1" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97e72ba082eeb9da9dc68ff5a2bf727ef6ce362556e8d29ec1aed3bd05e7d86a" +checksum = "cb77c29baba9e4d3a6182d51fa75e3215c7fd1dab8f4ea9d107c716878e55fc0" dependencies = [ "typewit_proc_macros", ] @@ -5690,24 +5437,12 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a1a07cc7db3810833284e8d372ccdc6da29741639ecc70c9ec107df0fa6154c" -[[package]] -name = "unicode-xid" -version = "0.2.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853" - [[package]] name = "unsafe-libyaml" version = "0.2.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "673aac59facbab8a9007c7f6108d11f63b603f7cabff99fabf650fea5c32b861" -[[package]] -name = "untrusted" -version = "0.7.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" - [[package]] name = "untrusted" version = "0.9.0" @@ -5723,7 +5458,7 @@ dependencies = [ "base64 0.22.1", "log", "once_cell", - "rustls 0.23.29", + "rustls", "rustls-pki-types", "url", "webpki-roots 0.26.11", @@ -5858,7 +5593,7 @@ dependencies = [ "log", "proc-macro2", "quote", - "syn 2.0.104", + "syn", "wasm-bindgen-shared", ] @@ -5893,7 +5628,7 @@ checksum = "8ae87ea40c9f689fc23f209965b6fb8a99ad69aeeb0231408be24920604395de" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", "wasm-bindgen-backend", "wasm-bindgen-shared", ] @@ -5955,14 +5690,14 @@ version = "0.26.11" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "521bc38abb08001b01866da9f51eb7c5d647a19260e00054a8c7fd5f9e57f7a9" dependencies = [ - "webpki-roots 1.0.2", + "webpki-roots 1.0.1", ] [[package]] name = "webpki-roots" -version = "1.0.2" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e8983c3ab33d6fb807cfcdad2491c4ea8cbc8ed839181c7dfd9c67c83e261b2" +checksum = "8782dd5a41a24eed3a4f40b606249b3e236ca61adf1f25ea4d45c73de122b502" dependencies = [ "rustls-pki-types", ] @@ -6073,7 +5808,7 @@ checksum = "a47fddd13af08290e67f4acabf4b459f647552718f683a7b415d290ac744a836" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -6084,7 +5819,7 @@ checksum = "bd9211b69f8dcdfa817bfd14bf1c97c9188afa36f4750130fcdf3f400eca9fa8" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -6373,9 +6108,9 @@ checksum = "271414315aff87387382ec3d271b52d7ae78726f5d44ac98b4f4030c91880486" [[package]] name = "winnow" -version = "0.7.12" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f3edebf492c8125044983378ecb5766203ad3b4c2f7a922bd7dd207f6d443e95" +checksum = "74c7b26e3480b707944fc872477815d29a8e429d2f93a1ce000f5fa84a15cbcd" dependencies = [ "memchr", ] @@ -6405,23 +6140,6 @@ version = "0.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ea2f10b9bb0928dfb1b42b65e1f9e36f7f54dbdf08457afefb38afcdec4fa2bb" -[[package]] -name = "x509-parser" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7069fba5b66b9193bd2c5d3d4ff12b839118f6bcbef5328efafafb5395cf63da" -dependencies = [ - "asn1-rs", - "data-encoding", - "der-parser", - "lazy_static", - "nom", - "oid-registry", - "rusticata-macros", - "thiserror 1.0.69", - "time", -] - [[package]] name = "xml5ever" version = "0.18.1" @@ -6435,7 +6153,7 @@ dependencies = [ [[package]] name = "xtask" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "clap", "serde", @@ -6444,7 +6162,7 @@ dependencies = [ [[package]] name = "xtask-generate-commands" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" dependencies = [ "clap-markdown", "clap_builder", @@ -6479,8 +6197,8 @@ checksum = "38da3c9736e16c5d3c8c597a9aaa5d1fa565d0532ae05e27c24aa62fb32c0ab6" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", - "synstructure 0.13.2", + "syn", + "synstructure", ] [[package]] @@ -6500,7 +6218,7 @@ checksum = "9ecf5b4cc5364572d7f4c329661bcc82724222973f2cab6f050a4e5c22f75181" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -6520,8 +6238,8 @@ checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", - "synstructure 0.13.2", + "syn", + "synstructure", ] [[package]] @@ -6560,7 +6278,7 @@ checksum = "5b96237efa0c878c64bd89c436f661be4e46b2f3eff1ebb976f7ef2321d2f58f" dependencies = [ "proc-macro2", "quote", - "syn 2.0.104", + "syn", ] [[package]] @@ -6587,6 +6305,7 @@ version = "2.0.15+zstd.1.5.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237" dependencies = [ + "bindgen 0.71.1", "cc", "pkg-config", ] @@ -6608,9 +6327,9 @@ dependencies = [ [[package]] name = "zune-jpeg" -version = "0.4.19" +version = "0.4.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2c9e525af0a6a658e031e95f14b7f889976b74a11ba0eca5a5fc9ac8a1c43a6a" +checksum = "0f6fe2e33d02a98ee64423802e16df3de99c43e5cf5ff983767e1128b394c8ac" dependencies = [ "zune-core", ] diff --git a/Cargo.toml b/Cargo.toml index 4cf0bbca..5b6c8143 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -21,7 +21,7 @@ license = "Apache-2.0" readme = "README.md" repository = "https://forgejo.ellis.link/continuwuation/continuwuity" rust-version = "1.86.0" -version = "0.5.0-rc.7" +version = "0.5.0-rc.6" [workspace.metadata.crane] name = "conduwuit" @@ -392,7 +392,7 @@ features = [ [workspace.dependencies.rust-rocksdb] git = "https://forgejo.ellis.link/continuwuation/rust-rocksdb-zaidoon1" -rev = "99b0319416b64830dd6f8943e1f65e15aeef18bc" +rev = "fc9a99ac54a54208f90fdcba33ae6ee8bc3531dd" default-features = false features = [ "multi-threaded-cf", @@ -547,11 +547,6 @@ features = ["std"] [workspace.dependencies.maplit] version = "1.0.2" -[workspace.dependencies.ldap3] -version = "0.11.5" -default-features = false -features = ["sync", "tls-rustls"] - # # Patches # @@ -873,7 +868,7 @@ unused-qualifications = "warn" #unused-results = "warn" # TODO ## some sadness -mismatched_lifetime_syntaxes = "allow" # TODO! +elided_named_lifetimes = "allow" # TODO! let_underscore_drop = "allow" missing_docs = "allow" # cfgs cannot be limited to expected cfgs or their de facto non-transitive/opt-in use-case e.g. @@ -1012,6 +1007,3 @@ literal_string_with_formatting_args = { level = "allow", priority = 1 } needless_raw_string_hashes = "allow" - -# TODO: Enable this lint & fix all instances -collapsible_if = "allow" diff --git a/README.md b/README.md index a5f77a5b..e63fe80f 100644 --- a/README.md +++ b/README.md @@ -57,7 +57,7 @@ Continuwuity aims to: ### Can I try it out? -Check out the [documentation](https://continuwuity.org) for installation instructions. +Check out the [documentation](introduction) for installation instructions. There are currently no open registration Continuwuity instances available. diff --git a/arch/conduwuit.service b/arch/conduwuit.service index 34c3995e..f7100179 100644 --- a/arch/conduwuit.service +++ b/arch/conduwuit.service @@ -64,7 +64,7 @@ StateDirectory=conduwuit RuntimeDirectory=conduwuit RuntimeDirectoryMode=0750 -Environment=CONTINUWUITY_CONFIG=%d/config.toml +Environment=CONTINUWUITY_CONFIG=${CREDENTIALS_DIRECTORY}/config.toml LoadCredential=config.toml:/etc/conduwuit/conduwuit.toml BindPaths=/var/lib/private/conduwuit:/var/lib/matrix-conduit BindPaths=/var/lib/private/conduwuit:/var/lib/private/matrix-conduit diff --git a/conduwuit-example.toml b/conduwuit-example.toml index f0e510b4..541050b1 100644 --- a/conduwuit-example.toml +++ b/conduwuit-example.toml @@ -1696,10 +1696,6 @@ # #config_reload_signal = true -# This item is undocumented. Please contribute documentation for it. -# -#ldap = false - [global.tls] # Path to a valid TLS certificate file. @@ -1778,91 +1774,3 @@ # is 33.55MB. Setting it to 0 disables blurhashing. # #blurhash_max_raw_size = 33554432 - -[global.ldap] - -# Whether to enable LDAP login. -# -# example: "true" -# -#enable = false - -# Whether to force LDAP authentication or authorize classical password -# login. -# -# example: "true" -# -#ldap_only = false - -# URI of the LDAP server. -# -# example: "ldap://ldap.example.com:389" -# -#uri = "" - -# Root of the searches. -# -# example: "ou=users,dc=example,dc=org" -# -#base_dn = "" - -# Bind DN if anonymous search is not enabled. -# -# You can use the variable `{username}` that will be replaced by the -# entered username. In such case, the password used to bind will be the -# one provided for the login and not the one given by -# `bind_password_file`. Beware: automatically granting admin rights will -# not work if you use this direct bind instead of a LDAP search. -# -# example: "cn=ldap-reader,dc=example,dc=org" or -# "cn={username},ou=users,dc=example,dc=org" -# -#bind_dn = "" - -# Path to a file on the system that contains the password for the -# `bind_dn`. -# -# The server must be able to access the file, and it must not be empty. -# -#bind_password_file = "" - -# Search filter to limit user searches. -# -# You can use the variable `{username}` that will be replaced by the -# entered username for more complex filters. -# -# example: "(&(objectClass=person)(memberOf=matrix))" -# -#filter = "(objectClass=*)" - -# Attribute to use to uniquely identify the user. -# -# example: "uid" or "cn" -# -#uid_attribute = "uid" - -# Attribute containing the display name of the user. -# -# example: "givenName" or "sn" -# -#name_attribute = "givenName" - -# Root of the searches for admin users. -# -# Defaults to `base_dn` if empty. -# -# example: "ou=admins,dc=example,dc=org" -# -#admin_base_dn = "" - -# The LDAP search filter to find administrative users for continuwuity. -# -# If left blank, administrative state must be configured manually for each -# user. -# -# You can use the variable `{username}` that will be replaced by the -# entered username for more complex filters. -# -# example: "(objectClass=conduwuitAdmin)" or "(uid={username})" -# -#admin_filter = "" diff --git a/docker/Dockerfile b/docker/Dockerfile index 55150902..bd6e72d1 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -78,7 +78,7 @@ RUN --mount=type=cache,target=/var/cache/apt,sharing=locked \ WORKDIR /app COPY ./rust-toolchain.toml . RUN rustc --version \ - && xx-cargo --setup-target-triple + && rustup target add $(xx-cargo --print-target-triple) # Build binary # We disable incremental compilation to save disk space, as it only produces a minimal speedup for this case. @@ -87,10 +87,8 @@ RUN echo "CARGO_INCREMENTAL=0" >> /etc/environment # Configure pkg-config RUN </dev/null 2>/dev/null; then - echo "PKG_CONFIG_LIBDIR=/usr/lib/$(xx-info)/pkgconfig" >> /etc/environment - echo "PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /etc/environment - fi + echo "PKG_CONFIG_LIBDIR=/usr/lib/$(xx-info)/pkgconfig" >> /etc/environment + echo "PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /etc/environment echo "PKG_CONFIG_ALLOW_CROSS=true" >> /etc/environment EOF @@ -111,17 +109,16 @@ RUN <> /etc/environment - echo "CXXFLAGS='${CXXFLAGS} -march=${TARGET_CPU}'" >> /etc/environment - echo "RUSTFLAGS='${RUSTFLAGS} -C target-cpu=${TARGET_CPU}'" >> /etc/environment - fi + set -o allexport + set -o xtrace + . /etc/environment + if [ -n "${TARGET_CPU}" ]; then + echo "CFLAGS='${CFLAGS} -march=${TARGET_CPU}'" >> /etc/environment + echo "CXXFLAGS='${CXXFLAGS} -march=${TARGET_CPU}'" >> /etc/environment + echo "RUSTFLAGS='${RUSTFLAGS} -C target-cpu=${TARGET_CPU}'" >> /etc/environment + fi EOF # Prepare output directories @@ -139,12 +136,12 @@ ARG TARGETPLATFORM RUN xx-cargo --print-target-triple # Conduwuit version info -ARG GIT_COMMIT_HASH -ARG GIT_COMMIT_HASH_SHORT -ARG GIT_REMOTE_URL -ARG GIT_REMOTE_COMMIT_URL -ARG CONDUWUIT_VERSION_EXTRA -ARG CONTINUWUITY_VERSION_EXTRA +ARG GIT_COMMIT_HASH= +ARG GIT_COMMIT_HASH_SHORT= +ARG GIT_REMOTE_URL= +ARG GIT_REMOTE_COMMIT_URL= +ARG CONDUWUIT_VERSION_EXTRA= +ARG CONTINUWUITY_VERSION_EXTRA= ENV GIT_COMMIT_HASH=$GIT_COMMIT_HASH ENV GIT_COMMIT_HASH_SHORT=$GIT_COMMIT_HASH_SHORT ENV GIT_REMOTE_URL=$GIT_REMOTE_URL @@ -172,7 +169,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \ jq -r ".packages[] | select(.name == \"$PACKAGE\") | .targets[] | select( .kind | map(. == \"bin\") | any ) | .name")) for BINARY in "${BINARIES[@]}"; do echo $BINARY - xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY + xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY cp $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY /out/sbin/$BINARY done EOF diff --git a/docker/musl.Dockerfile b/docker/musl.Dockerfile deleted file mode 100644 index 2221525b..00000000 --- a/docker/musl.Dockerfile +++ /dev/null @@ -1,200 +0,0 @@ -# Why does this exist? -# Debian doesn't provide prebuilt musl packages -# rocksdb requires a prebuilt liburing, and linking fails if a gnu one is provided - -ARG RUST_VERSION=1 -ARG ALPINE_VERSION=3.22 - -FROM --platform=$BUILDPLATFORM docker.io/tonistiigi/xx AS xx -FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS base -FROM --platform=$BUILDPLATFORM rust:${RUST_VERSION}-alpine${ALPINE_VERSION} AS toolchain - -# Install repo tools and dependencies -RUN --mount=type=cache,target=/etc/apk/cache apk add \ - build-base pkgconfig make jq bash \ - curl git file \ - llvm-dev clang clang-static lld - - -# Developer tool versions -# renovate: datasource=github-releases depName=cargo-bins/cargo-binstall -ENV BINSTALL_VERSION=1.13.0 -# renovate: datasource=github-releases depName=psastras/sbom-rs -ENV CARGO_SBOM_VERSION=0.9.1 -# renovate: datasource=crate depName=lddtree -ENV LDDTREE_VERSION=0.3.7 - -# Install unpackaged tools -RUN <> /etc/environment - -# Configure pkg-config -RUN </dev/null 2>/dev/null; then - echo "PKG_CONFIG_LIBDIR=/usr/lib/$(xx-info)/pkgconfig" >> /etc/environment - echo "PKG_CONFIG=/usr/bin/$(xx-info)-pkg-config" >> /etc/environment - fi - echo "PKG_CONFIG_ALLOW_CROSS=true" >> /etc/environment -EOF - -# Configure cc to use clang version -RUN <> /etc/environment - echo "CXX=clang++" >> /etc/environment -EOF - -# Cross-language LTO -RUN <> /etc/environment - echo "CXXFLAGS=-flto" >> /etc/environment - # Linker is set to target-compatible clang by xx - echo "RUSTFLAGS='-Clinker-plugin-lto -Clink-arg=-fuse-ld=lld'" >> /etc/environment -EOF - -# Apply CPU-specific optimizations if TARGET_CPU is provided -ARG TARGET_CPU - -RUN <> /etc/environment - echo "CXXFLAGS='${CXXFLAGS} -march=${TARGET_CPU}'" >> /etc/environment - echo "RUSTFLAGS='${RUSTFLAGS} -C target-cpu=${TARGET_CPU}'" >> /etc/environment - fi -EOF - -# Prepare output directories -RUN mkdir /out - -FROM toolchain AS builder - - -# Get source -COPY . . - -ARG TARGETPLATFORM - -# Verify environment configuration -RUN xx-cargo --print-target-triple - -# Conduwuit version info -ARG GIT_COMMIT_HASH -ARG GIT_COMMIT_HASH_SHORT -ARG GIT_REMOTE_URL -ARG GIT_REMOTE_COMMIT_URL -ARG CONDUWUIT_VERSION_EXTRA -ARG CONTINUWUITY_VERSION_EXTRA -ENV GIT_COMMIT_HASH=$GIT_COMMIT_HASH -ENV GIT_COMMIT_HASH_SHORT=$GIT_COMMIT_HASH_SHORT -ENV GIT_REMOTE_URL=$GIT_REMOTE_URL -ENV GIT_REMOTE_COMMIT_URL=$GIT_REMOTE_COMMIT_URL -ENV CONDUWUIT_VERSION_EXTRA=$CONDUWUIT_VERSION_EXTRA -ENV CONTINUWUITY_VERSION_EXTRA=$CONTINUWUITY_VERSION_EXTRA - -ARG RUST_PROFILE=release - -# Build the binary -RUN --mount=type=cache,target=/usr/local/cargo/registry \ - --mount=type=cache,target=/usr/local/cargo/git/db \ - --mount=type=cache,target=/app/target,id=cargo-target-${TARGET_CPU}-${TARGETPLATFORM}-musl-${RUST_PROFILE} \ - bash <<'EOF' - set -o allexport - set -o xtrace - . /etc/environment - TARGET_DIR=($(cargo metadata --no-deps --format-version 1 | \ - jq -r ".target_directory")) - mkdir /out/sbin - PACKAGE=conduwuit - xx-cargo build --locked --profile ${RUST_PROFILE} \ - -p $PACKAGE --no-default-features --features bindgen-static,release_max_log_level,standard; - BINARIES=($(cargo metadata --no-deps --format-version 1 | \ - jq -r ".packages[] | select(.name == \"$PACKAGE\") | .targets[] | select( .kind | map(. == \"bin\") | any ) | .name")) - for BINARY in "${BINARIES[@]}"; do - echo $BINARY - xx-verify $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY - cp $TARGET_DIR/$(xx-cargo --print-target-triple)/release/$BINARY /out/sbin/$BINARY - done -EOF - -# Generate Software Bill of Materials (SBOM) -RUN --mount=type=cache,target=/usr/local/cargo/registry \ - --mount=type=cache,target=/usr/local/cargo/git/db \ - bash <<'EOF' - set -o xtrace - mkdir /out/sbom - typeset -A PACKAGES - for BINARY in /out/sbin/*; do - BINARY_BASE=$(basename ${BINARY}) - package=$(cargo metadata --no-deps --format-version 1 | jq -r ".packages[] | select(.targets[] | select( .kind | map(. == \"bin\") | any ) | .name == \"$BINARY_BASE\") | .name") - if [ -z "$package" ]; then - continue - fi - PACKAGES[$package]=1 - done - for PACKAGE in $(echo ${!PACKAGES[@]}); do - echo $PACKAGE - cargo sbom --cargo-package $PACKAGE > /out/sbom/$PACKAGE.spdx.json - done -EOF - -# Extract dynamically linked dependencies -RUN < return Err!("Couldn't reset the password for user {user_id}: {e}"), | Ok(()) => { diff --git a/src/api/Cargo.toml b/src/api/Cargo.toml index 9b4ea460..15ada812 100644 --- a/src/api/Cargo.toml +++ b/src/api/Cargo.toml @@ -49,9 +49,6 @@ jemalloc_stats = [ "conduwuit-core/jemalloc_stats", "conduwuit-service/jemalloc_stats", ] -ldap = [ - "conduwuit-service/ldap" -] release_max_log_level = [ "conduwuit-core/release_max_log_level", "conduwuit-service/release_max_log_level", diff --git a/src/api/client/account.rs b/src/api/client/account.rs index 67dc2a01..7b8464b5 100644 --- a/src/api/client/account.rs +++ b/src/api/client/account.rs @@ -373,7 +373,7 @@ pub(crate) async fn register_route( let password = if is_guest { None } else { body.password.as_deref() }; // Create user - services.users.create(&user_id, password, None).await?; + services.users.create(&user_id, password)?; // Default to pretty displayname let mut displayname = user_id.localpart().to_owned(); @@ -659,8 +659,7 @@ pub(crate) async fn change_password_route( services .users - .set_password(sender_user, Some(&body.new_password)) - .await?; + .set_password(sender_user, Some(&body.new_password))?; if body.logout_devices { // Logout all devices except the current one diff --git a/src/api/client/message.rs b/src/api/client/message.rs index 4f027847..bd26473d 100644 --- a/src/api/client/message.rs +++ b/src/api/client/message.rs @@ -8,7 +8,7 @@ use conduwuit::{ ref_at, utils::{ IterStream, ReadyExt, - result::LogErr, + result::{FlatOk, LogErr}, stream::{BroadbandExt, TryIgnore, WidebandExt}, }, }; @@ -35,7 +35,6 @@ use ruma::{ }; use tracing::warn; -use super::utils::{count_to_token, parse_pagination_token as parse_token}; use crate::Ruma; /// list of safe and common non-state events to ignore if the user is ignored @@ -85,14 +84,14 @@ pub(crate) async fn get_message_events_route( let from: PduCount = body .from .as_deref() - .map(parse_token) + .map(str::parse) .transpose()? .unwrap_or_else(|| match body.dir { | Direction::Forward => PduCount::min(), | Direction::Backward => PduCount::max(), }); - let to: Option = body.to.as_deref().map(parse_token).transpose()?; + let to: Option = body.to.as_deref().map(str::parse).flat_ok(); let limit: usize = body .limit @@ -181,8 +180,8 @@ pub(crate) async fn get_message_events_route( .collect(); Ok(get_message_events::v3::Response { - start: count_to_token(from), - end: next_token.map(count_to_token), + start: from.to_string(), + end: next_token.as_ref().map(ToString::to_string), chunk, state, }) diff --git a/src/api/client/mod.rs b/src/api/client/mod.rs index e4be20b7..be54e65f 100644 --- a/src/api/client/mod.rs +++ b/src/api/client/mod.rs @@ -36,7 +36,6 @@ pub(super) mod typing; pub(super) mod unstable; pub(super) mod unversioned; pub(super) mod user_directory; -pub(super) mod utils; pub(super) mod voip; pub(super) mod well_known; diff --git a/src/api/client/profile.rs b/src/api/client/profile.rs index ab259eee..ff328dec 100644 --- a/src/api/client/profile.rs +++ b/src/api/client/profile.rs @@ -90,7 +90,7 @@ pub(crate) async fn get_displayname_route( .await { if !services.users.exists(&body.user_id).await { - services.users.create(&body.user_id, None, None).await?; + services.users.create(&body.user_id, None)?; } services @@ -189,7 +189,7 @@ pub(crate) async fn get_avatar_url_route( .await { if !services.users.exists(&body.user_id).await { - services.users.create(&body.user_id, None, None).await?; + services.users.create(&body.user_id, None)?; } services @@ -248,7 +248,7 @@ pub(crate) async fn get_profile_route( .await { if !services.users.exists(&body.user_id).await { - services.users.create(&body.user_id, None, None).await?; + services.users.create(&body.user_id, None)?; } services diff --git a/src/api/client/relations.rs b/src/api/client/relations.rs index 4e791cf4..52f1747f 100644 --- a/src/api/client/relations.rs +++ b/src/api/client/relations.rs @@ -18,7 +18,6 @@ use ruma::{ events::{TimelineEventType, relation::RelationType}, }; -use super::utils::{count_to_token, parse_pagination_token as parse_token}; use crate::Ruma; /// # `GET /_matrix/client/r0/rooms/{roomId}/relations/{eventId}/{relType}/{eventType}` @@ -111,14 +110,14 @@ async fn paginate_relations_with_filter( dir: Direction, ) -> Result { let start: PduCount = from - .map(parse_token) + .map(str::parse) .transpose()? .unwrap_or_else(|| match dir { | Direction::Forward => PduCount::min(), | Direction::Backward => PduCount::max(), }); - let to: Option = to.map(parse_token).transpose()?; + let to: Option = to.map(str::parse).flat_ok(); // Use limit or else 30, with maximum 100 let limit: usize = limit @@ -130,11 +129,6 @@ async fn paginate_relations_with_filter( // Spec (v1.10) recommends depth of at least 3 let depth: u8 = if recurse { 3 } else { 1 }; - // Check if this is a thread request - let is_thread = filter_rel_type - .as_ref() - .is_some_and(|rel| *rel == RelationType::Thread); - let events: Vec<_> = services .rooms .pdu_metadata @@ -158,58 +152,23 @@ async fn paginate_relations_with_filter( .collect() .await; - // For threads, check if we should include the root event - let mut root_event = None; - if is_thread && dir == Direction::Backward { - // Check if we've reached the beginning of the thread - // (fewer events than requested means we've exhausted the thread) - if events.len() < limit { - // Try to get the thread root event - if let Ok(root_pdu) = services.rooms.timeline.get_pdu(target).await { - // Check visibility - if services - .rooms - .state_accessor - .user_can_see_event(sender_user, room_id, target) - .await - { - // Store the root event to add to the response - root_event = Some(root_pdu); - } - } - } + let next_batch = match dir { + | Direction::Forward => events.last(), + | Direction::Backward => events.first(), } - - // Determine if there are more events to fetch - let has_more = if root_event.is_some() { - false // We've included the root, no more events - } else { - // Check if we got a full page of results (might be more) - events.len() >= limit - }; - - let next_batch = if has_more { - match dir { - | Direction::Forward => events.last(), - | Direction::Backward => events.first(), - } - .map(|(count, _)| count_to_token(*count)) - } else { - None - }; - - // Build the response chunk with thread root if needed - let chunk: Vec<_> = root_event - .into_iter() - .map(Event::into_format) - .chain(events.into_iter().map(at!(1)).map(Event::into_format)) - .collect(); + .map(at!(0)) + .as_ref() + .map(ToString::to_string); Ok(get_relating_events::v1::Response { next_batch, prev_batch: from.map(Into::into), recursion_depth: recurse.then_some(depth.into()), - chunk, + chunk: events + .into_iter() + .map(at!(1)) + .map(Event::into_format) + .collect(), }) } diff --git a/src/api/client/session.rs b/src/api/client/session.rs index da7bed2c..992073c6 100644 --- a/src/api/client/session.rs +++ b/src/api/client/session.rs @@ -3,14 +3,13 @@ use std::time::Duration; use axum::extract::State; use axum_client_ip::InsecureClientIp; use conduwuit::{ - Err, Error, Result, debug, err, info, - utils::{self, ReadyExt, hash}, + Err, Error, Result, debug, err, info, utils, + utils::{ReadyExt, hash}, }; -use conduwuit_core::{debug_error, debug_warn}; -use conduwuit_service::{Services, uiaa::SESSION_ID_LENGTH}; +use conduwuit_service::uiaa::SESSION_ID_LENGTH; use futures::StreamExt; use ruma::{ - OwnedUserId, UserId, + UserId, api::client::{ session::{ get_login_token, @@ -50,154 +49,6 @@ pub(crate) async fn get_login_types_route( ])) } -/// Authenticates the given user by its ID and its password. -/// -/// Returns the user ID if successful, and an error otherwise. -#[tracing::instrument(skip_all, fields(%user_id), name = "password")] -pub(crate) async fn password_login( - services: &Services, - user_id: &UserId, - lowercased_user_id: &UserId, - password: &str, -) -> Result { - // Restrict login to accounts only of type 'password', including untyped - // legacy accounts which are equivalent to 'password'. - if services - .users - .origin(user_id) - .await - .is_ok_and(|origin| origin != "password") - { - return Err!(Request(Forbidden("Account does not permit password login."))); - } - - let (hash, user_id) = match services.users.password_hash(user_id).await { - | Ok(hash) => (hash, user_id), - | Err(_) => services - .users - .password_hash(lowercased_user_id) - .await - .map(|hash| (hash, lowercased_user_id)) - .map_err(|_| err!(Request(Forbidden("Wrong username or password."))))?, - }; - - if hash.is_empty() { - return Err!(Request(UserDeactivated("The user has been deactivated"))); - } - - hash::verify_password(password, &hash) - .inspect_err(|e| debug_error!("{e}")) - .map_err(|_| err!(Request(Forbidden("Wrong username or password."))))?; - - Ok(user_id.to_owned()) -} - -/// Authenticates the given user through the configured LDAP server. -/// -/// Creates the user if the user is found in the LDAP and do not already have an -/// account. -#[tracing::instrument(skip_all, fields(%user_id), name = "ldap")] -pub(super) async fn ldap_login( - services: &Services, - user_id: &UserId, - lowercased_user_id: &UserId, - password: &str, -) -> Result { - let (user_dn, is_ldap_admin) = match services.config.ldap.bind_dn.as_ref() { - | Some(bind_dn) if bind_dn.contains("{username}") => - (bind_dn.replace("{username}", lowercased_user_id.localpart()), false), - | _ => { - debug!("Searching user in LDAP"); - - let dns = services.users.search_ldap(user_id).await?; - if dns.len() >= 2 { - return Err!(Ldap("LDAP search returned two or more results")); - } - - let Some((user_dn, is_admin)) = dns.first() else { - return password_login(services, user_id, lowercased_user_id, password).await; - }; - - (user_dn.clone(), *is_admin) - }, - }; - - let user_id = services - .users - .auth_ldap(&user_dn, password) - .await - .map(|()| lowercased_user_id.to_owned())?; - - // LDAP users are automatically created on first login attempt. This is a very - // common feature that can be seen on many services using a LDAP provider for - // their users (synapse, Nextcloud, Jellyfin, ...). - // - // LDAP users are crated with a dummy password but non empty because an empty - // password is reserved for deactivated accounts. The conduwuit password field - // will never be read to login a LDAP user so it's not an issue. - if !services.users.exists(lowercased_user_id).await { - services - .users - .create(lowercased_user_id, Some("*"), Some("ldap")) - .await?; - } - - let is_conduwuit_admin = services.admin.user_is_admin(lowercased_user_id).await; - - if is_ldap_admin && !is_conduwuit_admin { - services.admin.make_user_admin(lowercased_user_id).await?; - } else if !is_ldap_admin && is_conduwuit_admin { - services.admin.revoke_admin(lowercased_user_id).await?; - } - - Ok(user_id) -} - -pub(crate) async fn handle_login( - services: &Services, - body: &Ruma, - identifier: Option<&uiaa::UserIdentifier>, - password: &str, - user: Option<&String>, -) -> Result { - debug!("Got password login type"); - let user_id = - if let Some(uiaa::UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { - UserId::parse_with_server_name(user_id, &services.config.server_name) - } else if let Some(user) = user { - UserId::parse_with_server_name(user, &services.config.server_name) - } else { - return Err!(Request(Unknown( - debug_warn!(?body.login_info, "Valid identifier or username was not provided (invalid or unsupported login type?)") - ))); - } - .map_err(|e| err!(Request(InvalidUsername(warn!("Username is invalid: {e}")))))?; - - let lowercased_user_id = UserId::parse_with_server_name( - user_id.localpart().to_lowercase(), - &services.config.server_name, - )?; - - if !services.globals.user_is_local(&user_id) - || !services.globals.user_is_local(&lowercased_user_id) - { - return Err!(Request(Unknown("User ID does not belong to this homeserver"))); - } - - if cfg!(feature = "ldap") && services.config.ldap.enable { - match Box::pin(ldap_login(services, &user_id, &lowercased_user_id, password)).await { - | Ok(user_id) => Ok(user_id), - | Err(err) if services.config.ldap.ldap_only => Err(err), - | Err(err) => { - debug_warn!("{err}"); - password_login(services, &user_id, &lowercased_user_id, password).await - }, - } - } else { - password_login(services, &user_id, &lowercased_user_id, password).await - } -} - /// # `POST /_matrix/client/v3/login` /// /// Authenticates the user and returns an access token it can use in subsequent @@ -229,7 +80,70 @@ pub(crate) async fn login_route( password, user, .. - }) => handle_login(&services, &body, identifier.as_ref(), password, user.as_ref()).await?, + }) => { + debug!("Got password login type"); + let user_id = + if let Some(uiaa::UserIdentifier::UserIdOrLocalpart(user_id)) = identifier { + UserId::parse_with_server_name(user_id, &services.config.server_name) + } else if let Some(user) = user { + UserId::parse_with_server_name(user, &services.config.server_name) + } else { + return Err!(Request(Unknown( + debug_warn!(?body.login_info, "Valid identifier or username was not provided (invalid or unsupported login type?)") + ))); + } + .map_err(|e| err!(Request(InvalidUsername(warn!("Username is invalid: {e}")))))?; + + let lowercased_user_id = UserId::parse_with_server_name( + user_id.localpart().to_lowercase(), + &services.config.server_name, + )?; + + if !services.globals.user_is_local(&user_id) + || !services.globals.user_is_local(&lowercased_user_id) + { + return Err!(Request(Unknown("User ID does not belong to this homeserver"))); + } + + // first try the username as-is + let hash = services + .users + .password_hash(&user_id) + .await + .inspect_err(|e| debug!("{e}")); + + match hash { + | Ok(hash) => { + if hash.is_empty() { + return Err!(Request(UserDeactivated("The user has been deactivated"))); + } + + hash::verify_password(password, &hash) + .inspect_err(|e| debug!("{e}")) + .map_err(|_| err!(Request(Forbidden("Wrong username or password."))))?; + + user_id + }, + | Err(_e) => { + let hash_lowercased_user_id = services + .users + .password_hash(&lowercased_user_id) + .await + .inspect_err(|e| debug!("{e}")) + .map_err(|_| err!(Request(Forbidden("Wrong username or password."))))?; + + if hash_lowercased_user_id.is_empty() { + return Err!(Request(UserDeactivated("The user has been deactivated"))); + } + + hash::verify_password(password, &hash_lowercased_user_id) + .inspect_err(|e| debug!("{e}")) + .map_err(|_| err!(Request(Forbidden("Wrong username or password."))))?; + + lowercased_user_id + }, + } + }, | login::v3::LoginInfo::Token(login::v3::Token { token }) => { debug!("Got token login type"); if !services.server.config.login_via_existing_session { @@ -284,8 +198,8 @@ pub(crate) async fn login_route( .clone() .unwrap_or_else(|| utils::random_string(DEVICE_ID_LENGTH).into()); - // Generate a new token for the device (ensuring no collisions) - let token = services.users.generate_unique_token().await; + // Generate a new token for the device + let token = utils::random_string(TOKEN_LENGTH); // Determine if device_id was provided and exists in the db for this user let device_exists = if body.device_id.is_some() { diff --git a/src/api/client/sync/v4.rs b/src/api/client/sync/v4.rs index a16e4526..14cd50d8 100644 --- a/src/api/client/sync/v4.rs +++ b/src/api/client/sync/v4.rs @@ -45,7 +45,6 @@ use crate::{ type TodoRooms = BTreeMap, usize, u64)>; const SINGLE_CONNECTION_SYNC: &str = "single_connection_sync"; -#[allow(clippy::cognitive_complexity)] /// POST `/_matrix/client/unstable/org.matrix.msc3575/sync` /// /// Sliding Sync endpoint (future endpoint: `/_matrix/client/v4/sync`) diff --git a/src/api/client/unstable.rs b/src/api/client/unstable.rs index f8703ff3..08f70975 100644 --- a/src/api/client/unstable.rs +++ b/src/api/client/unstable.rs @@ -292,7 +292,7 @@ pub(crate) async fn get_timezone_key_route( .await { if !services.users.exists(&body.user_id).await { - services.users.create(&body.user_id, None, None).await?; + services.users.create(&body.user_id, None)?; } services @@ -352,7 +352,7 @@ pub(crate) async fn get_profile_key_route( .await { if !services.users.exists(&body.user_id).await { - services.users.create(&body.user_id, None, None).await?; + services.users.create(&body.user_id, None)?; } services diff --git a/src/api/client/utils.rs b/src/api/client/utils.rs deleted file mode 100644 index cc941b95..00000000 --- a/src/api/client/utils.rs +++ /dev/null @@ -1,28 +0,0 @@ -use conduwuit::{ - Result, err, - matrix::pdu::{PduCount, ShortEventId}, -}; - -/// Parse a pagination token, trying ShortEventId first, then falling back to -/// PduCount -pub(crate) fn parse_pagination_token(token: &str) -> Result { - // Try parsing as ShortEventId first - if let Ok(shorteventid) = token.parse::() { - // ShortEventId maps directly to a PduCount in our database - Ok(PduCount::Normal(shorteventid)) - } else if let Ok(count) = token.parse::() { - // Fallback to PduCount for backwards compatibility - Ok(PduCount::Normal(count)) - } else if let Ok(count) = token.parse::() { - // Also handle negative counts for backfilled events - Ok(PduCount::from_signed(count)) - } else { - Err(err!(Request(InvalidParam("Invalid pagination token")))) - } -} - -/// Convert a PduCount to a token string (using the underlying ShortEventId) -pub(crate) fn count_to_token(count: PduCount) -> String { - // The PduCount's unsigned value IS the ShortEventId - count.into_unsigned().to_string() -} diff --git a/src/api/router/auth.rs b/src/api/router/auth.rs index 44afc3ef..01254c32 100644 --- a/src/api/router/auth.rs +++ b/src/api/router/auth.rs @@ -5,14 +5,6 @@ use axum_extra::{ typed_header::TypedHeaderRejectionReason, }; use conduwuit::{Err, Error, Result, debug_error, err, warn}; -use futures::{ - TryFutureExt, - future::{ - Either::{Left, Right}, - select_ok, - }, - pin_mut, -}; use ruma::{ CanonicalJsonObject, CanonicalJsonValue, OwnedDeviceId, OwnedServerName, OwnedUserId, UserId, api::{ @@ -62,7 +54,17 @@ pub(super) async fn auth( | None => request.query.access_token.as_deref(), }; - let token = find_token(services, token).await?; + let token = if let Some(token) = token { + match services.appservice.find_from_token(token).await { + | Some(reg_info) => Token::Appservice(Box::new(reg_info)), + | _ => match services.users.find_from_token(token).await { + | Ok((user_id, device_id)) => Token::User((user_id, device_id)), + | _ => Token::Invalid, + }, + } + } else { + Token::None + }; if metadata.authentication == AuthScheme::None { match metadata { @@ -340,25 +342,3 @@ async fn parse_x_matrix(request: &mut Request) -> Result { Ok(x_matrix) } - -async fn find_token(services: &Services, token: Option<&str>) -> Result { - let Some(token) = token else { - return Ok(Token::None); - }; - - let user_token = services.users.find_from_token(token).map_ok(Token::User); - - let appservice_token = services - .appservice - .find_from_token(token) - .map_ok(Box::new) - .map_ok(Token::Appservice); - - pin_mut!(user_token, appservice_token); - // Returns Ok if either token type succeeds, Err only if both fail - match select_ok([Left(user_token), Right(appservice_token)]).await { - | Err(e) if !e.is_not_found() => Err(e), - | Ok((token, _)) => Ok(token), - | _ => Ok(Token::Invalid), - } -} diff --git a/src/core/config/mod.rs b/src/core/config/mod.rs index e8518ed4..aa021be7 100644 --- a/src/core/config/mod.rs +++ b/src/core/config/mod.rs @@ -1,4 +1,3 @@ -#![allow(clippy::doc_link_with_quotes)] pub mod check; pub mod manager; pub mod proxy; @@ -1948,10 +1947,6 @@ pub struct Config { pub allow_invalid_tls_certificates_yes_i_know_what_the_fuck_i_am_doing_with_this_and_i_know_this_is_insecure: bool, - // external structure; separate section - #[serde(default)] - pub ldap: LdapConfig, - // external structure; separate section #[serde(default)] pub blurhashing: BlurhashConfig, @@ -2046,114 +2041,6 @@ pub struct BlurhashConfig { pub blurhash_max_raw_size: u64, } -#[derive(Clone, Debug, Default, Deserialize)] -#[config_example_generator(filename = "conduwuit-example.toml", section = "global.ldap")] -pub struct LdapConfig { - /// Whether to enable LDAP login. - /// - /// example: "true" - #[serde(default)] - pub enable: bool, - - /// Whether to force LDAP authentication or authorize classical password - /// login. - /// - /// example: "true" - #[serde(default)] - pub ldap_only: bool, - - /// URI of the LDAP server. - /// - /// example: "ldap://ldap.example.com:389" - /// - /// default: "" - #[serde(default)] - pub uri: Option, - - /// Root of the searches. - /// - /// example: "ou=users,dc=example,dc=org" - /// - /// default: "" - #[serde(default)] - pub base_dn: String, - - /// Bind DN if anonymous search is not enabled. - /// - /// You can use the variable `{username}` that will be replaced by the - /// entered username. In such case, the password used to bind will be the - /// one provided for the login and not the one given by - /// `bind_password_file`. Beware: automatically granting admin rights will - /// not work if you use this direct bind instead of a LDAP search. - /// - /// example: "cn=ldap-reader,dc=example,dc=org" or - /// "cn={username},ou=users,dc=example,dc=org" - /// - /// default: "" - #[serde(default)] - pub bind_dn: Option, - - /// Path to a file on the system that contains the password for the - /// `bind_dn`. - /// - /// The server must be able to access the file, and it must not be empty. - /// - /// default: "" - #[serde(default)] - pub bind_password_file: Option, - - /// Search filter to limit user searches. - /// - /// You can use the variable `{username}` that will be replaced by the - /// entered username for more complex filters. - /// - /// example: "(&(objectClass=person)(memberOf=matrix))" - /// - /// default: "(objectClass=*)" - #[serde(default = "default_ldap_search_filter")] - pub filter: String, - - /// Attribute to use to uniquely identify the user. - /// - /// example: "uid" or "cn" - /// - /// default: "uid" - #[serde(default = "default_ldap_uid_attribute")] - pub uid_attribute: String, - - /// Attribute containing the display name of the user. - /// - /// example: "givenName" or "sn" - /// - /// default: "givenName" - #[serde(default = "default_ldap_name_attribute")] - pub name_attribute: String, - - /// Root of the searches for admin users. - /// - /// Defaults to `base_dn` if empty. - /// - /// example: "ou=admins,dc=example,dc=org" - /// - /// default: "" - #[serde(default)] - pub admin_base_dn: String, - - /// The LDAP search filter to find administrative users for continuwuity. - /// - /// If left blank, administrative state must be configured manually for each - /// user. - /// - /// You can use the variable `{username}` that will be replaced by the - /// entered username for more complex filters. - /// - /// example: "(objectClass=conduwuitAdmin)" or "(uid={username})" - /// - /// default: "" - #[serde(default)] - pub admin_filter: String, -} - #[derive(Deserialize, Clone, Debug)] #[serde(transparent)] struct ListeningPort { @@ -2543,9 +2430,3 @@ pub(super) fn default_blurhash_x_component() -> u32 { 4 } pub(super) fn default_blurhash_y_component() -> u32 { 3 } // end recommended & blurhashing defaults - -fn default_ldap_search_filter() -> String { "(objectClass=*)".to_owned() } - -fn default_ldap_uid_attribute() -> String { String::from("uid") } - -fn default_ldap_name_attribute() -> String { String::from("givenName") } diff --git a/src/core/debug.rs b/src/core/debug.rs index c728278d..21a5ada4 100644 --- a/src/core/debug.rs +++ b/src/core/debug.rs @@ -100,7 +100,7 @@ pub fn trap() { #[must_use] pub fn panic_str(p: &Box) -> &'static str { - (**p).downcast_ref::<&str>().copied().unwrap_or_default() + p.downcast_ref::<&str>().copied().unwrap_or_default() } #[inline(always)] diff --git a/src/core/error/mod.rs b/src/core/error/mod.rs index 541af793..e46edf09 100644 --- a/src/core/error/mod.rs +++ b/src/core/error/mod.rs @@ -110,8 +110,6 @@ pub enum Error { InconsistentRoomState(&'static str, ruma::OwnedRoomId), #[error(transparent)] IntoHttp(#[from] ruma::api::error::IntoHttpError), - #[error("{0}")] - Ldap(Cow<'static, str>), #[error(transparent)] Mxc(#[from] ruma::MxcUriError), #[error(transparent)] diff --git a/src/core/info/room_version.rs b/src/core/info/room_version.rs index ae16ab85..2036594f 100644 --- a/src/core/info/room_version.rs +++ b/src/core/info/room_version.rs @@ -17,8 +17,13 @@ pub const STABLE_ROOM_VERSIONS: &[RoomVersionId] = &[ ]; /// Experimental, partially supported room versions -pub const UNSTABLE_ROOM_VERSIONS: &[RoomVersionId] = - &[RoomVersionId::V3, RoomVersionId::V4, RoomVersionId::V5, RoomVersionId::V12]; +pub const UNSTABLE_ROOM_VERSIONS: &[RoomVersionId] = &[ + RoomVersionId::V2, + RoomVersionId::V3, + RoomVersionId::V4, + RoomVersionId::V5, + RoomVersionId::V12, +]; type RoomVersion = (RoomVersionId, RoomVersionStability); diff --git a/src/database/Cargo.toml b/src/database/Cargo.toml index 9f51f366..55d4793f 100644 --- a/src/database/Cargo.toml +++ b/src/database/Cargo.toml @@ -44,14 +44,6 @@ zstd_compression = [ "conduwuit-core/zstd_compression", "rust-rocksdb/zstd", ] -bindgen-static = [ - # "bindgen/static" - # "clang-sys/static" - "rust-rocksdb/bindgen-static" -] -bindgen-runtime = [ - "rust-rocksdb/bindgen-runtime" -] [dependencies] async-channel.workspace = true diff --git a/src/database/maps.rs b/src/database/maps.rs index da97ef45..214dbf34 100644 --- a/src/database/maps.rs +++ b/src/database/maps.rs @@ -374,10 +374,6 @@ pub(super) static MAPS: &[Descriptor] = &[ name: "userid_masterkeyid", ..descriptor::RANDOM_SMALL }, - Descriptor { - name: "userid_origin", - ..descriptor::RANDOM - }, Descriptor { name: "userid_password", ..descriptor::RANDOM diff --git a/src/main/Cargo.toml b/src/main/Cargo.toml index eafa1e48..cddf4156 100644 --- a/src/main/Cargo.toml +++ b/src/main/Cargo.toml @@ -43,11 +43,6 @@ assets = [ [features] default = [ - "standard", - "release_max_log_level", - "bindgen-runtime", # replace with bindgen-static on alpine -] -standard = [ "blurhashing", "brotli_compression", "element_hacks", @@ -56,19 +51,11 @@ standard = [ "jemalloc", "jemalloc_conf", "journald", - "ldap", "media_thumbnail", + "release_max_log_level", "systemd", "url_preview", - "zstd_compression" -] -full = [ - "standard", - # "hardened_malloc", # Conflicts with jemalloc - "jemalloc_prof", - "perf_measurements", - "tokio_console" - # sentry_telemetry + "zstd_compression", ] blurhashing = [ @@ -115,9 +102,6 @@ jemalloc_stats = [ jemalloc_conf = [ "conduwuit-core/jemalloc_conf", ] -ldap = [ - "conduwuit-api/ldap", -] media_thumbnail = [ "conduwuit-service/media_thumbnail", ] @@ -177,18 +161,6 @@ zstd_compression = [ conduwuit_mods = [ "conduwuit-core/conduwuit_mods", ] -bindgen-static = [ - # "bindgen/static" - # "clang-sys/static" - "conduwuit-database/bindgen-static" -] -bindgen-runtime = [ - "conduwuit-database/bindgen-runtime" -] - -[build-dependencies] -# bindgen = {version = "0.71.1", default-features = false} -# clang-sys = {version = "1", default-features = false} [dependencies] conduwuit-admin.workspace = true diff --git a/src/router/serve/unix.rs b/src/router/serve/unix.rs index 9bb3dd6e..2af17274 100644 --- a/src/router/serve/unix.rs +++ b/src/router/serve/unix.rs @@ -30,7 +30,7 @@ use tower::{Service, ServiceExt}; type MakeService = IntoMakeServiceWithConnectInfo; -const NULL_ADDR: net::SocketAddr = net::SocketAddr::new(IpAddr::V4(Ipv4Addr::UNSPECIFIED), 0); +const NULL_ADDR: net::SocketAddr = net::SocketAddr::new(IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0)), 0); const FINI_POLL_INTERVAL: Duration = Duration::from_millis(750); #[tracing::instrument(skip_all, level = "debug")] diff --git a/src/service/Cargo.toml b/src/service/Cargo.toml index 6e538f40..fdebd1d7 100644 --- a/src/service/Cargo.toml +++ b/src/service/Cargo.toml @@ -53,9 +53,6 @@ jemalloc_stats = [ "conduwuit-core/jemalloc_stats", "conduwuit-database/jemalloc_stats", ] -ldap = [ - "dep:ldap3" -] media_thumbnail = [ "dep:image", ] @@ -92,8 +89,6 @@ image.workspace = true image.optional = true ipaddress.workspace = true itertools.workspace = true -ldap3.workspace = true -ldap3.optional = true log.workspace = true loole.workspace = true lru-cache.workspace = true diff --git a/src/service/admin/create.rs b/src/service/admin/create.rs index 913acc2d..0b921749 100644 --- a/src/service/admin/create.rs +++ b/src/service/admin/create.rs @@ -38,7 +38,7 @@ pub async fn create_admin_room(services: &Services) -> Result { // Create a user for the server let server_user = services.globals.server_user.as_ref(); - services.users.create(server_user, None, None).await?; + services.users.create(server_user, None)?; let create_content = { use RoomVersionId::*; diff --git a/src/service/appservice/mod.rs b/src/service/appservice/mod.rs index adbf3b6e..7be8a471 100644 --- a/src/service/appservice/mod.rs +++ b/src/service/appservice/mod.rs @@ -4,14 +4,14 @@ mod registration_info; use std::{collections::BTreeMap, iter::IntoIterator, sync::Arc}; use async_trait::async_trait; -use conduwuit::{Err, Result, err, utils::stream::IterStream}; +use conduwuit::{Result, err, utils::stream::IterStream}; use database::Map; use futures::{Future, FutureExt, Stream, TryStreamExt}; use ruma::{RoomAliasId, RoomId, UserId, api::appservice::Registration}; use tokio::sync::{RwLock, RwLockReadGuard}; pub use self::{namespace_regex::NamespaceRegex, registration_info::RegistrationInfo}; -use crate::{Dep, globals, sending, users}; +use crate::{Dep, sending}; pub struct Service { registration_info: RwLock, @@ -20,9 +20,7 @@ pub struct Service { } struct Services { - globals: Dep, sending: Dep, - users: Dep, } struct Data { @@ -37,9 +35,7 @@ impl crate::Service for Service { Ok(Arc::new(Self { registration_info: RwLock::new(BTreeMap::new()), services: Services { - globals: args.depend::("globals"), sending: args.depend::("sending"), - users: args.depend::("users"), }, db: Data { id_appserviceregistrations: args.db["id_appserviceregistrations"].clone(), @@ -48,93 +44,23 @@ impl crate::Service for Service { } async fn worker(self: Arc) -> Result { - // First, collect all appservices to check for token conflicts - let appservices: Vec<(String, Registration)> = self.iter_db_ids().try_collect().await?; + // Inserting registrations into cache + self.iter_db_ids() + .try_for_each(async |appservice| { + self.registration_info + .write() + .await + .insert(appservice.0, appservice.1.try_into()?); - // Check for appservice-to-appservice token conflicts - for i in 0..appservices.len() { - for j in i.saturating_add(1)..appservices.len() { - if appservices[i].1.as_token == appservices[j].1.as_token { - return Err!(Database(error!( - "Token collision detected: Appservices '{}' and '{}' have the same token", - appservices[i].0, appservices[j].0 - ))); - } - } - } - - // Process each appservice - for (id, registration) in appservices { - // During startup, resolve any token collisions in favour of appservices - // by logging out conflicting user devices - if let Ok((user_id, device_id)) = self - .services - .users - .find_from_token(®istration.as_token) - .await - { - conduwuit::warn!( - "Token collision detected during startup: Appservice '{}' token was also \ - used by user '{}' device '{}'. Logging out the user device to resolve \ - conflict.", - id, - user_id.localpart(), - device_id - ); - - self.services - .users - .remove_device(&user_id, &device_id) - .await; - } - - self.start_appservice(id, registration).await?; - } - - Ok(()) + Ok(()) + }) + .await } fn name(&self) -> &str { crate::service::make_name(std::module_path!()) } } impl Service { - /// Starts an appservice, ensuring its sender_localpart user exists and is - /// active. Creates the user if it doesn't exist, or reactivates it if it - /// was deactivated. Then registers the appservice in memory for request - /// handling. - async fn start_appservice(&self, id: String, registration: Registration) -> Result { - let appservice_user_id = UserId::parse_with_server_name( - registration.sender_localpart.as_str(), - self.services.globals.server_name(), - )?; - - if !self.services.users.exists(&appservice_user_id).await { - self.services - .users - .create(&appservice_user_id, None, None) - .await?; - } else if self - .services - .users - .is_deactivated(&appservice_user_id) - .await - .unwrap_or(false) - { - // Reactivate the appservice user if it was accidentally deactivated - self.services - .users - .set_password(&appservice_user_id, None) - .await?; - } - - self.registration_info - .write() - .await - .insert(id, registration.try_into()?); - - Ok(()) - } - /// Registers an appservice and returns the ID to the caller pub async fn register_appservice( &self, @@ -142,40 +68,15 @@ impl Service { appservice_config_body: &str, ) -> Result { //TODO: Check for collisions between exclusive appservice namespaces - - // Check for token collision with other appservices (allow re-registration of - // same appservice) - if let Ok(existing) = self.find_from_token(®istration.as_token).await { - if existing.registration.id != registration.id { - return Err(err!(Request(InvalidParam( - "Cannot register appservice: Token is already used by appservice '{}'. \ - Please generate a different token.", - existing.registration.id - )))); - } - } - - // Prevent token collision with existing user tokens - if self - .services - .users - .find_from_token(®istration.as_token) + self.registration_info + .write() .await - .is_ok() - { - return Err(err!(Request(InvalidParam( - "Cannot register appservice: The provided token is already in use by a user \ - device. Please generate a different token for the appservice." - )))); - } + .insert(registration.id.clone(), registration.clone().try_into()?); self.db .id_appserviceregistrations .insert(®istration.id, appservice_config_body); - self.start_appservice(registration.id.clone(), registration.clone()) - .await?; - Ok(()) } @@ -212,14 +113,12 @@ impl Service { .map(|info| info.registration) } - /// Returns Result to match users::find_from_token for select_ok usage - pub async fn find_from_token(&self, token: &str) -> Result { + pub async fn find_from_token(&self, token: &str) -> Option { self.read() .await .values() .find(|info| info.registration.as_token == token) .cloned() - .ok_or_else(|| err!(Request(NotFound("Appservice token not found")))) } /// Checks if a given user id matches any exclusive appservice regex diff --git a/src/service/emergency/mod.rs b/src/service/emergency/mod.rs index f8ecbb3e..3a61f710 100644 --- a/src/service/emergency/mod.rs +++ b/src/service/emergency/mod.rs @@ -41,11 +41,6 @@ impl crate::Service for Service { return Ok(()); } - if self.services.config.ldap.enable { - warn!("emergency password feature not available with LDAP enabled."); - return Ok(()); - } - self.set_emergency_access().await.inspect_err(|e| { error!("Could not set the configured emergency password for the server user: {e}"); }) @@ -62,8 +57,7 @@ impl Service { self.services .users - .set_password(server_user, self.services.config.emergency_password.as_deref()) - .await?; + .set_password(server_user, self.services.config.emergency_password.as_deref())?; let (ruleset, pwd_set) = match self.services.config.emergency_password { | Some(_) => (Ruleset::server_default(server_user), true), diff --git a/src/service/rooms/pdu_metadata/data.rs b/src/service/rooms/pdu_metadata/data.rs index a746b4cc..c1376cb0 100644 --- a/src/service/rooms/pdu_metadata/data.rs +++ b/src/service/rooms/pdu_metadata/data.rs @@ -61,12 +61,9 @@ impl Data { from: PduCount, dir: Direction, ) -> impl Stream + Send + '_ { - // Query from exact position then filter excludes it (saturating_inc could skip - // events at min/max boundaries) - let from_unsigned = from.into_unsigned(); let mut current = ArrayVec::::new(); current.extend(target.to_be_bytes()); - current.extend(from_unsigned.to_be_bytes()); + current.extend(from.saturating_inc(dir).into_unsigned().to_be_bytes()); let current = current.as_slice(); match dir { | Direction::Forward => self.tofrom_relation.raw_keys_from(current).boxed(), @@ -76,17 +73,6 @@ impl Data { .ready_take_while(move |key| key.starts_with(&target.to_be_bytes())) .map(|to_from| u64_from_u8(&to_from[8..16])) .map(PduCount::from_unsigned) - .ready_filter(move |count| { - if from == PduCount::min() || from == PduCount::max() { - true - } else { - let count_unsigned = count.into_unsigned(); - match dir { - | Direction::Forward => count_unsigned > from_unsigned, - | Direction::Backward => count_unsigned < from_unsigned, - } - } - }) .wide_filter_map(move |shorteventid| async move { let pdu_id: RawPduId = PduId { shortroomid, shorteventid }.into(); diff --git a/src/service/rooms/state_cache/update.rs b/src/service/rooms/state_cache/update.rs index 86c1afe7..32c67947 100644 --- a/src/service/rooms/state_cache/update.rs +++ b/src/service/rooms/state_cache/update.rs @@ -49,7 +49,7 @@ pub async fn update_membership( #[allow(clippy::collapsible_if)] if !self.services.globals.user_is_local(user_id) { if !self.services.users.exists(user_id).await { - self.services.users.create(user_id, None, None).await?; + self.services.users.create(user_id, None)?; } } diff --git a/src/service/users/mod.rs b/src/service/users/mod.rs index fff1661c..d2dfccd9 100644 --- a/src/service/users/mod.rs +++ b/src/service/users/mod.rs @@ -1,19 +1,11 @@ -#[cfg(feature = "ldap")] -use std::collections::HashMap; use std::{collections::BTreeMap, mem, sync::Arc}; -#[cfg(feature = "ldap")] -use conduwuit::result::LogErr; use conduwuit::{ - Err, Error, Result, Server, at, debug_warn, err, is_equal_to, trace, + Err, Error, Result, Server, at, debug_warn, err, trace, utils::{self, ReadyExt, stream::TryIgnore, string::Unquoted}, }; -#[cfg(feature = "ldap")] -use conduwuit_core::{debug, error}; use database::{Deserialized, Ignore, Interfix, Json, Map}; use futures::{Stream, StreamExt, TryFutureExt}; -#[cfg(feature = "ldap")] -use ldap3::{LdapConnAsync, Scope, SearchEntry}; use ruma::{ DeviceId, KeyId, MilliSecondsSinceUnixEpoch, OneTimeKeyAlgorithm, OneTimeKeyId, OneTimeKeyName, OwnedDeviceId, OwnedKeyId, OwnedMxcUri, OwnedUserId, RoomId, UInt, UserId, @@ -27,7 +19,7 @@ use ruma::{ use serde::{Deserialize, Serialize}; use serde_json::json; -use crate::{Dep, account_data, admin, appservice, globals, rooms}; +use crate::{Dep, account_data, admin, globals, rooms}; #[derive(Debug, Clone, Serialize, Deserialize)] pub struct UserSuspension { @@ -48,7 +40,6 @@ struct Services { server: Arc, account_data: Dep, admin: Dep, - appservice: Dep, globals: Dep, state_accessor: Dep, state_cache: Dep, @@ -71,7 +62,6 @@ struct Data { userid_displayname: Arc, userid_lastonetimekeyupdate: Arc, userid_masterkeyid: Arc, - userid_origin: Arc, userid_password: Arc, userid_suspension: Arc, userid_selfsigningkeyid: Arc, @@ -86,7 +76,6 @@ impl crate::Service for Service { server: args.server.clone(), account_data: args.depend::("account_data"), admin: args.depend::("admin"), - appservice: args.depend::("appservice"), globals: args.depend::("globals"), state_accessor: args .depend::("rooms::state_accessor"), @@ -109,7 +98,6 @@ impl crate::Service for Service { userid_displayname: args.db["userid_displayname"].clone(), userid_lastonetimekeyupdate: args.db["userid_lastonetimekeyupdate"].clone(), userid_masterkeyid: args.db["userid_masterkeyid"].clone(), - userid_origin: args.db["userid_origin"].clone(), userid_password: args.db["userid_password"].clone(), userid_suspension: args.db["userid_suspension"].clone(), userid_selfsigningkeyid: args.db["userid_selfsigningkeyid"].clone(), @@ -146,21 +134,9 @@ impl Service { } /// Create a new user account on this homeserver. - /// - /// User origin is by default "password" (meaning that it will login using - /// its user_id/password). Users with other origins (currently only "ldap" - /// is available) have special login processes. #[inline] - pub async fn create( - &self, - user_id: &UserId, - password: Option<&str>, - origin: Option<&str>, - ) -> Result<()> { - self.db - .userid_origin - .insert(user_id, origin.unwrap_or("password")); - self.set_password(user_id, password).await + pub fn create(&self, user_id: &UserId, password: Option<&str>) -> Result<()> { + self.set_password(user_id, password) } /// Deactivate account @@ -174,7 +150,7 @@ impl Service { // result in an empty string, so the user will not be able to log in again. // Systems like changing the password without logging in should check if the // account is deactivated. - self.set_password(user_id, None).await?; + self.set_password(user_id, None)?; // TODO: Unhook 3PID Ok(()) @@ -275,34 +251,13 @@ impl Service { .ready_filter_map(|(u, p): (&UserId, &[u8])| (!p.is_empty()).then_some(u)) } - /// Returns the origin of the user (password/LDAP/...). - pub async fn origin(&self, user_id: &UserId) -> Result { - self.db.userid_origin.get(user_id).await.deserialized() - } - /// Returns the password hash for the given user. pub async fn password_hash(&self, user_id: &UserId) -> Result { self.db.userid_password.get(user_id).await.deserialized() } /// Hash and set the user's password to the Argon2 hash - pub async fn set_password(&self, user_id: &UserId, password: Option<&str>) -> Result<()> { - // Cannot change the password of a LDAP user. There are two special cases : - // - a `None` password can be used to deactivate a LDAP user - // - a "*" password is used as the default password of an active LDAP user - if cfg!(feature = "ldap") - && password.is_some_and(|pwd| pwd != "*") - && self - .db - .userid_origin - .get(user_id) - .await - .deserialized::() - .is_ok_and(is_equal_to!("ldap")) - { - return Err!(Request(InvalidParam("Cannot change password of a LDAP user"))); - } - + pub fn set_password(&self, user_id: &UserId, password: Option<&str>) -> Result<()> { password .map(utils::hash::password) .transpose() @@ -436,31 +391,6 @@ impl Service { self.db.userdeviceid_token.qry(&key).await.deserialized() } - /// Generate a unique access token that doesn't collide with existing tokens - pub async fn generate_unique_token(&self) -> String { - loop { - let token = utils::random_string(32); - - // Check for collision with appservice tokens - if self - .services - .appservice - .find_from_token(&token) - .await - .is_ok() - { - continue; - } - - // Check for collision with user tokens - if self.db.token_userdeviceid.get(&token).await.is_ok() { - continue; - } - - return token; - } - } - /// Replaces the access token of one device. pub async fn set_token( &self, @@ -477,19 +407,6 @@ impl Service { ))); } - // Check for token collision with appservices - if self - .services - .appservice - .find_from_token(token) - .await - .is_ok() - { - return Err!(Request(InvalidParam( - "Token conflicts with an existing appservice token" - ))); - } - // Remove old token if let Ok(old_token) = self.db.userdeviceid_token.qry(&key).await { self.db.token_userdeviceid.remove(&old_token); @@ -1175,154 +1092,6 @@ impl Service { self.db.useridprofilekey_value.del(key); } } - - #[cfg(not(feature = "ldap"))] - pub async fn search_ldap(&self, _user_id: &UserId) -> Result> { - Err!(FeatureDisabled("ldap")) - } - - #[cfg(feature = "ldap")] - pub async fn search_ldap(&self, user_id: &UserId) -> Result> { - let localpart = user_id.localpart().to_owned(); - let lowercased_localpart = localpart.to_lowercase(); - - let config = &self.services.server.config.ldap; - let uri = config - .uri - .as_ref() - .ok_or_else(|| err!(Ldap(error!("LDAP URI is not configured."))))?; - - debug!(?uri, "LDAP creating connection..."); - let (conn, mut ldap) = LdapConnAsync::new(uri.as_str()) - .await - .map_err(|e| err!(Ldap(error!(?user_id, "LDAP connection setup error: {e}"))))?; - - let driver = self.services.server.runtime().spawn(async move { - match conn.drive().await { - | Err(e) => error!("LDAP connection error: {e}"), - | Ok(()) => debug!("LDAP connection completed."), - } - }); - - match (&config.bind_dn, &config.bind_password_file) { - | (Some(bind_dn), Some(bind_password_file)) => { - let bind_pw = String::from_utf8(std::fs::read(bind_password_file)?)?; - ldap.simple_bind(bind_dn, bind_pw.trim()) - .await - .and_then(ldap3::LdapResult::success) - .map_err(|e| err!(Ldap(error!("LDAP bind error: {e}"))))?; - }, - | (..) => {}, - } - - let attr = [&config.uid_attribute, &config.name_attribute]; - - let user_filter = &config.filter.replace("{username}", &lowercased_localpart); - - let (entries, _result) = ldap - .search(&config.base_dn, Scope::Subtree, user_filter, &attr) - .await - .and_then(ldap3::SearchResult::success) - .inspect(|(entries, result)| trace!(?entries, ?result, "LDAP Search")) - .map_err(|e| err!(Ldap(error!(?attr, ?user_filter, "LDAP search error: {e}"))))?; - - let mut dns: HashMap = entries - .into_iter() - .filter_map(|entry| { - let search_entry = SearchEntry::construct(entry); - debug!(?search_entry, "LDAP search entry"); - search_entry - .attrs - .get(&config.uid_attribute) - .into_iter() - .chain(search_entry.attrs.get(&config.name_attribute)) - .any(|ids| ids.contains(&localpart) || ids.contains(&lowercased_localpart)) - .then_some((search_entry.dn, false)) - }) - .collect(); - - if !config.admin_filter.is_empty() { - let admin_base_dn = if config.admin_base_dn.is_empty() { - &config.base_dn - } else { - &config.admin_base_dn - }; - - let admin_filter = &config - .admin_filter - .replace("{username}", &lowercased_localpart); - - let (admin_entries, _result) = ldap - .search(admin_base_dn, Scope::Subtree, admin_filter, &attr) - .await - .and_then(ldap3::SearchResult::success) - .inspect(|(entries, result)| trace!(?entries, ?result, "LDAP Admin Search")) - .map_err(|e| { - err!(Ldap(error!(?attr, ?admin_filter, "Ldap admin search error: {e}"))) - })?; - - dns.extend(admin_entries.into_iter().filter_map(|entry| { - let search_entry = SearchEntry::construct(entry); - debug!(?search_entry, "LDAP search entry"); - search_entry - .attrs - .get(&config.uid_attribute) - .into_iter() - .chain(search_entry.attrs.get(&config.name_attribute)) - .any(|ids| ids.contains(&localpart) || ids.contains(&lowercased_localpart)) - .then_some((search_entry.dn, true)) - })); - } - - ldap.unbind() - .await - .map_err(|e| err!(Ldap(error!("LDAP unbind error: {e}"))))?; - - driver.await.log_err().ok(); - - Ok(dns.drain().collect()) - } - - #[cfg(not(feature = "ldap"))] - pub async fn auth_ldap(&self, _user_dn: &str, _password: &str) -> Result { - Err!(FeatureDisabled("ldap")) - } - - #[cfg(feature = "ldap")] - pub async fn auth_ldap(&self, user_dn: &str, password: &str) -> Result { - let config = &self.services.server.config.ldap; - let uri = config - .uri - .as_ref() - .ok_or_else(|| err!(Ldap(error!("LDAP URI is not configured."))))?; - - debug!(?uri, "LDAP creating connection..."); - let (conn, mut ldap) = LdapConnAsync::new(uri.as_str()) - .await - .map_err(|e| err!(Ldap(error!(?user_dn, "LDAP connection setup error: {e}"))))?; - - let driver = self.services.server.runtime().spawn(async move { - match conn.drive().await { - | Err(e) => error!("LDAP connection error: {e}"), - | Ok(()) => debug!("LDAP connection completed."), - } - }); - - ldap.simple_bind(user_dn, password) - .await - .and_then(ldap3::LdapResult::success) - .map_err(|e| { - err!(Request(Forbidden(debug_error!("LDAP authentication error: {e}")))) - })?; - - ldap.unbind() - .await - .map_err(|e| err!(Ldap(error!("LDAP unbind error: {e}"))))?; - - driver.await.log_err().ok(); - - Ok(()) - } } pub fn parse_master_key( diff --git a/tests/cargo_smoke.sh b/tests/cargo_smoke.sh index e8bb5512..946790c3 100755 --- a/tests/cargo_smoke.sh +++ b/tests/cargo_smoke.sh @@ -48,7 +48,7 @@ vector () { VECTOR_OPTS=$@ element "$TOOLCHAIN" $VECTOR_OPTS --no-default-features element "$TOOLCHAIN" $VECTOR_OPTS --features=default - element "$TOOLCHAIN" $VECTOR_OPTS --features full + element "$TOOLCHAIN" $VECTOR_OPTS --all-features } matrix () {