Compare commits
No commits in common. "master" and "peb_dev" have entirely different histories.
12 changed files with 301 additions and 660 deletions
142
attributs.py
142
attributs.py
|
@ -47,8 +47,7 @@ import random
|
||||||
import string
|
import string
|
||||||
from unicodedata import normalize
|
from unicodedata import normalize
|
||||||
from crans_utils import format_tel, format_mac, mailexist, validate_name, ip4_of_rid, ip6_of_mac, fetch_cert_info
|
from crans_utils import format_tel, format_mac, mailexist, validate_name, ip4_of_rid, ip6_of_mac, fetch_cert_info
|
||||||
from crans_utils import to_generalized_time_format, from_generalized_time_format, datetime_from_generalized_time_format
|
from crans_utils import to_generalized_time_format, from_generalized_time_format
|
||||||
from crans_utils import datetime_to_generalized_time_format
|
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
if '/usr/scripts' not in sys.path:
|
if '/usr/scripts' not in sys.path:
|
||||||
|
@ -243,7 +242,7 @@ class AttrsDict(dict):
|
||||||
"""
|
"""
|
||||||
ldif = {}
|
ldif = {}
|
||||||
for attr, vals in self.items():
|
for attr, vals in self.items():
|
||||||
ldif[attr] = [unicode(val).encode(config.ldap_encoding) for val in vals]
|
ldif[attr] = [ str(val) for val in vals ]
|
||||||
return ldif
|
return ldif
|
||||||
|
|
||||||
class Attr(object):
|
class Attr(object):
|
||||||
|
@ -351,7 +350,9 @@ class Attr(object):
|
||||||
raise UniquenessError("%s déjà existant" % attr, [r.dn for r in res])
|
raise UniquenessError("%s déjà existant" % attr, [r.dn for r in res])
|
||||||
|
|
||||||
def is_modifiable(self, liste_droits):
|
def is_modifiable(self, liste_droits):
|
||||||
"""L'attribut est-il modifiable par un des droits dans liste_droits ?"""
|
"""
|
||||||
|
L'attribut est-il modifiable par un des droits dans liste_droits ?
|
||||||
|
"""
|
||||||
return not set(liste_droits).isdisjoint(self.can_modify)
|
return not set(liste_droits).isdisjoint(self.can_modify)
|
||||||
|
|
||||||
class AttributeFactory(object):
|
class AttributeFactory(object):
|
||||||
|
@ -392,26 +393,13 @@ class rightProtectedAttr(Attr):
|
||||||
"""
|
"""
|
||||||
On permet la modification à un utilisateur
|
On permet la modification à un utilisateur
|
||||||
"""
|
"""
|
||||||
# Si on est soi-même, on peut changer son mot de passe sans condition
|
|
||||||
if not soi in liste_droits:
|
if not soi in liste_droits:
|
||||||
|
|
||||||
modifiables = set()
|
modifiables = set()
|
||||||
|
|
||||||
# On regarde la liste des droits qu'a la connexion courante, ce sont a priori
|
|
||||||
# les droits de l'utilisateur qui modifie le mot de passe, ajoutés de soi/parent
|
|
||||||
# les cas échéants.
|
|
||||||
for i in liste_droits:
|
for i in liste_droits:
|
||||||
|
|
||||||
# Si le droit est un droit "superviseur" (ie ayant le droit de modifier certains
|
|
||||||
# utilisateurs ayant un des droits "supervisés", on ajoute la liste des droits
|
|
||||||
# supervisés aux droits modifiables
|
|
||||||
if i in DROITS_SUPERVISEUR:
|
if i in DROITS_SUPERVISEUR:
|
||||||
modifiables = modifiables.union(DROITS_SUPERVISEUR[i])
|
modifiables = modifiables.union(DROITS_SUPERVISEUR[i])
|
||||||
modifiables = list(modifiables)
|
modifiables = list(modifiables)
|
||||||
|
|
||||||
# On prend les droits de l'utilisateur dont on cherche à modifier le mot de passe
|
|
||||||
# et on les compare à la liste des droits que l'utilisateur qui modifie a le droit
|
|
||||||
# de modifier. S'il y en a un qui n'est pas dans la liste des droits modifiables, on jette.
|
|
||||||
for droit in self.parent.get('droits', []):
|
for droit in self.parent.get('droits', []):
|
||||||
if droit not in modifiables and droit in TOUS_DROITS:
|
if droit not in modifiables and droit in TOUS_DROITS:
|
||||||
return False
|
return False
|
||||||
|
@ -525,14 +513,14 @@ class aid(intAttr):
|
||||||
self.value = int(aid)
|
self.value = int(aid)
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class uid(rightProtectedAttr):
|
class uid(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
option = False
|
option = False
|
||||||
legend = u"L'identifiant canonique de l'adhérent"
|
legend = u"L'identifiant canonique de l'adhérent"
|
||||||
category = 'perso'
|
category = 'perso'
|
||||||
unique = True
|
unique = True
|
||||||
can_modify = [cableur, nounou]
|
can_modify = [nounou]
|
||||||
ldap_name = "uid"
|
ldap_name = "uid"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
|
@ -648,31 +636,25 @@ class generalizedTimeFormat(Attr):
|
||||||
une donnée de temps suivant la RFC 4517
|
une donnée de temps suivant la RFC 4517
|
||||||
|
|
||||||
"""
|
"""
|
||||||
__slots__ = ("datetime",)
|
__slots__ = ("_stamp",)
|
||||||
python_type = datetime.datetime
|
default = "19700101000000Z"
|
||||||
default = datetime_from_generalized_time_format("19700101000000Z")
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return unicode(datetime_to_generalized_time_format(self.value))
|
|
||||||
|
|
||||||
def __float__(self):
|
def __float__(self):
|
||||||
return from_generalized_time_format(unicode(self))
|
return self._stamp
|
||||||
|
|
||||||
def __int__(self):
|
def __int__(self):
|
||||||
return int(float(self))
|
return int(self._stamp)
|
||||||
|
|
||||||
def __eq__(self, othertime):
|
def __eq__(self, othertime):
|
||||||
if isinstance(othertime, generalizedTimeFormat):
|
if isinstance(othertime, generalizedTimeFormat):
|
||||||
return self.value == othertime.value
|
return self._stamp == othertime._stamp
|
||||||
elif isinstance(othertime, float):
|
elif isinstance(othertime, float):
|
||||||
return float(self) == othertime
|
return self._stamp == othertime
|
||||||
elif isinstance(othertime, int):
|
elif isinstance(othertime, int):
|
||||||
return int(self) == othertime
|
return self._stamp == othertime
|
||||||
elif isinstance(othertime, unicode) or isinstance(othertime, str):
|
elif isinstance(othertime, unicode) or isinstance(othertime, str):
|
||||||
resource = generalizedTimeFormat(othertime, conn=None, Parent=None)
|
resource = generalizedTimeFormat(othertime, conn=None, Parent=None)
|
||||||
return self == resource
|
return self._stamp == resource._stamp
|
||||||
elif isinstance(othertime, datetime.datetime):
|
|
||||||
return self.value == othertime
|
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -681,16 +663,14 @@ class generalizedTimeFormat(Attr):
|
||||||
|
|
||||||
def __lt__(self, othertime):
|
def __lt__(self, othertime):
|
||||||
if isinstance(othertime, generalizedTimeFormat):
|
if isinstance(othertime, generalizedTimeFormat):
|
||||||
return self.value < othertime.value
|
return self._stamp < othertime._stamp
|
||||||
elif isinstance(othertime, float):
|
elif isinstance(othertime, float):
|
||||||
return float(self) < othertime
|
return self._stamp < othertime
|
||||||
elif isinstance(othertime, int):
|
elif isinstance(othertime, int):
|
||||||
return int(self) < othertime
|
return self._stamp < othertime
|
||||||
elif isinstance(othertime, unicode) or isinstance(othertime, str):
|
elif isinstance(othertime, unicode) or isinstance(othertime, str):
|
||||||
resource = generalizedTimeFormat(othertime, conn=None, Parent=None)
|
resource = generalizedTimeFormat(othertime, conn=None, Parent=None)
|
||||||
return self < resource
|
return self._stamp < resource._stamp
|
||||||
elif isinstance(othertime, datetime.datetime):
|
|
||||||
return self.value < othertime
|
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
@ -705,9 +685,15 @@ class generalizedTimeFormat(Attr):
|
||||||
|
|
||||||
def parse_value(self, gtf):
|
def parse_value(self, gtf):
|
||||||
if isinstance(gtf, str) or isinstance(gtf, unicode):
|
if isinstance(gtf, str) or isinstance(gtf, unicode):
|
||||||
self.value = datetime_from_generalized_time_format(gtf)
|
if not ('Z' in gtf or '+' in gtf or '-' in gtf):
|
||||||
elif isinstance(gtf, datetime.datetime):
|
self._stamp = gtf
|
||||||
|
self.value = to_generalized_time_format(float(gtf))
|
||||||
|
else:
|
||||||
|
self._stamp = from_generalized_time_format(gtf)
|
||||||
self.value = gtf
|
self.value = gtf
|
||||||
|
elif isinstance(gtf, float):
|
||||||
|
self._stamp = gtf
|
||||||
|
self.value = to_generalized_time_format(gtf)
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class debutAdhesion(generalizedTimeFormat):
|
class debutAdhesion(generalizedTimeFormat):
|
||||||
|
@ -754,43 +740,28 @@ class mail(rightProtectedAttr):
|
||||||
|
|
||||||
def check_uniqueness(self, liste_exclue):
|
def check_uniqueness(self, liste_exclue):
|
||||||
attr = self.__class__.__name__
|
attr = self.__class__.__name__
|
||||||
|
|
||||||
if str(self) in liste_exclue:
|
if str(self) in liste_exclue:
|
||||||
return
|
return
|
||||||
|
if attr in ["mailAlias", "canonicalAlias", 'mail']:
|
||||||
# On initialise le résultat, s'il vaut true en fin de course, le mail
|
mail, end = str(self).split('@', 1)
|
||||||
# est déjà pris.
|
if end.startswith('crans'):
|
||||||
res = False
|
|
||||||
|
|
||||||
mail = str(self)
|
|
||||||
|
|
||||||
_, domain = mail.split('@')
|
|
||||||
if domain in config.dns.mail_crans:
|
|
||||||
# On commence par vérifier auprès du serveur SMTP
|
|
||||||
# si l'adresse email est prise sur le réseau. Cela permet
|
|
||||||
# de tester aussi les adresses statiquement écrites dans
|
|
||||||
# aliases.db.
|
|
||||||
try:
|
try:
|
||||||
smtp = smtplib.SMTP(smtpserv)
|
smtp = smtplib.SMTP(smtpserv)
|
||||||
smtp.putcmd("vrfy", mail)
|
smtp.putcmd("vrfy", mail)
|
||||||
res = smtp.getreply()[0] in [250, 252]
|
res = smtp.getreply()[0] in [250, 252]
|
||||||
smtp.close()
|
smtp.close()
|
||||||
except:
|
except:
|
||||||
print 'Serveur de mail injoignable'
|
raise ValueError('Serveur de mail injoignable')
|
||||||
|
|
||||||
check = self.conn.search(
|
|
||||||
u'(|(mail=%(mail)s)(mailAlias=%(mail)s)(canonicalAlias=%(mail)s)(mailExt=%(mail)s))' % {
|
|
||||||
'mail': mail,
|
|
||||||
}
|
|
||||||
)
|
|
||||||
if len(check) >= 1:
|
|
||||||
res = True
|
|
||||||
|
|
||||||
if res:
|
if res:
|
||||||
raise ValueError("Le mail %s est déjà pris." % (str(self)))
|
raise ValueError("Le mail %s est déjà pris." % (str(self)))
|
||||||
|
else:
|
||||||
|
check = self.conn.search(u'mail=%s' % mail)
|
||||||
|
if len(check) >= 1:
|
||||||
|
raise ValueError("Le mail %s est déjà pris." % (str(self)))
|
||||||
|
|
||||||
def parse_value(self, mail):
|
def parse_value(self, mail):
|
||||||
if not re.match(u'^[-+_.0-9A-Za-z]+@([A-Za-z0-9]{1}[A-Za-z0-9-_]+[.])+[a-z]{2,20}$', mail):
|
if not re.match(u'^[-_.0-9A-Za-z]+@([A-Za-z0-9]{1}[A-Za-z0-9-_]+[.])+[a-z]{2,6}$', mail):
|
||||||
raise ValueError("%s invalide %r" % (self.legend, mail))
|
raise ValueError("%s invalide %r" % (self.legend, mail))
|
||||||
self.value = mail
|
self.value = mail
|
||||||
|
|
||||||
|
@ -816,6 +787,7 @@ class mailAlias(mail):
|
||||||
optional = True
|
optional = True
|
||||||
unique = True
|
unique = True
|
||||||
legend = u"Alias mail"
|
legend = u"Alias mail"
|
||||||
|
can_modify = [soi, cableur, nounou]
|
||||||
category = 'mail'
|
category = 'mail'
|
||||||
ldap_name = "mailAlias"
|
ldap_name = "mailAlias"
|
||||||
|
|
||||||
|
@ -835,7 +807,8 @@ class mailExt(mail):
|
||||||
singlevalue = False
|
singlevalue = False
|
||||||
optional = True
|
optional = True
|
||||||
unique = True
|
unique = True
|
||||||
legend = u"Mail de redirection ou de secours"
|
legend = u"Mail de secours"
|
||||||
|
can_modify = [soi, cableur, nounou]
|
||||||
category = 'mail'
|
category = 'mail'
|
||||||
ldap_name = "mailExt"
|
ldap_name = "mailExt"
|
||||||
|
|
||||||
|
@ -890,7 +863,7 @@ class chbre(Attr):
|
||||||
|
|
||||||
def parse_value(self, chambre):
|
def parse_value(self, chambre):
|
||||||
if self.parent != None and u'club' in [str(o) for o in self.parent['objectClass']]:
|
if self.parent != None and u'club' in [str(o) for o in self.parent['objectClass']]:
|
||||||
if chambre in annuaires_pg.locaux_clubs() or chambre in (u"EXT", u"????"):
|
if chambre in annuaires_pg.locaux_clubs():
|
||||||
self.value = chambre
|
self.value = chambre
|
||||||
else:
|
else:
|
||||||
raise ValueError("Club devrait etre en XclN, pas en %r" % chambre)
|
raise ValueError("Club devrait etre en XclN, pas en %r" % chambre)
|
||||||
|
@ -1082,6 +1055,7 @@ class rid(intAttr):
|
||||||
unique = True
|
unique = True
|
||||||
legend = u"Identifiant réseau de machine"
|
legend = u"Identifiant réseau de machine"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "rid"
|
ldap_name = "rid"
|
||||||
|
|
||||||
def parse_value(self, rid):
|
def parse_value(self, rid):
|
||||||
|
@ -1113,7 +1087,7 @@ class ipsec(Attr):
|
||||||
legend = u'Clef wifi'
|
legend = u'Clef wifi'
|
||||||
category = 'wifi'
|
category = 'wifi'
|
||||||
ldap_name = "ipsec"
|
ldap_name = "ipsec"
|
||||||
can_modify = [nounou, cableur, parent]
|
can_modify = [nounou, parent]
|
||||||
historique = "info"
|
historique = "info"
|
||||||
default = u'auto'
|
default = u'auto'
|
||||||
|
|
||||||
|
@ -1132,8 +1106,8 @@ class puissance(Attr):
|
||||||
optional = True
|
optional = True
|
||||||
legend = u"puissance d'émission pour les bornes wifi"
|
legend = u"puissance d'émission pour les bornes wifi"
|
||||||
category = 'wifi'
|
category = 'wifi'
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "puissance"
|
ldap_name = "puissance"
|
||||||
default = '60'
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class canal(intAttr):
|
class canal(intAttr):
|
||||||
|
@ -1142,8 +1116,8 @@ class canal(intAttr):
|
||||||
optional = True
|
optional = True
|
||||||
legend = u'Canal d\'émission de la borne'
|
legend = u'Canal d\'émission de la borne'
|
||||||
category = 'wifi'
|
category = 'wifi'
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "canal"
|
ldap_name = "canal"
|
||||||
default = "11"
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class hotspot(boolAttr):
|
class hotspot(boolAttr):
|
||||||
|
@ -1152,24 +1126,25 @@ class hotspot(boolAttr):
|
||||||
optional = True
|
optional = True
|
||||||
legend = u'Hotspot'
|
legend = u'Hotspot'
|
||||||
category = 'wifi'
|
category = 'wifi'
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "hotspot"
|
ldap_name = "hotspot"
|
||||||
default = "FALSE"
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class positionBorne(Attr):
|
class positionBorne(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
legend = u"Position de la borne"
|
legend = u"Position de la borne"
|
||||||
category = "wifi"
|
category = "wifi"
|
||||||
|
can_modify = [nounou]
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
ldap_name = "positionBorne"
|
ldap_name = "positionBorne"
|
||||||
default = "0 0"
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class nvram(Attr):
|
class nvram(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
legend = u"Configuration speciale"
|
legend = u"Configuration speciale"
|
||||||
optional = True
|
optional = True
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "nvram"
|
ldap_name = "nvram"
|
||||||
|
|
||||||
class portAttr(Attr):
|
class portAttr(Attr):
|
||||||
|
@ -1178,6 +1153,7 @@ class portAttr(Attr):
|
||||||
optional = True
|
optional = True
|
||||||
legend = u'Ouverture de port'
|
legend = u'Ouverture de port'
|
||||||
category = 'firewall'
|
category = 'firewall'
|
||||||
|
can_modify = [nounou]
|
||||||
|
|
||||||
def parse_value(self, port):
|
def parse_value(self, port):
|
||||||
if ":" in port:
|
if ":" in port:
|
||||||
|
@ -1251,6 +1227,7 @@ class nombrePrises(intAttr):
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
categoriy = 'base_tech'
|
categoriy = 'base_tech'
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "nombrePrises"
|
ldap_name = "nombrePrises"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
|
@ -1260,6 +1237,7 @@ class prise(Attr):
|
||||||
optional = True
|
optional = True
|
||||||
legend = u"Prise sur laquelle est branchée la machine"
|
legend = u"Prise sur laquelle est branchée la machine"
|
||||||
category = 'base_tech'
|
category = 'base_tech'
|
||||||
|
can_modify = [nounou]
|
||||||
ldap_name = "prise"
|
ldap_name = "prise"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
|
@ -1369,7 +1347,7 @@ class blacklist(Attr):
|
||||||
optional = True
|
optional = True
|
||||||
legend = u"Blackliste"
|
legend = u"Blackliste"
|
||||||
category = 'info'
|
category = 'info'
|
||||||
can_modify = [nounou, bureau]
|
can_modify = [nounou]
|
||||||
ldap_name = "blacklist"
|
ldap_name = "blacklist"
|
||||||
python_type = dict
|
python_type = dict
|
||||||
|
|
||||||
|
@ -1482,7 +1460,7 @@ class homeDirectory(rightProtectedAttr):
|
||||||
ldap_name = "homeDirectory"
|
ldap_name = "homeDirectory"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class loginShell(rightProtectedAttr):
|
class loginShell(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
|
@ -1499,7 +1477,7 @@ class loginShell(rightProtectedAttr):
|
||||||
self.value = shell
|
self.value = shell
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class uidNumber(intAttr, rightProtectedAttr):
|
class uidNumber(intAttr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
|
@ -1507,17 +1485,15 @@ class uidNumber(intAttr, rightProtectedAttr):
|
||||||
legend = "L'uid du compte de l'adherent"
|
legend = "L'uid du compte de l'adherent"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
ldap_name = "uidNumber"
|
ldap_name = "uidNumber"
|
||||||
can_modify = [cableur, nounou]
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class gidNumber(intAttr, rightProtectedAttr):
|
class gidNumber(intAttr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
legend = "Le gid du compte de l'adhérent"
|
legend = "Le gid du compte de l'adhérent"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
ldap_name = "gidNumber"
|
ldap_name = "gidNumber"
|
||||||
can_modify = [cableur, nounou]
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class gecos(Attr):
|
class gecos(Attr):
|
||||||
|
@ -1527,7 +1503,6 @@ class gecos(Attr):
|
||||||
legend = "Le gecos"
|
legend = "Le gecos"
|
||||||
category = 'id'
|
category = 'id'
|
||||||
ldap_name = "gecos"
|
ldap_name = "gecos"
|
||||||
can_modify = [cableur, nounou]
|
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class userPassword(rightProtectedAttr):
|
class userPassword(rightProtectedAttr):
|
||||||
|
@ -1620,7 +1595,6 @@ class gpgMail(mail):
|
||||||
legend = "Mail associé à une clef gpg"
|
legend = "Mail associé à une clef gpg"
|
||||||
can_modify = [soi, nounou]
|
can_modify = [soi, nounou]
|
||||||
ldap_name = "gpgMail"
|
ldap_name = "gpgMail"
|
||||||
|
|
||||||
def check_uniqueness(self, liste_exclue):
|
def check_uniqueness(self, liste_exclue):
|
||||||
super(mail, self).check_uniqueness(liste_exclue)
|
super(mail, self).check_uniqueness(liste_exclue)
|
||||||
|
|
||||||
|
@ -1633,7 +1607,6 @@ class cn(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = False
|
optional = False
|
||||||
can_modify = [cableur, nounou]
|
|
||||||
category = 'id'
|
category = 'id'
|
||||||
ldap_name = "cn"
|
ldap_name = "cn"
|
||||||
|
|
||||||
|
@ -1696,7 +1669,7 @@ class modePaiement(Attr):
|
||||||
self.value = mode
|
self.value = mode
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class recuPaiement(generalizedTimeFormat):
|
class recuPaiement(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
ldap_name = "recuPaiement"
|
ldap_name = "recuPaiement"
|
||||||
can_modify = [cableur, nounou]
|
can_modify = [cableur, nounou]
|
||||||
|
@ -1766,6 +1739,7 @@ class machineAlias(boolAttr):
|
||||||
class issuerCN(Attr):
|
class issuerCN(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
ldap_name = "issuerCN"
|
ldap_name = "issuerCN"
|
||||||
|
can_modify = [nounou]
|
||||||
legend = "Common Name de l'éméteur du certificat"
|
legend = "Common Name de l'éméteur du certificat"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
|
@ -1773,18 +1747,21 @@ class serialNumber(Attr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
ldap_name = "serialNumber"
|
ldap_name = "serialNumber"
|
||||||
python_type = int
|
python_type = int
|
||||||
|
can_modify = [nounou]
|
||||||
legend = "Numéro de série du certificat"
|
legend = "Numéro de série du certificat"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class start(intAttr):
|
class start(intAttr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
ldap_name = "start"
|
ldap_name = "start"
|
||||||
|
can_modify = [nounou]
|
||||||
legend = "Date de début"
|
legend = "Date de début"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
class end(intAttr):
|
class end(intAttr):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
ldap_name = "end"
|
ldap_name = "end"
|
||||||
|
can_modify = [nounou]
|
||||||
legend = "Date de fin"
|
legend = "Date de fin"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
|
@ -1801,6 +1778,7 @@ class revocked(boolAttr):
|
||||||
ldap_name = "revocked"
|
ldap_name = "revocked"
|
||||||
singlevalue = True
|
singlevalue = True
|
||||||
optional = True
|
optional = True
|
||||||
|
can_modify = [nounou]
|
||||||
legend = "Détermine si le certificat est révoqué"
|
legend = "Détermine si le certificat est révoqué"
|
||||||
|
|
||||||
@crans_attribute
|
@crans_attribute
|
||||||
|
|
|
@ -47,6 +47,7 @@ if '/usr/scripts' not in sys.path:
|
||||||
sys.path.append('/usr/scripts')
|
sys.path.append('/usr/scripts')
|
||||||
from gestion import config
|
from gestion import config
|
||||||
from unicodedata import normalize
|
from unicodedata import normalize
|
||||||
|
import subprocess
|
||||||
from netifaces import interfaces, ifaddresses, AF_INET
|
from netifaces import interfaces, ifaddresses, AF_INET
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -54,11 +55,6 @@ try:
|
||||||
except:
|
except:
|
||||||
pytz = None
|
pytz = None
|
||||||
|
|
||||||
try:
|
|
||||||
import dateutil.tz
|
|
||||||
except:
|
|
||||||
dateutil = None
|
|
||||||
|
|
||||||
DEVNULL = open(os.devnull, 'w')
|
DEVNULL = open(os.devnull, 'w')
|
||||||
|
|
||||||
def find_rid_plage(rid):
|
def find_rid_plage(rid):
|
||||||
|
@ -249,6 +245,7 @@ def escape(chaine):
|
||||||
dans une requête ldap."""
|
dans une requête ldap."""
|
||||||
return ldap.filter.escape_filter_chars(chaine)
|
return ldap.filter.escape_filter_chars(chaine)
|
||||||
|
|
||||||
|
|
||||||
def hash_password(password, salt=None, longueur=4):
|
def hash_password(password, salt=None, longueur=4):
|
||||||
if longueur < 4:
|
if longueur < 4:
|
||||||
raise ValueError("salt devrait faire au moins 4 octets")
|
raise ValueError("salt devrait faire au moins 4 octets")
|
||||||
|
@ -344,57 +341,21 @@ def from_generalized_time_format(gtf):
|
||||||
"""
|
"""
|
||||||
return time.mktime(time.strptime(gtf.split("-", 1)[0].split("+", 1)[0].split('Z', 1)[0], "%Y%m%d%H%M%S"))
|
return time.mktime(time.strptime(gtf.split("-", 1)[0].split("+", 1)[0].split('Z', 1)[0], "%Y%m%d%H%M%S"))
|
||||||
|
|
||||||
def localized_datetime(date=None, tz=None):
|
|
||||||
"""Builds a datetime object based on a date string formatted as
|
|
||||||
%Y%m%d%H%M%S, and a tz timezone looking like +0200"""
|
|
||||||
|
|
||||||
if tz is None:
|
|
||||||
if date is not None:
|
|
||||||
if "+" in date or '-' in date or 'Z' in date:
|
|
||||||
if date.endswith("Z"):
|
|
||||||
date = date[:-1] + "+0000"
|
|
||||||
date, tz = date[:-5], date[-5:]
|
|
||||||
|
|
||||||
_notz = (tz is None)
|
|
||||||
|
|
||||||
# Shit may happen
|
|
||||||
if tz == "Z":
|
|
||||||
tz = "+0000"
|
|
||||||
|
|
||||||
if date is not None:
|
|
||||||
the_date = datetime.datetime.strptime(date, "%Y%m%d%H%M%S")
|
|
||||||
else:
|
|
||||||
the_date = datetime.datetime.now()
|
|
||||||
|
|
||||||
# No timezone means we try to get from the system
|
|
||||||
# if we have dateutil, else, UTC.
|
|
||||||
if tz is None:
|
|
||||||
if dateutil is not None:
|
|
||||||
tz = datetime.datetime.now(dateutil.tz.tzlocal()).strftime("%z")
|
|
||||||
else:
|
|
||||||
tz = "+0000"
|
|
||||||
|
|
||||||
# No pytz means no timezoned datetime
|
|
||||||
if pytz is not None:
|
|
||||||
the_timezone = pytz.FixedOffset(int(tz[0:-2])*60 + int(tz[-2:]))
|
|
||||||
the_date = the_timezone.localize(the_date)
|
|
||||||
the_date = the_timezone.normalize(the_date)
|
|
||||||
else:
|
|
||||||
# Maybe we can do something
|
|
||||||
if dateutil is not None:
|
|
||||||
if _notz:
|
|
||||||
the_date.replace(tzinfo=dateutil.tz.tzlocal())
|
|
||||||
|
|
||||||
return the_date
|
|
||||||
|
|
||||||
def datetime_from_generalized_time_format(gtf):
|
def datetime_from_generalized_time_format(gtf):
|
||||||
"""Returns a datetime from generalized time format"""
|
"""Returns a datetime from generalized time format
|
||||||
|
|
||||||
|
"""
|
||||||
if '-' in gtf or '+' in gtf:
|
if '-' in gtf or '+' in gtf:
|
||||||
date, tz = gtf[0:14], gtf[14:]
|
date, tz = gtf[0:14], gtf[14:]
|
||||||
else:
|
else:
|
||||||
date = gtf.replace("Z", '')
|
date = gtf.replace("Z", '')
|
||||||
tz = '+0000'
|
tz = '+0000'
|
||||||
return localized_datetime(date, tz)
|
the_date = datetime.datetime.strptime(date, "%Y%m%d%H%M%S")
|
||||||
|
if pytz is not None:
|
||||||
|
the_timezone = pytz.FixedOffset(int(tz[0:-2])*60 + int(tz[-2:]))
|
||||||
|
the_date = the_timezone.localize(the_date)
|
||||||
|
the_date = the_timezone.normalize(the_date)
|
||||||
|
return the_date
|
||||||
|
|
||||||
def datetime_to_generalized_time_format(datetime_obj):
|
def datetime_to_generalized_time_format(datetime_obj):
|
||||||
"""Transforms a datetime to a GTF"""
|
"""Transforms a datetime to a GTF"""
|
||||||
|
|
32
lc_ldap.py
32
lc_ldap.py
|
@ -1,3 +1,4 @@
|
||||||
|
#!/usr/bin/env python
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
#
|
#
|
||||||
# LC_LDAP.PY-- LightWeight CransLdap
|
# LC_LDAP.PY-- LightWeight CransLdap
|
||||||
|
@ -38,7 +39,6 @@
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
import re
|
import re
|
||||||
import time
|
|
||||||
from contextlib import contextmanager
|
from contextlib import contextmanager
|
||||||
|
|
||||||
import ldap
|
import ldap
|
||||||
|
@ -53,12 +53,11 @@ import variables
|
||||||
import copy
|
import copy
|
||||||
import itertools
|
import itertools
|
||||||
|
|
||||||
## import de /usr/scripts
|
## import de /usr/scripts/
|
||||||
if "/usr/scripts" not in sys.path:
|
if not "/usr/scripts/" in sys.path:
|
||||||
sys.path.append('/usr/scripts')
|
sys.path.append('/usr/scripts/')
|
||||||
|
|
||||||
import gestion.config as config
|
import gestion.config as config
|
||||||
from gestion import secrets_new as secrets
|
|
||||||
import cranslib.deprecated
|
import cranslib.deprecated
|
||||||
|
|
||||||
# A priori, ldif_to_uldif et ldif_to_cldif sont obsolètes,
|
# A priori, ldif_to_uldif et ldif_to_cldif sont obsolètes,
|
||||||
|
@ -106,10 +105,6 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
|
|
||||||
# Si un username, on récupère le dn associé…
|
# Si un username, on récupère le dn associé…
|
||||||
if user and not dn:
|
if user and not dn:
|
||||||
if readonly_dn is None:
|
|
||||||
readonly_dn = secrets.get('ldap_readonly_auth_dn')
|
|
||||||
if readonly_password is None:
|
|
||||||
readonly_password = secrets.get('ldap_readonly_password')
|
|
||||||
dn = self.user_to_dn(user, readonly_dn, readonly_password)
|
dn = self.user_to_dn(user, readonly_dn, readonly_password)
|
||||||
|
|
||||||
# Si on a un dn, on se connecte avec à la base ldap sinon on s'y
|
# Si on a un dn, on se connecte avec à la base ldap sinon on s'y
|
||||||
|
@ -117,7 +112,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
if dn:
|
if dn:
|
||||||
self.conn = self.bind_s(dn, cred)
|
self.conn = self.bind_s(dn, cred)
|
||||||
self.dn = dn
|
self.dn = dn
|
||||||
self.droits = [droit.decode(config.ldap_encoding) for droit in self.search_s(dn, ldap.SCOPE_BASE, attrlist=['droits'])[0][1].get('droits', [])]
|
self.droits = self.search_s(dn, ldap.SCOPE_BASE, attrlist=['droits'])[0][1].get('droits', [])
|
||||||
if dn == variables.admin_dn:
|
if dn == variables.admin_dn:
|
||||||
self.droits += [attributs.nounou]
|
self.droits += [attributs.nounou]
|
||||||
# Il faut peupler current_login, qui sera utilisé pour écrire dans l'historique qui fait des modifications
|
# Il faut peupler current_login, qui sera utilisé pour écrire dans l'historique qui fait des modifications
|
||||||
|
@ -252,7 +247,6 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
res = {}
|
res = {}
|
||||||
parent = {}
|
parent = {}
|
||||||
machines = {}
|
machines = {}
|
||||||
factures = {}
|
|
||||||
# (proxying de la base ldap)
|
# (proxying de la base ldap)
|
||||||
for dn, attrs in self.search_s(variables.base_dn, scope=2):
|
for dn, attrs in self.search_s(variables.base_dn, scope=2):
|
||||||
# On crée les listes des machines et propriétaires
|
# On crée les listes des machines et propriétaires
|
||||||
|
@ -262,26 +256,14 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
if not machines.has_key(parent_dn):
|
if not machines.has_key(parent_dn):
|
||||||
machines[parent_dn] = []
|
machines[parent_dn] = []
|
||||||
machines[parent_dn].append(m)
|
machines[parent_dn].append(m)
|
||||||
if dn.startswith('fid='): # les factures
|
|
||||||
f = objets.new_cransldapobject(self, dn, mode, uldif=ldif_to_uldif(attrs))
|
|
||||||
parent_dn = dn.split(',', 1)[1]
|
|
||||||
if not factures.has_key(parent_dn):
|
|
||||||
factures[parent_dn] = []
|
|
||||||
factures[parent_dn].append(f)
|
|
||||||
elif (dn.startswith('aid=') or dn.startswith('cid=') or dn == variables.base_dn) and not parent.has_key(dn):
|
elif (dn.startswith('aid=') or dn.startswith('cid=') or dn == variables.base_dn) and not parent.has_key(dn):
|
||||||
parent[dn] = objets.new_cransldapobject(self, dn, mode, uldif=ldif_to_uldif(attrs))
|
parent[dn] = objets.new_cransldapobject(self, dn, mode, uldif=ldif_to_uldif(attrs))
|
||||||
allmachines = []
|
allmachines = []
|
||||||
for dn in parent: # on associe propriétaires et factures, machines
|
for dn, mlist in machines.iteritems(): # on associe propriétaires et machines
|
||||||
mlist = machines.get(dn, [])
|
|
||||||
flist = factures.get(dn, [])
|
|
||||||
parent[dn]._machines = mlist
|
parent[dn]._machines = mlist
|
||||||
parent[dn]._factures = flist
|
|
||||||
parent[dn]._factures_last_update = time.time()
|
|
||||||
for m in mlist:
|
for m in mlist:
|
||||||
m._proprio = parent[dn]
|
m._proprio = parent[dn]
|
||||||
allmachines.append(m)
|
allmachines.append(m)
|
||||||
for f in flist:
|
|
||||||
f._proprio = parent[dn]
|
|
||||||
return allmachines, parent.values() # on renvoie la liste des machines et des adherents (dont club et crans)
|
return allmachines, parent.values() # on renvoie la liste des machines et des adherents (dont club et crans)
|
||||||
|
|
||||||
def allMachines(self, mode='ro'):
|
def allMachines(self, mode='ro'):
|
||||||
|
@ -329,7 +311,7 @@ class lc_ldap(ldap.ldapobject.LDAPObject, object):
|
||||||
uldif['objectClass'] = [u'machineCrans']
|
uldif['objectClass'] = [u'machineCrans']
|
||||||
assert isinstance(owner, objets.AssociationCrans)
|
assert isinstance(owner, objets.AssociationCrans)
|
||||||
|
|
||||||
elif realm in ["bornes", "bornes-v6"]:
|
elif realm == "bornes":
|
||||||
uldif['objectClass'] = [u'borneWifi']
|
uldif['objectClass'] = [u'borneWifi']
|
||||||
assert isinstance(owner, objets.AssociationCrans)
|
assert isinstance(owner, objets.AssociationCrans)
|
||||||
|
|
||||||
|
|
|
@ -179,7 +179,7 @@ class LdapLockHolder:
|
||||||
host, pid, begin = self.getlock(item, value)
|
host, pid, begin = self.getlock(item, value)
|
||||||
time_left = self.timeout - (time.time() - begin)
|
time_left = self.timeout - (time.time() - begin)
|
||||||
if time_left <= delai:
|
if time_left <= delai:
|
||||||
raise LockExpired("Le lock sur la donnée %r=%r à expiré" % (item, value))
|
raise LockExpired("Le lock sur la donnée %r=%r à expiré" % (item, value, time_left))
|
||||||
|
|
||||||
def removelock(self, item, value, Id='default', force=False):
|
def removelock(self, item, value, Id='default', force=False):
|
||||||
"""
|
"""
|
||||||
|
@ -214,3 +214,6 @@ class LdapLockHolder:
|
||||||
except ldap.INVALID_DN_SYNTAX:
|
except ldap.INVALID_DN_SYNTAX:
|
||||||
print '%s=%s,%s' % (item, value, LOCKS_DN)
|
print '%s=%s,%s' % (item, value, LOCKS_DN)
|
||||||
raise
|
raise
|
||||||
|
except ValueError as e:
|
||||||
|
self.removelock(item, value, Id, force=True)
|
||||||
|
raise LockNotFound()
|
||||||
|
|
530
objets.py
530
objets.py
|
@ -56,9 +56,9 @@ import ldap_locks
|
||||||
import variables
|
import variables
|
||||||
import printing
|
import printing
|
||||||
|
|
||||||
## import de /usr/scripts
|
## import de /usr/scripts/
|
||||||
if "/usr/scripts" not in sys.path:
|
if not "/usr/scripts/" in sys.path:
|
||||||
sys.path.append('/usr/scripts')
|
sys.path.append('/usr/scripts/')
|
||||||
|
|
||||||
import gestion.config as config
|
import gestion.config as config
|
||||||
import gestion.config.impression
|
import gestion.config.impression
|
||||||
|
@ -66,7 +66,6 @@ import cranslib.deprecated
|
||||||
|
|
||||||
#: Champs à ignorer dans l'historique
|
#: Champs à ignorer dans l'historique
|
||||||
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp", "historique"]
|
HIST_IGNORE_FIELDS = ["modifiersName", "entryCSN", "modifyTimestamp", "historique"]
|
||||||
FACTURES_REFRESH_PERIOD = 60
|
|
||||||
|
|
||||||
def new_cransldapobject(conn, dn, mode='ro', uldif=None, lockId=None):
|
def new_cransldapobject(conn, dn, mode='ro', uldif=None, lockId=None):
|
||||||
"""Crée un objet :py:class:`CransLdapObject` en utilisant la classe correspondant à
|
"""Crée un objet :py:class:`CransLdapObject` en utilisant la classe correspondant à
|
||||||
|
@ -84,7 +83,7 @@ def new_cransldapobject(conn, dn, mode='ro', uldif=None, lockId=None):
|
||||||
else:
|
else:
|
||||||
res = conn.search_s(dn, 0)
|
res = conn.search_s(dn, 0)
|
||||||
if not res:
|
if not res:
|
||||||
raise ValueError('objet inexistant: %s' % dn)
|
raise ValueError ('objet inexistant: %s' % dn)
|
||||||
_, attrs = res[0]
|
_, attrs = res[0]
|
||||||
classe = ObjectFactory.get(attrs['objectClass'][0])
|
classe = ObjectFactory.get(attrs['objectClass'][0])
|
||||||
|
|
||||||
|
@ -101,8 +100,7 @@ class CransLdapObject(object):
|
||||||
|
|
||||||
""" Qui peut faire quoi ? """
|
""" Qui peut faire quoi ? """
|
||||||
__slots__ = ("in_context", "conn", "lockId", "attrs", "_modifs", "dn", "parent_dn", "mode")
|
__slots__ = ("in_context", "conn", "lockId", "attrs", "_modifs", "dn", "parent_dn", "mode")
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou],
|
||||||
variables.created: [attributs.nounou],
|
|
||||||
variables.modified: [attributs.nounou],
|
variables.modified: [attributs.nounou],
|
||||||
variables.deleted: [attributs.nounou],
|
variables.deleted: [attributs.nounou],
|
||||||
}
|
}
|
||||||
|
@ -171,7 +169,7 @@ class CransLdapObject(object):
|
||||||
else:
|
else:
|
||||||
res = self.conn.search_s(dn, 0)
|
res = self.conn.search_s(dn, 0)
|
||||||
if not res:
|
if not res:
|
||||||
raise ValueError('objet inexistant: %s' % dn)
|
raise ValueError ('objet inexistant: %s' % dn)
|
||||||
self.dn, ldif = res[0]
|
self.dn, ldif = res[0]
|
||||||
|
|
||||||
# L'objet sortant de la base ldap, on ne fait pas de vérifications sur
|
# L'objet sortant de la base ldap, on ne fait pas de vérifications sur
|
||||||
|
@ -204,12 +202,21 @@ class CransLdapObject(object):
|
||||||
for v in nldif[attr]:
|
for v in nldif[attr]:
|
||||||
if v in vals:
|
if v in vals:
|
||||||
vals.remove(v)
|
vals.remove(v)
|
||||||
nvals = [nldif[attr][vals.index(v)] for v in vals]
|
nvals = [nldif[attr][vals.index(v)] for v in vals ]
|
||||||
raise EnvironmentError("λv. str(Attr(v)) n'est peut-être pas une projection (ie non idempotente):", attr, nvals, vals)
|
raise EnvironmentError("λv. str(Attr(v)) n'est peut-être pas une projection (ie non idempotente):", attr, nvals, vals)
|
||||||
|
|
||||||
def oid(self):
|
def _id(self):
|
||||||
"""Retourne l'id de l'objet courant"""
|
"""Retourne l'id de l'objet courant"""
|
||||||
return [self.dn.split(",")[0].split("=")[1]]
|
if isinstance(self, adherent):
|
||||||
|
return self['aid']
|
||||||
|
elif isinstance(self, machine):
|
||||||
|
return self['mid']
|
||||||
|
elif isinstance(self, club):
|
||||||
|
return self['cid']
|
||||||
|
elif isinstance(self, facture):
|
||||||
|
return self['fid']
|
||||||
|
else:
|
||||||
|
return [self.dn]
|
||||||
|
|
||||||
def _out_of_context(self, *args, **kwargs):
|
def _out_of_context(self, *args, **kwargs):
|
||||||
raise EnvironmentError("Hors du context, impossible de faire des écritures")
|
raise EnvironmentError("Hors du context, impossible de faire des écritures")
|
||||||
|
@ -221,6 +228,8 @@ class CransLdapObject(object):
|
||||||
#self.save = self._out_of_context
|
#self.save = self._out_of_context
|
||||||
#self.create = self._out_of_context
|
#self.create = self._out_of_context
|
||||||
#self.delete = self._out_of_context
|
#self.delete = self._out_of_context
|
||||||
|
# On retombe en read only
|
||||||
|
self.mode = 'ro'
|
||||||
# On purge les lock de l'objet
|
# On purge les lock de l'objet
|
||||||
self.conn.lockholder.purge(self.lockId)
|
self.conn.lockholder.purge(self.lockId)
|
||||||
|
|
||||||
|
@ -250,11 +259,11 @@ class CransLdapObject(object):
|
||||||
def c_mul(a, b):
|
def c_mul(a, b):
|
||||||
return eval(hex((long(a) * b) & 0xFFFFFFFFL)[:-1])
|
return eval(hex((long(a) * b) & 0xFFFFFFFFL)[:-1])
|
||||||
value = 0x345678
|
value = 0x345678
|
||||||
l = 0
|
l=0
|
||||||
keys = self.keys()
|
keys = self.keys()
|
||||||
keys.sort()
|
keys.sort()
|
||||||
for key in keys:
|
for key in keys:
|
||||||
l += len(self.attrs[key])
|
l+=len(self.attrs[key])
|
||||||
for item in self.attrs[key]:
|
for item in self.attrs[key]:
|
||||||
value = c_mul(1000003, value) ^ hash(item)
|
value = c_mul(1000003, value) ^ hash(item)
|
||||||
value = value ^ l
|
value = value ^ l
|
||||||
|
@ -263,31 +272,31 @@ class CransLdapObject(object):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
if self.mode in ['w', 'rw']:
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
return self._modifs.__iter__()
|
return self._modifs.__iter__()
|
||||||
else:
|
else:
|
||||||
return self.attrs.__iter__()
|
return self.attrs.__iter__()
|
||||||
|
|
||||||
def keys(self):
|
def keys(self):
|
||||||
if self.mode in ['w', 'rw']:
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
return self._modifs.keys()
|
return self._modifs.keys()
|
||||||
else:
|
else:
|
||||||
return self.attrs.keys()
|
return self.attrs.keys()
|
||||||
|
|
||||||
def values(self):
|
def values(self):
|
||||||
if self.mode in ['w', 'rw']:
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
return self._modifs.values()
|
return self._modifs.values()
|
||||||
else:
|
else:
|
||||||
return self.attrs.values()
|
return self.attrs.values()
|
||||||
|
|
||||||
def items(self):
|
def items(self):
|
||||||
if self.mode in ['w', 'rw']:
|
if self.mode in [ 'w', 'rw' ]:
|
||||||
return self._modifs.items()
|
return self._modifs.items()
|
||||||
else:
|
else:
|
||||||
return self.attrs.items()
|
return self.attrs.items()
|
||||||
|
|
||||||
def display(self, *args, **kwargs):
|
def display(self, historique=5, blacklist=5):
|
||||||
print printing.sprint(self, *args, **kwargs)
|
print printing.sprint(self, historique=historique, blacklist=blacklist)
|
||||||
|
|
||||||
def history_add(self, login, chain):
|
def history_add(self, login, chain):
|
||||||
"""Ajoute une ligne à l'historique de l'objet.
|
"""Ajoute une ligne à l'historique de l'objet.
|
||||||
|
@ -303,8 +312,7 @@ class CransLdapObject(object):
|
||||||
"Génère une ligne d'historique pour l'arribut attr ou une ligne par attributs pour l'objet courant"
|
"Génère une ligne d'historique pour l'arribut attr ou une ligne par attributs pour l'objet courant"
|
||||||
if attr is None:
|
if attr is None:
|
||||||
for attr in self.keys():
|
for attr in self.keys():
|
||||||
self.history_gen(attr, login=login)
|
self.history_gen(attr)
|
||||||
return
|
|
||||||
def partial_name(name, max_len=14, start=7, end=7):
|
def partial_name(name, max_len=14, start=7, end=7):
|
||||||
if len(name) > max_len:
|
if len(name) > max_len:
|
||||||
return "%s…%s" % (name[:start], name[-end:])
|
return "%s…%s" % (name[:start], name[-end:])
|
||||||
|
@ -335,8 +343,8 @@ class CransLdapObject(object):
|
||||||
if attr.historique == "full":
|
if attr.historique == "full":
|
||||||
comm = u"%s (%s -> %s)" % (attr.ldap_name, old_values[0], new_values[0])
|
comm = u"%s (%s -> %s)" % (attr.ldap_name, old_values[0], new_values[0])
|
||||||
elif attr.historique == "partial":
|
elif attr.historique == "partial":
|
||||||
old = partial_name(unicode(old_values[0]))
|
old = partial_name(str(old_values[0]))
|
||||||
new = partial_name(unicode(new_values[0]))
|
new = partial_name(str(new_values[0]))
|
||||||
comm = u"%s (%s -> %s)" % (attr.ldap_name, old, new)
|
comm = u"%s (%s -> %s)" % (attr.ldap_name, old, new)
|
||||||
elif attr.historique == "info":
|
elif attr.historique == "info":
|
||||||
comm = u"%s" % attr.ldap_name
|
comm = u"%s" % attr.ldap_name
|
||||||
|
@ -345,7 +353,7 @@ class CransLdapObject(object):
|
||||||
if attr.historique == "info":
|
if attr.historique == "info":
|
||||||
comm = u"+%s" % attr.ldap_name
|
comm = u"+%s" % attr.ldap_name
|
||||||
elif attr.historique in ["full", "partial"]:
|
elif attr.historique in ["full", "partial"]:
|
||||||
new = unicode(new_values[0])
|
new = str(new_values[0])
|
||||||
if attr.historique == "partial":
|
if attr.historique == "partial":
|
||||||
new = partial_name(new)
|
new = partial_name(new)
|
||||||
comm = u"%s+%s" % (attr.ldap_name, new)
|
comm = u"%s+%s" % (attr.ldap_name, new)
|
||||||
|
@ -354,7 +362,7 @@ class CransLdapObject(object):
|
||||||
if attr.historique == "info":
|
if attr.historique == "info":
|
||||||
comm = u"-%s" % attr.ldap_name
|
comm = u"-%s" % attr.ldap_name
|
||||||
elif attr.historique in ["full", "partial"]:
|
elif attr.historique in ["full", "partial"]:
|
||||||
old = unicode(old_values[0])
|
old = str(old_values[0])
|
||||||
if attr.historique == "partial":
|
if attr.historique == "partial":
|
||||||
old = partial_name(old)
|
old = partial_name(old)
|
||||||
comm = u"%s-%s" % (attr.ldap_name, old)
|
comm = u"%s-%s" % (attr.ldap_name, old)
|
||||||
|
@ -362,9 +370,9 @@ class CransLdapObject(object):
|
||||||
added = []
|
added = []
|
||||||
deleted = []
|
deleted = []
|
||||||
if attr.historique == "partial":
|
if attr.historique == "partial":
|
||||||
append = lambda x: partial_name(unicode(x))
|
append = lambda x: partial_name(str(x))
|
||||||
else:
|
else:
|
||||||
append = lambda x: unicode(x)
|
append = lambda x: str(x)
|
||||||
for a in new_values:
|
for a in new_values:
|
||||||
if not a in old_values:
|
if not a in old_values:
|
||||||
added.append(append(a))
|
added.append(append(a))
|
||||||
|
@ -429,7 +437,7 @@ class CransLdapObject(object):
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if self.conn.search(dn=self.dn):
|
if self.conn.search(dn=self.dn):
|
||||||
raise ValueError('objet existant: %s' % self.dn)
|
raise ValueError ('objet existant: %s' % self.dn)
|
||||||
except ldap.NO_SUCH_OBJECT:
|
except ldap.NO_SUCH_OBJECT:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -444,8 +452,8 @@ class CransLdapObject(object):
|
||||||
|
|
||||||
ldif = self._modifs.to_ldif()
|
ldif = self._modifs.to_ldif()
|
||||||
for attr in binary:
|
for attr in binary:
|
||||||
ldif['%s;binary' % attr] = ldif[attr]
|
ldif['%s;binary' % attr]=ldif[attr]
|
||||||
del ldif[attr]
|
del(ldif[attr])
|
||||||
# Création de la requête LDAP
|
# Création de la requête LDAP
|
||||||
modlist = addModlist(ldif)
|
modlist = addModlist(ldif)
|
||||||
# Requête LDAP de création de l'objet
|
# Requête LDAP de création de l'objet
|
||||||
|
@ -584,11 +592,11 @@ class CransLdapObject(object):
|
||||||
ldif = self._modifs.to_ldif()
|
ldif = self._modifs.to_ldif()
|
||||||
orig_ldif = self.attrs.to_ldif()
|
orig_ldif = self.attrs.to_ldif()
|
||||||
for attr in binary:
|
for attr in binary:
|
||||||
ldif['%s;binary' % (attr,)] = ldif[attr]
|
ldif['%s;binary' % attr]=ldif[attr]
|
||||||
orig_ldif['%s;binary' % (attr,)] = orig_ldif.get(attr, [])
|
orig_ldif['%s;binary' % attr]=orig_ldif.get(attr, [])
|
||||||
del ldif[attr]
|
del(ldif[attr])
|
||||||
try:
|
try:
|
||||||
del orig_ldif[attr]
|
del(orig_ldif[attr])
|
||||||
except KeyError:
|
except KeyError:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
|
@ -602,10 +610,10 @@ class CransLdapObject(object):
|
||||||
return default
|
return default
|
||||||
|
|
||||||
def __getitem__(self, attr, default=None):
|
def __getitem__(self, attr, default=None):
|
||||||
if self._modifs.has_key(attr) and self.mode in ['w', 'rw']:
|
if self._modifs.has_key(attr) and self.mode in [ 'w', 'rw' ]:
|
||||||
return attributs.AttrsList(self, attr, [v for v in self._modifs[attr]])
|
return attributs.AttrsList(self, attr, [ v for v in self._modifs[attr] ])
|
||||||
elif self.attrs.has_key(attr):
|
elif self.attrs.has_key(attr):
|
||||||
return attributs.AttrsList(self, attr, [v for v in self.attrs[attr]])
|
return attributs.AttrsList(self, attr, [ v for v in self.attrs[attr] ])
|
||||||
elif self.has_key(attr):
|
elif self.has_key(attr):
|
||||||
return attributs.AttrsList(self, attr, []) if default is None else default
|
return attributs.AttrsList(self, attr, []) if default is None else default
|
||||||
else:
|
else:
|
||||||
|
@ -670,11 +678,8 @@ class CransLdapObject(object):
|
||||||
try:
|
try:
|
||||||
for attribut in attrs_before_verif:
|
for attribut in attrs_before_verif:
|
||||||
# Vérification que (attr, value) est localement unique
|
# Vérification que (attr, value) est localement unique
|
||||||
# Il vaut mieux le vérifier ici, car l'erreur que LDAP
|
|
||||||
# lève n'est pas très claire. (mais il est clair qu'il ne
|
|
||||||
# tolère pas les doublons dans un objet)
|
|
||||||
if attrs_before_verif.count(attribut) > 1:
|
if attrs_before_verif.count(attribut) > 1:
|
||||||
raise ValueError("%r en double\n(%r)" % (attribut.legend if attribut.legend else attr, attribut))
|
raise ValueError("%s en double\n(%s)" % (attribut.legend if attribut.legend else attr, attribut))
|
||||||
|
|
||||||
# On lock les nouvelles valeurs globalement unique
|
# On lock les nouvelles valeurs globalement unique
|
||||||
if not no_uniq_lock and attribut.unique and not attribut in self._modifs.get(attr, []) and not attribut in attribut.unique_exclue:
|
if not no_uniq_lock and attribut.unique and not attribut in self._modifs.get(attr, []) and not attribut in attribut.unique_exclue:
|
||||||
|
@ -694,8 +699,8 @@ class CransLdapObject(object):
|
||||||
if not no_concurrent_lock and not attributs.AttributeFactory.get(attr).concurrent and self._modifs.get(attr, []) == self.attrs.get(attr, []) and attrs_before_verif != self.attrs.get(attr, []):
|
if not no_concurrent_lock and not attributs.AttributeFactory.get(attr).concurrent and self._modifs.get(attr, []) == self.attrs.get(attr, []) and attrs_before_verif != self.attrs.get(attr, []):
|
||||||
if not self.in_context:
|
if not self.in_context:
|
||||||
cranslib.deprecated.usage("Des locks ne devrait être ajoutés que dans un context manager", level=2)
|
cranslib.deprecated.usage("Des locks ne devrait être ajoutés que dans un context manager", level=2)
|
||||||
self.conn.lockholder.addlock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',', '_'), attr), self.lockId)
|
self.conn.lockholder.addlock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId)
|
||||||
locked.append(("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',', '_'), attr), self.lockId))
|
locked.append(("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId))
|
||||||
try:
|
try:
|
||||||
# une fois le lock acquit, on vérifie que l'attribut n'a pas été édité entre temps
|
# une fois le lock acquit, on vérifie que l'attribut n'a pas été édité entre temps
|
||||||
if self.conn.search(dn=self.dn, scope=0)[0].get(attr, []) != self.attrs.get(attr, []):
|
if self.conn.search(dn=self.dn, scope=0)[0].get(attr, []) != self.attrs.get(attr, []):
|
||||||
|
@ -717,7 +722,7 @@ class CransLdapObject(object):
|
||||||
self.conn.lockholder.removelock(attr, str(attribut), self.lockId)
|
self.conn.lockholder.removelock(attr, str(attribut), self.lockId)
|
||||||
# Si on remet la valeur antérieure au lock, on le libère
|
# Si on remet la valeur antérieure au lock, on le libère
|
||||||
if not attributs.AttributeFactory.get(attr).concurrent and self._modifs.get(attr, []) != self.attrs.get(attr, []) and attrs_before_verif == self.attrs.get(attr, []):
|
if not attributs.AttributeFactory.get(attr).concurrent and self._modifs.get(attr, []) != self.attrs.get(attr, []) and attrs_before_verif == self.attrs.get(attr, []):
|
||||||
self.conn.lockholder.removelock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',', '_'), attr), self.lockId)
|
self.conn.lockholder.removelock("dn", "%s_%s" % (self.dn.replace('=', '-').replace(',','_'), attr), self.lockId)
|
||||||
|
|
||||||
# On met à jour self._modifs avec les nouvelles valeurs
|
# On met à jour self._modifs avec les nouvelles valeurs
|
||||||
self._modifs[attr] = attrs_before_verif
|
self._modifs[attr] = attrs_before_verif
|
||||||
|
@ -774,7 +779,7 @@ class CransLdapObject(object):
|
||||||
Améliorations possibles:
|
Améliorations possibles:
|
||||||
- Vérifier les blacklistes des machines pour les adhérents ?
|
- Vérifier les blacklistes des machines pour les adhérents ?
|
||||||
"""
|
"""
|
||||||
blacklist_liste = []
|
blacklist_liste=[]
|
||||||
# blacklistes virtuelle si on est un adhérent pour carte étudiant et chambre invalides
|
# blacklistes virtuelle si on est un adhérent pour carte étudiant et chambre invalides
|
||||||
if isinstance(self, adherent):
|
if isinstance(self, adherent):
|
||||||
if self['chbre'][0] == '????':
|
if self['chbre'][0] == '????':
|
||||||
|
@ -786,11 +791,11 @@ class CransLdapObject(object):
|
||||||
blacklist_liste.append(bl)
|
blacklist_liste.append(bl)
|
||||||
blacklist_liste.extend(bl for bl in self.get("blacklist", []) if bl.is_actif())
|
blacklist_liste.extend(bl for bl in self.get("blacklist", []) if bl.is_actif())
|
||||||
if excepts:
|
if excepts:
|
||||||
return [b for b in blacklist_liste if b['type'] not in excepts]
|
return [ b for b in blacklist_liste if b['type'] not in excepts ]
|
||||||
else:
|
else:
|
||||||
return blacklist_liste
|
return blacklist_liste
|
||||||
|
|
||||||
def blacklist(self, sanction, commentaire, debut="now", fin='-'):
|
def blacklist(self, sanction, commentaire, debut="now", fin = '-'):
|
||||||
"""
|
"""
|
||||||
Blacklistage de la ou de toutes la machines du propriétaire
|
Blacklistage de la ou de toutes la machines du propriétaire
|
||||||
* debut et fin sont le nombre de secondes depuis epoch
|
* debut et fin sont le nombre de secondes depuis epoch
|
||||||
|
@ -842,51 +847,31 @@ def crans_object(classe):
|
||||||
class InetOrgPerson(CransLdapObject):
|
class InetOrgPerson(CransLdapObject):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
ldap_name = "inetOrgPerson"
|
ldap_name = "inetOrgPerson"
|
||||||
def __unicode__(self):
|
|
||||||
return u"%s : cn=%s" % (self.__class__.__name__, self['cn'][0])
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return str(self.__class__.__name__) + " : cn=" + str(self['cn'][0])
|
||||||
pass
|
pass
|
||||||
|
|
||||||
class proprio(CransLdapObject):
|
class proprio(CransLdapObject):
|
||||||
u""" Un propriétaire de machine (adhérent, club…) """
|
u""" Un propriétaire de machine (adhérent, club…) """
|
||||||
__slots__ = ("_machines", "_factures", "full", '_factures_last_update')
|
__slots__ = ("_machines", "_factures", "full")
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou, attributs.bureau, attributs.soi, attributs.cableur],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou, attributs.bureau,],
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.soi,
|
|
||||||
attributs.cableur,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
crans_account_attribs = [
|
crans_account_attribs = [attributs.uid, attributs.canonicalAlias, attributs.solde,
|
||||||
attributs.uid, attributs.canonicalAlias, attributs.solde,
|
|
||||||
attributs.contourneGreylist, attributs.derniereConnexion,
|
attributs.contourneGreylist, attributs.derniereConnexion,
|
||||||
attributs.homepageAlias, attributs.loginShell, attributs.gecos,
|
attributs.homepageAlias, attributs.loginShell, attributs.gecos,
|
||||||
attributs.uidNumber, attributs.homeDirectory,
|
attributs.uidNumber, attributs.homeDirectory,
|
||||||
attributs.gidNumber, attributs.userPassword,
|
attributs.gidNumber, attributs.userPassword,
|
||||||
attributs.mailAlias, attributs.cn, attributs.rewriteMailHeaders,
|
attributs.mailAlias, attributs.cn, attributs.rewriteMailHeaders,
|
||||||
attributs.mailExt, attributs.compteWiki, attributs.droits,
|
attributs.mailExt, attributs.compteWiki, attributs.droits,
|
||||||
attributs.shadowExpire,
|
attributs.shadowExpire]
|
||||||
]
|
default_attribs = [attributs.nom, attributs.chbre, attributs.paiement, attributs.info,
|
||||||
default_attribs = [
|
|
||||||
attributs.nom, attributs.chbre, attributs.paiement, attributs.info,
|
|
||||||
attributs.blacklist, attributs.controle, attributs.historique,
|
attributs.blacklist, attributs.controle, attributs.historique,
|
||||||
attributs.debutAdhesion, attributs.finAdhesion, attributs.debutConnexion,
|
attributs.debutAdhesion, attributs.finAdhesion, attributs.debutConnexion,
|
||||||
attributs.finConnexion,
|
attributs.finConnexion]
|
||||||
]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attribs(self):
|
def attribs(self):
|
||||||
|
@ -903,17 +888,13 @@ class proprio(CransLdapObject):
|
||||||
"""Renvoie la liste des clubs dont l'adherent est imprimeur (surchargée dans les objets adherent)"""
|
"""Renvoie la liste des clubs dont l'adherent est imprimeur (surchargée dans les objets adherent)"""
|
||||||
return []
|
return []
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return u"%s : nom=%s" % (self.__class__.__name__, self['nom'][0])
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return str(self.__class__.__name__) + " : nom=" + str(self['nom'][0])
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(proprio, self).__init__(*args, **kwargs)
|
super(proprio, self).__init__(*args, **kwargs)
|
||||||
self._machines = None
|
self._machines = None
|
||||||
self._factures = None
|
self._factures = None
|
||||||
self._factures_last_update = 0
|
|
||||||
|
|
||||||
def delete_compte(self, mail):
|
def delete_compte(self, mail):
|
||||||
# Je pense qu'en pratique cette vérification ne sert à rien puisqu'on se fera jetter à la tentative de modification
|
# Je pense qu'en pratique cette vérification ne sert à rien puisqu'on se fera jetter à la tentative de modification
|
||||||
|
@ -932,15 +913,15 @@ class proprio(CransLdapObject):
|
||||||
self['uidNumber'] = []
|
self['uidNumber'] = []
|
||||||
self['gidNumber'] = []
|
self['gidNumber'] = []
|
||||||
self['gecos'] = []
|
self['gecos'] = []
|
||||||
self['shadowExpire'] = []
|
self['shadowExpire']=[]
|
||||||
self['derniereConnexion'] = []
|
self['derniereConnexion']=[]
|
||||||
self['mailExt'] = []
|
self['mailExt']=[]
|
||||||
self['uid'] = []
|
self['uid' ]=[]
|
||||||
self._modifs['objectClass'] = [u'adherent']
|
self._modifs['objectClass'] = [u'adherent']
|
||||||
self.full = False
|
self.full = False
|
||||||
|
|
||||||
|
|
||||||
def compte(self, login=None, uidNumber=0, hash_pass='', shell=config.login_shell):
|
def compte(self, login = None, uidNumber=0, hash_pass = '', shell=config.login_shell):
|
||||||
u"""Renvoie le nom du compte crans. S'il n'existe pas, et que login
|
u"""Renvoie le nom du compte crans. S'il n'existe pas, et que login
|
||||||
est précisé, le crée."""
|
est précisé, le crée."""
|
||||||
|
|
||||||
|
@ -948,6 +929,7 @@ class proprio(CransLdapObject):
|
||||||
return self['uid'][0]
|
return self['uid'][0]
|
||||||
|
|
||||||
elif login:
|
elif login:
|
||||||
|
fn = crans_utils.strip_accents(unicode(self['prenom'][0]).capitalize())
|
||||||
ln = crans_utils.strip_accents(unicode(self['nom'][0]).capitalize())
|
ln = crans_utils.strip_accents(unicode(self['nom'][0]).capitalize())
|
||||||
login = crans_utils.strip_spaces(crans_utils.strip_accents(login), by=u'-').lower()
|
login = crans_utils.strip_spaces(crans_utils.strip_accents(login), by=u'-').lower()
|
||||||
if not re.match('^[a-z][-a-z]{1,15}$', login):
|
if not re.match('^[a-z][-a-z]{1,15}$', login):
|
||||||
|
@ -955,43 +937,25 @@ class proprio(CransLdapObject):
|
||||||
if crans_utils.mailexist(login):
|
if crans_utils.mailexist(login):
|
||||||
raise ValueError("Login existant ou correspondant à un alias mail.")
|
raise ValueError("Login existant ou correspondant à un alias mail.")
|
||||||
|
|
||||||
if self.ldap_name == u'adherent':
|
home = u'/home/' + login
|
||||||
|
|
||||||
home = u'/home/' + login[0] + '/' + login
|
|
||||||
if os.path.exists(home):
|
if os.path.exists(home):
|
||||||
raise ValueError('Création du compte impossible : home existant')
|
raise ValueError('Création du compte impossible : home existant')
|
||||||
|
|
||||||
if os.path.exists("/home/mail/" + login):
|
if os.path.exists("/var/mail/" + login):
|
||||||
raise ValueError('Création du compte impossible : /home/mail/%s existant' % str(login))
|
raise ValueError('Création du compte impossible : /var/mail/%s existant' % str(login))
|
||||||
|
|
||||||
fn = crans_utils.strip_accents(unicode(self['prenom'][0]).capitalize())
|
|
||||||
self._modifs['objectClass'] = [u'adherent', u'cransAccount', u'posixAccount', u'shadowAccount']
|
self._modifs['objectClass'] = [u'adherent', u'cransAccount', u'posixAccount', u'shadowAccount']
|
||||||
|
self['uid' ] = [login]
|
||||||
self['homeDirectory'] = [home]
|
self['homeDirectory'] = [home]
|
||||||
self['cn'] = [fn + u' ' + ln]
|
|
||||||
self['mail'] = [login + u"@crans.org"]
|
self['mail'] = [login + u"@crans.org"]
|
||||||
calias = crans_utils.strip_spaces(fn) + u'.' + crans_utils.strip_spaces(ln) + '@crans.org'
|
calias = crans_utils.strip_spaces(fn) + u'.' + crans_utils.strip_spaces(ln) + '@crans.org'
|
||||||
if crans_utils.mailexist(calias):
|
if crans_utils.mailexist(calias):
|
||||||
calias = login + u'@crans.org'
|
calias = login
|
||||||
if crans_utils.mailexist(calias):
|
|
||||||
raise ValueError('Creation impossible, Alias canonique déjà pris, merci de choisir un autre login')
|
|
||||||
self['canonicalAlias'] = [calias]
|
self['canonicalAlias'] = [calias]
|
||||||
|
self['cn'] = [ fn + u' ' + ln ]
|
||||||
else:
|
|
||||||
# C'est un club
|
|
||||||
home = u'/home/c/club/' + login.split('-', 1)[-1]
|
|
||||||
if os.path.exists(home):
|
|
||||||
raise ValueError('Création du compte impossible : home existant')
|
|
||||||
if os.path.exists("/home/mail/" + login):
|
|
||||||
raise ValueError('Création du compte impossible : /home/mail/%s existant' % str(login))
|
|
||||||
self._modifs['objectClass'] = [u'club', u'cransAccount', u'posixAccount', u'shadowAccount']
|
|
||||||
self['homeDirectory'] = [home]
|
|
||||||
self['cn'] = [ln]
|
|
||||||
|
|
||||||
# Les attributs communs
|
|
||||||
self['uid'] = [login]
|
|
||||||
self['loginShell'] = [unicode(shell)]
|
self['loginShell'] = [unicode(shell)]
|
||||||
if hash_pass:
|
|
||||||
self['userPassword'] = [unicode(hash_pass)]
|
self['userPassword'] = [unicode(hash_pass)]
|
||||||
|
self["solde"] = 0.0
|
||||||
|
|
||||||
if uidNumber:
|
if uidNumber:
|
||||||
if self.conn.search(u'(uidNumber=%s)' % uidNumber):
|
if self.conn.search(u'(uidNumber=%s)' % uidNumber):
|
||||||
|
@ -1045,45 +1009,11 @@ class proprio(CransLdapObject):
|
||||||
|
|
||||||
def fin_adhesion(self):
|
def fin_adhesion(self):
|
||||||
"""Retourne la date de fin d'adhésion"""
|
"""Retourne la date de fin d'adhésion"""
|
||||||
return max([
|
return max([float(facture.get('finAdhesion', [crans_utils.from_generalized_time_format(attributs.finAdhesion.default)])[0]) for facture in self.factures(refresh=True, mode="ro") if facture.get('controle', [''])[0] != u"FALSE" and facture.get('recuPaiement', [''])[0] != ''] + [0.0])
|
||||||
facture.get('finAdhesion', [attributs.finAdhesion.default])[0]
|
|
||||||
for facture in self.factures(refresh=(time.time() - self._factures_last_update > FACTURES_REFRESH_PERIOD))
|
|
||||||
if facture.get('controle', [''])[0] != u"FALSE" and facture.get('recuPaiement', [])
|
|
||||||
] + [attributs.finAdhesion.default])
|
|
||||||
|
|
||||||
def fin_connexion(self):
|
def fin_connexion(self):
|
||||||
"""Retourne la date de fin de connexion"""
|
"""Retourne la date de fin de connexion"""
|
||||||
return max([
|
return max([float(facture.get('finConnexion', [crans_utils.from_generalized_time_format(attributs.finConnexion.default)])[0]) for facture in self.factures(refresh=True, mode="ro") if facture.get('controle', [''])[0] != u"FALSE" and facture.get('recuPaiement', [''])[0] != ''] + [0.0])
|
||||||
facture.get('finConnexion', [attributs.finConnexion.default])[0]
|
|
||||||
for facture in self.factures(refresh=(time.time() - self._factures_last_update > FACTURES_REFRESH_PERIOD))
|
|
||||||
if facture.get('controle', [''])[0] != u"FALSE" and facture.get('recuPaiement', [])
|
|
||||||
] + [attributs.finConnexion.default])
|
|
||||||
|
|
||||||
def adhesion_ok(self, no_bl=False):
|
|
||||||
"""Renvoie si le propriétaire a une adhésion en cours."""
|
|
||||||
|
|
||||||
if self.dn == variables.base_dn:
|
|
||||||
return True
|
|
||||||
|
|
||||||
_now = crans_utils.localized_datetime()
|
|
||||||
|
|
||||||
fin_paiement = self.fin_adhesion()
|
|
||||||
|
|
||||||
paiement = (
|
|
||||||
_now < fin_paiement
|
|
||||||
or
|
|
||||||
(
|
|
||||||
config.periode_transitoire
|
|
||||||
and
|
|
||||||
(
|
|
||||||
crans_utils.datetime_from_generalized_time_format(config.gtf_debut_periode_transitoire)
|
|
||||||
<= fin_paiement
|
|
||||||
<= crans_utils.datetime_from_generalized_time_format(config.gtf_fin_periode_transitoire)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return paiement
|
|
||||||
|
|
||||||
def paiement_ok(self, no_bl=False):
|
def paiement_ok(self, no_bl=False):
|
||||||
u"""
|
u"""
|
||||||
|
@ -1092,33 +1022,15 @@ class proprio(CransLdapObject):
|
||||||
"""
|
"""
|
||||||
if self.dn == variables.base_dn:
|
if self.dn == variables.base_dn:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
if not no_bl:
|
if not no_bl:
|
||||||
for bl in self.blacklist_actif():
|
for bl in self.blacklist_actif():
|
||||||
if bl['type'] == 'paiement':
|
if bl['type'] == 'paiement':
|
||||||
return False
|
return False
|
||||||
|
|
||||||
_now = crans_utils.localized_datetime()
|
|
||||||
|
|
||||||
if isinstance(self, adherent):
|
if isinstance(self, adherent):
|
||||||
fin_paiement = min(self.fin_adhesion(), self.fin_connexion())
|
fin_paiement = min(self.fin_adhesion(), self.fin_connexion())
|
||||||
else:
|
else:
|
||||||
fin_paiement = self.fin_adhesion()
|
fin_paiement = self.fin_adhesion()
|
||||||
|
paiement = time.time() < fin_paiement or (config.periode_transitoire and config.debut_periode_transitoire <= fin_paiement <= config.fin_periode_transitoire)
|
||||||
paiement = (
|
|
||||||
_now < fin_paiement
|
|
||||||
or
|
|
||||||
(
|
|
||||||
config.periode_transitoire
|
|
||||||
and
|
|
||||||
(
|
|
||||||
crans_utils.datetime_from_generalized_time_format(config.gtf_debut_periode_transitoire)
|
|
||||||
<= fin_paiement
|
|
||||||
<= crans_utils.datetime_from_generalized_time_format(config.gtf_fin_periode_transitoire)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
|
|
||||||
return paiement
|
return paiement
|
||||||
|
|
||||||
def carte_ok(self):
|
def carte_ok(self):
|
||||||
|
@ -1144,7 +1056,7 @@ class proprio(CransLdapObject):
|
||||||
if new_solde < config.impression.decouvert:
|
if new_solde < config.impression.decouvert:
|
||||||
raise ValueError(u"Solde minimal atteint, opération non effectuée.")
|
raise ValueError(u"Solde minimal atteint, opération non effectuée.")
|
||||||
|
|
||||||
transaction = u"credit" if diff >= 0 else u"debit"
|
transaction = u"credit" if diff >=0 else u"debit"
|
||||||
new_solde = u"%.2f" % new_solde
|
new_solde = u"%.2f" % new_solde
|
||||||
self.history_add(login, u"%s %.2f Euros [%s]" % (transaction, abs(diff), comment))
|
self.history_add(login, u"%s %.2f Euros [%s]" % (transaction, abs(diff), comment))
|
||||||
self["solde"] = new_solde
|
self["solde"] = new_solde
|
||||||
|
@ -1157,7 +1069,7 @@ class proprio(CransLdapObject):
|
||||||
"""Renvoie la liste des machines"""
|
"""Renvoie la liste des machines"""
|
||||||
if self._machines is None or refresh:
|
if self._machines is None or refresh:
|
||||||
try:
|
try:
|
||||||
self._machines = self.conn.search(u'mid=*', dn=self.dn, scope=1, mode=self.mode if mode is None else mode)
|
self._machines = self.conn.search(u'mid=*', dn = self.dn, scope = 1, mode=self.mode if mode is None else mode)
|
||||||
for m in self._machines:
|
for m in self._machines:
|
||||||
m._proprio = self
|
m._proprio = self
|
||||||
except ldap.NO_SUCH_OBJECT:
|
except ldap.NO_SUCH_OBJECT:
|
||||||
|
@ -1173,10 +1085,9 @@ class proprio(CransLdapObject):
|
||||||
refresh = True
|
refresh = True
|
||||||
if self._factures is None or refresh:
|
if self._factures is None or refresh:
|
||||||
try:
|
try:
|
||||||
self._factures = self.conn.search(u'fid=*', dn=self.dn, scope=1, mode=mode)
|
self._factures = self.conn.search(u'fid=*', dn = self.dn, scope = 1, mode=mode)
|
||||||
for m in self._factures:
|
for m in self._factures:
|
||||||
m._proprio = self
|
m._proprio = self
|
||||||
self._factures_last_update = time.time()
|
|
||||||
# Si on manipule un objet pas encore enregistré dans la la bdd
|
# Si on manipule un objet pas encore enregistré dans la la bdd
|
||||||
except ldap.NO_SUCH_OBJECT:
|
except ldap.NO_SUCH_OBJECT:
|
||||||
self._factures = []
|
self._factures = []
|
||||||
|
@ -1236,44 +1147,20 @@ class proprio(CransLdapObject):
|
||||||
class machine(CransLdapObject):
|
class machine(CransLdapObject):
|
||||||
u""" Une machine """
|
u""" Une machine """
|
||||||
__slots__ = ("_proprio", "_certificats")
|
__slots__ = ("_proprio", "_certificats")
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.cableur, attributs.parent, attributs.respo],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou, attributs.bureau, attributs.cableur, attributs.parent, attributs.respo],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou, attributs.bureau, attributs.cableur, attributs.parent, attributs.respo],
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
attributs.parent,
|
|
||||||
attributs.respo,
|
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
attributs.parent,
|
|
||||||
attributs.respo,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
attributs.parent,
|
|
||||||
attributs.respo,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
|
|
||||||
attribs = [
|
attribs = [attributs.mid, attributs.macAddress, attributs.host,
|
||||||
attributs.mid, attributs.macAddress, attributs.host,
|
|
||||||
attributs.rid, attributs.info, attributs.blacklist, attributs.hostAlias,
|
attributs.rid, attributs.info, attributs.blacklist, attributs.hostAlias,
|
||||||
attributs.exempt, attributs.portTCPout, attributs.portTCPin,
|
attributs.exempt, attributs.portTCPout, attributs.portTCPin,
|
||||||
attributs.portUDPout, attributs.portUDPin, attributs.sshFingerprint,
|
attributs.portUDPout, attributs.portUDPin, attributs.sshFingerprint,
|
||||||
attributs.ipHostNumber, attributs.ip6HostNumber, attributs.historique,
|
attributs.ipHostNumber, attributs.ip6HostNumber, attributs.historique,
|
||||||
attributs.dnsIpv6, attributs.machineAlias,
|
attributs.dnsIpv6, attributs.machineAlias]
|
||||||
]
|
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return u"%s : host=%s" % (self.__class__.__name__, self['host'][0])
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return str(self.__class__.__name__) + " : host=" + str(self['host'][0])
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(machine, self).__init__(*args, **kwargs)
|
super(machine, self).__init__(*args, **kwargs)
|
||||||
|
@ -1288,16 +1175,12 @@ class machine(CransLdapObject):
|
||||||
qu'un de ses certificats l'utilise.
|
qu'un de ses certificats l'utilise.
|
||||||
"""
|
"""
|
||||||
if attr in ['host', 'hostAlias']:
|
if attr in ['host', 'hostAlias']:
|
||||||
deleted = [value for value in self[attr] if value not in values]
|
deleted = [ value for value in self[attr] if value not in values ]
|
||||||
for domain in deleted:
|
for domain in deleted:
|
||||||
for certificat in self.certificats():
|
for certificat in self.certificats():
|
||||||
if domain in certificat['hostCert']:
|
if domain in certificat['hostCert']:
|
||||||
raise EnvironmentError("Vous devez d'abord supprimer ou éditer les certificats utilisant le nom de domaine %s avant de le retirer de la machine" % domain)
|
raise EnvironmentError("Vous devez d'abord supprimer ou éditer les certificats utilisant le nom de domaine %s avant de le retirer de la machine" % domain)
|
||||||
|
|
||||||
def oid(self):
|
|
||||||
"""Retourne l'id de l'objet courant"""
|
|
||||||
return self['mid']
|
|
||||||
|
|
||||||
def proprio(self, mode=None, refresh=False):
|
def proprio(self, mode=None, refresh=False):
|
||||||
u"""Renvoie le propriétaire de la machine"""
|
u"""Renvoie le propriétaire de la machine"""
|
||||||
if not hasattr(self, '_proprio') or not self._proprio or refresh:
|
if not hasattr(self, '_proprio') or not self._proprio or refresh:
|
||||||
|
@ -1308,7 +1191,7 @@ class machine(CransLdapObject):
|
||||||
"""Renvoie la liste des certificats de la machine"""
|
"""Renvoie la liste des certificats de la machine"""
|
||||||
if refresh or self._certificats is None:
|
if refresh or self._certificats is None:
|
||||||
try:
|
try:
|
||||||
self._certificats = self.conn.search(u'xid=*', dn=self.dn, scope=1, mode=self.mode)
|
self._certificats = self.conn.search(u'xid=*', dn = self.dn, scope = 1, mode=self.mode)
|
||||||
for m in self._certificats:
|
for m in self._certificats:
|
||||||
m._machine = self
|
m._machine = self
|
||||||
except ldap.NO_SUCH_OBJECT:
|
except ldap.NO_SUCH_OBJECT:
|
||||||
|
@ -1317,7 +1200,7 @@ class machine(CransLdapObject):
|
||||||
|
|
||||||
def blacklist_actif(self, excepts=[]):
|
def blacklist_actif(self, excepts=[]):
|
||||||
u"""Renvoie la liste des blacklistes actives sur la machine et le proprio"""
|
u"""Renvoie la liste des blacklistes actives sur la machine et le proprio"""
|
||||||
black = self.proprio().blacklist_actif(excepts)
|
black=self.proprio().blacklist_actif(excepts)
|
||||||
black.extend(super(machine, self).blacklist_actif(excepts))
|
black.extend(super(machine, self).blacklist_actif(excepts))
|
||||||
return black
|
return black
|
||||||
|
|
||||||
|
@ -1384,7 +1267,7 @@ class machine(CransLdapObject):
|
||||||
sbm['rid'] = (orid, nrid)
|
sbm['rid'] = (orid, nrid)
|
||||||
# Les macAddress sont déjà des unicodes.
|
# Les macAddress sont déjà des unicodes.
|
||||||
# On change l'ip6
|
# On change l'ip6
|
||||||
if old['macAddress'] != new['macAddress']:
|
elif old['macAddress'] != new['macAddress']:
|
||||||
nip6 = unicode(crans_utils.ip6_of_mac(new['macAddress'], new['rid']))
|
nip6 = unicode(crans_utils.ip6_of_mac(new['macAddress'], new['rid']))
|
||||||
try:
|
try:
|
||||||
oip6 = unicode(self._modifs['ip6HostNumber'][0])
|
oip6 = unicode(self._modifs['ip6HostNumber'][0])
|
||||||
|
@ -1418,7 +1301,6 @@ class machine(CransLdapObject):
|
||||||
if unicode(self['ipHostNumber'][0]) != unicode(crans_utils.ip4_of_rid(sbm['rid'][1])):
|
if unicode(self['ipHostNumber'][0]) != unicode(crans_utils.ip4_of_rid(sbm['rid'][1])):
|
||||||
raise ValueError("L'ipv4 et le rid ne concordent pas !")
|
raise ValueError("L'ipv4 et le rid ne concordent pas !")
|
||||||
self['ip6HostNumber'] = [unicode(crans_utils.ip6_of_mac(self['macAddress'][0].value, self['rid'][0].value))]
|
self['ip6HostNumber'] = [unicode(crans_utils.ip6_of_mac(self['macAddress'][0].value, self['rid'][0].value))]
|
||||||
self['rid'] = [sbm['rid'][1]]
|
|
||||||
if sbm['ipHostNumber']:
|
if sbm['ipHostNumber']:
|
||||||
if sbm['ipHostNumber'][1] == u"":
|
if sbm['ipHostNumber'][1] == u"":
|
||||||
ip4 = []
|
ip4 = []
|
||||||
|
@ -1455,21 +1337,14 @@ class AssociationCrans(proprio):
|
||||||
|
|
||||||
def delete(self, comm, login):
|
def delete(self, comm, login):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return u"Le Crans"
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return str(self.__class__.__name__) + " : Le Crans"
|
||||||
|
|
||||||
class BaseInvites(proprio):
|
class BaseInvites(proprio):
|
||||||
u"""Un artefact de la base ldap"""
|
u"""Un artefact de la base ldap"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
def __unicode__(self):
|
|
||||||
return u"%s" % (self.__class__.__name__,)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return str(self.__class__.__name__)
|
||||||
|
|
||||||
def delete(self, comm, login):
|
def delete(self, comm, login):
|
||||||
raise EnvironmentError("Les pauvres invites")
|
raise EnvironmentError("Les pauvres invites")
|
||||||
|
@ -1481,8 +1356,7 @@ class adherent(proprio):
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attribs(self):
|
def attribs(self):
|
||||||
return super(adherent, self).attribs + [
|
return super(adherent, self).attribs + [attributs.aid, attributs.prenom, attributs.tel,
|
||||||
attributs.aid, attributs.prenom, attributs.tel,
|
|
||||||
attributs.mail, attributs.mailInvalide, attributs.charteMA,
|
attributs.mail, attributs.mailInvalide, attributs.charteMA,
|
||||||
attributs.derniereConnexion, attributs.gpgFingerprint,
|
attributs.derniereConnexion, attributs.gpgFingerprint,
|
||||||
attributs.carteEtudiant, attributs.etudes,
|
attributs.carteEtudiant, attributs.etudes,
|
||||||
|
@ -1490,11 +1364,8 @@ class adherent(proprio):
|
||||||
]
|
]
|
||||||
ldap_name = "adherent"
|
ldap_name = "adherent"
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return u"Adhérent : %s %s" % (self['prenom'][0], self['nom'][0])
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return "Adhérent : " + str(self['prenom'][0]) + " " + str(self['nom'][0])
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(adherent, self).__init__(*args, **kwargs)
|
super(adherent, self).__init__(*args, **kwargs)
|
||||||
|
@ -1505,13 +1376,13 @@ class adherent(proprio):
|
||||||
def clubs(self):
|
def clubs(self):
|
||||||
"""Renvoie la liste des clubs dont l'adherent est responsable"""
|
"""Renvoie la liste des clubs dont l'adherent est responsable"""
|
||||||
if self._clubs is None:
|
if self._clubs is None:
|
||||||
self._clubs = self.conn.search(u'responsable=%s' % self['aid'][0], scope=1, mode=self.mode)
|
self._clubs = self.conn.search(u'responsable=%s' % self['aid'][0], scope = 1, mode=self.mode)
|
||||||
return self._clubs
|
return self._clubs
|
||||||
|
|
||||||
def imprimeur_clubs(self):
|
def imprimeur_clubs(self):
|
||||||
"""Renvoie la liste des clubs dont l'adherent est imprimeur"""
|
"""Renvoie la liste des clubs dont l'adherent est imprimeur"""
|
||||||
if self._imprimeur_clubs is None:
|
if self._imprimeur_clubs is None:
|
||||||
self._imprimeur_clubs = self.conn.search(u'imprimeurClub=%s' % self['aid'][0], scope=1, mode=self.mode)
|
self._imprimeur_clubs = self.conn.search(u'imprimeurClub=%s' % self['aid'][0], scope = 1, mode=self.mode)
|
||||||
return self._imprimeur_clubs
|
return self._imprimeur_clubs
|
||||||
|
|
||||||
def delete(self, comm="", login=None):
|
def delete(self, comm="", login=None):
|
||||||
|
@ -1520,31 +1391,13 @@ class adherent(proprio):
|
||||||
raise EnvironmentError("L'adhérent est responsable ou imprimeur pour les clubs %s, suppression impossible" % ", ".join(str(c["cid"][0]) for c in clubs))
|
raise EnvironmentError("L'adhérent est responsable ou imprimeur pour les clubs %s, suppression impossible" % ", ".join(str(c["cid"][0]) for c in clubs))
|
||||||
super(adherent, self).delete(comm, login)
|
super(adherent, self).delete(comm, login)
|
||||||
|
|
||||||
def oid(self):
|
|
||||||
"""Retourne l'id de l'objet courant"""
|
|
||||||
return self['aid']
|
|
||||||
|
|
||||||
@crans_object
|
@crans_object
|
||||||
class club(proprio):
|
class club(proprio):
|
||||||
u"""Club crans"""
|
u"""Club crans"""
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou, attributs.bureau, attributs.respo, attributs.cableur, attributs.soi],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou, attributs.bureau],
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.respo,
|
|
||||||
attributs.cableur,
|
|
||||||
attributs.soi,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
ldap_name = "club"
|
ldap_name = "club"
|
||||||
|
|
||||||
|
@ -1555,15 +1408,8 @@ class club(proprio):
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
super(club, self).__init__(*args, **kwargs)
|
super(club, self).__init__(*args, **kwargs)
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return u"Club : %s" % (self['nom'][0],)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return "Club : " + str(self['nom'][0])
|
||||||
|
|
||||||
def oid(self):
|
|
||||||
"""Retourne l'id de l'objet courant"""
|
|
||||||
return self['cid']
|
|
||||||
|
|
||||||
@crans_object
|
@crans_object
|
||||||
class machineFixe(machine):
|
class machineFixe(machine):
|
||||||
|
@ -1613,95 +1459,50 @@ class machineWifi(machine):
|
||||||
@crans_object
|
@crans_object
|
||||||
class machineCrans(machine):
|
class machineCrans(machine):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou],
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
attribs = machine.attribs + [
|
attribs = machine.attribs + [attributs.prise, attributs.nombrePrises]
|
||||||
attributs.prise, attributs.nombrePrises,
|
|
||||||
]
|
|
||||||
ldap_name = "machineCrans"
|
ldap_name = "machineCrans"
|
||||||
|
|
||||||
@crans_object
|
@crans_object
|
||||||
class borneWifi(machine):
|
class borneWifi(machine):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou],
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
attribs = machine.attribs + [
|
attribs = machine.attribs + [attributs.canal, attributs.puissance, attributs.hotspot,
|
||||||
attributs.canal, attributs.puissance, attributs.hotspot,
|
attributs.prise, attributs.positionBorne, attributs.nvram]
|
||||||
attributs.prise, attributs.positionBorne, attributs.nvram,
|
|
||||||
]
|
|
||||||
ldap_name = "borneWifi"
|
ldap_name = "borneWifi"
|
||||||
|
|
||||||
@crans_object
|
@crans_object
|
||||||
class switchCrans(machine):
|
class switchCrans(machine):
|
||||||
__slots__ = ()
|
__slots__ = ()
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou],
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
attribs = machine.attribs + [
|
attribs = machine.attribs + [attributs.nombrePrises]
|
||||||
attributs.nombrePrises,
|
|
||||||
]
|
|
||||||
|
|
||||||
ldap_name = "switchCrans"
|
ldap_name = "switchCrans"
|
||||||
|
|
||||||
@crans_object
|
@crans_object
|
||||||
class facture(CransLdapObject):
|
class facture(CransLdapObject):
|
||||||
__slots__ = ("_proprio", "_recuPaiement")
|
__slots__ = ("_proprio", "_recuPaiement")
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou, attributs.bureau, attributs.cableur],
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.cableur,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
attribs = [
|
attribs = [attributs.fid, attributs.modePaiement, attributs.recuPaiement,
|
||||||
attributs.fid, attributs.modePaiement, attributs.recuPaiement,
|
|
||||||
attributs.historique, attributs.article, attributs.info,
|
attributs.historique, attributs.article, attributs.info,
|
||||||
attributs.debutAdhesion, attributs.finAdhesion, attributs.debutConnexion,
|
attributs.debutAdhesion, attributs.finAdhesion, attributs.debutConnexion,
|
||||||
attributs.finConnexion, attributs.controle,
|
attributs.finConnexion, attributs.controle ]
|
||||||
]
|
|
||||||
ldap_name = "facture"
|
ldap_name = "facture"
|
||||||
|
|
||||||
def __unicode__(self):
|
|
||||||
return u"Facture : fid=%s" % (self['fid'][0],)
|
|
||||||
|
|
||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return repr(self.__unicode__())
|
return str(self.__class__.__name__) + " : fid=" + str(self['fid'][0])
|
||||||
|
|
||||||
def __init__(self, *args, **kwargs):
|
def __init__(self, *args, **kwargs):
|
||||||
self._proprio = None
|
self._proprio = None
|
||||||
|
@ -1713,14 +1514,10 @@ class facture(CransLdapObject):
|
||||||
raise EnvironmentError("Paiement déjà effectué pour cette facture, impossible de modifier son contenu")
|
raise EnvironmentError("Paiement déjà effectué pour cette facture, impossible de modifier son contenu")
|
||||||
return super(facture, self).__setitem__(attr, value)
|
return super(facture, self).__setitem__(attr, value)
|
||||||
|
|
||||||
def oid(self):
|
|
||||||
"""Retourne l'id de l'objet courant"""
|
|
||||||
return self['fid']
|
|
||||||
|
|
||||||
def total(self):
|
def total(self):
|
||||||
total = 0
|
total=0
|
||||||
for article in self["article"]:
|
for article in self["article"]:
|
||||||
total += int(article['nombre'])*float(article['pu'])
|
total+=int(article['nombre'])*float(article['pu'])
|
||||||
return total
|
return total
|
||||||
|
|
||||||
def crediter(self):
|
def crediter(self):
|
||||||
|
@ -1742,12 +1539,11 @@ class facture(CransLdapObject):
|
||||||
proprio_save = True
|
proprio_save = True
|
||||||
return proprio_save
|
return proprio_save
|
||||||
|
|
||||||
|
|
||||||
if not self._recuPaiement:
|
if not self._recuPaiement:
|
||||||
with self.proprio() as proprio:
|
with self.proprio() as proprio:
|
||||||
proprio_save = credite_arts(proprio)
|
proprio_save = credite_arts(proprio)
|
||||||
# On vient de créditer, le paiement a été reçu
|
# On vient de créditer, le paiement a été reçu
|
||||||
self['recuPaiement'] = crans_utils.datetime_to_generalized_time_format(crans_utils.localized_datetime())
|
self['recuPaiement']=unicode(time.strftime("%Y-%m-%d %H:%M:%S"))
|
||||||
self._recuPaiement = True
|
self._recuPaiement = True
|
||||||
|
|
||||||
# Il faudrait faire quelquechose pour que si l'enregistrement suivant de la facture crash,
|
# Il faudrait faire quelquechose pour que si l'enregistrement suivant de la facture crash,
|
||||||
|
@ -1767,30 +1563,6 @@ class facture(CransLdapObject):
|
||||||
proprio.save()
|
proprio.save()
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def adhesion_connexion(self):
|
|
||||||
u"""Effectue l'adhésion ou la connexion, rempli les attribus ldap correspondants"""
|
|
||||||
|
|
||||||
def do_adh_conn(proprio):
|
|
||||||
u"""Rempli les attribus qu'il faut sur les factures d'adhésion et de connexion"""
|
|
||||||
# On parse les art et on update les attribus
|
|
||||||
_now = crans_utils.localized_datetime()
|
|
||||||
for art in self['article']:
|
|
||||||
if 'ADH' in art['code']:
|
|
||||||
self['debutAdhesion'] = max(proprio.fin_adhesion(), _now)
|
|
||||||
self['finAdhesion'] = max(proprio.fin_adhesion(), _now).replace(year=max(proprio.fin_adhesion(), _now).year + 1)
|
|
||||||
if 'CAI' in art['code']:
|
|
||||||
nbr_mois = int(art['code'].replace('CAI',''))
|
|
||||||
self['debutConnexion'] = max(proprio.fin_connexion(), _now)
|
|
||||||
con_month = max(proprio.fin_connexion(), _now).month
|
|
||||||
con_year = max(proprio.fin_connexion(), _now).year
|
|
||||||
self['finConnexion'] = max(proprio.fin_connexion(), _now).replace(year=con_year + ((con_month + nbr_mois) // 12), month= (con_month + nbr_mois - 1 ) % 12 + 1)
|
|
||||||
return
|
|
||||||
|
|
||||||
# On effectue les opérations
|
|
||||||
do_adh_conn(self.proprio())
|
|
||||||
self.crediter()
|
|
||||||
|
|
||||||
|
|
||||||
def proprio(self, refresh=False):
|
def proprio(self, refresh=False):
|
||||||
u"""Renvoie le propriétaire de la facture"""
|
u"""Renvoie le propriétaire de la facture"""
|
||||||
if refresh or not self._proprio:
|
if refresh or not self._proprio:
|
||||||
|
@ -1800,41 +1572,19 @@ class facture(CransLdapObject):
|
||||||
@crans_object
|
@crans_object
|
||||||
class baseCert(CransLdapObject):
|
class baseCert(CransLdapObject):
|
||||||
__slots__ = ("_machine",)
|
__slots__ = ("_machine",)
|
||||||
can_be_by = {
|
can_be_by = { variables.created: [attributs.nounou, attributs.bureau, attributs.parent],
|
||||||
variables.created: [
|
variables.modified: [attributs.nounou, attributs.bureau, attributs.parent],
|
||||||
attributs.nounou,
|
variables.deleted: [attributs.nounou, attributs.bureau, attributs.parent],
|
||||||
attributs.bureau,
|
|
||||||
attributs.parent,
|
|
||||||
],
|
|
||||||
variables.modified: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.parent,
|
|
||||||
],
|
|
||||||
variables.deleted: [
|
|
||||||
attributs.nounou,
|
|
||||||
attributs.bureau,
|
|
||||||
attributs.parent,
|
|
||||||
],
|
|
||||||
}
|
}
|
||||||
default_attribs = [
|
default_attribs = [ attributs.xid, attributs.certificat, attributs.hostCert, attributs.historique,
|
||||||
attributs.xid, attributs.certificat, attributs.hostCert, attributs.historique,
|
attributs.info, attributs.csr ]
|
||||||
attributs.info, attributs.csr,
|
|
||||||
]
|
|
||||||
|
|
||||||
tlsa_attribs = [
|
tlsa_attribs = [ attributs.certificatUsage, attributs.selector, attributs.matchingType,
|
||||||
attributs.certificatUsage, attributs.selector, attributs.matchingType,
|
attributs.portTCPin, attributs.portUDPin]
|
||||||
attributs.portTCPin, attributs.portUDPin,
|
x509_attribs = [ attributs.issuerCN, attributs.start, attributs.end,
|
||||||
]
|
attributs.crlUrl, attributs.revocked, attributs.serialNumber ]
|
||||||
|
|
||||||
x509_attribs = [
|
private_attribs = [ attributs.privatekey, attributs.encrypted ]
|
||||||
attributs.issuerCN, attributs.start, attributs.end,
|
|
||||||
attributs.crlUrl, attributs.revocked, attributs.serialNumber,
|
|
||||||
]
|
|
||||||
|
|
||||||
private_attribs = [
|
|
||||||
attributs.privatekey, attributs.encrypted,
|
|
||||||
]
|
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def attribs(self):
|
def attribs(self):
|
||||||
|
@ -1869,9 +1619,9 @@ class baseCert(CransLdapObject):
|
||||||
s'il est réèlement présent dans les données du certificat.
|
s'il est réèlement présent dans les données du certificat.
|
||||||
"""
|
"""
|
||||||
if attr in ['hostCert']:
|
if attr in ['hostCert']:
|
||||||
deleted = [value for value in self[attr] if value not in values]
|
deleted = [ value for value in self[attr] if value not in values ]
|
||||||
for domain in deleted:
|
for domain in deleted:
|
||||||
if domain in [self['certificat'][0]['subject']['CN']] + self['certificat'][0]['extensions'].get('subjectAltName', []):
|
if domain in [self['certificat'][0]['subject']['CN']] + self['certificat'][0]['extensions'].get('subjectAltName',[]):
|
||||||
raise EnvironmentError("Vous ne pouvez pas retirer le domaine %s alors qu'il est déclaré dans le certificat" % domain)
|
raise EnvironmentError("Vous ne pouvez pas retirer le domaine %s alors qu'il est déclaré dans le certificat" % domain)
|
||||||
|
|
||||||
def private(self, privatekey, encrypted):
|
def private(self, privatekey, encrypted):
|
||||||
|
@ -1881,8 +1631,8 @@ class baseCert(CransLdapObject):
|
||||||
return
|
return
|
||||||
self._modifs['objectClass'].append(u"privateKey")
|
self._modifs['objectClass'].append(u"privateKey")
|
||||||
#self.attribs.extend(self.private_attribs)
|
#self.attribs.extend(self.private_attribs)
|
||||||
self['encrypted'] = encrypted
|
self['encrypted']=encrypted
|
||||||
self['privatekey'] = privatekey
|
self['privatekey']=privatekey
|
||||||
|
|
||||||
def tlsa(self, certificatUsage, matchingType):
|
def tlsa(self, certificatUsage, matchingType):
|
||||||
if not self.mode in ['w', 'rw']:
|
if not self.mode in ['w', 'rw']:
|
||||||
|
@ -1891,9 +1641,9 @@ class baseCert(CransLdapObject):
|
||||||
return
|
return
|
||||||
self._modifs['objectClass'].append(u"TLSACert")
|
self._modifs['objectClass'].append(u"TLSACert")
|
||||||
#self.attribs.extend(self.tlsa_attribs)
|
#self.attribs.extend(self.tlsa_attribs)
|
||||||
self['certificatUsage'] = certificatUsage
|
self['certificatUsage']=certificatUsage
|
||||||
self['matchingType'] = matchingType
|
self['matchingType']=matchingType
|
||||||
self['selector'] = 0
|
self['selector']=0
|
||||||
|
|
||||||
def x509(self, issuerCN, start, end, serialNumber, crlUrl=None):
|
def x509(self, issuerCN, start, end, serialNumber, crlUrl=None):
|
||||||
if not self.mode in ['w', 'rw']:
|
if not self.mode in ['w', 'rw']:
|
||||||
|
|
|
@ -3,17 +3,13 @@
|
||||||
{{["aid=",o.aid.0]|join|coul('bleu')}} {{"Nom : "|coul('gras')}}{{o.prenom|join(' ')}} {{o.nom|join(' ')}}
|
{{["aid=",o.aid.0]|join|coul('bleu')}} {{"Nom : "|coul('gras')}}{{o.prenom|join(' ')}} {{o.nom|join(' ')}}
|
||||||
{% endblock%}
|
{% endblock%}
|
||||||
{% block proprio %}
|
{% block proprio %}
|
||||||
{% if disp_telephone %}
|
|
||||||
{{"Numéro de téléphone : "|coul('gras')}}{{o.tel|telephone|join(', ')}}
|
{{"Numéro de téléphone : "|coul('gras')}}{{o.tel|telephone|join(', ')}}
|
||||||
{% endif %}
|
|
||||||
{% if disp_adresse %}
|
|
||||||
{% if o.chbre.0 == 'EXT' and o.postalAddress %}
|
{% if o.chbre.0 == 'EXT' and o.postalAddress %}
|
||||||
{{"Adresse : "|coul('gras')}}{{o.postalAddress.0}} {{o.postalAddress.1}}
|
{{"Adresse : "|coul('gras')}}{{o.postalAddress.0}} {{o.postalAddress.1}}
|
||||||
{{o.postalAddress.2}} {{o.postalAddress.3}}
|
{{o.postalAddress.2}} {{o.postalAddress.3}}
|
||||||
{% else %}
|
{% else %}
|
||||||
{{"Chambre : "|coul('gras')}}{{o.chbre.0}} ({{o.chbre.0|string|prise_etat}})
|
{{"Chambre : "|coul('gras')}}{{o.chbre.0}} ({{o.chbre.0|string|prise_etat}})
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% endif %}
|
|
||||||
{{"Études : "|coul('gras')}}{{o.etudes|join(' ')}}
|
{{"Études : "|coul('gras')}}{{o.etudes|join(' ')}}
|
||||||
{{adh}} {% if o.get('controle', []) and 'p' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
{{adh}} {% if o.get('controle', []) and 'p' in o.controle.0.value %}{{"(OK)"|coul('vert')}}{% endif %}
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
{{["fid=",o.oid().0]|join|coul('bleu')}} {{"À : "|coul('gras')}}{{o.proprio().prenom|join(' ')}} {{o.proprio().nom|join(' ')}} ({{o.proprio().oid().0}})
|
{{["fid=",o._id().0]|join|coul('bleu')}} {{"À : "|coul('gras')}}{{o.proprio().prenom|join(' ')}} {{o.proprio().nom|join(' ')}} ({{o.proprio()._id().0}})
|
||||||
{% if o.article %}
|
{% if o.article %}
|
||||||
{{"Article : "|coul('gras')}} Prix N° Total Commentaire
|
{{"Article : "|coul('gras')}} Prix N° Total Commentaire
|
||||||
{% set total = [] %}{% for a in o.article %}
|
{% set total = [] %}{% for a in o.article %}
|
||||||
|
|
|
@ -6,9 +6,6 @@
|
||||||
{{"IPv4 : "|coul('gras')}}{{o.ipHostNumber|join(', ')}}
|
{{"IPv4 : "|coul('gras')}}{{o.ipHostNumber|join(', ')}}
|
||||||
{% if o.ip6HostNumber %}{{"IPv6 : "|coul('gras')}}{{o.ip6HostNumber|join(', ')}}
|
{% if o.ip6HostNumber %}{{"IPv6 : "|coul('gras')}}{{o.ip6HostNumber|join(', ')}}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% if sshfp and o.sshFingerprint %}
|
|
||||||
{{"Fingerprints SSH : "|coul('gras')}}{{o.sshFingerprint|join('\n ')}}
|
|
||||||
{% endif %}
|
|
||||||
{{"DnsIpv6 : "|coul('gras')}}{% if not o.dnsIpv6 or o.dnsIpv6.0.value %}
|
{{"DnsIpv6 : "|coul('gras')}}{% if not o.dnsIpv6 or o.dnsIpv6.0.value %}
|
||||||
{{"TRUE"|coul('vert')}}
|
{{"TRUE"|coul('vert')}}
|
||||||
{% else %}
|
{% else %}
|
||||||
|
|
|
@ -16,7 +16,6 @@ import gestion.annuaires_pg
|
||||||
import gestion.hptools2 as hptools2
|
import gestion.hptools2 as hptools2
|
||||||
|
|
||||||
import lc_ldap.attributs as attributs
|
import lc_ldap.attributs as attributs
|
||||||
import lc_ldap.crans_utils as crans_utils
|
|
||||||
|
|
||||||
def try_import(lib):
|
def try_import(lib):
|
||||||
"""
|
"""
|
||||||
|
@ -202,21 +201,16 @@ def list_factures(factures, width=None):
|
||||||
data = []
|
data = []
|
||||||
for facture in factures:
|
for facture in factures:
|
||||||
controle = facture.get('controle', [""])[0]
|
controle = facture.get('controle', [""])[0]
|
||||||
if controle == u"TRUE":
|
if controle == "TRUE":
|
||||||
controle = style(u"Validée", "vert")
|
controle = style(u"Validée", "vert")
|
||||||
elif controle == u"FALSE":
|
elif controle == "FALSE":
|
||||||
controle = style(u"Invalide", "rouge")
|
controle = style(u"Invalide", "rouge")
|
||||||
else:
|
else:
|
||||||
controle = u"N/A"
|
controle = u"N/A"
|
||||||
if facture.get('recuPaiement', []):
|
|
||||||
_dtime = crans_utils.datetime_from_generalized_time_format(unicode(facture.get('recuPaiement', [attributs.recuPaiement.default])[0]))
|
|
||||||
_recu = _dtime.strftime("%d/%m/%Y %H:%M:%S")
|
|
||||||
else:
|
|
||||||
_recu = False
|
|
||||||
data.append([
|
data.append([
|
||||||
facture['fid'][0],
|
facture['fid'][0],
|
||||||
facture['modePaiement'][0],
|
facture['modePaiement'][0],
|
||||||
style(_recu, 'vert') if _recu else style(u"NON", 'rouge'),
|
style(facture.get('recuPaiement', [])[0], "vert") if facture.get('recuPaiement', []) else style("NON", "rouge"),
|
||||||
controle,
|
controle,
|
||||||
' '.join(attr['code'] for attr in facture.get('article',[])),
|
' '.join(attr['code'] for attr in facture.get('article',[])),
|
||||||
u"%s €" % sum([float(a['pu'])*int(a['nombre']) for a in facture.get('article',[])])
|
u"%s €" % sum([float(a['pu'])*int(a['nombre']) for a in facture.get('article',[])])
|
||||||
|
@ -229,69 +223,49 @@ def list_factures(factures, width=None):
|
||||||
width=width)
|
width=width)
|
||||||
|
|
||||||
def list_adherents(adherents, width=None):
|
def list_adherents(adherents, width=None):
|
||||||
return tableau(
|
return tableau([
|
||||||
[
|
[a['aid'][0],
|
||||||
[
|
|
||||||
a['aid'][0],
|
|
||||||
u' '.join(unicode(i) for i in a['prenom'] + a['nom']),
|
u' '.join(unicode(i) for i in a['prenom'] + a['nom']),
|
||||||
a['chbre'][0],
|
a['chbre'][0], style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
||||||
style('o', 'vert') if a.adhesion_ok() else style('n', 'rouge'),
|
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
||||||
style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
] for a in adherents ],
|
||||||
u', '.join(unicode(m['host'][0]).split('.', 1)[0] for m in a.machines())
|
titre = [u'aid', u'Prénom Nom', u'Chbre', u'P', u'Machines'],
|
||||||
]
|
largeur = [5, 35, 5, 1, '*'],
|
||||||
for a in adherents
|
alignement = ['d', 'c', 'c', 'c', 'g'],
|
||||||
],
|
width=width)
|
||||||
titre=[u'aid', u'Prénom Nom', u'Chbre', u'A', u'C', u'Machines'],
|
|
||||||
largeur=[5, 35, 5, 1, 1, '*'],
|
|
||||||
alignement=['d', 'c', 'c', 'c', 'c', 'g'],
|
|
||||||
width=width
|
|
||||||
)
|
|
||||||
|
|
||||||
def list_clubs(clubs, width=None):
|
def list_clubs(clubs, width=None):
|
||||||
return tableau(
|
return tableau([
|
||||||
[
|
[a['cid'][0],
|
||||||
[
|
|
||||||
a['cid'][0],
|
|
||||||
u' '.join(unicode(i) for i in a['nom']),
|
u' '.join(unicode(i) for i in a['nom']),
|
||||||
a['chbre'][0],
|
a['chbre'][0], style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
||||||
style('o', 'vert') if a.adhesion_ok() else style('n', 'rouge'),
|
|
||||||
style('o', 'vert') if a.paiement_ok() else style('n', 'rouge'),
|
|
||||||
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
u', '.join(unicode(m['host'][0]).split('.',1)[0] for m in a.machines())
|
||||||
]
|
] for a in clubs ],
|
||||||
for a in clubs
|
titre = [u'cid', u'Nom', u'Chbre', u'P', u'Machines'],
|
||||||
],
|
largeur = [5, 35, 5, 1, '*'],
|
||||||
titre = [u'cid', u'Nom', u'Chbre', u'A', u'C', u'Machines'],
|
alignement = ['d', 'c', 'c', 'c', 'g'],
|
||||||
largeur = [5, 35, 5, 1, 1, '*'],
|
width=width)
|
||||||
alignement = ['d', 'c', 'c', 'c', 'c', 'g'],
|
|
||||||
width=width
|
|
||||||
)
|
|
||||||
|
|
||||||
def proprio(proprio, params):
|
def proprio(proprio, params):
|
||||||
_now = crans_utils.localized_datetime()
|
params['o']=proprio
|
||||||
params['o'] = proprio
|
etat_administratif=[]
|
||||||
etat_administratif = []
|
|
||||||
|
|
||||||
if proprio.paiement_ok():
|
if proprio.paiement_ok():
|
||||||
etat_administratif.append(style(u"à jour", "vert"))
|
etat_administratif.append(style(u"à jour", "vert"))
|
||||||
|
|
||||||
if not proprio.paiement_ok():
|
if not proprio.paiement_ok():
|
||||||
etat_administratif.append(style(u"cotisation non réglée", "violet"))
|
etat_administratif.append(style(u"cotisation non réglée", "violet"))
|
||||||
|
if proprio.fin_adhesion() >= time.time():
|
||||||
if proprio.fin_adhesion() >= _now:
|
|
||||||
adh = style(u"Adhésion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_adhesion())),), "vert")
|
adh = style(u"Adhésion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_adhesion())),), "vert")
|
||||||
elif proprio.paiement_ok():
|
elif proprio.paiement_ok():
|
||||||
adh = style(u"Adhésion terminée, mais il y a un sursis.", 'orange')
|
adh = style(u"Adhésion terminée, mais il y a un sursis.", 'orange')
|
||||||
else:
|
else:
|
||||||
adh = style(u"Pas adhérent actuellement.", 'rouge')
|
adh = style(u"Pas adhérent actuellement.", 'rouge')
|
||||||
|
|
||||||
params["adh"] = adh
|
params["adh"] = adh
|
||||||
if proprio.fin_connexion() >= _now:
|
if proprio.fin_connexion() >= time.time():
|
||||||
conn = style(u"Connexion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_connexion())),), "vert")
|
conn = style(u"Connexion jusqu'au %s" % (time.strftime("%d/%m/%Y %H:%M:%S", time.localtime(proprio.fin_connexion())),), "vert")
|
||||||
elif proprio.paiement_ok():
|
elif proprio.paiement_ok():
|
||||||
conn = style(u"Connexion terminée, mais il y a un sursis.", 'orange')
|
conn = style(u"Connexion terminée, mais il y a un sursis.", 'orange')
|
||||||
else:
|
else:
|
||||||
conn = style(u"Pas connecté actuellement.", 'rouge')
|
conn = style(u"Pas connecté actuellement.", 'rouge')
|
||||||
|
|
||||||
params["conn"] = conn
|
params["conn"] = conn
|
||||||
params['etat_administratif'] = etat_administratif
|
params['etat_administratif'] = etat_administratif
|
||||||
|
|
||||||
|
@ -324,10 +298,7 @@ def blacklist(blacklist, params):
|
||||||
|
|
||||||
def sprint(object, historique=5, blacklist_len=5, **params):
|
def sprint(object, historique=5, blacklist_len=5, **params):
|
||||||
from lc_ldap import objets, attributs
|
from lc_ldap import objets, attributs
|
||||||
params.update({
|
params.update({'historique':historique, "blacklist":blacklist_len})
|
||||||
'historique': historique,
|
|
||||||
'blacklist': blacklist_len,
|
|
||||||
})
|
|
||||||
if isinstance(object, objets.machine):
|
if isinstance(object, objets.machine):
|
||||||
return machine(object, params)
|
return machine(object, params)
|
||||||
elif isinstance(object, objets.adherent):
|
elif isinstance(object, objets.adherent):
|
||||||
|
|
|
@ -32,6 +32,7 @@ services_to_attrs['mail_modif'] = [ attributs.droits, attributs.exempt ] + servi
|
||||||
services_to_objects={}
|
services_to_objects={}
|
||||||
services_to_objects['delete']={}
|
services_to_objects['delete']={}
|
||||||
services_to_objects['create']={}
|
services_to_objects['create']={}
|
||||||
|
services_to_objects['create']['home'] = [objets.adherent, objets.club]
|
||||||
services_to_objects['delete']['del_user'] = [objets.adherent, objets.club]
|
services_to_objects['delete']['del_user'] = [objets.adherent, objets.club]
|
||||||
|
|
||||||
NOW = time.time()
|
NOW = time.time()
|
||||||
|
|
|
@ -15,7 +15,7 @@ try:
|
||||||
from gestion import secrets_new as secrets
|
from gestion import secrets_new as secrets
|
||||||
except ImportError:
|
except ImportError:
|
||||||
sys.stderr.write("lc_ldap shortcuts: shaa, cannot import secrets_new. " +
|
sys.stderr.write("lc_ldap shortcuts: shaa, cannot import secrets_new. " +
|
||||||
"try again with /usr/scripts in PYTHONPATH " +
|
"try again with /usr/scripts/ in PYTHONPATH " +
|
||||||
"(argv: %s)\n" % " ".join(getattr(sys, 'argv', [])))
|
"(argv: %s)\n" % " ".join(getattr(sys, 'argv', [])))
|
||||||
sys.path.append("/usr/scripts")
|
sys.path.append("/usr/scripts")
|
||||||
from gestion import secrets_new as secrets
|
from gestion import secrets_new as secrets
|
||||||
|
@ -51,7 +51,7 @@ def lc_ldap_test(*args, **kwargs):
|
||||||
except OSError:
|
except OSError:
|
||||||
pass
|
pass
|
||||||
# On impose le serveur
|
# On impose le serveur
|
||||||
kwargs["uri"] = 'ldap://%s' % (DB_TEST_OVERRIDE or 'vo.adm.crans.org')
|
kwargs["uri"] = 'ldap://%s' % (DB_TEST_OVERRIDE or 'localhost')
|
||||||
kwargs.setdefault("dn", 'cn=admin,dc=crans,dc=org')
|
kwargs.setdefault("dn", 'cn=admin,dc=crans,dc=org')
|
||||||
# Le mot de passe de la base de test
|
# Le mot de passe de la base de test
|
||||||
kwargs.setdefault("cred", variables.ldap_test_password)
|
kwargs.setdefault("cred", variables.ldap_test_password)
|
||||||
|
|
2
test.py
2
test.py
|
@ -14,6 +14,8 @@ import lc_ldap
|
||||||
import shortcuts
|
import shortcuts
|
||||||
import variables
|
import variables
|
||||||
|
|
||||||
|
## import dans /usr/scripts/
|
||||||
|
sys.path.append("/usr/scripts/")
|
||||||
from gestion.affich_tools import anim, OK, cprint, ERREUR
|
from gestion.affich_tools import anim, OK, cprint, ERREUR
|
||||||
|
|
||||||
mail_format = False
|
mail_format = False
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue