educommon 3.13.0__py3-none-any.whl → 3.13.2__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.
Files changed (220) hide show
  1. educommon/__init__.py +0 -1
  2. educommon/about/ui/actions.py +16 -30
  3. educommon/about/ui/ui.py +3 -12
  4. educommon/about/utils.py +6 -5
  5. educommon/async_task/__init__.py +0 -1
  6. educommon/async_task/actions.py +18 -13
  7. educommon/async_task/apps.py +4 -0
  8. educommon/async_task/locker.py +2 -5
  9. educommon/async_task/migrations/0001_initial.py +55 -9
  10. educommon/async_task/migrations/0002_task_type_and_status_data.py +94 -89
  11. educommon/async_task/migrations/0003_alter_runningtask_options.py +0 -1
  12. educommon/async_task/models.py +9 -6
  13. educommon/async_task/tasks.py +11 -7
  14. educommon/async_task/ui.py +16 -35
  15. educommon/async_tasks/__init__.py +0 -1
  16. educommon/async_tasks/apps.py +4 -0
  17. educommon/async_tasks/locks.py +11 -21
  18. educommon/async_tasks/migrations/0001_initial.py +68 -8
  19. educommon/async_tasks/migrations/0002_load_initial_data.py +0 -1
  20. educommon/async_tasks/models.py +9 -29
  21. educommon/async_tasks/tasks.py +25 -54
  22. educommon/audit_log/__init__.py +1 -0
  23. educommon/audit_log/actions.py +27 -36
  24. educommon/audit_log/app_meta.py +7 -4
  25. educommon/audit_log/apps.py +44 -29
  26. educommon/audit_log/constants.py +7 -4
  27. educommon/audit_log/error_log/actions.py +1 -3
  28. educommon/audit_log/helpers.py +2 -4
  29. educommon/audit_log/management/commands/reinstall_audit_log.py +11 -7
  30. educommon/audit_log/migrations/0001_initial.py +91 -16
  31. educommon/audit_log/migrations/0002_install_audit_log.py +13 -13
  32. educommon/audit_log/migrations/0003_logproxy.py +1 -3
  33. educommon/audit_log/migrations/0004_reinstall_audit_log.py +1 -4
  34. educommon/audit_log/migrations/0005_postgresql_error.py +4 -2
  35. educommon/audit_log/migrations/0006_auto_20200806_1707.py +3 -4
  36. educommon/audit_log/migrations/0007_create_selective_tables_function.py +8 -5
  37. educommon/audit_log/migrations/0008_table_logged.py +0 -1
  38. educommon/audit_log/migrations/0009_reinstall_audit_log.py +0 -1
  39. educommon/audit_log/models.py +36 -42
  40. educommon/audit_log/permissions.py +11 -9
  41. educommon/audit_log/proxies.py +12 -23
  42. educommon/audit_log/ui.py +18 -15
  43. educommon/audit_log/utils/__init__.py +28 -60
  44. educommon/audit_log/utils/operations.py +16 -2
  45. educommon/auth/__init__.py +0 -3
  46. educommon/auth/rbac/__init__.py +2 -4
  47. educommon/auth/rbac/actions.py +148 -145
  48. educommon/auth/rbac/app_meta.py +9 -6
  49. educommon/auth/rbac/backends/base.py +2 -8
  50. educommon/auth/rbac/backends/caching.py +27 -37
  51. educommon/auth/rbac/backends/simple.py +1 -4
  52. educommon/auth/rbac/checker.py +1 -3
  53. educommon/auth/rbac/management/commands/rbac.py +6 -11
  54. educommon/auth/rbac/manager.py +18 -47
  55. educommon/auth/rbac/migrations/0001_initial.py +73 -12
  56. educommon/auth/rbac/migrations/0002_model_modifier_metaclass_fix.py +7 -6
  57. educommon/auth/rbac/migrations/0003_permission_hidden.py +1 -5
  58. educommon/auth/rbac/migrations/0004_auto_20171024_1245.py +26 -19
  59. educommon/auth/rbac/models.py +63 -68
  60. educommon/auth/rbac/permissions.py +6 -7
  61. educommon/auth/rbac/ui.py +83 -84
  62. educommon/auth/rbac/utils.py +10 -11
  63. educommon/auth/rbac/validators.py +4 -5
  64. educommon/auth/simple_auth/__init__.py +1 -5
  65. educommon/auth/simple_auth/actions.py +79 -92
  66. educommon/auth/simple_auth/app_meta.py +2 -9
  67. educommon/auth/simple_auth/checkers.py +3 -3
  68. educommon/auth/simple_auth/migrations/0001_initial.py +23 -4
  69. educommon/auth/simple_auth/validators.py +0 -1
  70. educommon/contingent/actions.py +7 -7
  71. educommon/contingent/app_meta.py +1 -4
  72. educommon/contingent/base.py +10 -15
  73. educommon/contingent/catalogs.py +424 -540
  74. educommon/contingent/contingent_plugin/actions.py +4 -15
  75. educommon/contingent/contingent_plugin/apps.py +10 -4
  76. educommon/contingent/contingent_plugin/migrations/0001_initial.py +5 -6
  77. educommon/contingent/contingent_plugin/migrations/0002_add_contingent_model_deleted.py +6 -11
  78. educommon/contingent/contingent_plugin/model_views.py +2 -12
  79. educommon/contingent/contingent_plugin/models.py +2 -7
  80. educommon/contingent/contingent_plugin/observer.py +14 -13
  81. educommon/contingent/contingent_plugin/plugin_meta.py +1 -3
  82. educommon/contingent/contingent_plugin/storage.py +8 -7
  83. educommon/contingent/contingent_plugin/utils.py +6 -6
  84. educommon/django/db/fields.py +72 -86
  85. educommon/django/db/migration/__init__.py +3 -7
  86. educommon/django/db/migration/operations.py +29 -51
  87. educommon/django/db/mixins/__init__.py +16 -10
  88. educommon/django/db/mixins/date_interval.py +47 -75
  89. educommon/django/db/mixins/validation.py +26 -26
  90. educommon/django/db/model_view/__init__.py +18 -22
  91. educommon/django/db/models.py +9 -8
  92. educommon/django/db/observer.py +9 -27
  93. educommon/django/db/partitioning/__init__.py +66 -92
  94. educommon/django/db/partitioning/management/commands/apply_partitioning.py +3 -13
  95. educommon/django/db/partitioning/management/commands/clear_table.py +18 -14
  96. educommon/django/db/partitioning/management/commands/split_table.py +18 -13
  97. educommon/django/db/routers.py +6 -15
  98. educommon/django/db/signals.py +4 -2
  99. educommon/django/db/utils.py +14 -19
  100. educommon/django/db/validators/__init__.py +1 -0
  101. educommon/django/db/validators/simple.py +72 -100
  102. educommon/django/storages/atcfs/api.py +39 -53
  103. educommon/django/storages/atcfs/app_meta.py +1 -1
  104. educommon/django/storages/atcfs/management/commands/atcfs_migrate.py +42 -55
  105. educommon/django/storages/atcfs/models.py +0 -3
  106. educommon/django/storages/atcfs/monkey_patching.py +18 -12
  107. educommon/django/storages/atcfs/storage.py +14 -23
  108. educommon/extjs/fields/input_params.py +15 -45
  109. educommon/importer/XLSReader.py +143 -241
  110. educommon/importer/__init__.py +86 -4
  111. educommon/importer/api.py +53 -84
  112. educommon/importer/constants.py +4 -14
  113. educommon/importer/loggers.py +16 -26
  114. educommon/importer/proxy.py +131 -176
  115. educommon/importer/proxy_import.py +11 -12
  116. educommon/importer/report.py +4 -6
  117. educommon/importer/ui.py +32 -26
  118. educommon/importer/validators.py +4 -7
  119. educommon/integration_entities/helpers.py +14 -18
  120. educommon/ioc/__init__.py +3 -6
  121. educommon/logger/loggers.py +10 -14
  122. educommon/m3/__init__.py +20 -38
  123. educommon/m3/extensions/__init__.py +1 -0
  124. educommon/m3/extensions/listeners/__init__.py +22 -38
  125. educommon/m3/extensions/listeners/delete_check/listeners.py +31 -41
  126. educommon/m3/extensions/listeners/delete_check/mixins.py +20 -25
  127. educommon/m3/extensions/listeners/delete_check/signals.py +2 -2
  128. educommon/m3/extensions/listeners/delete_check/ui.py +15 -14
  129. educommon/m3/extensions/listeners/delete_check/utils.py +9 -11
  130. educommon/m3/extensions/ui.py +15 -33
  131. educommon/m3/transaction_context.py +17 -19
  132. educommon/objectpack/actions.py +70 -88
  133. educommon/objectpack/apps.py +5 -0
  134. educommon/objectpack/filters.py +9 -15
  135. educommon/objectpack/ui.py +59 -77
  136. educommon/report/__init__.py +9 -5
  137. educommon/report/actions.py +29 -32
  138. educommon/report/constructor/__init__.py +5 -8
  139. educommon/report/constructor/app_meta.py +1 -3
  140. educommon/report/constructor/apps.py +1 -0
  141. educommon/report/constructor/base.py +33 -80
  142. educommon/report/constructor/builders/excel/_base.py +138 -286
  143. educommon/report/constructor/builders/excel/_header.py +2 -9
  144. educommon/report/constructor/builders/excel/product.py +13 -34
  145. educommon/report/constructor/builders/excel/with_merged_cells.py +18 -14
  146. educommon/report/constructor/config.py +2 -0
  147. educommon/report/constructor/editor/actions.py +101 -215
  148. educommon/report/constructor/editor/ui.py +71 -93
  149. educommon/report/constructor/exceptions.py +6 -12
  150. educommon/report/constructor/migrations/0001_initial.py +36 -44
  151. educommon/report/constructor/migrations/0002_report_filters.py +86 -72
  152. educommon/report/constructor/migrations/0003_reportfilter_exclude.py +5 -5
  153. educommon/report/constructor/migrations/0004_reportfilter_fields.py +22 -18
  154. educommon/report/constructor/migrations/0005_reportcolumn_visible.py +5 -4
  155. educommon/report/constructor/migrations/0006_reportsorting.py +21 -17
  156. educommon/report/constructor/migrations/0007_include_available_units.py +14 -14
  157. educommon/report/constructor/migrations/0008_auto_20170407_1318.py +4 -5
  158. educommon/report/constructor/migrations/0009_auto_20180405_0642.py +1 -4
  159. educommon/report/constructor/migrations/0010_add_aggregate_fields.py +7 -8
  160. educommon/report/constructor/mixins.py +14 -15
  161. educommon/report/constructor/models.py +76 -124
  162. educommon/report/constructor/utils.py +3 -8
  163. educommon/report/constructor/validators.py +1 -3
  164. educommon/report/reporter.py +25 -43
  165. educommon/report/utils.py +14 -40
  166. educommon/rest/actions.py +7 -11
  167. educommon/rest/context.py +6 -16
  168. educommon/rest/controllers.py +10 -10
  169. educommon/rest/mixins.py +29 -27
  170. educommon/secure_media/app_meta.py +9 -9
  171. educommon/utils/__init__.py +3 -2
  172. educommon/utils/caching.py +1 -3
  173. educommon/utils/conversion.py +1 -3
  174. educommon/utils/crypto.py +1 -2
  175. educommon/utils/date.py +13 -26
  176. educommon/utils/db/__init__.py +17 -26
  177. educommon/utils/db/postgresql.py +1 -4
  178. educommon/utils/fonts/__init__.py +3 -4
  179. educommon/utils/licence/__init__.py +5 -16
  180. educommon/utils/misc.py +9 -18
  181. educommon/utils/object_grid.py +55 -62
  182. educommon/utils/phone_number/modelfields.py +1 -3
  183. educommon/utils/phone_number/phone_number.py +5 -8
  184. educommon/utils/phone_number/validators.py +8 -23
  185. educommon/utils/plugins.py +15 -28
  186. educommon/utils/registry.py +2 -1
  187. educommon/utils/seqtools.py +1 -3
  188. educommon/utils/serializer.py +9 -16
  189. educommon/utils/storage.py +3 -2
  190. educommon/utils/system.py +1 -3
  191. educommon/utils/system_app/management/commands/delete_objects.py +17 -34
  192. educommon/utils/ui.py +87 -84
  193. educommon/utils/xml/__init__.py +2 -7
  194. educommon/utils/xml/resolver.py +1 -0
  195. educommon/ws_log/actions.py +31 -76
  196. educommon/ws_log/base.py +6 -20
  197. educommon/ws_log/migrations/0001_initial.py +25 -8
  198. educommon/ws_log/migrations/0002_auto_20160628_1334.py +0 -1
  199. educommon/ws_log/migrations/0003_add_fields_to_smev_logs.py +20 -4
  200. educommon/ws_log/migrations/0004_auto_20160727_1600.py +7 -6
  201. educommon/ws_log/migrations/0005_auto_20161130_1615.py +14 -4
  202. educommon/ws_log/migrations/0006_auto_20170327_1027.py +3 -2
  203. educommon/ws_log/migrations/0007_auto_20180607_1040.py +8 -9
  204. educommon/ws_log/migrations/0008_auto_20180713_1445.py +23 -10
  205. educommon/ws_log/migrations/0009_auto_20201130_1553.py +7 -2
  206. educommon/ws_log/models.py +21 -35
  207. educommon/ws_log/provider.py +2 -1
  208. educommon/ws_log/report.py +8 -13
  209. educommon/ws_log/smev/applications.py +12 -27
  210. educommon/ws_log/smev/exceptions.py +2 -3
  211. educommon/ws_log/ui.py +32 -32
  212. educommon/ws_log/utils.py +1 -3
  213. {educommon-3.13.0.dist-info → educommon-3.13.2.dist-info}/METADATA +26 -14
  214. educommon-3.13.2.dist-info/RECORD +354 -0
  215. educommon/utils/patches.py +0 -27
  216. educommon/version.conf +0 -11
  217. educommon-3.13.0.dist-info/RECORD +0 -357
  218. educommon-3.13.0.dist-info/dependency_links.txt +0 -1
  219. {educommon-3.13.0.dist-info → educommon-3.13.2.dist-info}/WHEEL +0 -0
  220. {educommon-3.13.0.dist-info → educommon-3.13.2.dist-info}/top_level.txt +0 -0
