brilliance-admin 0.44.16__py3-none-any.whl → 0.44.18__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.
@@ -1,3 +1,4 @@
1
+ import inspect
1
2
  from typing import Callable
2
3
 
3
4
  from brilliance_admin.auth import AdminAuthentication, AuthData, AuthResult, UserABC, UserResult
@@ -14,7 +15,7 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
14
15
  user_model = None
15
16
  pk_name = None
16
17
 
17
- password_validator: Callable[[UserABC, str], bool] | None = None
18
+ password_validator = None
18
19
 
19
20
  def __init__(self, secret: str, db_async_session, user_model, pk_name='id', password_validator=None):
20
21
  self.pk_name = pk_name
@@ -76,14 +77,19 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
76
77
 
77
78
  try:
78
79
  if self.password_validator:
79
- if not self.password_validator(user, data.password):
80
+ if inspect.iscoroutinefunction(self.password_validator):
81
+ valid_password = await self.password_validator(user, data.password)
82
+ else:
83
+ valid_password = self.password_validator(user, data.password)
84
+
85
+ if not valid_password:
80
86
  raise AdminAPIException(APIError(code="user_not_found"), status_code=401)
81
87
 
82
88
  except AdminAPIException as e:
83
89
  raise e
84
90
  except Exception as e:
85
91
  msg = _('errors.password_exception') % {
86
- 'error_type': str(e) if schema.debug else type(e).__name__,
92
+ 'error_type': str(e) if debug else type(e).__name__,
87
93
  }
88
94
  raise AdminAPIException(APIError(message=msg, code="password_exception"), status_code=500) from e
89
95
 
@@ -15,7 +15,6 @@ errors:
15
15
  filters_exception: 'An unknown technical error occurred while filtering data: %(error_type)s'
16
16
  method_not_allowed: 'Error, method not allowed. This action is not permitted.'
17
17
  filter_error: 'An error occurred during filtering: {error}'
18
- bad_type_error: 'Invalid data type: %(type)s but %(expected)s expected'
19
18
 
20
19
  serialize_error:
21
20
  field_error: 'Field %(field_slug)s serialize error: %(error)s'
@@ -30,3 +29,16 @@ sqlalchemy_search_help: |
30
29
  <b>""</b> - quotes for exact match
31
30
  <b>%%</b> - any sequence of characters
32
31
  <b>_</b> - any single character
32
+
33
+ password:
34
+ new_password: 'New password'
35
+ change_password: 'Change password'
36
+ password_changed: 'Password successfully updated'
37
+
38
+ validation:
39
+ bad_type_error: 'Invalid data type: %(type)s but %(expected)s expected'
40
+ min_value_error: 'Value must be at least %(min)s'
41
+ max_value_error: 'Value must be at most %(max)s'
42
+ min_length_error: 'Length must be at least %(min)s characters'
43
+ max_length_error: 'Length must be at most %(max)s characters'
44
+
@@ -11,13 +11,12 @@ errors:
11
11
  db_error_retrieve: 'Ошибка получения записи из базы данных: %(error_type)s'
12
12
  db_error_list: 'Ошибка получения данных таблицы из базы данных: %(error_type)s'
13
13
 
14
- password_exception: 'Произошла неизвестная ошибка при проверке пароля: %(error_type)s'
15
-
16
14
  connection_refused_error: 'Ошибка подключения к базе данных: %(error)s'
17
15
  filters_exception: 'Произошла неизвестная техническая ошибка при фильтрации данных: %(error_type)s'
18
16
  method_not_allowed: 'Ошибка, данный метод недоступен.'
19
17
  filter_error: 'Проишла ошибка при фильтрации: %(error)s'
20
- bad_type_error: 'Некорректный тип данных: %(type)s; ожидается %(expected)s'
18
+
19
+ password_exception: 'Произошла неизвестная ошибка при проверке пароля: %(error_type)s'
21
20
 
22
21
  serialize_error:
23
22
  field_error: 'ошибка чтения поля %(field_slug)s: %(error)s'
@@ -32,3 +31,15 @@ sqlalchemy_search_help: |
32
31
  <b>""</b> - кавычки для точного совпадения
33
32
  <b>%%</b> - любая последовательность символов
34
33
  <b>_</b> - один любой символ
