py.lib.aw_web_tools

Yohn Y. 2025-10-15 Parent:0920ae304dfd Child:c53a61e27af8

15:645c171efc96 Go to Latest

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

* Изменения в системе сборки пакетов Python

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