py.lib.aw_web_tools
py.lib.aw_web_tools/src/aw_web_tools/authelia_helper.py
* Ошибка в написании метода
| 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@16 | 91 groups = tuple(map(lambda x: x.strip(), 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) |