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:
LocoAgent
2026-08-05 08:58:17 +04:00
parent ac122451b3
commit 230a392a15
12 changed files with 277 additions and 57 deletions
+15 -2
View File
@@ -425,19 +425,32 @@ def _import_152_is_list(wb, data, settings, log_fn):
log_fn(f" ⚠ ИС без названия — использовано имя листа: {is_obj['name']}")
# Автоопределение категорий ПДн
# По 152-ФЗ категории взаимоисключающие: если найдены специальные/биометрические —
# «иные» не добавляем, иначе расчёт УЗ по ПП-1119 пойдёт по неверной категории.
pd_cats = []
all_pd_text = ' '.join(p.lower() for p in pd_items_raw)
special_kw = ['состоян.*здоров', 'национальн', 'политическ', 'религиозн', 'философ', 'судимост', 'интимн']
if any(re.search(kw, all_pd_text) for kw in special_kw):
pd_cats.append('специальные')
bio_kw = ['биометрическ', 'изображен.*лиц', 'голос.*человек', 'папилляр', 'дактилоскоп', 'фото.*изображен']
if any(re.search(kw, all_pd_text) for kw in bio_kw):
if not pd_cats and any(re.search(kw, all_pd_text) for kw in bio_kw):
pd_cats.append('биометрические')
if pd_items_raw:
if pd_items_raw and not pd_cats:
pd_cats.append('иные')
if pd_cats:
is_obj['personalDataCategory'] = pd_cats
log_fn(f" Категории ПДн: {', '.join(pd_cats)}")
# Автопересчёт УЗ по ПП-1119 (тип угроз по умолчанию — 3, оператор уточнит)
try:
from .defence import calc_defence_level
subj = is_obj.get('pd_subjects_list') or []
has_only_employees = len(subj) > 0 and all('сотрудник' in s.lower() for s in subj)
is_employees = has_only_employees or len(subj) == 0
is_large = 'более' in str(is_obj.get('personalDataCount', '')).lower()
is_obj['defenceLevel'] = str(calc_defence_level(pd_cats, is_employees, is_large, '3'))
log_fn(f" УЗ (авто, угрозы 3 типа): {is_obj['defenceLevel']}")
except Exception:
pass
is_list.append(is_obj)
log_fn(f"{is_obj['name']} — импортирована")