34
+
35
+ password:
36
+ new_password: 'Новый пароль'
37
+ change_password: 'Изменить пароль'
38
+ password_changed: 'Пароль успешно обновлен'
39
+
40
+ validation:
41
+ bad_type_error: 'Некорректный тип данных: %(type)s; ожидается %(expected)s'
42
+ min_value_error: 'Значение должно быть не меньше %(min)s'
43
+ max_value_error: 'Значение должно быть не больше %(max)s'
44
+ min_length_error: 'Длина должна быть не меньше %(min)s символов'
45
+ max_length_error: 'Длина должна быть не больше %(max)s символов'
@@ -30,6 +30,7 @@ class FieldSchemaData(DataclassBase):
30
30
 
31
31
  max_length: int | None = None
32
32
  min_length: int | None = None
33
+ password: bool | None = None
33
34
 
34
35
  choices: List[dict] | None = None
35
36
 
@@ -81,7 +81,18 @@ class IntegerField(TableField):
81
81
  async def deserialize(self, value, action: DeserializeAction, extra: dict, *args, **kwargs) -> Any:
82
82
  value = await super().deserialize(value, action, extra, *args, **kwargs)
83
83
  if value and not isinstance(value, int):
84
- raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'init'})
84
+ raise FieldError(_('validation.bad_type_error') % {'type': type(value), 'expected': 'init'})
85
+
86
+ if value is None:
87
+ if self.min_value is not None:
88
+ raise FieldError(_('validation.min_value_error') % {'min': self.min_value})
89
+ return
90
+
91
+ if self.min_value is not None and value < self.min_value:
92
+ raise FieldError(_('validation.min_value_error') % {'min': self.min_value})
93
+
94
+ if self.max_value is not None and value > self.max_value:
95
+ raise FieldError(_('validation.max_value_error') % {'max': self.max_value})
85
96
 
86
97
  return value
87
98
 
@@ -96,6 +107,7 @@ class StringField(TableField):
96
107
 
97
108
  min_length: int | None = None
98
109
  max_length: int | None = None
110
+ password: bool | None = False
99
111
 
100
112
  choices: Any | None = None
101
113
 
@@ -105,6 +117,7 @@ class StringField(TableField):
105
117
  schema.multilined = self.multilined
106
118
  schema.ckeditor = self.ckeditor
107
119
  schema.tinymce = self.tinymce
120
+ schema.password = self.password
108
121
 
109
122
  if self.min_length is not None:
110
123
  schema.min_length = self.min_length
@@ -117,7 +130,18 @@ class StringField(TableField):
117
130
  async def deserialize(self, value, action: DeserializeAction, extra: dict, *args, **kwargs) -> Any:
118
131
  value = await super().deserialize(value, action, extra, *args, **kwargs)
119
132
  if value and not isinstance(value, str):
120
- raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'string'})
133
+ raise FieldError(_('validation.bad_type_error') % {'type': type(value), 'expected': 'string'})
134
+
135
+ if value is None:
136
+ if self.min_length is not None and self.min_length > 0:
137
+ raise FieldError(_('validation.min_length_error') % {'min': self.min_length})
138
+ return
139
+
140
+ if self.min_length is not None and len(value) < self.min_length:
141
+ raise FieldError(_('validation.min_length_error') % {'min': self.min_length})
142
+
143
+ if self.max_length is not None and len(value) > self.max_length:
144
+ raise FieldError(_('validation.max_length_error') % {'max': self.max_length})
121
145
 
122
146
  return value
123
147
 
@@ -164,7 +188,7 @@ class DateTimeField(TableField):
164
188
  return
165
189
 
166
190
  if value and not isinstance(value, (str, dict)):
167
- raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'datetime'})
191
+ raise FieldError(_('validation.bad_type_error') % {'type': type(value), 'expected': 'datetime'})
168
192
 
169
193
  if isinstance(value, str):
170
194
  return _parse_iso(value)
@@ -180,7 +204,7 @@ class DateTimeField(TableField):
180
204
  'to': _parse_iso(value['to']),
181
205
  }
182
206
 
183
- raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'datetime'})
207
+ raise FieldError(_('validation.bad_type_error') % {'type': type(value), 'expected': 'datetime'})
184
208
 
185
209
 
186
210
  @dataclass
@@ -194,7 +218,7 @@ class JSONField(TableField):
194
218
  return
195
219
 
196
220
  if not isinstance(value, (dict, list)):
197
- raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'JSON'})
221
+ raise FieldError(_('validation.bad_type_error') % {'type': type(value), 'expected': 'JSON'})
198
222
 
199
223
  return value
200
224
 
@@ -219,7 +243,7 @@ class ArrayField(TableField):
219
243
  return