@@ -58,20 +58,19 @@ class CachingBackend(BackendBase):
58
58
  """Ключ кеша, в котором сохраняется время изменения объектов в БД."""
59
59
 
60
60
  # Модели, данные которых кэшируются.
61
- _cached_models = {
62
- Permission,
63
- Role,
64
- RoleParent,
65
- UserRole,
66
- RolePermission
67
- }
61
+ _cached_models = {Permission, Role, RoleParent, UserRole, RolePermission}
68
62
 
69
63
  @cached_property
70
64
  def _logger(self):
71
65
  return getLogger(__name__.rpartition('.')[0])
72
66
 
73
67
  def __init__(self, *args, **kwargs):
74
- super(CachingBackend, self).__init__(*args, **kwargs)
68
+ """Инициализация бэкенда RBAC с поддержкой кэширования.
69
+
70
+ Устанавливает параметры кэширования и подписывается на сигналы
71
+ для обновления кэша при изменениях в связанных моделях.
72
+ """
73
+ super().__init__(*args, **kwargs)
75
74
 
76
75
  # Максимальная продолжительность кеширования объектов до их
77
76
  # перезагрузки (в секундах).
@@ -107,7 +106,8 @@ class CachingBackend(BackendBase):
107
106
  """Обработчик сигналов об изменениях в моделях."""
