educommon 3.15.0__py3-none-any.whl → 3.17.0__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -62,3 +62,32 @@
62
62
  в request уже был определен пользователь.
63
63
 
64
64
  4. Создать и выполнить миграции.
65
+
66
+ Расширение
67
+ --------------
68
+
69
+ Для реализации локальных расширений логирования продукта на уровне БД реализовано применение настройки
70
+ AUDIT_LOG_EXTENSION_SCRIPTS при выполнении МК reinstall_audit_log.
71
+
72
+ Настройка может содержать пути до SQL-скриптов, которые будут выполняться помимо основного скрипта install_audit_log.sql.
73
+
74
+ Примером заполнения настройки может послужить установка через AppConfig приложения,
75
+ в котором хранится необходимый SQL файл.
76
+
77
+ Например:
78
+ .. code-block:: python
79
+
80
+ class PluginAppConfig(AppConfig):
81
+ """Конфигурация плагина."""
82
+
83
+ name = 'project.plugins.plugin'
84
+ label = 'plugin'
85
+
86
+ def ready(self):
87
+ """Добавляет SQL скрипт в процесс установки audit_log."""
88
+ sql_files_dir = os.path.abspath(
89
+ os.path.join(os.path.dirname(__file__), 'sql')
90
+ )
91
+
92
+ sql_file_path = os.path.join(sql_files_dir, 'audit_log_extension.sql')
93
+ settings.AUDIT_LOG_EXTENSION_SCRIPTS += (sql_file_path,)
@@ -148,11 +148,6 @@ class AuditLogPack(ViewWindowPackMixin, PackValidationMixin, ObjectPack, metacla
148
148
  control_creator=ExtStringField,
149
149
  ),
150
150
  },
151
- {
152
- 'data_index': '',
153
- 'width': 40,
154
- 'header': 'Имитация',
155
- },
156
151
  ]
157
152
 
158
153
  return columns
@@ -1,6 +1,9 @@
1
1
  import codecs
2
2
  import os
3
3
 
4
+ from django.conf import (
5
+ settings,
6
+ )
4
7
  from django.core.management.base import (
5
8
  BaseCommand,
6
9
  )
@@ -31,19 +34,19 @@ class Command(BaseCommand):
31
34
  Удаляет схему audit. В этой схеме не должно храниться никаких таблиц
32
35
  с данными.
33
36
  После удаления устанавливает audit_log заново.
