From 03dd7e7cf2073a4da4756a8d04ee229d6889435a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Tue, 28 Apr 2026 12:49:43 +0200 Subject: [PATCH 1/6] linting - fix casts --- src/vaultwarden/models/bitwarden.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/vaultwarden/models/bitwarden.py b/src/vaultwarden/models/bitwarden.py index 17de6c0..1ea4f4e 100644 --- a/src/vaultwarden/models/bitwarden.py +++ b/src/vaultwarden/models/bitwarden.py @@ -67,8 +67,8 @@ def api_client(self) -> BitwardenAPIClient: def decode_bytes( value: Any, handler: ValidatorFunctionWrapHandler, info: ValidationInfo ) -> bytes: - context: dict = cast(dict, info.context) - keys: list[bytes] = cast(list[bytes], context.get("cctx")) + context: dict = cast("dict", info.context) + keys: list[bytes] = cast("list[bytes]", context.get("cctx")) for key in keys[::-1]: try: return decrypt(handler(value), key) @@ -227,8 +227,8 @@ def set_key( info: ValidationInfo, ) -> Self: if (key := data.get("key")) is not None: - context = cast(dict, info.context) - cctx = cast(list[bytes], context.get("cctx")) + context = cast("dict", info.context) + cctx = cast("list[bytes]", context.get("cctx")) cctx.append(decrypt(key, cctx[0])) From d67ace3a9c501f5a0add1a3d944c05be69052d9f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Tue, 28 Apr 2026 12:57:35 +0200 Subject: [PATCH 2/6] typing/Self - use typing_extensions --- pyproject.toml | 1 + src/vaultwarden/models/bitwarden.py | 8 +++++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 55114db..7791d4d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -39,6 +39,7 @@ dependencies = [ "pycryptodome >=3.17.0", "pydantic >=2.5.0", "httpx >=0.24.1", + 'typing_extensions; python_version<"3.12"', ] [dev-dependencies] test = [ diff --git a/src/vaultwarden/models/bitwarden.py b/src/vaultwarden/models/bitwarden.py index 1ea4f4e..45a09bd 100644 --- a/src/vaultwarden/models/bitwarden.py +++ b/src/vaultwarden/models/bitwarden.py @@ -1,12 +1,12 @@ import dataclasses import datetime +import sys from typing import ( TYPE_CHECKING, Annotated, Any, Generic, Literal, - Self, TypeVar, Union, cast, @@ -37,6 +37,12 @@ if TYPE_CHECKING: import vaultwarden.clients.bitwarden +if sys.version_info < (3, 12): + from typing_extensions import Self +else: + from typing import Self + + # Pydantic models for Bitwarden data structures T = TypeVar("T", bound="BitwardenBaseModel") From 0924861a8db7f7eaf3980b8530808bd5df1df2b1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Tue, 28 Apr 2026 13:27:27 +0200 Subject: [PATCH 3/6] ci - change order giving vaultwarden more time to start --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 99a6173..8a73a50 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,14 +21,14 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade hatch - name: Run Vaultwarden server run: | temp_dir=$(mktemp -d) cp ${{ github.workspace }}/tests/fixtures/server/* $temp_dir docker run -d --name vaultwarden -v $temp_dir:/data --env I_REALLY_WANT_VOLATILE_STORAGE=true --env ADMIN_TOKEN=admin --restart unless-stopped -p 80:80 vaultwarden/server:${{ matrix.vaultwarden-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade hatch - name: Run tests run: | hatch run +py=${{ matrix.py || matrix.python-version }} test:with-coverage From 17ff403ea072c2a6aa802d3bd35f5fc1f2b408cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Tue, 28 Apr 2026 13:36:52 +0200 Subject: [PATCH 4/6] Revert "ci - change order" This reverts commit 0924861a8db7f7eaf3980b8530808bd5df1df2b1. --- .github/workflows/ci.yml | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8a73a50..99a6173 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -21,14 +21,14 @@ jobs: uses: actions/setup-python@v4 with: python-version: ${{ matrix.python-version }} + - name: Install dependencies + run: | + python -m pip install --upgrade hatch - name: Run Vaultwarden server run: | temp_dir=$(mktemp -d) cp ${{ github.workspace }}/tests/fixtures/server/* $temp_dir docker run -d --name vaultwarden -v $temp_dir:/data --env I_REALLY_WANT_VOLATILE_STORAGE=true --env ADMIN_TOKEN=admin --restart unless-stopped -p 80:80 vaultwarden/server:${{ matrix.vaultwarden-version }} - - name: Install dependencies - run: | - python -m pip install --upgrade hatch - name: Run tests run: | hatch run +py=${{ matrix.py || matrix.python-version }} test:with-coverage From e5249673065c341f682ec2f9f55ffc0b58162fa0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Tue, 28 Apr 2026 13:37:12 +0200 Subject: [PATCH 5/6] ci - db was corrupted --- tests/fixtures/server/db.sqlite3 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/fixtures/server/db.sqlite3 b/tests/fixtures/server/db.sqlite3 index 93b7dcd..bf27515 100644 --- a/tests/fixtures/server/db.sqlite3 +++ b/tests/fixtures/server/db.sqlite3 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:45f2e69202615d295d7687fa4752e189ad29cae7de8852101f93f0b679cbcab6 -size 262144 +oid sha256:c8c11a331ba097f1644b297885cd09b4ac5fc975ed5605176c880bc5cf08a813 +size 245760 From 672482b0da559e6d5a6f81cd3631863adceaf9d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Markus=20K=C3=B6tter?= Date: Tue, 28 Apr 2026 13:54:26 +0200 Subject: [PATCH 6/6] ci/tests - revert renaming keyword arguments --- src/vaultwarden/utils/crypto.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/vaultwarden/utils/crypto.py b/src/vaultwarden/utils/crypto.py index 9353546..7b47841 100644 --- a/src/vaultwarden/utils/crypto.py +++ b/src/vaultwarden/utils/crypto.py @@ -118,19 +118,19 @@ def is_encrypted(cipher_string): return True -def make_master_key(password_: str, salt_: str, kdf: "vaultwarden.models.bitwarden.Kdf"): +def make_master_key(password: str, salt: str, kdf: "vaultwarden.models.bitwarden.Kdf"): import vaultwarden.models.bitwarden - assert isinstance(salt_, str) - assert isinstance(password_, str) + assert isinstance(salt, str) + assert isinstance(password, str) - password = password_.encode("utf-8") - salt = salt_.lower().encode("utf-8") + password_: bytes = password.encode("utf-8") + salt_: bytes = salt.lower().encode("utf-8") match kdf.Kdf: case vaultwarden.models.bitwarden.KdfType.Pbkdf2: assert kdf.KdfIterations is not None - return pbkdf2_hmac("sha256", password, salt, kdf.KdfIterations) + return pbkdf2_hmac("sha256", password_, salt_, kdf.KdfIterations) case vaultwarden.models.bitwarden.KdfType.Argon2id: # c.f. # https://github.com/vaultwarden/vw_web_builds/blob/355bddc6c9d5c110e55fe74c5fcfa86ddd85572c/libs/common/src/platform/services/key-generation.service.ts#L55-L75 @@ -138,9 +138,9 @@ def make_master_key(password_: str, salt_: str, kdf: "vaultwarden.models.bitward assert kdf.KdfIterations is not None assert kdf.KdfMemory is not None assert kdf.KdfParallelism is not None - hsalt = hashlib.new("sha256", salt).digest() + hsalt = hashlib.new("sha256", salt_).digest() v = argon2.low_level.hash_secret_raw( - password, + password_, hsalt, time_cost=kdf.KdfIterations, memory_cost=kdf.KdfMemory * 1024,