108
107
  if (
109
108
  # changed приходит только от post_init
110
- kwargs.get('changed', False) or
109
+ kwargs.get('changed', False)
110
+ or
111
111
  # а port_save и post_delete нужно обрабатывать только для
112
112
  # кэшируемых моделей
113
113
  sender in self._cached_models
@@ -158,23 +158,17 @@ class CachingBackend(BackendBase):
158
158
 
159
159
  def _load_role_permissions(self):
160
160
  """Загрузка данных о разрешениях ролей RBAC."""
161
- for role_id, permission_id in RolePermission.objects.values_list(
162
- 'role', 'permission'
163
- ):
161
+ for role_id, permission_id in RolePermission.objects.values_list('role', 'permission'):
164
162
  self._role_permissions[role_id].add(permission_id)
165
163
 
166
164
  def _load_user_roles(self):
167
165
  """Загрузка данных о ролях пользователей."""
168
166
  query = UserRole.objects.filter(
169
167
  Q(date_to__isnull=True) | Q(date_to__gte=date.today()),
170
- ).values_list(
171
- 'content_type', 'object_id', 'date_from', 'date_to', 'role'
172
- )
168
+ ).values_list('content_type', 'object_id', 'date_from', 'date_to', 'role')
173
169
 
174
170
  for ct_id, obj_id, date_from, date_to, role_id in query:
