py.lib
2018-02-25
py.lib/ldapUtil.py
ldapUtil.py
1.1 --- /dev/null Thu Jan 01 00:00:00 1970 +0000 1.2 +++ b/ldapUtil.py Sun Feb 25 17:02:00 2018 +0300 1.3 @@ -0,0 +1,86 @@ 1.4 +# coding: utf-8 1.5 +import ldap 1.6 + 1.7 +# =========================================================== 1.8 +# Статус завершения оперций 1.9 +STATUS_OK = 0 # Всё ОК. 1.10 +STATUS_BADAUTH = 1 # Не верные пользователь или пароль. 1.11 +STATUS_SERVERDOWN = 2 # Сервер не доступен. 1.12 +STATUS_SERVERERROR = 3 # Ошибка при взаимодействии с сервером. 1.13 + 1.14 +class LdapError(Exception): pass 1.15 + 1.16 +class LdapAuth(object): 1.17 + def __init__(self, server, userPrefix = 'CORP\\', baseDN = 'DC=example,DC=net', attr = []): 1.18 + self.server = server 1.19 + self.prefix = userPrefix 1.20 + self.status = '' 1.21 + self.baseDN = baseDN 1.22 + self.statusCode = 0 1.23 + self.groups = None 1.24 + self.attr = None 1.25 + self._needAttr = [ i for i in map(str, attr) ] 1.26 + 1.27 + def __call__(self, user, passwd): 1.28 + try: 1.29 + conn = ldap.initialize(self.server) 1.30 + conn.set_option(ldap.OPT_REFERRALS, 0) 1.31 + conn.simple_bind_s(self.prefix + user, passwd) 1.32 + except ldap.INVALID_CREDENTIALS: 1.33 + conn.unbind() 1.34 + self.status = 'Invalid credentials' 1.35 + self.statusCode = STATUS_BADAUTH 1.36 + return False 1.37 + except ldap.SERVER_DOWN: 1.38 + self.status = 'Server is down' 1.39 + self.statusCode = STATUS_SERVERDOWN 1.40 + return False 1.41 + 1.42 + self.groups = [] 1.43 + try: 1.44 + ldapData = conn.search_s(self.baseDN, ldap.SCOPE_SUBTREE, '(cn=%s)' % user, ['memberOf'] + self._needAttr)[0][1] 1.45 + for i in ldapData['memberOf']: 1.46 + self.groups.append(i.split(',')[0].split('=')[1].decode('utf-8')) 1.47 + del ldapData['memberOf'] 1.48 + self.attr = ldapData 1.49 + except KeyError: 1.50 + self.status = 'User object from LDAP is wrong, it can be anonymous logon' 1.51 + self.statusCode = STATUS_SERVERERROR 1.52 + return False 1.53 + finally: 1.54 + conn.unbind() 1.55 + 1.56 + return True 1.57 + 1.58 + def __getitem__(self, key): 1.59 + return self.attr[key] 1.60 + 1.61 + def memberOf(self, group): 1.62 + """Проверка на присутствие у пользователя некоторой группы 1.63 + """ 1.64 + if self.groups == None: 1.65 + raise LdapError('Request membership before auth call.') 1.66 + 1.67 + if not isinstance(group, unicode): 1.68 + if isinstance(group, str): 1.69 + group = group.decode('utf-8') 1.70 + else: 1.71 + group = str(group).decode('utf-8') 1.72 + 1.73 + if group in self.groups: 1.74 + return True 1.75 + else: 1.76 + return False 1.77 + 1.78 + def __contains__(self, group): 1.79 + return self.memberOf(group) 1.80 + 1.81 + def memberOfGroups(self, groups): 1.82 + if not len(groups) > 0: 1.83 + return False 1.84 + 1.85 + for group in groups: 1.86 + if not group in self: 1.87 + return False 1.88 + 1.89 + return True