brilliance-admin 0.44.14__py3-none-any.whl → 0.44.16__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.
@@ -22,7 +22,7 @@ async def login(request: Request, auth_data: AuthData) -> AuthResult:
22
22
 
23
23
  auth: AdminAuthentication = schema.auth
24
24
  try:
25
- result: AuthResult = await auth.login(auth_data)
25
+ result: AuthResult = await auth.login(auth_data, debug=schema.debug)
26
26
  except AdminAPIException as e:
27
27
  return JSONResponse(e.get_error().model_dump(mode='json', context=context), status_code=e.status_code)
28
28
 
brilliance_admin/auth.py CHANGED
@@ -25,7 +25,7 @@ class AuthResult(BaseModel):
25
25
 
26
26
 
27
27
  class AdminAuthentication(abc.ABC):
28
- async def login(self, data: AuthData) -> AuthResult:
28
+ async def login(self, data: AuthData, debug: bool = False) -> AuthResult:
29
29
  raise NotImplementedError('Login is not implemented')
30
30
 
31
31
  async def authenticate(self, headers: dict) -> UserABC:
@@ -1,3 +1,5 @@
1
+ from typing import Callable
2
+
1
3
  from brilliance_admin.auth import AdminAuthentication, AuthData, AuthResult, UserABC, UserResult
2
4
  from brilliance_admin.exceptions import AdminAPIException, APIError
3
5
  from brilliance_admin.translations import TranslateText as _
@@ -12,11 +14,18 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
12
14
  user_model = None
13
15
  pk_name = None
14
16
 
15
- def __init__(self, secret: str, db_async_session, user_model, pk_name='id'):
17
+ password_validator: Callable[[UserABC, str], bool] | None = None
18
+
19
+ def __init__(self, secret: str, db_async_session, user_model, pk_name='id', password_validator=None):
16
20
  self.pk_name = pk_name
17
21
  self.secret = secret
18
22
  self.db_async_session = db_async_session
19
23
  self.user_model = user_model
24
+ self.password_validator = password_validator
25
+
26
+ if self.password_validator:
27
+ if not callable(self.password_validator):
28
+ raise ValueError("password_validator must be callable")
20
29
 
21
30
  if not isinstance(secret, str) or not secret:
22
31
  raise ValueError("JWT secret must be a non-empty string")
@@ -41,7 +50,7 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
41
50
  msg = f"user_model is missing required columns: {', '.join(sorted(missing))}"
42
51
  raise ValueError(msg)
43
52
 
44
- async def login(self, data: AuthData) -> AuthResult:
53
+ async def login(self, data: AuthData, debug: bool = False) -> AuthResult:
45
54
  # pylint: disable=import-outside-toplevel
46
55
  from sqlalchemy import select
47
56
 
@@ -65,6 +74,19 @@ class SQLAlchemyJWTAdminAuthentication(AdminAuthentication):
65
74
  if not user:
66
75
  raise AdminAPIException(APIError(code="user_not_found"), status_code=401)
67
76
 
77
+ try:
78
+ if self.password_validator:
79
+ if not self.password_validator(user, data.password):
80
+ raise AdminAPIException(APIError(code="user_not_found"), status_code=401)
81
+
82
+ except AdminAPIException as e:
83
+ raise e
84
+ except Exception as e:
85
+ msg = _('errors.password_exception') % {
86
+ 'error_type': str(e) if schema.debug else type(e).__name__,
87
+ }
88
+ raise AdminAPIException(APIError(message=msg, code="password_exception"), status_code=500) from e
89
+
68
90
  if not user.is_admin:
69
91
  raise AdminAPIException(APIError(code="not_an_admin"), status_code=401)
70
92
 
@@ -11,6 +11,8 @@ 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
+
14
16
  connection_refused_error: 'Ошибка подключения к базе данных: %(error)s'
15
17
  filters_exception: 'Произошла неизвестная техническая ошибка при фильтрации данных: %(error_type)s'
16
18
  method_not_allowed: 'Ошибка, данный метод недоступен.'