220
244
 
221
245
  if not isinstance(value, list):
222
- raise FieldError(_('errors.bad_type_error') % {'type': type(value), 'expected': 'Array'})
246
+ raise FieldError(_('validation.bad_type_error') % {'type': type(value), 'expected': 'Array'})
223
247
 
224
248
  return value
225
249
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brilliance-admin
3
- Version: 0.44.16
3
+ Version: 0.44.18
4
4
  Summary: Simple and lightweight data managment framework powered by FastAPI and Vue3 Vuetify all-in-one. Some call it heavenly in its brilliance.
5
5
  License-Expression: MIT
6
6
  Requires-Python: >=3.10
@@ -17,7 +17,7 @@ brilliance_admin/api/views/settings.py,sha256=2A9suZQONEtW9LkFban29Fe5ipQaaGT0Cz
17
17
  brilliance_admin/api/views/table.py,sha256=dLo_ic9LPeAvkeelbkHZs9oC9g9ZlXPPMiQMszlwDIQ,5979
18
18
  brilliance_admin/integrations/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
19
  brilliance_admin/integrations/sqlalchemy/__init__.py,sha256=AmQHOvegS6_uaE4xYDHzRMdA9PyHn0cCt1s1IWc9G2U,318
20
- brilliance_admin/integrations/sqlalchemy/auth.py,sha256=nvTZd1HW-2_vs672ohcbWLP8pA2bHDXd66tuEkD-2f0,5853
20
+ brilliance_admin/integrations/sqlalchemy/auth.py,sha256=X8AfmGCV9bZnYk61rGJ6Gcy8NUcHyKn0vXylG2QqylE,6058
21
21
  brilliance_admin/integrations/sqlalchemy/autocomplete.py,sha256=IKZwdjb5tM_pA5PBUhwYo4n_8nEfy_WcSu8Yu4ftarI,1572
22
22
  brilliance_admin/integrations/sqlalchemy/fields.py,sha256=7D0E4-12rqraqHek2yNuHzRdO7hhxjp0edhJu-mTnWQ,9897
23
23
  brilliance_admin/integrations/sqlalchemy/fields_schema.py,sha256=7WkOrt5dVvrsZppNZEZS8QaQPMSrfcWChwOaOFSRVOg,11419
@@ -28,11 +28,11 @@ brilliance_admin/integrations/sqlalchemy/table/delete.py,sha256=kcDEM7WDNu3lFdfd
28
28
  brilliance_admin/integrations/sqlalchemy/table/list.py,sha256=Y76B5CFqQb2nfV0i0MrMrK3_kn9cyDvx10gEF8smrIA,8008
29
29
  brilliance_admin/integrations/sqlalchemy/table/retrieve.py,sha256=EKwGH8Mz3Jd-uR43WibD3hFiZVGK_ra_5Cu5XeoEf6Y,3508
30
30
  brilliance_admin/integrations/sqlalchemy/table/update.py,sha256=NxcYPqRZbm_BM-4QHzEbhgAhYSs3SXzYMMzKCalqahU,3800
31
- brilliance_admin/locales/en.yml,sha256=YBjkq2Tm0KjXKOMgnIM5etO42Pkm8mDdQlvmpITwsA4,1453
32
- brilliance_admin/locales/ru.yml,sha256=__reAnXeIo3KDqiyAxL4xp4rbsclWcYS002sK8iRAps,2185
31
+ brilliance_admin/locales/en.yml,sha256=SQhYlcOYgzmCOvSWWSjIvvH5qXBFU2H_9eOn8iBA6Ls,1830
32
+ brilliance_admin/locales/ru.yml,sha256=36LBcm4Y90yqyeQeU1EHMvIMRZ07zLh49k_wGsMVK88,2737
33
33
  brilliance_admin/schema/__init__.py,sha256=H5UFO5dub_k5id8WdGRVy9G8RnqZuBSjw9XgPafj1VQ,293
34
34
  brilliance_admin/schema/admin_schema.py,sha256=SGdNuYUKrwAc6SA4RYh8TgSrod5RuY7lpXKzmY1SHZ4,6812
35
- brilliance_admin/schema/category.py,sha256=UTnUexbCHe9vfwi3ygX34YkLAH2ixfMWqe4H6xos0fI,6604
35
+ brilliance_admin/schema/category.py,sha256=viJ_BsP5_5NHu7KlOG4MTzhKIDPlQ1e0ByYXQ0XvKC0,6637
36
36
  brilliance_admin/schema/dashboard/__init__.py,sha256=RxE5nNs5X3iWGXBOA518hFyJMSRLEcXr0PNb8HZrjxs,50
