fix: аудит ветки source — критические и высокие замечания
- api_settings: убраны реальные API-ключи из кода (чтение из env/файла) — 1.1
- variables: {{is_security_requirements}} больше не подставляет всегда УЗ-4;
extended_fields/defence_level передаются в контекст — 1.2
- defence.py: эталонная таблица ПП-1119 (п.9-12), 48 комбинаций;
ui.py: авторасчёт УЗ переведён на неё (public больше не 'всегда 4',
спец/био/общедоступные/иные разделены) — 2.1
- generator: убран дубль хвоста параграфа в _highlight_unmatched — 2.2
- importer: категории ПДн взаимоисключающие ('иные' только если нет
спец/био); УЗ пересчитывается при импорте — 2.3
- import_settings(.py/.json): убран перехват 'администратора безопасности'
правилом ответственного за ПДн — 3.1
- variables: {{category}}/{{is.category}} резолвятся из personal_data_category — 3.2
- verify: ИИ-предложения ИНН/ОГРН/КПП валидируются контрольными суммами
перед применением — 3.3
- models: defence_level None вместо '' (не маскирует 'не рассчитано')
- .gitignore: api_settings.json/.env не попадают в git
- test_defence.py: юнит-тест всех 48 комбинаций таблицы УЗ
This commit is contained in:
+17
-4
@@ -139,8 +139,14 @@ def build_replacements(
|
||||
doc_number: str = "",
|
||||
doc_date: str = "",
|
||||
direction: str = "152fz",
|
||||
extended_fields: Dict = None,
|
||||
) -> Dict[str, str]:
|
||||
"""Строит полный словарь замен {{переменная}} → значение."""
|
||||
"""Строит полный словарь замен {{переменная}} → значение.
|
||||
|
||||
extended_fields — доп. поля для контекста (например, {'defence_level': '2'}).
|
||||
Если не задано — уровень берётся из первой ИС (is_list[0].defence_level),
|
||||
чтобы {{is_security_requirements}} не подставлял всегда УЗ-4.
|
||||
"""
|
||||
if is_list is None:
|
||||
is_list = []
|
||||
|
||||
@@ -148,6 +154,10 @@ def build_replacements(
|
||||
commission_data = _build_commission_data(company)
|
||||
|
||||
# ---------- Контекст ----------
|
||||
if not extended_fields and is_list:
|
||||
dl = getattr(is_list[0], 'defence_level', '') or ''
|
||||
if dl:
|
||||
extended_fields = {'defence_level': dl}
|
||||
ctx = {
|
||||
'company': company,
|
||||
'is_list': is_list,
|
||||
@@ -155,6 +165,7 @@ def build_replacements(
|
||||
'doc_number': doc_number or '',
|
||||
'doc_date': doc_date or '',
|
||||
'direction': direction,
|
||||
'extended_fields': extended_fields or {},
|
||||
}
|
||||
|
||||
replacements = {}
|
||||
@@ -447,7 +458,7 @@ def _resolve(source: str, ctx: Dict) -> str:
|
||||
field_map = {
|
||||
'name': 'name',
|
||||
'description': 'description',
|
||||
'category': 'category',
|
||||
'category': lambda: ', '.join(first.personal_data_category) or first.category or '—',
|
||||
'defence_level': 'defence_level',
|
||||
'threat_type': 'threat_type',
|
||||
'pd_list': lambda: ', '.join(first.personal_data_list or []),
|
||||
@@ -502,10 +513,12 @@ def _get_fio(company: Company, who: str) -> str:
|
||||
|
||||
def _get_security_text(ctx: Dict) -> str:
|
||||
"""Возвращает текст требований для уровня защищённости."""
|
||||
defence_level = ctx.get('extended_fields', {}).get('defence_level', '4')
|
||||
defence_level = ctx.get('extended_fields', {}).get('defence_level') or ''
|
||||
is_list = ctx.get('is_list', [])
|
||||
if not defence_level and is_list:
|
||||
defence_level = str(getattr(is_list[0], 'defence_level', '4') or '4')
|
||||
defence_level = str(getattr(is_list[0], 'defence_level', '') or '')
|
||||
if not defence_level:
|
||||
defence_level = '4'
|
||||
dl = str(defence_level).strip()[0]
|
||||
|
||||
TEXTS = {
|
||||
|
||||
Reference in New Issue
Block a user