py.lib

Yohn Y. 2022-03-07 Parent:1668cc57225b

24:ff755f64cda8 Go to Latest

py.lib/ldap_utils/ldap_util.py

.

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