py.lib

John Y. 2018-02-25 Parent:5236a9505448 Child:cb88c7d80d6f

3:f3ecca8e4adc Browse Files

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