py.lib

Yohn Y. 2022-08-14 Parent:1668cc57225b

34:84b54a8a6d4c Go to Latest

py.lib/ldap_utils/ldap_util.py

+ Возможность обработки параметров конфигурации перед добавлением в класс конфигурации . Переформатирование части кода по PEP

History
awgur@3 1 # coding: utf-8
awgur@3 2 import ldap
awgur@3 3
awgur@3 4 # ===========================================================
awgur@23 5 # Статус завершения операций
awgur@3 6 STATUS_OK = 0 # Всё ОК.
awgur@3 7 STATUS_BADAUTH = 1 # Не верные пользователь или пароль.
awgur@3 8 STATUS_SERVERDOWN = 2 # Сервер не доступен.
awgur@3 9 STATUS_SERVERERROR = 3 # Ошибка при взаимодействии с сервером.
awgur@3 10
awgur@23 11
awgur@23 12 class LdapError(Exception):
awgur@23 13 pass
awgur@23 14
awgur@3 15
awgur@3 16 class LdapAuth(object):
awgur@23 17 def __init__(self, server, user_prefix='CORP\\', base_dn='DC=example,DC=net', attr=None):
awgur@23 18 self.server = server
awgur@23 19 self.prefix = user_prefix
awgur@23 20 self.status = ''
awgur@23 21 self.baseDN = base_dn
awgur@23 22 self.status_code = 0
awgur@23 23 self.groups = None
awgur@23 24 self.attr = None
awgur@23 25 self._needAttr = [i for i in map(str, attr)] if attr is not None else []
awgur@23 26
awgur@23 27 def __call__(self, user, passwd):
awgur@23 28 conn = None
awgur@23 29 try:
awgur@23 30 conn = ldap.initialize(self.server)
awgur@23 31 conn.set_option(ldap.OPT_REFERRALS, 0)
awgur@23 32 conn.simple_bind_s(self.prefix + user, passwd)
awgur@23 33
awgur@23 34 except ldap.INVALID_CREDENTIALS:
awgur@23 35 if conn is not None:
awgur@23 36 conn.unbind()
awgur@23 37
awgur@23 38 self.status = 'Invalid credentials'
awgur@23 39 self.status_code = STATUS_BADAUTH
awgur@23 40 return False
awgur@23 41
awgur@23 42 except ldap.SERVER_DOWN:
awgur@23 43 self.status = 'Server is down'
awgur@23 44 self.status_code = STATUS_SERVERDOWN
awgur@23 45 return False
awgur@23 46
awgur@23 47 self.groups = []
awgur@23 48 try:
awgur@23 49 ldap_data = conn.search_s(self.baseDN, ldap.SCOPE_SUBTREE, f'(cn={user})',
awgur@23 50 ['memberOf'] + self._needAttr)[0][1]
awgur@23 51
awgur@23 52 for i in ldap_data['memberOf']:
awgur@23 53 self.groups.append(i.split(',')[0].split('=')[1].decode('utf-8'))
awgur@23 54
awgur@23 55 del ldap_data['memberOf']
awgur@23 56 self.attr = ldap_data
awgur@3 57
awgur@23 58 except KeyError:
awgur@23 59 self.status = 'User object from LDAP is wrong, it can be anonymous logon'
awgur@23 60 self.status_code = STATUS_SERVERERROR
awgur@23 61 return False
awgur@23 62
awgur@23 63 finally:
awgur@23 64 conn.unbind()
awgur@23 65
awgur@23 66 return True
awgur@23 67
awgur@23 68 def __getitem__(self, key):
awgur@23 69 return self.attr[key]
awgur@23 70
awgur@23 71 def member_of(self, group):
awgur@23 72 """Проверка на присутствие у пользователя некоторой группы
awgur@23 73 """
awgur@23 74 if self.groups is None:
awgur@23 75 raise LdapError('Request membership before auth call')
awgur@23 76
awgur@23 77 if not isinstance(group, unicode):
awgur@23 78 if isinstance(group, str):
awgur@23 79 group = group.decode('utf-8')
awgur@23 80 else:
awgur@23 81 group = str(group).decode('utf-8')
awgur@23 82
awgur@23 83 if group in self.groups:
awgur@23 84 return True
awgur@23 85 else:
awgur@23 86 return False
awgur@23 87
awgur@23 88 def __contains__(self, group):
awgur@23 89 return self.member_of(group)
awgur@23 90
awgur@23 91 def member_of_groups(self, groups):
awgur@23 92 if not len(groups) > 0:
awgur@23 93 return False
awgur@23 94
awgur@23 95 for group in groups:
awgur@23 96 if group not in self:
awgur@23 97 return False
awgur@23 98
awgur@23 99 return True