Make SpaceDevs cache files readable by the web server

This commit is contained in:
Edward Betts 2026-09-30 19:13:02 +01:00
parent 5dce485216
commit 51b8bf6ecb
2 changed files with 34 additions and 0 deletions

View file

@ -34,6 +34,8 @@ def write_json_cache(filename: str, payload: StrDict) -> None:
temporary = cache.name temporary = cache.name
cache.write(contents) cache.write(contents)
cache.flush() cache.flush()
# The updater and web server run as different users.
os.fchmod(cache.fileno(), 0o644)
os.fsync(cache.fileno()) os.fsync(cache.fileno())
os.replace(temporary, filename) os.replace(temporary, filename)
finally: finally:

View file

@ -2,6 +2,7 @@
import errno import errno
import json import json
import typing
from datetime import datetime, timedelta from datetime import datetime, timedelta
from pathlib import Path from pathlib import Path
from unittest.mock import Mock from unittest.mock import Mock
@ -64,3 +65,34 @@ def test_all_empty_launch_files_return_no_cache(tmp_path: Path) -> None:
(tmp_path / "2026-09-30_12:00:00.json").touch() (tmp_path / "2026-09-30_12:00:00.json").touch()
assert thespacedevs.load_cached_launches(str(tmp_path)) is None assert thespacedevs.load_cached_launches(str(tmp_path)) is None
assert not thespacedevs.is_launches_cache_fresh(str(tmp_path)) assert not thespacedevs.is_launches_cache_fresh(str(tmp_path))
@pytest.mark.parametrize("existing_mode", [None, 0o600, 0o644])
def test_published_cache_is_readable_by_web_server(
tmp_path: Path, existing_mode: int | None
) -> None:
filename = tmp_path / "cache.json"
if existing_mode is not None:
filename.touch(mode=existing_mode)
thespacedevs.write_json_cache(str(filename), {"results": []})
assert filename.stat().st_mode & 0o777 == 0o644
def test_unreadable_cache_falls_back(
tmp_path: Path, monkeypatch: pytest.MonkeyPatch
) -> None:
older = tmp_path / "2026-09-29_12:00:00.json"
newer = tmp_path / "2026-09-30_12:00:00.json"
older.write_text('{"results": []}')
newer.write_text('{"results": []}')
import builtins
original_open = builtins.open
def open_cache(filename: str) -> typing.TextIO:
if filename == str(newer):
raise PermissionError(errno.EACCES, "Permission denied", filename)
return original_open(filename)
monkeypatch.setattr("agenda.thespacedevs.open", open_cache, raising=False)
assert thespacedevs.load_cached_launches(str(tmp_path)) == {"results": []}