diff --git a/gestion/ldap_crans.py b/gestion/ldap_crans.py index 5c435a28..3a3a0023 100755 --- a/gestion/ldap_crans.py +++ b/gestion/ldap_crans.py @@ -236,26 +236,50 @@ class crans_ldap: ### Configuration de la recheche # Dictionnaire de transformation des champs - trans = { 'prénom': 'prenom' , + trans = { 'prénom': 'prenom', 'chambre': 'chbre', - 'login': 'mail' , + 'login': 'mail', 'hostname': 'host', 'mac': 'macAddress', 'ip': 'ipHostNumber', 'telephone': 'tel'} # Champs de recherche pour la recherche automatique - auto_search_champs = { 'adherent': [ 'nom', 'prenom', 'tel', 'mail', 'chbre', 'mailAlias', 'cannonicalAlias' ], \ - 'machine': [ 'macAddress', 'host', 'ipHostNumber', 'hostAlias'] , - 'club': [ 'nom', 'chbre' ] } + auto_search_machines_champs = \ + ['macAddress', 'host', 'ipHostNumber', 'hostAlias'] + + auto_search_champs = { \ + 'adherent': \ + ['nom', 'prenom', 'tel', 'mail', 'chbre', 'mailAlias', 'cannonicalAlias' ], + 'club': ['nom', 'chbre'], + 'machineFixe': auto_search_machines_champs, + 'machineWifi': auto_search_machines_champs, + 'machineCrans': auto_search_machines_champs, + 'borneWifi': auto_search_machines_champs } # Champs de recherche pour la recherche manuelle (en plus de la recherche auto) - non_auto_search_champs = { 'adherent': [ 'etudes', 'paiement', 'carteEtudiant', 'aid' , 'postalAddress', 'historique' ,'blacklist', 'droits', 'uidNumber', 'uid', 'info', 'solde', 'controle', 'contourneGreylist', 'rewriteMailHeaders', 'ablacklist'], \ - 'machine': [ 'mid' , 'ipsec', 'historique', 'blacklist' , 'puissance', 'canal', 'portTCPin', 'portTCPout', 'portUDPin', 'portUDPout', 'prise' , 'info', 'exempt', 'mblacklist'] , - 'club': [ 'cid' , 'responsable', 'paiement', 'historique', 'blacklist', 'mailAlias', 'info', 'controle' ] } - + non_auto_search_machines_champs = \ + ['mid', 'historique', 'blacklist', 'info', 'exempt', 'mblacklist', + 'portTCPin', 'portTCPout', 'portUDPin', 'portUDPout'] + + non_auto_search_champs = { \ + 'adherent': \ + ['etudes', 'paiement', 'carteEtudiant', 'aid', 'postalAddress', + 'historique', 'blacklist', 'droits', 'uidNumber', 'uid', 'info', + 'solde', 'controle', 'contourneGreylist', 'rewriteMailHeaders', + 'ablacklist'], \ + 'club': \ + ['cid', 'responsable', 'paiement', 'historique', 'blacklist', + 'mailAlias', 'info', 'controle'], \ + 'machineFixe': non_auto_search_machines_champs, + 'machineCrans': non_auto_search_machines_champs + ['prise'], + 'borneWifi': non_auto_search_machines_champs + ['prise', 'puissance', 'canal'], + 'machineWifi': non_auto_search_machines_champs + ['ipsec'] } + # Profondeur des différentes recherches (scope) - scope = { 'adherent': 1 , 'machine': 2 , 'club': 1 } + scope = {'adherent': 1, 'club': 1, + 'machineFixe': 2, 'machineWifi': 2, + 'machineCrans': 2, 'borneWifi': 2 } def __init__(self,readonly=False): self.connect(readonly) @@ -503,6 +527,28 @@ class crans_ldap: # Existe déja => rien à faire pass + + def make(self, entry, mode=''): + """ + Crée le bon objet à partir de entry. + mode a la même signification que dans search. + """ + # On récupère la bonne classe + nom_classe = (entry[1].get('objectClass') or ['none'])[0] + nom_classe = nom_classe[0].upper() + nom_classe[1:] + try: + # Hack temporaire, à enlever quand on aura tout renommé + if nom_classe in ['Adherent', 'Club']: + nom_classe = nom_classe.lower() + if nom_classe in ['MachineFixe', 'MachineWifi', 'MachineCrans']: + nom_classe = 'Machine' + classe = globals()[nom_classe] + # On crée l'objet + return classe(entry, mode, self.conn) + except: + raise ValueError(u"Impossible de créer l'objet %s" % nom_classe) + + def search(self, expression, mode=''): """ Recherche dans la base LDAP, expression est une chaîne : @@ -528,7 +574,9 @@ class crans_ldap: # Il faut un filtre par type d'objet de la base filtres = self.auto_search_champs.keys() - result = {'adherent': [], 'machine': [], 'club': []} + result = {} + for i in filtres: + result[i] = [] # Fonction utile def build_filtre(champ, expr, neg=False): @@ -580,7 +628,7 @@ class crans_ldap: #### Recherche avec conditions explicites ## Construction des filtres - # initialisation + # Initialisation filtre = {} for i in filtres: filtre[i] = '' @@ -616,6 +664,7 @@ class crans_ldap: ## Recherche avec chacun des filtres r = {} # contiendra les réponses par filtre + for i in filtres: if filtre[i] != '': # Filtre valide @@ -628,13 +677,23 @@ class crans_ldap: ## r = {categorie1: [(result1), (result2), ...], ...} # Traitement - if r['machine'] != None \ + + if (r['machineFixe'] != None or r['machineWifi'] != None) \ and (r['adherent'] != None or r['club'] != None) \ and len(conds) > 1: - # Il faut croiser les résultats machine et propriétaire + + # On renvoie toutes les machineCrans et borneWifi + for i in 'machineCrans', 'borneWifi': + if r[i] == None: + continue + for res in r[i]: + result[i].append(self.make(res, mode)) + + # On croise maintenant les résultats machine et propriétaire + # Traitement des machines mach_adh = [] # liste de dn d'adhérents et de clubs - for res in r['machine']: + for res in r['machineFixe'] + r['machineWifi']: dn = ','.join(res[0].split(',')[-4:]) if dn[:3] != 'aid' and dn[:3] != 'cid': continue @@ -643,25 +702,20 @@ class crans_ldap: # Croisement bons_dn = [] # liste des dn d'adhérents qui correspondent aux critères - for a in r['adherent']: - if a[0] in mach_adh and not a[0] in bons_dn: - bons_dn.append(a[0]) - result['adherent'].append(adherent(a, mode, self.conn)) - for a in r['club']: - if a[0] in mach_adh and not a[0] in bons_dn: - bons_dn.append(a[0]) - result['club'].append(club(a, mode, self.conn)) + for i in 'adherent', 'club': + for a in r[i]: + if a[0] in mach_adh and not a[0] in bons_dn: + bons_dn.append(a[0]) + result[i].append(self.make(a, mode)) # Maintenant c'est au tour des bonnes machines bons_dn2 = [] - for a in r['machine']: - dn = string.join(a[0].split(',')[-4:], ',') - if dn in bons_dn and not a[0] in bons_dn2: - bons_dn2.append(dn) - if a[1].has_key('puissance'): - result['machine'].append(BorneWifi(a, mode, self.conn)) - else: - result['machine'].append(Machine(a, mode, self.conn)) + for i in 'machineFixe', 'machineWifi': + for a in r[i]: + dn = string.join(a[0].split(',')[-4:], ',') + if dn in bons_dn and not a[0] in bons_dn2: + bons_dn2.append(dn) + result[i].append(self.make(a, mode)) else: # On retourne tout @@ -669,39 +723,28 @@ class crans_ldap: if r[i] == None: continue for res in r[i]: - if i == "machine": - if res[1].has_key('puissance'): - result['machine'].append(BorneWifi(res, mode, self.conn)) - else: - result['machine'].append(Machine(res, mode, self.conn)) - else: - result[i].append(globals()[i](res, mode, self.conn)) + result[i].append(self.make(res, mode)) else: ### Recherche d'une chaine sur tous les champs - conv = { 'club': club, 'adherent': adherent } - for i in filtres: - cl = conv.get(i) - # Construction du filtre - filtre = '(&(|' + filtre = '' for champ in self.auto_search_champs[i]: filtre += build_filtre(champ, expression) - filtre += ')(objectClass=%s))' % i + filtre = '(&(|%s)(objectClass=%s))' % (filtre, i) # Recherche for r in self.conn.search_s(self.base_dn, self.scope[i], filtre): - if i == 'machine': - if r[1].has_key('puissance'): - result['machine'].append(BorneWifi(r, mode, self.conn)) - else: - result['machine'].append(Machine(r, mode, self.conn)) - else: - result[i].append(cl(r, mode, self.conn)) + result[i].append(self.make(r, mode)) + # Backward-compatibilité + result['machine'] = result['machineCrans'] + result['borneWifi'] + result['machine'] += result['machineFixe'] + result['machineWifi'] + return result + __machines = () def all_machines(self, graphic=False): """Renvoie toutes les machines autorisées. @@ -1020,7 +1063,7 @@ class base_classes_crans(crans_ldap): if not self._init_data: ### Nouvel enregistrement # Génération du dn - res = self.conn.search_s(self.base_dn,2,'objectClass=%s' % self._data['objectClass'][0],['']) + res = self.conn.search_s(self.base_dn, 2, self.filtre_idn) vidn=1 vidns=[] # Liste des dn pris @@ -1496,6 +1539,7 @@ class adherent(base_proprietaire): """ Classe de définition d'un adhérent """ objectClass = 'adherent' idn = 'aid' + filtre_idn = '(objectClass=adherent)' ### Méthodes Nom utilisée lors de l'affichage des propriétés ### (commune avec les classes crans et club) @@ -1912,6 +1956,7 @@ class adherent(base_proprietaire): class club(base_proprietaire): """ Classe de définition d'un club """ idn = 'cid' + filtre_idn = '(objectClass=club)' objectClass = 'club' def Nom(self,new=None): @@ -2039,6 +2084,8 @@ class club(base_proprietaire): class Machine(base_classes_crans): """ Classe de définition d'une machine """ idn = 'mid' + filtre_idn = '(|(objectClass=machineFixe)(objectClass=machineWifi)' + filtre_idn += '(objectClass=machineCrans)(objectClass=borneWifi))' def __init__(self, parent_or_tuple, typ='fixe', conn=None): """