175
- self._user_roles[ct_id, obj_id].add(
176
- (date_from, date_to, role_id)
177
- )
171
+ self._user_roles[ct_id, obj_id].add((date_from, date_to, role_id))
178
172
 
179
173
  def _get_role_descendants(self, role_id, include_self=False):
180
174
  """Возвращает вложенные роли."""
@@ -184,9 +178,7 @@ class CachingBackend(BackendBase):
184
178
  result.add(role_id)
185
179
 
186
180
  for child_role_id in self._role_children[role_id]:
187
- result.update(
188
- self._get_role_descendants(child_role_id, include_self=True)
189
- )
181
+ result.update(self._get_role_descendants(child_role_id, include_self=True))
190
182
 
191
183
  return result
192
184
 
@@ -199,30 +191,30 @@ class CachingBackend(BackendBase):
199
191
  roles_data = self._user_roles[content_type_id, user.id]
200
192
  today = date.today()
201
193
 
202
- return set(chain(*(
203
- self._get_role_descendants(role_id, include_self=True)
204
- for date_from, date_to, role_id in roles_data
205
- if (date_from or today) <= today <= (date_to or today)
206
- )))
194
+ return set(
195
+ chain(
196
+ *(
197
+ self._get_role_descendants(role_id, include_self=True)
198
+ for date_from, date_to, role_id in roles_data
199
+ if (date_from or today) <= today <= (date_to or today)
200
+ )
201
+ )
202
+ )
207
203
 
208
204
  def _get_user_permissions(self, user):
209
205
  """Возврвщает все доступные пользователю разрешения.
210
206
 
211
207
  :rtype: itertools.chain
212
208
  """
209
+
213
210
  def get_role_permissions(role_id):
214
211
  # pylint: disable=protected-access
215
212
  for permission_id in self._role_permissions[role_id]:
216
213
  yield permission_id
217
- for name in self._manager.get_dependent_permissions(
218
- self._permissions_by_id[permission_id]
219
- ):
214
+ for name in self._manager.get_dependent_permissions(self._permissions_by_id[permission_id]):
220
215
  yield self._permissions_by_name[name]
221
216
 
222
- return chain(*(
223
- get_role_permissions(role_id)
224
- for role_id in self._get_user_roles(user)
225
- ))
217
+ return chain(*(get_role_permissions(role_id) for role_id in self._get_user_roles(user)))
226
218
 
227
219
  def _reload(self, force=False):
