орг. меры: словарик заменён на текст заказчика (15 пунктов), автогенерация с учётом ответов по физической безопасности из опросника (да/нет), импорт ответов в модель

This commit is contained in:
LocoAgent
2026-08-05 13:39:24 +04:00
parent 614044a6ca
commit 28fa7edaa8
6 changed files with 407 additions and 53 deletions
+15 -7
View File
@@ -1,9 +1,17 @@
[ [
"Установление контролируемой зоны", "Установлены границы контролируемой зоны.",
"Контроль физического доступа к объекту", "Физическая охрана периметра обеспечена бетонным забором с колючей проволокой, исключающим прямой доступ к зданиям, и турникетом на проходной; въезд и вход осуществляются по пропускам с применением СКУД, ведется учет посетителей.",
"Разработка документов (регламентов, инструкций, руководств) по обеспечению безопасности объекта", "Имеется система видеонаблюдения.",
"Назначение ответственных за обеспечение безопасности объекта", "Здания не имеют окон, выходящих во вне, входная группа оснащена металлической дверью.",
"Обучение и инструктаж персонала", "Установлены охранно-пожарная сигнализация и тревожная кнопка.",
"Регламентация действий при компьютерных инцидентах", "Исключена возможность неконтролируемого пребывания посторонних лиц в помещениях, где ведется работа с объектами критической информационной инфраструктуры.",
"Утверждение перечня лиц, имеющих доступ к объекту" "Назначены: ответственный за организацию обеспечения безопасности объектов критической информационной инфраструктуры, администратор и администратор безопасности объектов критической информационной инфраструктуры, утверждены инструкции, регламентирующие работу с данными и объектами критической информационной инфраструктуры.",
"Осуществляется внутренний контроль соответствия обеспечения безопасности объектов критической информационной инфраструктуры установленным требованиям.",
"Работники, непосредственно осуществляющие работу с объектами критической информационной инфраструктуры, ознакомлены с положениями законодательства Российской Федерации об объектах критической информационной инфраструктуры, документами, определяющими политику организации в отношении работы с объектами критической информационной инфраструктуры.",
"Обеспечивается учет машинных носителей объектов критической информационной инфраструктуры.",
"Обеспечивается резервирование и восстановление данных, модифицированных или уничтоженных вследствие несанкционированного доступа к ним.",
"Разработаны правила доступа к данным, обрабатываемым в объектах критической информационной инфраструктуры.",
"Определён перечень сотрудников, осуществляющих работу с объектами критической информационной инфраструктуры.",
"Ведётся учёт всех защищаемых носителей информации с помощью их маркировки и занесения учетных данных в журнал учета с отметкой об их выдаче (приеме).",
"Обеспечено раздельное хранение материальных носителей, обработка которых осуществляется в различных целях."
] ]
+312 -43
View File
@@ -7,48 +7,317 @@
], ],
"value_column": 1, "value_column": 1,
"fields": [ "fields": [
{"name": "Полное наименование организации", "var": "fullName", "cell": "", "keywords": "полное наименование организации"}, {
{"name": "Сокращённое наименование организации", "var": "shortName", "cell": "", "keywords": "сокращенное наименование организации"}, "name": "Полное наименование организации",
{"name": "Юридический адрес", "var": "addressLegal", "cell": "", "keywords": "адрес организации \\(юридический\\)"}, "var": "fullName",
{"name": "Фактический адрес", "var": "addressActual", "cell": "", "keywords": "адрес организации \\(фактический\\)"}, "cell": "",
{"name": "Электронная почта", "var": "email", "cell": "", "keywords": "электронная почта"}, "keywords": "полное наименование организации"
{"name": "Телефон", "var": "phone", "cell": "", "keywords": "телефон"}, },
{"name": "ИНН", "var": "inn", "cell": "", "keywords": "инн"}, {
{"name": "ОГРН", "var": "ogrn", "cell": "", "keywords": "огрн"}, "name": "Сокращённое наименование организации",
{"name": "Дата получения ОГРН", "var": "ogrnDate", "cell": "", "keywords": "дата получения огрн|дата.*огрн"}, "var": "shortName",
{"name": "КПП", "var": "kpp", "cell": "", "keywords": "кпп"}, "cell": "",
{"name": "Основной ОКВЭД", "var": "okved", "cell": "", "keywords": "основной оквэд"}, "keywords": "сокращенное наименование организации"
{"name": "Дополнительные ОКВЭД", "var": "okvedExtra", "cell": "", "keywords": "дополнительные оквэд"}, },
{"name": "Должность руководителя", "var": "chiefPosition", "cell": "", "keywords": "должность руководителя"}, {
{"name": "ФИО руководителя", "var": "chiefFio", "cell": "", "keywords": "фио руководителя"}, "name": "Юридический адрес",
{"name": "Должность ответственного лица (безопасность ЗОКИИ)", "var": "responsiblePosition", "cell": "", "keywords": "должность ответственного лица"}, "var": "addressLegal",
{"name": "ФИО ответственного лица (безопасность ЗОКИИ)", "var": "responsibleFio", "cell": "", "keywords": "фио ответственного лица"}, "cell": "",
{"name": "Подразделение по безопасности ОКИИ", "var": "ispdnDepartment", "cell": "", "keywords": "структур.*подраздел"}, "keywords": "адрес организации \\(юридический\\)"
{"name": "Рабочий телефон ответственного", "var": "ispdnPhone", "cell": "", "keywords": "рабочий телефон ответственного|мобильный телефон ответственного"}, },
{"name": "Электронная почта ответственного", "var": "ispdnEmail", "cell": "", "keywords": "электронная почта ответственного"}, {
{"name": "Должность специалиста по ЗИ/администратора", "var": "administratorPosition", "cell": "", "keywords": "должность специалиста по защите информации|должность.*администрат"}, "name": "Фактический адрес",
{"name": "ФИО специалиста по ЗИ/администратора", "var": "administratorFio", "cell": "", "keywords": "фио специалиста по защите информации|фио.*администрат"}, "var": "addressActual",
{"name": "Право владения зданием", "var": "buildingRight", "cell": "", "keywords": "право владения зданием"}, "cell": "",
{"name": "Сумма прибыли за год", "var": "profit", "cell": "", "keywords": "сумма прибыли"}, "keywords": "адрес организации \\(фактический\\)"
{"name": "Сумма налога с прибыли", "var": "profitTax", "cell": "", "keywords": "сумма налога с прибыли"}, },
{"name": "Доменное имя и внешний IP", "var": "domainName", "cell": "", "keywords": "доменное имя и внешний сетевой адрес"}, {
{"name": "Сайт организации", "var": "site_name", "cell": "", "keywords": "сайт организации"}, "name": "Электронная почта",
{"name": "Должность ответственного за сайт", "var": "site_responsible_position", "cell": "", "keywords": "должность ответственного за сайт"}, "var": "email",
{"name": "ФИО ответственного за сайт", "var": "site_responsible_fio", "cell": "", "keywords": "фио ответственного за сайт"}, "cell": "",
{"name": "Разработчик сайта", "var": "site_service_provider", "cell": "", "keywords": "организации, которая разрабатывала и размещала корпоративный сайт"}, "keywords": "электронная почта"
{"name": "ИНН разработчика сайта", "var": "site_service_provider_inn", "cell": "", "keywords": "инн организации, которая разрабатывала"}, },
{"name": "Размещение сайта", "var": "site_hosting", "cell": "", "keywords": "размещение сайта"}, {
{"name": "Адрес расположения серверов", "var": "site_hosting_address", "cell": "", "keywords": "адрес расположения серверов"}, "name": "Телефон",
{"name": "Облачная платформа", "var": "cloud_platform", "cell": "", "keywords": "облачную платформу"}, "var": "phone",
{"name": "Аренда выделенного сервера", "var": "cloud_dedicated_server", "cell": "", "keywords": "выделенный сервер"}, "cell": "",
{"name": "Аренда виртуального ЦОД", "var": "cloud_vdc", "cell": "", "keywords": "виртуальный дата-центр"}, "keywords": "телефон"
{"name": "Серверы в дата-центре", "var": "cloud_datacenter", "cell": "", "keywords": "сервера в дата-центре"}, },
{"name": "Средства контейнеризации", "var": "cloud_container", "cell": "", "keywords": "контейнеризации"}, {
{"name": "Собственная серверная (ЦОД)", "var": "cloud_own_server", "cell": "", "keywords": "собственная серверная"}, "name": "ИНН",
{"name": "Общее количество компьютеров", "var": "computers_total", "cell": "", "keywords": "общее количество компьютеров"}, "var": "inn",
{"name": "Компьютеры, подключённые к объектам КИИ", "var": "computers_kii", "cell": "", "keywords": "компьютеров подключенных к объектам кии"}, "cell": "",
{"name": "Центр мониторинга", "var": "monitoring_center", "cell": "", "keywords": "к какому центру подключены"}, "keywords": "инн"
{"name": "Детали подключения к центру мониторинга", "var": "monitoring_details", "cell": "", "keywords": "детали подключения"}, },
{"name": "Дополнительная информация", "var": "additionalInfo", "cell": "", "keywords": "дополнительная информация"} {
"name": "ОГРН",
"var": "ogrn",
"cell": "",
"keywords": "огрн"
},
{
"name": "Дата получения ОГРН",
"var": "ogrnDate",
"cell": "",
"keywords": "дата получения огрн|дата.*огрн"
},
{
"name": "КПП",
"var": "kpp",
"cell": "",
"keywords": "кпп"
},
{
"name": "Основной ОКВЭД",
"var": "okved",
"cell": "",
"keywords": "основной оквэд"
},
{
"name": "Дополнительные ОКВЭД",
"var": "okvedExtra",
"cell": "",
"keywords": "дополнительные оквэд"
},
{
"name": "Должность руководителя",
"var": "chiefPosition",
"cell": "",
"keywords": "должность руководителя"
},
{
"name": "ФИО руководителя",
"var": "chiefFio",
"cell": "",
"keywords": "фио руководителя"
},
{
"name": "Должность ответственного лица (безопасность ЗОКИИ)",
"var": "responsiblePosition",
"cell": "",
"keywords": "должность ответственного лица"
},
{
"name": "ФИО ответственного лица (безопасность ЗОКИИ)",
"var": "responsibleFio",
"cell": "",
"keywords": "фио ответственного лица"
},
{
"name": "Подразделение по безопасности ОКИИ",
"var": "ispdnDepartment",
"cell": "",
"keywords": "структур.*подраздел"
},
{
"name": "Рабочий телефон ответственного",
"var": "ispdnPhone",
"cell": "",
"keywords": "рабочий телефон ответственного|мобильный телефон ответственного"
},
{
"name": "Электронная почта ответственного",
"var": "ispdnEmail",
"cell": "",
"keywords": "электронная почта ответственного"
},
{
"name": "Должность специалиста по ЗИ/администратора",
"var": "administratorPosition",
"cell": "",
"keywords": "должность специалиста по защите информации|должность.*администрат"
},
{
"name": "ФИО специалиста по ЗИ/администратора",
"var": "administratorFio",
"cell": "",
"keywords": "фио специалиста по защите информации|фио.*администрат"
},
{
"name": "Право владения зданием",
"var": "buildingRight",
"cell": "",
"keywords": "право владения зданием"
},
{
"name": "Сумма прибыли за год",
"var": "profit",
"cell": "",
"keywords": "сумма прибыли"
},
{
"name": "Сумма налога с прибыли",
"var": "profitTax",
"cell": "",
"keywords": "сумма налога с прибыли"
},
{
"name": "Доменное имя и внешний IP",
"var": "domainName",
"cell": "",
"keywords": "доменное имя и внешний сетевой адрес"
},
{
"name": "Сайт организации",
"var": "site_name",
"cell": "",
"keywords": "сайт организации"
},
{
"name": "Должность ответственного за сайт",
"var": "site_responsible_position",
"cell": "",
"keywords": "должность ответственного за сайт"
},
{
"name": "ФИО ответственного за сайт",
"var": "site_responsible_fio",
"cell": "",
"keywords": "фио ответственного за сайт"
},
{
"name": "Разработчик сайта",
"var": "site_service_provider",
"cell": "",
"keywords": "организации, которая разрабатывала и размещала корпоративный сайт"
},
{
"name": "ИНН разработчика сайта",
"var": "site_service_provider_inn",
"cell": "",
"keywords": "инн организации, которая разрабатывала"
},
{
"name": "Размещение сайта",
"var": "site_hosting",
"cell": "",
"keywords": "размещение сайта"
},
{
"name": "Адрес расположения серверов",
"var": "site_hosting_address",
"cell": "",
"keywords": "адрес расположения серверов"
},
{
"name": "Облачная платформа",
"var": "cloud_platform",
"cell": "",
"keywords": "облачную платформу"
},
{
"name": "Аренда выделенного сервера",
"var": "cloud_dedicated_server",
"cell": "",
"keywords": "выделенный сервер"
},
{
"name": "Аренда виртуального ЦОД",
"var": "cloud_vdc",
"cell": "",
"keywords": "виртуальный дата-центр"
},
{
"name": "Серверы в дата-центре",
"var": "cloud_datacenter",
"cell": "",
"keywords": "сервера в дата-центре"
},
{
"name": "Средства контейнеризации",
"var": "cloud_container",
"cell": "",
"keywords": "контейнеризации"
},
{
"name": "Собственная серверная (ЦОД)",
"var": "cloud_own_server",
"cell": "",
"keywords": "собственная серверная"
},
{
"name": "Общее количество компьютеров",
"var": "computers_total",
"cell": "",
"keywords": "общее количество компьютеров"
},
{
"name": "Компьютеры, подключённые к объектам КИИ",
"var": "computers_kii",
"cell": "",
"keywords": "компьютеров подключенных к объектам кии"
},
{
"name": "Центр мониторинга",
"var": "monitoring_center",
"cell": "",
"keywords": "к какому центру подключены"
},
{
"name": "Детали подключения к центру мониторинга",
"var": "monitoring_details",
"cell": "",
"keywords": "детали подключения"
},
{
"name": "Дополнительная информация",
"var": "additionalInfo",
"cell": "",
"keywords": "дополнительная информация"
},
{
"name": "Физическая охрана (ЧОП, сторожа, охранники)",
"var": "physicalGuard",
"cell": "",
"keywords": "физическая охрана"
},
{
"name": "Пожарная сигнализация",
"var": "physicalFireAlarm",
"cell": "",
"keywords": "пожарная сигнализация"
},
{
"name": "Тревожная кнопка",
"var": "physicalPanicButton",
"cell": "",
"keywords": "тревожная кнопка"
},
{
"name": "Решётки на окнах",
"var": "physicalBars",
"cell": "",
"keywords": "решетки на окнах"
},
{
"name": "Металлические двери",
"var": "physicalMetalDoors",
"cell": "",
"keywords": "металлические двери"
},
{
"name": "Система видеонаблюдения",
"var": "physicalVideoSurveillance",
"cell": "",
"keywords": "система видеонаблюдения"
},
{
"name": "Видеодомофон",
"var": "physicalVideoIntercom",
"cell": "",
"keywords": "видеодомофон"
},
{
"name": "Турникет на входе",
"var": "physicalTurnstile",
"cell": "",
"keywords": "турникет на входе"
},
{
"name": "Журнал учёта посетителей",
"var": "physicalVisitorLog",
"cell": "",
"keywords": "журнал учета посетителей|журнал учёта посетителей"
}
] ]
} }
+15
View File
@@ -174,6 +174,21 @@ def import_187fz(filepath: str, log_fn: Optional[Callable] = None, settings_path
finally: finally:
wb.close() wb.close()
# Ответы раздела «Физическая безопасность» (да/нет) — собираем в словарь,
# чтобы текст организационных мер генерировался с учётом реальных средств.
ps_keys = [
'physicalGuard', 'physicalFireAlarm', 'physicalPanicButton',
'physicalBars', 'physicalMetalDoors', 'physicalVideoSurveillance',
'physicalVideoIntercom', 'physicalTurnstile', 'physicalVisitorLog',
]
ps = {}
for k in ps_keys:
v = str(data.get(k) or '').strip()
if v:
ps[k] = v
if ps:
data['physicalSecurity'] = ps
# Копирование полей ИСПДн в админа, если админ не заполнен # Копирование полей ИСПДн в админа, если админ не заполнен
for src, dst in [('ispdnFio', 'administratorFio'), ('ispdnFio', 'adminFio'), for src, dst in [('ispdnFio', 'administratorFio'), ('ispdnFio', 'adminFio'),
('ispdnPosition', 'administratorPosition'), ('ispdnPosition', 'adminPosition'), ('ispdnPosition', 'administratorPosition'), ('ispdnPosition', 'adminPosition'),
+5
View File
@@ -152,6 +152,11 @@ class Company:
# Наименование структурного подразделения по безопасности # Наименование структурного подразделения по безопасности
security_department: str = "" security_department: str = ""
# Ответы раздела «Физическая безопасность» опросника (да/нет):
# охрана, пожарная сигнализация, тревожная кнопка, решётки, металлические двери,
# видеонаблюдение, видеодомофон, турникет, журнал посетителей.
physical_security: Dict[str, str] = field(default_factory=dict)
def update_declensions(self, inflect_func): def update_declensions(self, inflect_func):
"""Обновить склонения полного названия""" """Обновить склонения полного названия"""
if self.full_name: if self.full_name:
+4
View File
@@ -4446,6 +4446,10 @@ class DokoGenApp:
# Автоопределение города из адреса после импорта # Автоопределение города из адреса после импорта
self._on_address_changed() self._on_address_changed()
# Ответы по физической безопасности (для автогенерации орг. мер)
if data.get('physicalSecurity'):
self.model.physical_security = dict(data['physicalSecurity'])
# Должностные лица (маппинг) # Должностные лица (маппинг)
officials_map = { officials_map = {
'chief_position': 'chiefPosition', 'chief_position': 'chiefPosition',
+54 -1
View File
@@ -357,7 +357,10 @@ def _build_loop_data(company: Company, is_list: List) -> Dict[str, List[Dict]]:
'incidents': getattr(isys, 'incidents', '') or '', 'incidents': getattr(isys, 'incidents', '') or '',
'criteria_values': getattr(isys, 'criteria_values', '') or '', 'criteria_values': getattr(isys, 'criteria_values', '') or '',
'criteria_justification': getattr(isys, 'criteria_justification', '') or '', 'criteria_justification': getattr(isys, 'criteria_justification', '') or '',
'org_measures': getattr(isys, 'org_measures', '') or '', # Орг. меры: если не заполнены вручную — автогенерация по опроснику
# (с учётом ответов раздела «Физическая безопасность»).
'org_measures': (getattr(isys, 'org_measures', '') or '')
or _build_org_measures_text(company, isys),
'tech_measures': getattr(isys, 'tech_measures', '') or '', 'tech_measures': getattr(isys, 'tech_measures', '') or '',
}) })
loops['information_systems'] = items loops['information_systems'] = items
@@ -505,6 +508,56 @@ def _calc_criterion_8_9(company, isys, num):
return text, cat return text, cat
def _build_org_measures_text(company, isys=None):
"""Формирует текст организационных мер из словаря org_measures.json
с учётом ответов раздела «Физическая безопасность» опросника.
Если в опроснике указано «нет» (охрана, сигнализация, тревожная кнопка,
видеонаблюдение, металлические двери и т.п.) соответствующие пункты
из текста убираются. Пункты, не привязанные к средствам, остаются всегда.
"""
import os as _os
items = _load_json('org_measures.json')
if not isinstance(items, list):
items = []
ps = getattr(company, 'physical_security', None) or {}
def _no(*keys):
"""True, если хотя бы по одному ключу явно указано «нет»/«не имеется»."""
for k in keys:
v = str(ps.get(k) or '').strip().lower()
if v in ('нет', 'не имеется', 'нет,', '0', 'false'):
return True
return False
rules = [
# (подстрока пункта, ключи physical_security, при которых пункт УБИРАЕМ)
('Физическая охрана периметра', ('physicalGuard', 'physicalTurnstile', 'physicalVisitorLog')),
('Имеется система видеонаблюдения', ('physicalVideoSurveillance',)),
('Здания не имеют окон', ('physicalMetalDoors',)),
('охранно-пожарная сигнализация и тревожная кнопка', ('physicalFireAlarm', 'physicalPanicButton')),
('охранно-пожарная сигнализация', ('physicalFireAlarm',)),
('тревожная кнопка', ('physicalPanicButton',)),
('турникетом на проходной', ('physicalTurnstile',)),
('СКУД', ('physicalTurnstile',)),
('учет посетителей', ('physicalVisitorLog',)),
]
out = []
for line in items:
line = str(line).strip()
if not line:
continue
drop = False
for sub, keys in rules:
if sub in line and _no(*keys):
drop = True
break
if not drop:
out.append(line)
return '\n'.join(out) if out else ''
def _build_categorization_indicators(company, is_list): def _build_categorization_indicators(company, is_list):
"""Строки таблицы показателей критериев значимости для шаблона """Строки таблицы показателей критериев значимости для шаблона
«Сведения о результатах категорирования» (цикл categorization_indicators). «Сведения о результатах категорирования» (цикл categorization_indicators).