From 3310433d5116deade52a913f7edba834bdc2b6c2 Mon Sep 17 00:00:00 2001 From: Lorenz Steinert Date: Sun, 5 Aug 2018 19:03:58 +0200 Subject: [PATCH] restrucktured the ldap connection --- bin/module/esme.py | 167 +++++++++++++++++++++++++++------------------ bin/proto.py | 18 +---- 2 files changed, 104 insertions(+), 81 deletions(-) diff --git a/bin/module/esme.py b/bin/module/esme.py index 90ac6d7..2db4f5e 100644 --- a/bin/module/esme.py +++ b/bin/module/esme.py @@ -12,6 +12,7 @@ import sys import time import codecs import configparser +from enum import Flag, auto import ldap3 as ldap try: @@ -21,6 +22,11 @@ except ImportError: pwd = None +class Error(Flag): + UNSEC_SEARCH = auto() + NO_FILE = auto() + LDAP_FAIL = auto() + def current_user(): """get the current user""" if pwd: @@ -28,15 +34,35 @@ def current_user(): return getpass.getuser() +def resort_fsr(fsr, num_cols=5): + """resort list for pascal style sorting""" + fsr += [""] * (num_cols - len(fsr) % num_cols) + depth = len(fsr) // num_cols + + tmp = [[] for i in range(depth)] + + for index, elem in zip(range(len(fsr)), fsr): + tmp[index % depth] += [elem] + + return [j for i in tmp for j in i] + + class FsrLdap: """Class die die protokoll .tex datei erstellt""" - def __init__(self, server, base, debug=False, timeout=1): + + def __init__(self, server, base, share_dir, debug=False, timeout=1, testing=None): self.debug = debug self.server = ldap.Server(server, connect_timeout=timeout) + if not testing: + self.conn = ldap.Connection(self.server) + else: + self.conn = ldap.Connection(self.server, client_strategy=ldap.MOCK_SYNC) + self.conn.bind() self.base = base + self.share_dir = share_dir def get_protokollant_ldap(self, config, testing=False): """search the LDAP for the current user""" @@ -61,101 +87,109 @@ class FsrLdap: print("Couldn't Connect to ldap.\nUsing fallback default.\n") return get_protokollant(config) - def get_fsr_ldap(self, share_dir=None, gen_fallback=False, testing=False): + def _get_fsr_ldap(self): """get fsr from LDAP""" print("Fetching FSR from LDAP ...") try: - if testing: - conn = ldap.Connection(self.server, client_strategy=ldap.MOCK_SYNC) - else: - conn = ldap.Connection(self.server) - conn.bind() fil = '(cn=intern)' fsr = [] - if conn.search('ou=group,'+self.base, fil, - attributes=['memberUid']): - for i in conn.entries[0]['memberUid']: - if conn.search('ou=people,' + self.base, - '(uid='+i+')', attributes=['displayName']): - fsr += [str(conn.entries[0]['displayName'])] + if self.conn.search('ou=group,'+self.base, fil, + attributes=['memberUid']): + for i in self.conn.entries[0]['memberUid']: + if self.conn.search('ou=people,' + self.base, + '(uid='+i+')', attributes=['displayName']): + fsr += [str(self.conn.entries[0]['displayName'])] fsr.sort() fsr = [" ".join(i.split(', ')[::-1]) for i in fsr] print("Done") return fsr - if not gen_fallback: - return get_fallback_fsr(share_dir) - print("Could not fetch from LDAP Server. Aborting.") - sys.exit(1) + return Error.UNSEC_SEARCH except ldap.core.exceptions.LDAPException as error_message: if self.debug: print("Couldn't Connect to ldap.\n \ Using fallback File.\n%s\n" % error_message) else: print("Couldn't Connect to ldap.\nUsing fallback File.\n") - if not gen_fallback: - return get_fallback_fsr(share_dir) + return (Error.LDAP_FAIL, error_message) + + @staticmethod + def _get_fallback_fsr(share_dir): + """get fsr form fallback file""" + if os.path.isfile(os.path.join(share_dir, 'fsr')): + with codecs.open(os.path.join(share_dir, 'fsr'), 'r', 'utf-8') as fobj: + fsr = sorted([re.sub(re.escape('\t'), ' ', + line.rstrip('\n')) + for line in fobj.readlines()], + key=lambda x: ''.join(x.split(' ')[::-1])) + return fsr + return Error.NO_FILE + + def get_fsr(self, share_dir=None, gen_fallback=None): + """get fsr""" + if not share_dir: + share_dir = self.share_dir + + fsr = self._get_fsr_ldap() + if isinstance(fsr, tuple): + pass + fsr = fsr[0] + if fsr == Error.UNSEC_SEARCH | Error.LDAP_FAIL and not gen_fallback: + fsr = self._get_fallback_fsr(share_dir) + if fsr == Error.NO_FILE | Error.UNSEC_SEARCH: + fsr = [] + return resort_fsr(fsr) - def get_fsr_extern_ldap(self, share_dir=None, gen_fallback=False, testing=False): + def _get_fsr_extern_ldap(self): """get the EFSR from LDAP""" print("Fetching EFSR from LDAP ...") try: - if testing: - conn = ldap.Connection(self.server, client_strategy=ldap.MOCK_SYNC) - else: - conn = ldap.Connection(self.server) - conn.bind() fil = '(cn=extern)' fsr_extern = [] - if conn.search('ou=group,'+self.base, fil, - attributes=['memberUid']): - for i in conn.entries[0]['memberUid']: - if conn.search('ou=people,' + self.base, - '(uid='+i+')', attributes=['displayName']): - fsr_extern += [str(conn.entries[0]['displayName'])] + if self.conn.search('ou=group,'+self.base, fil, + attributes=['memberUid']): + for i in self.conn.entries[0]['memberUid']: + if self.conn.search('ou=people,' + self.base, + '(uid='+i+')', attributes=['displayName']): + fsr_extern += [str(self.conn.entries[0]['displayName'])] fsr_extern.sort() fsr_extern = [" ".join(i.split(', ')[::-1]) for i in fsr_extern] print("Done") return fsr_extern - if not gen_fallback: - return get_fallback_fsr_extern(share_dir) - print("Could not fetch from LDAP Server. Aborting") - sys.exit(1) + return Error.UNSEC_SEARCH except ldap.core.exceptions.LDAPException as error_message: if self.debug: print("Couldn't Connect to ldap.\n \ Using fallback File.\n%s\n" % error_message) else: print("Couldn't Connect to ldap.\nUsing fallback File.\n") - if not gen_fallback: - return get_fallback_fsr_extern(share_dir) - - -def get_fallback_fsr(share_dir): - """get fsr form fallback file""" - if os.path.isfile(os.path.join(share_dir, 'fsr')): - with codecs.open(os.path.join(share_dir, 'fsr'), 'r', 'utf-8') as fobj: - fsr = sorted([re.sub(re.escape('\t'), ' ', - line.rstrip('\n')) - for line in fobj.readlines()], - key=lambda x: ''.join(x.split(' ')[::-1])) - return fsr - print(os.path.abspath(os.path.join(share_dir, 'fsr')) - + ' not found. Using empty FSR.') - return [] - - -def get_fallback_fsr_extern(share_dir): - """get fsr_extern from fallback file""" - if os.path.isfile(os.path.join(share_dir, 'fsr_extern')): - with codecs.open(os.path.join(share_dir, 'fsr_extern'), 'r', 'utf-8') as fobj: - fsr_extern = sorted([re.sub(re.escape('\t'), ' ', - line.rstrip('\n')) - for line in fobj.readlines()], - key=lambda x: ''.join(x.split(' ')[::-1])) - return fsr_extern - print(os.path.abspath(os.path.join(share_dir, 'fsr_extern')) - + ' not found. Using empty FSR_extern.') - return [] + return (Error.LDAP_FAIL, error_message) + + @staticmethod + def _get_fallback_fsr_extern(share_dir): + """get fsr_extern from fallback file""" + if os.path.isfile(os.path.join(share_dir, 'fsr_extern')): + with codecs.open(os.path.join(share_dir, 'fsr_extern'), 'r', 'utf-8') as fobj: + fsr_extern = sorted([re.sub(re.escape('\t'), ' ', + line.rstrip('\n')) + for line in fobj.readlines()], + key=lambda x: ''.join(x.split(' ')[::-1])) + return fsr_extern + return Error.NO_FILE + + def get_fsr_extern(self, share_dir=None, gen_fallback=None): + """get fsr extern""" + if not share_dir: + share_dir = self.share_dir + + fsr = self._get_fsr_extern_ldap() + if isinstance(fsr, tuple): + pass + fsr = fsr[0] + if fsr == Error.UNSEC_SEARCH | Error.LDAP_FAIL and not gen_fallback: + fsr = self._get_fallback_fsr_extern(share_dir) + if fsr == Error.NO_FILE | Error.UNSEC_SEARCH: + fsr = [] + return resort_fsr(fsr) def get_sprecher(config=None, getinput=input): @@ -284,6 +318,7 @@ def get_path(rundir, config=None, path=None): + os.path.abspath(os.path.join(rundir, '../..'))) sys.exit(1) + def get_ldap_server(config=None, server=None): """get the ldap server for the fsr lookup""" if server: @@ -293,6 +328,7 @@ def get_ldap_server(config=None, server=None): print("No LDAP Server supplied. Triing to use \"rincwind.fs.physik.uni-kl.de\".") return "rincewind.fs.physik.uni-kl.de" + def get_ldap_base(config=None, base=None): """get the search base for the ldap server""" if base: @@ -302,6 +338,7 @@ def get_ldap_base(config=None, base=None): print("No LDAP search base supplied. Triing to use \"dc=fs,dc=physik,dc=uni-kl,dc=de\".") return "dc=fs,dc=physik,dc=uni-kl,dc=de" + def get_server_timeout(config=None, test=None): """get the timeout for the connection to the ldap server""" if test: diff --git a/bin/proto.py b/bin/proto.py index d22e22f..98af9c0 100755 --- a/bin/proto.py +++ b/bin/proto.py @@ -85,23 +85,10 @@ def gen_head(share_dir, reg, sprecher, protokollant, date): return f_head -def resort_fsr(fsr, num_cols=5): - """resort list for pascal style sorting""" - fsr += [""] * (num_cols - len(fsr) % num_cols) - depth = len(fsr) // num_cols - - tmp = [[] for i in range(depth)] - - for index, elem in zip(range(len(fsr)), fsr): - tmp[index % depth] += [elem] - - return [j for i in tmp for j in i] def gen_attendance_tab(fsr, num_cols=5, ext=False): """generate the atandance tables""" - fsr = resort_fsr(fsr, num_cols) - tabdef = '||' + 'c|l||' * num_cols fsr_tab = '' @@ -192,7 +179,7 @@ if __name__ == "__main__": NUM_COLS = 5 NUM_COLS_EXT = 5 - ESME = FsrLdap(LDAP_SERVER, LDAP_SERVER_BASE, OPT.debug, + ESME = FsrLdap(LDAP_SERVER, LDAP_SERVER_BASE, SHARE_DIR, OPT.debug, SERVER_TIMEOUT) print("\n") @@ -205,8 +192,7 @@ if __name__ == "__main__": #Fetch the FSR from the Server #and if not able to connect fall back to the textfiles - FSR = [ESME.get_fsr_ldap(SHARE_DIR), - ESME.get_fsr_extern_ldap(SHARE_DIR)] + FSR = [ESME.get_fsr(), ESME.get_fsr_extern()] #Generate the Path for the Protokoll in depandance of OPT.VV #and make the directory -- GitLab