228
220
  """Перезагрузка кешируемых объектов при необходимости.
@@ -278,15 +270,13 @@ class CachingBackend(BackendBase):
278
270
 
279
271
  # Id разрешений экшена, доступность которых будем проверять
280
272
  action_permissions = set(
281
- self._permissions_by_name[perm_name]
282
- for perm_name in self._get_action_permissions(action)
273
+ self._permissions_by_name[perm_name] for perm_name in self._get_action_permissions(action)
283
274
  )
284
275
 
285
276
  for permission_id in self._get_user_permissions(user):
286
277
  if permission_id in action_permissions:
287
278
  permission_name = self._permissions_by_id[permission_id]
288
- if self._check_permission(permission_name, action, request,
289
- user):
279
+ if self._check_permission(permission_name, action, request, user):
290
280
  return True
291
281
 
292
282
  return False
@@ -72,7 +72,6 @@ def _get_user_permissions_query(user, permissions=None):
72
72
 
73
73
 
74
74
  class SimpleBackend(BackendBase):
75
-
76
75
  """Предоставляет прямой доступ к объектам RBAC.
77
76
 
78
77
  Доступ к объектам RBAC (разрешениям, ролям и их связям между собой)
@@ -91,9 +90,7 @@ class SimpleBackend(BackendBase):
91
90
  :rtype: generator
92
91
  """
93
92
  # pylint: disable=protected-access
94
- for name in _get_user_permissions_query(user, permissions).values_list(
95
- 'name', flat=True
96
- ):
93
+ for name in _get_user_permissions_query(user, permissions).values_list('name', flat=True):
97
94
  yield name
98
95
  for name in self._manager.get_dependent_permissions(name):
99
96
  yield name
@@ -53,9 +53,7 @@ class PermissionChecker(AbstractPermissionChecker):
53
53
 
54
54
  pack_perm_code = getattr(pack, 'perm_code', False)
55
55
  if not pack_perm_code:
56
- pack_perm_code = '/'.join(
57
- (pack.__class__.__module__, pack.__class__.__name__)
58
- )
56
+ pack_perm_code = '/'.join((pack.__class__.__module__, pack.__class__.__name__))
59
57
 
60
58
  if action is None:
61
59
  action_perm_code = 'default'
@@ -1,4 +1,5 @@
1
1
  """Management-команда для обслуживания системы авторизации."""
2
+
2
3
  import os
3
4
 
4
5
  from django.core.management import (
@@ -21,7 +22,6 @@ from educommon.auth.rbac.models import (
21
22
 
22
23
 
23
24
  class Command(BaseCommand):
24
-
25
25
  """Обслуживание системы авторизации."""
26
26
 
27
27
  use_argparse = False
@@ -84,8 +84,6 @@ class Command(BaseCommand):
84
84
  return
85
85
 
86
86
  max_width = max(len(permission) for permission in permissions)
87
- template = ' {} {:<%s}\n' % max_width
88
-
89
87
  self.stdout.write('Permissions:\n')
90
88
 
91
89
  for permission in sorted(permissions):
@@ -96,9 +94,8 @@ class Command(BaseCommand):
96
94
  else:
97
95
  status, color = '[ REGISTERED ]', 'green'
98
96
 
99
- self.stdout.write(
100
- colored(template.format(status, permission), color)
101
- )
97
+ line = f' {status} {permission:<{max_width}}\n'
98
+ self.stdout.write(colored(line, color))
102
99
 
103
100
  def _show(self, objects='permissions', *args, **options):
104
101
  """Отображение данных системы авторизации."""
@@ -119,13 +116,11 @@ class Command(BaseCommand):
119
116
  return
120
117
 
121
118
  max_width = max(len(p.name) for p in permissions)
122
- template = '{:<%s} [DELETED]\n' % max_width
123
119
 
124
120
  for permission in permissions:
125
121
  permission.delete()
126
- self.stdout.write(
127
- colored(template.format(permission.name), 'red')
128
- )
122
+ line = f'{permission.name:<{max_width}} [DELETED]\n'
123
+ self.stdout.write(colored(line, 'red'))
129
124
 
130
125
  def _clean(self, objects='all', **options):
131
126
  """Удаление незарегистрированных правил и разрешений."""
@@ -137,7 +132,7 @@ class Command(BaseCommand):
137
132
  raise CommandError('Unknown objects type: {}'.format(objects))
138
133
 
139
134
  def handle(self, action, *args, **options):
140
- # TODO: Написать документацию
135
+ """Обработка команды управления RBAC."""
141
136
  rbac.init(update_db=False)
142
137
 
143
138
  if not self.stdout.isatty():
@@ -42,6 +42,7 @@ def _get_handler(handler):
42
42
  module, handler = handler.rsplit('.', 1)
43
43
  module = __import__(module, fromlist=[handler])
44
44
  handler = getattr(module, handler)
45
+
45
46
  return handler
46
47
 
47
48
 
@@ -89,11 +90,7 @@ def _set_permission(permission, name, title, description, hidden):
89
90
  permission.full_clean()
90
91
  permission.save()
91
92
  changed = True
92
- elif (
93
- permission.title != title or
94
- permission.description != description or
95
- permission.hidden != hidden
96
- ):
93
+ elif permission.title != title or permission.description != description or permission.hidden != hidden:
97
94
  permission.title = title
98
95
  permission.description = description
99
96
  permission.hidden = hidden
@@ -129,6 +126,7 @@ class RBACManager:
129
126
  :returns: ``('employee', 'Сотрудники')``
130
127
  """
131
128
  group_name = permission_name.split('/')[0]
129
+
132
130
  return group_name, self.groups[group_name]
133
131
 
134
132
  def get_partition_title(self, group_name) -> Optional[str]:
@@ -154,8 +152,7 @@ class RBACManager:
154
152
  for title, group_codes in partitions.items():
155
153
  for code in group_codes:
156
154
  assert code not in processed_codes, (
157
- 'Группа разрешений "{}" уже закреплена за другим '
158
- 'разделом системы.'.format(code)
155
+ 'Группа разрешений "{}" уже закреплена за другим разделом системы.'.format(code)
159
156
  )
160
157
  self.partitions[title].add(code)
161
158
  processed_codes.add(code)
@@ -170,9 +167,8 @@ class RBACManager:
170
167
  continue
171
168
 
172
169
  for code, title in groups.items():
173
- assert code not in self.groups, (
174
- 'Группа разрешений "{}" ({}) уже описана в другом '
175
- 'приложении.'.format(code, title)
170
+ assert code not in self.groups, 'Группа разрешений "{}" ({}) уже описана в другом приложении.'.format(
171
+ code, title
176
172
  )
177
173
 
178
174
  self.groups[code] = title
@@ -203,13 +199,9 @@ class RBACManager:
203
199
  if hidden:
204
200
  self.hidden_permissions.add(name)
205
201
  else:
206
- raise ValueError(
207
- 'Invalid permission params: ' + repr(params)
208
- )
202
+ raise ValueError('Invalid permission params: ' + repr(params))
209
203
 
210
- assert name in self.permissions_by_name, (
211
- 'Permission {} not found'.format(name)
212
- )
204
+ assert name in self.permissions_by_name, 'Permission {} not found'.format(name)
213
205
 
214
206
  _title, _description = self.permissions_by_name[name]
215
207
  self.permissions_by_name[name] = (
@@ -227,27 +219,16 @@ class RBACManager:
227
219
  module_dependencies = module_dependencies()
228
220
 
229
221
  for name, dependencies in module_dependencies.items():
230
- assert name in self.permissions_by_name, (
231
- 'Permission {} not found'.format(name)
232
- )
222
+ assert name in self.permissions_by_name, 'Permission {} not found'.format(name)
233
223
  assert name not in self.hidden_permissions or all(
234
- dependency in self.hidden_permissions
235
- for dependency in dependencies
236
- ), (
237
- 'Скрытые разрешения могут зависеть только от скрытых '
238
- 'разрешений: ' + name
239
- )
224
+ dependency in self.hidden_permissions for dependency in dependencies
225
+ ), 'Скрытые разрешения могут зависеть только от скрытых разрешений: ' + name
240
226
  if __debug__:
241
227
  for dependency in dependencies:
242
228
  if name == dependency:
243
- raise AssertionError(
244
- 'Permission {} can''t depend on itself'
245
- .format(dependency)
246
- )
229
+ raise AssertionError('Permission {} cant depend on itself'.format(dependency))
247
230
  if dependency not in self.permissions_by_name:
248
- raise AssertionError(
249
- 'Permission {} not found'.format(dependency)
250
- )
231
+ raise AssertionError('Permission {} not found'.format(dependency))
251
232
 
252
233
  self.permission_dependencies[name].update(dependencies)
253
234
 
@@ -271,10 +252,7 @@ class RBACManager:
271
252
  with Lock(settings.DEFAULT_DB_ALIAS, 'rbac_lock'):
272
253
  permissions_changed = False
273
254
 
274
- permissions = {
275
- permission.name: permission
276
- for permission in Permission.objects.iterator()
277
- }
255
+ permissions = {permission.name: permission for permission in Permission.objects.iterator()}
278
256
 
279
257
  for params in self.permissions_by_name.items():
280
258
  name, (title, description) = params
@@ -307,9 +285,7 @@ class RBACManager:
307
285
  for dependency in self.permission_dependencies[name]:
308
286
  if dependency not in _result:
309
287
  _result.add(dependency)
310
- _result.update(
311
- self.get_dependent_permissions(dependency, _result)
312
- )
288
+ _result.update(self.get_dependent_permissions(dependency, _result))
313
289
 
314
290
  if primary_name:
315
291
  _result.remove(primary_name)
@@ -351,6 +327,7 @@ class RBACManager:
351
327
 
352
328
  @cached_property
353
329
  def _backend(self):
330
+ """Инициализирует и возвращает выбранный бэкенд RBAC."""
354
331
  backend_name = getattr(settings, 'RBAC_BACKEND', None) or (
355
332
  __name__.rpartition('.')[0] + '.backends.caching.CachingBackend'
356
333
  )
@@ -359,18 +336,12 @@ class RBACManager:
359
336
  try:
360
337
  module = import_module(module_name)
361
338
  except ImportError as e:
362
- raise ImproperlyConfigured(
363
- 'Error importing RBAC backend module {}: "{}"'
364
- .format(module_name, e)
365
- )
339
+ raise ImproperlyConfigured('Error importing RBAC backend module {}: "{}"'.format(module_name, e))
366
340
 
367
341
  try:
368
342
  backend_class = getattr(module, class_name)
369
343
  except AttributeError:
370
- raise ImproperlyConfigured(
371
- 'Module "{}" does not define a RBAC backend "{}"'
372
- .format(module, class_name)
373
- )
344
+ raise ImproperlyConfigured('Module "{}" does not define a RBAC backend "{}"'.format(module, class_name))
374
345
  else:
375
346
  backend = backend_class(self)
376
347
 
@@ -5,7 +5,6 @@ from django.db import (
5
5
 
6
6
 
7
7
  class Migration(migrations.Migration):
8
-
9
8
  dependencies = [
10
9
  ('contenttypes', '0001_initial'),
11
10
  ]
@@ -15,9 +14,23 @@ class Migration(migrations.Migration):
15
14
  name='Permission',
16
15
  fields=[
17
16
  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
18
- ('name', models.CharField(unique=True, max_length=100, verbose_name='\u0418\u043c\u044f', db_index=True)),
19
- ('title', models.CharField(max_length=200, null=True, verbose_name='\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435', blank=True)),
20
- ('description', models.TextField(verbose_name='\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435', blank=True)),
17
+ (
18
+ 'name',
19
+ models.CharField(unique=True, max_length=100, verbose_name='\u0418\u043c\u044f', db_index=True),
20
+ ),
21
+ (
22
+ 'title',
23
+ models.CharField(
24
+ max_length=200,
25
+ null=True,
26
+ verbose_name='\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435',
27
+ blank=True,
28
+ ),
29
+ ),
30
+ (
31
+ 'description',
32
+ models.TextField(verbose_name='\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435', blank=True),
33
+ ),
21
34
  ],
22
35
  options={
23
36
  'verbose_name': '\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435',
@@ -29,9 +42,26 @@ class Migration(migrations.Migration):
29
42
  name='Role',
30
43
  fields=[
31
44
  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
32
- ('name', models.CharField(unique=True, max_length=300, verbose_name='\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435', db_index=True)),
33
- ('description', models.TextField(verbose_name='\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435', blank=True)),
34
- ('can_be_assigned', models.BooleanField(default=True, verbose_name='\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e')),
45
+ (
46
+ 'name',
47
+ models.CharField(
48
+ unique=True,
49
+ max_length=300,
50
+ verbose_name='\u041d\u0430\u0437\u0432\u0430\u043d\u0438\u0435',
51
+ db_index=True,
52
+ ),
53
+ ),
54
+ (
55
+ 'description',
56
+ models.TextField(verbose_name='\u041e\u043f\u0438\u0441\u0430\u043d\u0438\u0435', blank=True),
57
+ ),
58
+ (
59
+ 'can_be_assigned',
60
+ models.BooleanField(
61
+ default=True,
62
+ verbose_name='\u041c\u043e\u0436\u0435\u0442 \u0431\u044b\u0442\u044c \u043d\u0430\u0437\u043d\u0430\u0447\u0435\u043d\u0430 \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044e',
63
+ ),
64
+ ),
35
65
  ],
36
66
  options={
37
67
  'verbose_name': '\u0420\u043e\u043b\u044c',
@@ -56,8 +86,20 @@ class Migration(migrations.Migration):
56
86
  name='RolePermission',
57
87
  fields=[
58
88
  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
59
- ('permission', models.ForeignKey(verbose_name='\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435', to='rbac.Permission', on_delete=models.CASCADE)),
60
- ('role', models.ForeignKey(verbose_name='\u0420\u043e\u043b\u044c', to='rbac.Role', on_delete=models.CASCADE)),
89
+ (
90
+ 'permission',
91
+ models.ForeignKey(
92
+ verbose_name='\u0420\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u0435',
93
+ to='rbac.Permission',
94
+ on_delete=models.CASCADE,
95
+ ),
96
+ ),
97
+ (
98
+ 'role',
99
+ models.ForeignKey(
100
+ verbose_name='\u0420\u043e\u043b\u044c', to='rbac.Role', on_delete=models.CASCADE
101
+ ),
102
+ ),
61
103
  ],
62
104
  options={
63
105
  'db_table': 'rbac_role_permissions',
@@ -71,10 +113,29 @@ class Migration(migrations.Migration):
71
113
  fields=[
72
114
  ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)),
73
115
  ('object_id', models.PositiveIntegerField()),
74
- ('date_from', models.DateField(null=True, verbose_name='\u041d\u0430\u0447\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430', blank=True)),
75
- ('date_to', models.DateField(null=True, verbose_name='\u041a\u043e\u043d\u0435\u0446 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430', blank=True)),
116
+ (
117
+ 'date_from',
118
+ models.DateField(
119
+ null=True,
120
+ verbose_name='\u041d\u0430\u0447\u0430\u043b\u043e \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430',
121
+ blank=True,
122
+ ),
123
+ ),
124
+ (
125
+ 'date_to',
126
+ models.DateField(
127
+ null=True,
128
+ verbose_name='\u041a\u043e\u043d\u0435\u0446 \u0438\u043d\u0442\u0435\u0440\u0432\u0430\u043b\u0430',
129
+ blank=True,
130
+ ),
131
+ ),
76
132
  ('content_type', models.ForeignKey(to='contenttypes.ContentType', on_delete=models.CASCADE)),
77
- ('role', models.ForeignKey(verbose_name='\u0420\u043e\u043b\u044c', to='rbac.Role', on_delete=models.CASCADE)),
133
+ (
134
+ 'role',
135
+ models.ForeignKey(
136
+ verbose_name='\u0420\u043e\u043b\u044c', to='rbac.Role', on_delete=models.CASCADE
137
+ ),
138
+ ),
78
139
  ],
79
140
  options={
80
141
  'verbose_name': '\u0420\u043e\u043b\u044c \u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u0442\u0435\u043b\u044f',
@@ -5,18 +5,19 @@ from django.db import (
5
5
 
6
6
 
7
7
  class Migration(migrations.Migration):
8
-
9
- dependencies = [('rbac', '0001_initial'), ]
8
+ dependencies = [
9
+ ('rbac', '0001_initial'),
10
+ ]
10
11
 
11
12
  operations = [
12
13
  migrations.AlterField(
13
14
  model_name='userrole',
14
15
  name='date_from',
15
- field=models.DateField(
16
- blank=True, null=True, verbose_name='Действует с'), ),
16
+ field=models.DateField(blank=True, null=True, verbose_name='Действует с'),
17
+ ),
17
18
  migrations.AlterField(
18
19
  model_name='userrole',
19
20
  name='date_to',
20
- field=models.DateField(
21
- blank=True, null=True, verbose_name='по'), ),
21
+ field=models.DateField(blank=True, null=True, verbose_name='по'),
22
+ ),
22
23
  ]
@@ -5,7 +5,6 @@ from django.db import (
5
5
 
6
6
 
7
7
  class Migration(migrations.Migration):
8
-
9
8
  dependencies = [
10
9
  ('rbac', '0002_model_modifier_metaclass_fix'),
11
10
  ]
@@ -14,9 +13,6 @@ class Migration(migrations.Migration):
14
13
  migrations.AddField(
15
14
  model_name='permission',
16
15
  name='hidden',
17
- field=models.BooleanField(
18
- default=False,
19
- verbose_name='Видимость пользователям'
20
- ),
16
+ field=models.BooleanField(default=False, verbose_name='Видимость пользователям'),
21
17
  ),
22
18
  ]
@@ -8,7 +8,6 @@ from django.db import (
8
8
 
9
9
 
10
10
  class Migration(migrations.Migration):
11
-
12
11
  dependencies = [
13
12
  ('contenttypes', '0002_remove_content_type_name'),
14
13
  ('rbac', '0003_permission_hidden'),
@@ -18,26 +17,31 @@ class Migration(migrations.Migration):
18
17
  migrations.CreateModel(
19
18
  name='RoleUserType',
20
19
  fields=[
21
- ('id', models.AutoField(
22
- auto_created=True,
23
- primary_key=True,
24
- serialize=False,
25
- verbose_name='ID')),
26
- ('role', models.ForeignKey(
27
- on_delete=django.db.models.deletion.CASCADE,
28
- related_name='+',
29
- to='rbac.Role',
30
- verbose_name='Роль')),
31
- ('user_type', models.ForeignKey(
32
- on_delete=django.db.models.deletion.CASCADE,
33
- related_name='+',
34
- to='contenttypes.ContentType',
35
- verbose_name='Тип пользователя')),
20
+ ('id', models.AutoField(auto_created=True, primary_key=True, serialize=False, verbose_name='ID')),
21
+ (
22
+ 'role',
23
+ models.ForeignKey(
24
+ on_delete=django.db.models.deletion.CASCADE,
25
+ related_name='+',
26
+ to='rbac.Role',
27
+ verbose_name='Роль',
28
+ ),
29
+ ),
30
+ (
31
+ 'user_type',
32
+ models.ForeignKey(
33
+ on_delete=django.db.models.deletion.CASCADE,
34
+ related_name='+',
35
+ to='contenttypes.ContentType',
36
+ verbose_name='Тип пользователя',
37
+ ),
38
+ ),
36
39
  ],
37
40
  options={
38
41
  'verbose_name': 'Тип пользователя роли',
39
42
  'verbose_name_plural': 'Типы пользователей ролей',
40
- }, ),
43
+ },
44
+ ),
41
45
  migrations.AlterModelManagers(
42
46
  name='userrole',
43
47
  managers=[
@@ -52,8 +56,11 @@ class Migration(migrations.Migration):
52
56
  related_name='_role_user_types_+',
53
57
  through='rbac.RoleUserType',
54
58
  to='contenttypes.ContentType',
55
- verbose_name='Может быть назначена'), ),
59
+ verbose_name='Может быть назначена',
60
+ ),
61
+ ),
56
62
  migrations.AlterUniqueTogether(
57
63
  name='roleusertype',
58
- unique_together=set([('role', 'user_type')]), ),
64
+ unique_together=set([('role', 'user_type')]),
65
+ ),
59
66
  ]