diff --git a/attributs.py b/attributs.py index da45bea..7797626 100644 --- a/attributs.py +++ b/attributs.py @@ -30,12 +30,13 @@ # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS # SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. -import re, sys +import re, sys, netaddr, time from unicodedata import normalize -from crans_utils import format_tel, mailexist, validate_name +from crans_utils import format_tel, format_mac, mailexist, validate_name sys.path.append("/usr/scripts/gestion") import config, annuaires_pg +from midtools import Mid def attrify(val, attr, ldif, conn, ctxt_check = True): @@ -68,11 +69,11 @@ class Attr(object): self.value = None self.conn = conn assert isinstance(val, unicode) - self.parse_value(val) + self.parse_value(val, ldif) if ctxt_check: self.validate(ldif) - def parse_value(self, val): + def parse_value(self, val, ldif): """Transforme l'attribut pour travailler avec notre validateur""" self.value = val @@ -106,7 +107,7 @@ class Attr(object): if attr in [ "mid", "uid", "cid", "fid"]: #... etc assert not self.conn.search('%s=%s' % (attr, str(self))) if attr in [ "mailAlias", "canonicalAlias"]: - assert not self.conn.search('|(mailAlias=%s)(canonicalAlias=%s)' % (str(self),)*2) + assert not self.conn.search('|(mailAlias=%s)(canonicalAlias=%s)' % ((str(self),)*2)) assert not mailexist(str(self)) def _check_users_restrictions(self, values): @@ -122,7 +123,7 @@ class objectClass(Attr): optional = False legend = "entité" - def parse_value(self, val): + def parse_value(self, val, ldif): if val not in [ 'top', 'posixAccount', 'shadowAccount', 'proprio', 'adherent', 'club', 'machine', 'machineCrans', 'borneWifi', 'machineWifi', 'machineFixe', @@ -137,7 +138,7 @@ class nom(Attr): optional = False legend = "Nom" - def parse_value(self, val): + def parse_value(self, val, ldif): self.value = validate_name(val) @@ -146,7 +147,7 @@ class prenom(Attr): optional = False legend = u"Prénom" - def parse_value(self, val): + def parse_value(self, val, ldif): self.value = validate_name(val) @@ -155,7 +156,7 @@ class tel(Attr): optional = False legend = u"Téléphone" - def parse_value(self, val): + def parse_value(self, val, ldif): self.value = format_tel(val) if len(self.value) == 0: raise ValueError("Numéro de téléphone invalide ('%s')" % val) @@ -166,7 +167,7 @@ class paiement(Attr): optional = True legend = u"Paiement" - def parse_value(self, val): + def parse_value(self, val, ldif): if int(val) < 1998 or int(val) > config.ann_scol: raise ValueError("Année de cotisation invalide (%s)" % val) self.value = int(val) @@ -180,7 +181,7 @@ class carteEtudiant(Attr): optional = True legend = u"Carte d'étudiant" - def parse_value(self, val): + def parse_value(self, val, ldif): if int(val) < 1998 or int(val) > config.ann_scol: raise ValueError("Année de cotisation invalide (%s)" % val) self.value = int(val) @@ -194,7 +195,7 @@ class mailAlias(Attr): optional = True legend = u"Alias mail" - def parse_value(self, val): + def parse_value(self, val, ldif): val = val.lower() if not re.match('[a-z][-_.0-9a-z]+', val): raise ValueError("Alias mail invalide (%s)" % val) @@ -206,7 +207,7 @@ class canonicalAlias(Attr): optional = False legend = u"Alias mail canonique" - def parse_value(self, val): + def parse_value(self, val, ldif): val = val.lower() if not re.match('[a-z][-_.0-9a-z]+', val): raise ValueError("Alias mail invalide (%s)" % val) @@ -218,7 +219,7 @@ class etudes(Attr): optional = False legend = u"Études" - def parse_value(self, val): + def parse_value(self, val, ldif): # who cares self.value = val @@ -228,7 +229,7 @@ class chbre(Attr): optional = False legend = u"Chambre sur le campus" - def parse_value(self, val): + def parse_value(self, val, ldif): annuaires_pg.chbre_prises(val[0], val[1:]) self.value = val @@ -237,7 +238,7 @@ class droits(Attr): optional = True legend = u"Droits sur les serveurs" - def parse_value(self, val): + def parse_value(self, val, ldif): if val not in ['apprenti', 'nounou', 'cableur', 'tresorier', 'bureau', 'webmaster', 'webradio', 'imprimeur', 'multimachines', 'victime']: raise ValueError("Ces droits n'existent pas ('%s')" % val) @@ -248,33 +249,70 @@ class solde(Attr): optional = True legend = u"Solde d'impression" + def parse_value(self, solde, ldif): + # on évite les dépassements + assert 0. >= float(solde) and float(solde) <= 1024. + self.value = solde + class host(Attr): singlevalue = True optional = False hname = legend = u"Nom d'hôte" + def parse_value(self, dns, ldif): + dns = dns.lower() + assert dns.endswith('.crans.org') + assert re.match('[a-z][-_a-z0-9]+', dns) + self.value = dns + class macAddress(Attr): singlevalue = True optional = False legend = u"Adresse physique de la carte réseau" hname = "Adresse MAC" + def parse_value(self, mac, ldif): + self.value = format_mac(mac) + + def __unicode__(self): + return unicode(self.value) + class ipHostNumber(Attr): singlevalue = True optional = False legend = u"Adresse IPv4 de la machine" hname = "IPv4" + def parse_value(self, ip, ldif): + if ip == '': + ip = Mid(mid= ldif['mid'][0]).ipv4() + self.value = netaddr.ip.IPAddress(ip) + + def __unicode__(self): + return unicode(self.value) + class mid(Attr): singlevalue = True optional = False legend = "Identifiant de machine" + def parse_value(self, mid, ldif): + self.value = Mid(mid = mid) + + def __unicode__(self): + return unicode(int(self.value)) + class hostAlias(Attr): singlevalue = False optional = True legend = u'Alias de nom de machine' + def parse_value(self, dns, ldif): + dns = dns.lower() + assert dns.endswith('.crans.org') + assert re.match('[a-z][-_a-z0-9]+', dns) + self.value = dns + class ipsec(Attr): singlevalue = False optional = True @@ -290,24 +328,28 @@ class canal(Attr): optional = True legend = u'Canal d\'émission de la borne' -class portTCPout(Attr): + +class portAttr(Attr): singlevalue = False optional = True + + def parse_value(self, port, ldif): + self.value = int(port) + + def __unicode__(self): + return unicode(self.value) + + +class portTCPout(portAttr): legend = u'Port TCP ouvert vers l\'extérieur' -class portTCPin(Attr): - singlevalue = False - optional = True +class portTCPin(portAttr): legend = u"Port TCP ouvert depuis l'extérieur" -class portUDPout(Attr): - singlevalue = False - optional = True +class portUDPout(portAttr): legend = u"Port UDP ouvert vers l'extérieur" -class portUDPin(Attr): - singlevalue = False - optional = True +class portUDPin(portAttr): legend = u"Port UDP ouvert depuis l'extérieur" class prise(Attr): @@ -315,22 +357,50 @@ class prise(Attr): optional = True legend = u"Prise sur laquelle est branchée la machine" + def parse_value(self, prise, ldif): + ### Tu es une nounou, je te fais confiance + self.value = prise + class cid(Attr): singlevalue = True optional = True legend = u"Identifiant du club" + def parse_value(self, cid, ldif): + self.value = int(cid) + + def __unicode__(self): + return unicode(self.value) + + class responsable(Attr): singlevalue = True optional = True legend = u"Responsable du club" + def parse_value(self, resp, ldif): + self.value = self.conn.search('aid=%d' % self.value)[0] + + def __unicode__(self): + return self.value.attrs['aid'][0] + class blacklist(Attr): singlevalue = False optional = True legend = u"Blackliste" + def parse_value(self, bl, ldif): + bl_debut, bl_fin, bl_comm = bl.split('$', 3) + now = time.time() + self.value = { 'debut' : int (bl_debut), + 'fin' : bl_fin if bl_fin == '-' else int(bl_fin), + 'comm' : bl_comm, + 'actif' : int(bl_debut) < now and (bl_fin == '-' or int(bl_fin) > now) } + + def __unicode__(self): + return u'$%(debut)s$%(fin)s$%(comm)s' % self.value + class historique(Attr): singlevalue = False optional = True diff --git a/crans_utils.py b/crans_utils.py index 1262d80..f56bc34 100644 --- a/crans_utils.py +++ b/crans_utils.py @@ -68,7 +68,7 @@ def format_mac(mac): Transforme une adresse pour obtenir la forme xx:xx:xx:xx:xx:xx Retourne la mac formatée. """ - netaddr.EUI(mac, dialect='mac_unix') + mac = netaddr.EUI(mac, dialect='mac_unix') if not mac: raise ValueError(u"MAC nulle interdite\nIl doit être possible de modifier l'adresse de la carte.") return mac