py.lib.aw_web_tools

Yohn Y. 2025-10-15 Parent:74f5377d83ab Child:c53a61e27af8

14:0920ae304dfd Go to Latest

py.lib.aw_web_tools/src/aw_web_tools/authelia_helper.py

.. 1.202510.1 + Режим фековой авторизации для адаптера authelia. Режим требуется для отладки, поскольку вряд ли на машине разработчика будет развёрнуто это ПО на ранних стадиях разработки (преальфа). Возможно режим будет полезен при поиска проблем в приложении при авторизации.

History
1 # coding: utf-8
2 """\
3 Поддержка работы с системой авторизации [authelia](https://www.authelia.com/)
4 """
5 import bottle
6 from typing import Optional, List
7 from collections import namedtuple
9 from . import Error
12 # Константы
13 HEADER_USER = 'Remote-User' # Заголовок по умолчанию, в котором система аутентификации передаёт имя УЗ пользователя
14 HEADER_GROUPS = 'Remote-Groups' # Заголовок по умолчанию, в котором система аутентификации передаёт группы пользовтеля
15 HEADER_EMAIL = 'Remote-Email' # Заголовок по умолчанию, в котором система аутентификации передаёт e-mail пользователя
16 HEADER_NAME = 'Remote-Name' # Заголовок по умолчанию, в котором система аутентификации передаёт имя пользователя
19 class AHError(Error):
20 """\
21 Базовый класс исключений модуля адаптера Authelia
22 """
25 class AHAuthError(AHError):
26 """\
27 Проблемы с авторизацией пользователя
28 """
29 def __init__(self):
30 super().__init__('Пользователь не авторизован')
33 AHUser = namedtuple('AHUser', ['uname', 'groups', 'email', 'name'])
36 class AutheliaHelper(object):
37 def __init__(self,
38 group_filter: Optional[List[str]] = None,
39 header_user: str = HEADER_USER,
40 header_groups: str = HEADER_GROUPS,
41 header_email: str = HEADER_EMAIL,
42 header_name: str = HEADER_NAME,
43 fake_auth: bool = False
44 ):
45 """\
46 :param group_filter: Фильтр передаваемый системой аутентификации групп, которые интересны нам. Если ``None``
47 группы, передаваемые в заголовке не фильтруются
48 :param header_user: Имя заголовка с именем УЗ пользователя.
49 :param header_groups: Имя заголовка с группами пользователя
50 :param header_email: Имя заголовка c e-mail пользователя
51 :param header_name: Имя заголовка с именем пользователя
52 :param fake_auth: Режим без авторизации. Создаётся для отладки или решения проблем с авторизацией.
53 Не проводит авторизацию по заголовкам, а вместо этого подставляет заранее заданные значения.
54 """
55 self.header_user = header_user
56 self.header_groups = header_groups
57 self.header_email = header_email
58 self.header_name = header_name
59 self.fake_auth = fake_auth
61 self.group_filter = None
62 self.group_filter_set = None
63 if group_filter is not None:
64 self.group_filter = {}
65 for i in group_filter:
66 self.group_filter[i.lower()] = i
68 self.group_filter_set = set(self.group_filter.keys())
70 def __call__(self, request: bottle.BaseRequest = bottle.request) -> AHUser:
71 """\
72 Обработка запроса. Если заголовки системы авторизации присутствуют, информацией из них заполняется
73 объект ``AHUser``. Если данные не найдены, то будет возбуждено исключение.
75 :param request: Обрабатываемый запрос
76 :returns: Объект ``AHUser`` с данным авторизации.
77 """
79 if self.fake_auth:
80 return AHUser(uname='__UNK__', groups=[], name='John Doe', email='devnull@localhost.localdomain')
82 uname = request.get_header(self.header_user)
83 email = request.get_header(self.header_email)
84 name = request.get_header(self.header_name)
85 groups = request.get_header(self.header_groups)
87 if uname is None:
88 raise AHAuthError()
90 if groups is not None:
91 groups = tuple(map(lambda x: x.stip(), groups.split(',')))
92 if self.group_filter is not None:
93 _groups = []
94 _buf = set(map(lambda x: x.lower(), groups))
96 for grp in _buf & self.group_filter_set:
97 try:
98 _groups.append(self.group_filter[grp])
100 except KeyError:
101 AHError(f'Ошибка в фильтре групп. Для ключа "{grp}" не нашлось значения, хотя оно присутствует '
102 f'в множестве возможных значений.')
104 return AHUser(uname=uname, groups=groups, name=name, email=email)