Files
ACORE/core/models/fields.py
T
lokses 719d0b737b infra: надёжное обнаружение тестов, Redis-кэш и хардненинг прода
- AcoreDiscoverRunner собирает tests/tests_* всех локальных приложений
  (manage.py test находил 38 тестов из ~466 — теперь все).
- CACHES на Redis (отдельная DB от Celery) + обязательный requirepass
  в production, SECURE_HSTS_PRELOAD.
- Фикс stored-XSS в админке: format_html вместо mark_safe + f-string.
- Утилиты безопасности/тестов, шифрование полей.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
2026-09-09 18:03:11 +03:00

39 lines
1.7 KiB
Python

import logging
from django.db import models
from core.utils.crypto import encrypt_secret, decrypt_secret
logger = logging.getLogger(__name__)
class EncryptedCharField(models.CharField):
"""CharField, который хранит значение в БД в зашифрованном виде (Fernet).
Для приложения поле ведёт себя как обычная строка: чтение отдаёт открытый
текст, запись сохраняет шифртекст. Шифрование выполняется на границе с БД,
поэтому читатели (`cfg.password`, `cfg.token`) и админка изменений не требуют.
Шифртекст длиннее исходного текста (~1.4×) плюс постоянный оверхед Fernet,
поэтому колонку нужно объявлять с запасом по `max_length`.
"""
def get_db_prep_save(self, value, connection):
value = super().get_db_prep_save(value, connection)
if value in (None, ''):
return value
return encrypt_secret(value)
def from_db_value(self, value, expression, connection):
if value in (None, ''):
return value
try:
return decrypt_secret(value)
except Exception:
# Значение записано до включения шифрования — вернуть как есть.
logger.warning(
'EncryptedCharField: decrypt failed, returning raw DB value '
'(check FIELD_ENCRYPTION_KEY rotation)'
)
return value