37
37
  brilliance_admin/schema/dashboard/category_dashboard.py,sha256=rsEuWLpcfcrnzMeKIQCMFDYNF9H7LEfqEKlm63Sh7PE,2650
38
38
  brilliance_admin/schema/table/__init__.py,sha256=vuRw8HBuak2LaTZi2dNn5YOrJPalQps-O3Ht-d0AZV4,378
@@ -41,7 +41,7 @@ brilliance_admin/schema/table/category_table.py,sha256=5QQISkIxOeNU-58r9UmiszrFV
41
41
  brilliance_admin/schema/table/fields_schema.py,sha256=2D4J2FAFupOsE0YWLn1reB0LT5KJOygvJHJnajPCe6U,8475
42
42
  brilliance_admin/schema/table/table_models.py,sha256=xidraifRYbXGkiVLn6dJ96dkOhW8-22ynE-fbiOjfAU,1018
43
43
  brilliance_admin/schema/table/fields/__init__.py,sha256=RW-sIFTAaSQo4mMR6iWtnefogWPjmg6KAsDwe9mKW1k,291
44
- brilliance_admin/schema/table/fields/base.py,sha256=rSVTsY1ph9ix33NiPslDjPjnwWvHwNtvt90FAByE4mQ,10243
44
+ brilliance_admin/schema/table/fields/base.py,sha256=A7zphmRtlYjzfnLg8viM780Rio1opbNvaWcxF4W_jLM,11368
45
45
  brilliance_admin/schema/table/fields/function_field.py,sha256=N9BB-4JoVfIY3tvVgLaDTw16u87Tu2rHUk-aGDYuB1U,1780
46
46
  brilliance_admin/static/index-EybvSE2q.js,sha256=_SbWHCYCzHTGnmqkXsqpMLtBIGP1KbA5hLEulqvJb9A,3210050
47
47
  brilliance_admin/static/index-wIukkQjw.css,sha256=u0BgR_BRor31z8igNlSBRxStdSCV1FgEZY1_ytCz23E,984450
@@ -66,8 +66,8 @@ brilliance_admin/static/tinymce/plugins/codesample/css/prism.css,sha256=exAdMtHb
66
66
  brilliance_admin/static/tinymce/plugins/customLink/plugin.js,sha256=illBNpnHDkBsLG6wo_jDPF6z7CGnO1MQWUoDwZKy6vQ,5589
67
67
  brilliance_admin/static/tinymce/plugins/customLink/css/link.css,sha256=gh5nvY8Z92hJfCEBPnIm4jIPCcKKbJnab-30oIfX7Hc,56
68
68
  brilliance_admin/templates/index.html,sha256=RKvUZ386hjV5EV09vneHhFY3BrwmMsTsm9wUpPV7D08,1294
69
- brilliance_admin-0.44.16.dist-info/licenses/LICENSE,sha256=rgWE5Cxk53W0PhTOVmcQedABEWN1QMG-PRz3fz531sE,1074
70
- brilliance_admin-0.44.16.dist-info/METADATA,sha256=dEpRtxx5sqZksbv5YHyZlyTL2SI5Xg9ShTzNK29MvRE,7449
71
- brilliance_admin-0.44.16.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
72
- brilliance_admin-0.44.16.dist-info/top_level.txt,sha256=almFFSWrVYieI3i54hYL0fMUaeuIYiazS2Kx4wtK-ns,17
73
- brilliance_admin-0.44.16.dist-info/RECORD,,
69
+ brilliance_admin-0.44.18.dist-info/licenses/LICENSE,sha256=rgWE5Cxk53W0PhTOVmcQedABEWN1QMG-PRz3fz531sE,1074
70
+ brilliance_admin-0.44.18.dist-info/METADATA,sha256=NXVoddBfffAAhcstivaSpmcfv-Vom0sy9UAHYbPh9XY,7449
71
+ brilliance_admin-0.44.18.dist-info/WHEEL,sha256=wUyA8OaulRlbfwMtmQsvNngGrxQHAvkKcvRmdizlJi0,92
72
+ brilliance_admin-0.44.18.dist-info/top_level.txt,sha256=almFFSWrVYieI3i54hYL0fMUaeuIYiazS2Kx4wtK-ns,17
73
+ brilliance_admin-0.44.18.dist-info/RECORD,,