- 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 комбинаций таблицы УЗ
87 lines
3.6 KiB
Python
87 lines
3.6 KiB
Python
# -*- 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
|