Files
Dokogenerator-152FZ/dokogen/defence.py
LocoAgent 230a392a15 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 комбинаций таблицы УЗ
2026-08-05 08:58:17 +04:00

87 lines
3.6 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# -*- coding: utf-8 -*-
"""DokoGen — расчёт уровня защищённости ПДн по ПП РФ № 1119 от 01.11.2012.
Эталонная таблица (п. 9–12 ПП-1119), сверено с текстом постановления:
Специальные категории:
- угрозы 1 типа → УЗ-1 (любое количество, п.9а)
- угрозы 2 типа: >100к не-сотрудников → УЗ-1 (п.9б); сотрудники или ≤100к → УЗ-2 (п.10б)
- угрозы 3 типа: >100к не-сотрудников → УЗ-2 (п.10е); сотрудники или ≤100к → УЗ-3 (п.11в)
Биометрические:
- угрозы 1 типа → УЗ-1 (п.9а); угрозы 2 типа → УЗ-2 (п.10в); угрозы 3 типа → УЗ-3 (п.11г)
(без разбивки по количеству)
Общедоступные:
- угрозы 1 типа → УЗ-2 (п.10а)
- угрозы 2 типа: >100к → УЗ-2 (п.10г); сотрудники или ≤100к → УЗ-3 (п.11а)
- угрозы 3 типа → УЗ-4 (п.12а)
Иные категории:
- угрозы 1 типа → УЗ-1 (п.9а)
- угрозы 2 типа: >100к не-сотрудников → УЗ-2 (п.10д); сотрудники или ≤100к → УЗ-3 (п.11б)
- угрозы 3 типа: >100к не-сотрудников → УЗ-3 (п.11д); сотрудники или ≤100к → УЗ-4 (п.12б)
Используется и в авторасчёте (ui.py), и при импорте (importer.py).
"""
from typing import List
def calc_defence_level(
categories: List[str],
is_employees: bool,
is_large: bool,
threat_type: str,
) -> int:
"""Расчёт уровня защищённости ПДн (1–4) по ПП РФ № 1119.
categories — список категорий ПДн ('специальные', 'биометрические',
'общедоступные', 'иные').
is_employees — True, если обрабатываются ПДн только сотрудников оператора.
is_large — True, если количество субъектов > 100 000.
threat_type — тип актуальных угроз: '1', '2' или '3'.
"""
threat = str(threat_type or '3').strip()
has = lambda *names: any(n in categories for n in names)
# Приоритет категорий: специальные > биометрические > общедоступные > иные
if has('специальные'):
return _special(threat, is_employees, is_large)
if has('биометрические'):
return _bio(threat)
if has('общедоступные') and not has('иные'):
return _public(threat, is_employees, is_large)
return _other(threat, is_employees, is_large)
def _special(threat: str, employees: bool, large: bool) -> int:
if threat == '1':
return 1
if threat == '2':
return 1 if (not employees and large) else 2
# threat == '3'
return 2 if (not employees and large) else 3
def _bio(threat: str) -> int:
return {'1': 1, '2': 2, '3': 3}.get(threat, 3)
def _public(threat: str, employees: bool, large: bool) -> int:
if threat == '1':
return 2
if threat == '2':
return 2 if (not employees and large) else 3
# threat == '3'
return 4
def _other(threat: str, employees: bool, large: bool) -> int:
if threat == '1':
return 1
if threat == '2':
return 2 if (not employees and large) else 3
# threat == '3'
return 3 if (not employees and large) else 4