From aea1ed3f389e1e3a43dcc0dc60737ec3d823229d Mon Sep 17 00:00:00 2001 From: shamoon <4887959+shamoon@users.noreply.github.com> Date: Wed, 19 Aug 2026 13:45:58 -0700 Subject: [PATCH] Use secrete key to make IMAP polling offset stable --- src/paperless/settings/custom.py | 5 +++-- src/paperless/tests/settings/test_custom_parsers.py | 9 ++++++--- 2 files changed, 9 insertions(+), 5 deletions(-) diff --git a/src/paperless/settings/custom.py b/src/paperless/settings/custom.py index 5b659ee26..2bf53a8cc 100644 --- a/src/paperless/settings/custom.py +++ b/src/paperless/settings/custom.py @@ -1,7 +1,7 @@ import datetime import logging import os -import random +from hashlib import sha256 from pathlib import Path from typing import Any @@ -178,7 +178,8 @@ def parse_beat_schedule() -> dict: and task["env_key"] not in os.environ ): # Spread default polling across the ten-minute interval. - offset = random.randrange(10) + secret = os.environ["PAPERLESS_SECRET_KEY"].encode() + offset = int.from_bytes(sha256(secret).digest()) % 10 minutes = ",".join(str(minute) for minute in range(offset, 60, 10)) value = f"{minutes} * * * *" # I find https://crontab.guru/ super helpful diff --git a/src/paperless/tests/settings/test_custom_parsers.py b/src/paperless/tests/settings/test_custom_parsers.py index c3019c7e2..162f8b8ff 100644 --- a/src/paperless/tests/settings/test_custom_parsers.py +++ b/src/paperless/tests/settings/test_custom_parsers.py @@ -168,7 +168,7 @@ class TestParseHostingSettings: def make_expected_schedule( overrides: dict[str, dict[str, Any]] | None = None, disabled: set[str] | None = None, - email_minute: str = "3,13,23,33,43,53", + email_minute: str = "6,16,26,36,46,56", ) -> dict[str, Any]: """ Build the expected schedule with optional overrides and disabled tasks. @@ -310,8 +310,11 @@ class TestParseBeatSchedule: expected: dict[str, Any], mocker: MockerFixture, ) -> None: - mocker.patch.dict(os.environ, env, clear=False) - mocker.patch("paperless.settings.custom.random.randrange", return_value=3) + mocker.patch.dict( + os.environ, + {"PAPERLESS_SECRET_KEY": "test-secret", **env}, + clear=False, + ) schedule = parse_beat_schedule() assert schedule == expected