37
+ Через настройки проекта возможна передача дополнительных sql файлов
38
+ для выполнения вместе с основным скриптом установки.
34
39
  """
35
40
 
36
41
  help = 'Команда для переустановки audit_log.'
37
42
 
38
- def add_arguments(self, parser):
43
+ def add_arguments(self, parser) -> None:
39
44
  """Добавление аргументов команды."""
40
- (
41
- parser.add_argument(
42
- '--clear_audit_logs',
43
- action='store_true',
44
- default=False,
45
- help='Удалить записи из audit_log для неотслеживаемых таблиц',
46
- ),
45
+ parser.add_argument(
46
+ '--clear_audit_logs',
47
+ action='store_true',
48
+ default=False,
49
+ help='Удалить записи из audit_log для неотслеживаемых таблиц',
47
50
  )
48
51
  parser.add_argument(
49
52
  '--chunk_size',
@@ -52,33 +55,42 @@ class Command(BaseCommand):
52
55
  help='Кол-во единовременно удаляемых записей',
53
56
  )
54
57
 
55
- def _read_sql(self, filename):
58
+ def _read_sql(self, sql_file_path: str) -> str:
56
59
  """Чтение SQL-кода из файла."""
57
- sql_file_path = os.path.join(SQL_FILES_DIR, filename)
58
-
59
60
  with codecs.open(sql_file_path, 'r', 'utf-8') as sql_file:
60
61
  sql = sql_file.read()
61
62
 
62
- self.stdout.write('reading SQL-code..\n')
63
+ file_name = os.path.basename(sql_file_path)
64
+ self.stdout.write(f'reading {file_name}..\n')
63
65
 
64
66
  return sql
65
67
 
66
- def _prepare_sql(self):
68
+ def _prepare_sql(self) -> list[str]:
67
69
  """Подготовка SQL-кода."""
68
70
  params = get_db_connection_params()
69
71
  params['lock_id'] = PG_LOCK_ID
70
72
 
71
73
  self.stdout.write('preparing SQL-code..\n')
72
74
 
73
- return self._read_sql(INSTALL_AUDIT_LOG_SQL_FILE_NAME).format(**params)
75
+ sql_files = [
76
+ os.path.join(SQL_FILES_DIR, INSTALL_AUDIT_LOG_SQL_FILE_NAME),
77
+ *getattr(settings, 'AUDIT_LOG_EXTENSION_SCRIPTS', [])
78
+ ]
79
+
80
+ sql_scripts = []
81
+ for sql_file_path in sql_files:
82
+ sql_scripts.append(self._read_sql(sql_file_path).format(**params))
83
+
84
+ return sql_scripts
74
85
 
75
- def handle(self, *args, **options):
86
+ def handle(self, *args, **options) -> None:
76
87
  """Формирование SQL-кода и его исполнение."""
77
88
  self.stdout.write('start reinstalling audit_log..\n')
78
89
 
79
90
  cursor = connection.cursor()
80
91
 
81
- cursor.execute(self._prepare_sql())
92
+ for sql in self._prepare_sql():
93
+ cursor.execute(sql)
82
94
 
83
95
  configure(force_update_triggers=True)
84
96
 
@@ -40,6 +40,7 @@ from django.db.transaction import (
40
40
  from django.http import (
41
41
  HttpRequest,
42
42
  )
43
+
43
44
  from m3_django_compat import (
44
45
  get_related,
45
46
  )
@@ -52,6 +53,9 @@ from educommon.audit_log.constants import (
52
53
  PG_LOCK_ID,
53
54
  SQL_FILES_DIR,
54
55
  )
56
+ from educommon.logger import (
57
+ error as logger_error,
58
+ )
55
59
  from educommon.utils.misc import (
56
60
  cached_property,
57
61
  )
@@ -99,6 +103,19 @@ def get_need_to_log_table_names() -> Set[str]:
99
103
  return table_names
100
104
 
101
105
 
106
+ def get_table_names_for_app_labels(app_labels: Iterable[str]) -> Set[str]:
107
+ """Возвращает множество с именами таблиц для указанных приложений."""
108
+ tables = set()
109
+ for app_label in app_labels:
110
+ try:
111
+ app_config = apps.get_app_config(app_label)
112
+ tables.update(model._meta.db_table for model in app_config.get_models())
113
+ except LookupError:
114
+ continue
115
+
116
+ return tables
117
+
118
+
102
119
  def update_or_create_tables(need_to_log_table_names: Iterable[str]) -> bool:
103
120
  """Создаёт записи Table для отслеживаемых таблиц, либо меняет флаг logged.
104
121
 
@@ -109,6 +126,21 @@ def update_or_create_tables(need_to_log_table_names: Iterable[str]) -> bool:
109
126
  need_to_log_table_names = set(need_to_log_table_names)
110
127
  existed_table_names = set(Table.objects.filter(schema='public').values_list('name', flat=True))
111
128
 
129
+ # Таблицы сервисных приложений, которые не должны отслеживаться аудит-логом
130
+ allowed_service_apps_labels = getattr(settings, 'ALLOWED_SERVICE_APPS_LABELS', [])
131
+ service_table_names = get_table_names_for_app_labels(allowed_service_apps_labels)
132
+
133
+ # Проверка конфликтных таблиц: должны логироваться, но находятся в сервисных приложениях
134
+ conflicting_tables = need_to_log_table_names & service_table_names
135
+ if conflicting_tables:
136
+ tables = ', '.join(sorted(conflicting_tables))
137
+ error_msg = (
138
+ f'Невозможно включить логирование для сервисных таблиц: {tables}. '
139
+ 'Исключите их из отслеживания или перенесите таблицы в основную БД.'
140
+ )
141
+ logger_error(error_msg)
142
+ raise ValueError(error_msg)
143
+
112
144
  to_create_table_names = need_to_log_table_names - existed_table_names
113
145
  to_disable_table_names = existed_table_names - need_to_log_table_names
114
146
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: educommon
3
- Version: 3.15.0
3
+ Version: 3.17.0
4
4
  Summary: Общая кодовая база для проектов БЦ Образование
5
5
  Author-email: BARS Group <education_dev@bars-open.ru>
6
6
  Project-URL: Homepage, https://stash.bars-open.ru/projects/EDUBASE/repos/educommon/browse
@@ -40,9 +40,9 @@ educommon/async_tasks/fixtures/initial_data.json,sha256=d5EGMoCY8CVJL80C8ZaPwVVU
40
40
  educommon/async_tasks/migrations/0001_initial.py,sha256=ohWQK9rzMdM6kSWs7IPmlOA5amkWdaWZ7u3MBl1uWd0,5632
41
41
  educommon/async_tasks/migrations/0002_load_initial_data.py,sha256=MMLyXnEl9KFb1jYNfDfunwoLrTLyZfSqmcUQUhr2V-M,477
42
42
  educommon/async_tasks/migrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
43
- educommon/audit_log/README.rst,sha256=qz0PxwnAMNnSYMemX_WQzttDA7068YzPc-jHMCSRxDY,2777
43
+ educommon/audit_log/README.rst,sha256=eiYUkU6T7l_vFjGYsbYNjTmrs_YqZzEmPtfUjTezaII,4123
44
44
  educommon/audit_log/__init__.py,sha256=fNpKUKim4ybYWxSXjJ77G0YsvtFiZcWb0x6SDT3GxMo,2773
45
- educommon/audit_log/actions.py,sha256=vsfoohNC4MOqCmi_WxuIF9jQMgYSR5BUBFaJw3eESC8,7381
45
+ educommon/audit_log/actions.py,sha256=kLdekdEkCyKAsV9IXKKuvXLmS2TgJBikrX34L-5hA-o,7243
46
46
  educommon/audit_log/app_meta.py,sha256=2xg9OKRhAFNmE_k10J5nTnFL8CVuI9iPbEBJha_UXsU,309
47
47
  educommon/audit_log/apps.py,sha256=A27iSAEWAVr7LmBmexVDrbWm3eQ-zFq1FYGQRClMJVM,6278
48
48
  educommon/audit_log/constants.py,sha256=8C1SCiwD1s_ED9C3Hh50LMAnToGvZmF21nrv18hRLEg,903
@@ -57,7 +57,7 @@ educommon/audit_log/error_log/__init__.py,sha256=lfAIm5GTGQ1-kRFxH1s0agSt2Oeguwj
57
57
  educommon/audit_log/error_log/actions.py,sha256=-KSy3RrBsbPWCML-gl5Hl5UGQdEsPZhoKrHq16LRmm8,2305
58
58
  educommon/audit_log/management/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
59
59
  educommon/audit_log/management/commands/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
60
- educommon/audit_log/management/commands/reinstall_audit_log.py,sha256=o7deAmr2DXcqprjrnfs7pfHtqbyO8fUwYFlwqGwE5wM,3013
60
+ educommon/audit_log/management/commands/reinstall_audit_log.py,sha256=HHpUeQwG_SuSsaxwZIq66piNhip_GHHQmAzpEzOFgaM,3573
61
61
  educommon/audit_log/migrations/0001_initial.py,sha256=HDhvBNyVSx_NlFmyA-t_ooFo_TiKf0UHNCZp1GOpLA8,6115
62
62
  educommon/audit_log/migrations/0002_install_audit_log.py,sha256=kAhtd1Xz8b6g33wmxBQyRBJIl-LGJdOc7yFy5yhoRJ8,2825
63
63
  educommon/audit_log/migrations/0003_logproxy.py,sha256=fx6nCoDtr3bZTtlwiOKP4QTVPxnnqyYDPMAT20Bv4n8,391
@@ -70,7 +70,7 @@ educommon/audit_log/migrations/0009_reinstall_audit_log.py,sha256=c95H2yamWyrCoG
70
70
  educommon/audit_log/migrations/__init__.py,sha256=AbpHGcgLb-kRsJGnwFEktk7uzpZOCcBY74-YBdrKVGs,1
71
71
  educommon/audit_log/sql/configure_audit_log.sql,sha256=M3QxNKTZbn-uNRxGDvNxE9iJh1EOQUTIho7rvc3yhlY,1511
72
72
  educommon/audit_log/sql/install_audit_log.sql,sha256=SHrZ7WaYxawUKQEpZnj9k4HTU25NvBlxX_POqZ95HU0,14107
73
- educommon/audit_log/utils/__init__.py,sha256=FSq-L4wNOrCTqve16c4KruIxTwHZuTh1lNLNgznAcv8,14843
73
+ educommon/audit_log/utils/__init__.py,sha256=14BHRbKdnvHNgomM-R__GqLk1N32ww_GN2xy81Ph_gs,16388
74
74
  educommon/audit_log/utils/operations.py,sha256=skxL7wE4Jx1XlNdPx-Pl3SfiZ1G9jBmcZrXKSQDUGzw,2555
75
75
  educommon/auth/__init__.py,sha256=xkGJgqQ5QaEU86n6tJV77ux-2bMTAKbjpVYBCDhcS0E,79
76
76
  educommon/auth/rbac/__init__.py,sha256=guO7sOX6e1Z-dqptsqXjbnMdgbSdKp2suDKJa5_pdVU,317
@@ -349,7 +349,7 @@ educommon/ws_log/smev/exceptions.py,sha256=VNfzNHlj5Pz8D4979d_msTkxC-RQVoMctsgoJ
349
349
  educommon/ws_log/templates/report/smev_logs.xlsx,sha256=nnYgB0Z_ix8HoxsRICjsZfFRQBdra-5Gd8nWhCxTjYg,10439
350
350
  educommon/ws_log/templates/ui-js/smev-logs-list-window.js,sha256=AGup3D8GTJSY9WdDPj0zBJeYQBFOmGgcbxPOJbKK-nY,513
351
351
  educommon/ws_log/templates/ui-js/smev-logs-report-setting-window.js,sha256=nQ7QYK9frJcE7g7kIt6INg9TlEEJAPPayBJgRaoTePA,1103
352
- educommon-3.15.0.dist-info/METADATA,sha256=_8hCUYe-OqYdSUa0pDvbkIF4peIPvOZT4_SU0kXkFek,2380
353
- educommon-3.15.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
354
- educommon-3.15.0.dist-info/top_level.txt,sha256=z5fbW7bz_0V1foUm_FGcZ9_MTpW3N1dBN7-kEmMowl4,10
355
- educommon-3.15.0.dist-info/RECORD,,
352
+ educommon-3.17.0.dist-info/METADATA,sha256=XU8hoY7CgSTjP2GH8wgaRb1EHhjRQYyCdI69uYHmmk8,2380
353
+ educommon-3.17.0.dist-info/WHEEL,sha256=1tXe9gY0PYatrMPMDd6jXqjfpz_B-Wqm32CPfRC58XU,91
354
+ educommon-3.17.0.dist-info/top_level.txt,sha256=z5fbW7bz_0V1foUm_FGcZ9_MTpW3N1dBN7-kEmMowl4,10
355
+ educommon-3.17.0.dist-info/RECORD,,