backend/tests/test_config_repo_encryption.py
Rama master · réplica de lectura del repositorio original.
"""Tests for transparent encryption-at-rest in ConfigRepository.
Sensitive keys (per sensitive_keys.is_sensitive_key) must be stored as
``enc:v1:`` ciphertext in the config_entries table, while reads via
get_config_entry / get_all_config_entries must keep returning plaintext.
Non-sensitive keys must remain stored verbatim (no behavior change).
"""
import pytest
import config_crypto
from db.models.core import ConfigEntry
from db.repositories.config import ConfigRepository
from extensions import db
@pytest.fixture
def repo(app_ctx):
"""Create a ConfigRepository instance within app context."""
return ConfigRepository()
@pytest.fixture(autouse=True)
def _isolated_key(tmp_path, monkeypatch):
"""Isolate the encryption master key per test (same pattern as test_config_crypto.py)."""
monkeypatch.setenv("SUBLARR_CONFIG_DIR", str(tmp_path))
config_crypto.reset_cipher_cache()
yield
config_crypto.reset_cipher_cache()
def test_sensitive_value_is_ciphertext_in_db(repo):
"""A sensitive key is encrypted at rest but reads back as plaintext."""
repo.save_config_entry("opensubtitles_api_key", "SECRET123")
raw = db.session.get(ConfigEntry, "opensubtitles_api_key").value
assert raw.startswith("enc:v1:")
assert "SECRET123" not in raw
assert repo.get_config_entry("opensubtitles_api_key") == "SECRET123"
def test_non_sensitive_value_stored_plaintext(repo):
"""A non-sensitive key is stored verbatim — no encryption overhead."""
repo.save_config_entry("wanted_search_interval", "3600")
raw = db.session.get(ConfigEntry, "wanted_search_interval").value
assert raw == "3600"
assert repo.get_config_entry("wanted_search_interval") == "3600"
def test_get_all_decrypts(repo):
"""get_all_config_entries transparently decrypts sensitive values."""
repo.save_config_entry("subdl_api_key", "abc")
repo.save_config_entry("wanted_search_interval", "3600")
all_entries = repo.get_all_config_entries()
assert all_entries["subdl_api_key"] == "abc"
assert all_entries["wanted_search_interval"] == "3600"