183 lines
8.7 KiB
Python
183 lines
8.7 KiB
Python
import random
|
|
|
|
import ldap
|
|
from qommon.publisher import utf82sitecharset, sitecharset2utf8
|
|
from qommon import get_logger
|
|
from quixote import get_response
|
|
import authentic.identities
|
|
from authentic.identities import Field, get_pwd_length, PasswordAccount, \
|
|
IdentityStoreException
|
|
|
|
import callback
|
|
|
|
class IdentitiesStoreIFEF(authentic.identities.IdentitiesStoreLdap):
|
|
label = N_('IFEF Ldap Directory')
|
|
fields = [
|
|
# Identification
|
|
Field('personalTitle', N_('Personal Title'),
|
|
on_register = False,
|
|
required = False, size = 4, widget_class = 'SingleSelectWidget',
|
|
options = [(None, None, '0'),
|
|
('Mme', N_('Madame'), '2'),
|
|
('Mlle', N_('Mademoiselle'), '3'),
|
|
('M.', N_('Monsieur'), '1'),]),
|
|
Field('sn', N_('Nom'), required = True, admin_required = True),
|
|
Field('givenName', N_('Prenom'), required = True, admin_required = True),
|
|
Field('dateOfBirth', N_('Date de naissance'), hint = _('jj/mm/aaaa'),
|
|
on_register = False, widget_class = 'DateWidget', jquery = False),
|
|
Field('placeOfBirth', N_('Lieu de naissance')),
|
|
# Contact
|
|
Field('email', N_('Adresse email'),
|
|
hint = _("exemple: jean@example.com"), required=True,
|
|
admin_required = True,
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Za-z]{2,4}',
|
|
unique = True),
|
|
# Addresses postales
|
|
Field('street', N_('Adresse'), required = True),
|
|
Field('postalCode', N_('Code postal'), widget_class = 'ValidatedStringWidget',
|
|
regex = r'[0-9]{5}', required = True, hint = _('Ce champ doit contenir cinq chiffres')),
|
|
Field('l', N_('Ville pro'), required = True),
|
|
Field('st', N_('Region pro'), on_register = False),
|
|
Field('department', N_('Departement pro'), on_register = False),
|
|
Field('homeStreetAddress', N_('Adresse perso'), on_register = False),
|
|
Field('homePostalCode', N_('Code postal perso'), widget_class = 'ValidatedStringWidget',
|
|
regex = r'[0-9]{5}', on_register = False, hint = _('Ce champ doit contenir cinq chiffres')),
|
|
Field('homeLocalityName', N_('Ville perso'), on_register = False),
|
|
Field('homeStateOrProvinceName', N_('Region perso'), on_register = False),
|
|
Field('homeDepartment', N_('Departement perso'),
|
|
on_register = False),
|
|
Field('userClass', N_('Classe d\'utilisateur'), read_only = True, value = ['GRAND.PUBLIC'],
|
|
admin_required = True, size = 4, widget_class = 'SingleSelectWidget',
|
|
options = ['GRAND.PUBLIC', 'EMPLOYEUR', 'SAL.SPE/ASSMAT', 'PRO.FORMA',
|
|
'INDIV.PART', 'SAL.IFEF' ], multivalued = True),
|
|
# Telephone
|
|
Field('mobile', N_('Telephone mobile'),
|
|
hint = _('Ce champ ne doit contenir que des chiffres, des points ou des espaces.'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^ *(|[0-9][0-9. ]*) *$', on_register = False),
|
|
Field('homePhone', N_('Telephone perso'),
|
|
hint = _('Ce champ ne doit contenir que des chiffres, des points ou des espaces.'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^ *(|[0-9][0-9. ]*) *$'),
|
|
Field('telephoneNumber', N_('Telephone pro'),
|
|
hint = _('Ce champ ne doit contenir que des chiffres, des points ou des espaces.'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^ *(|[0-9][0-9. ]*) *$', on_register = False),
|
|
# Web
|
|
Field('microBlogURL', N_('Adresse de micro-blogging'),
|
|
hint = _("exemple: twitter, identica, etc.")),
|
|
Field('socialNetworkURL', N_('Adresse de reseau social'),
|
|
hint = _("exemple: compte facebook, linkedin, viadeo, etc.")),
|
|
Field('labeledURI', N_('Page web'),
|
|
hint = _("votre page web personnelle")),
|
|
Field('voipURI', N_("Adresse telephonie IP"),
|
|
hint = _("exemple: skype, sip, gtalk"),
|
|
on_register = False),
|
|
# Attributs specificiques IFEF
|
|
Field('numeroPassFormaAssMat', N_('Numero de pass assistante maternelle'),
|
|
read_only = True, on_register = False,
|
|
hint = _('Entrez un nombre decimal'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^[0-9]*$'),
|
|
Field('numeroPassFormaSPE', N_('Numero de pass SPE'), read_only = True,
|
|
on_register = False,
|
|
hint = _('Entrez un nombre decimal'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^[0-9]*$'),
|
|
Field('numeroURSSAF', N_('Numero URSSAF'), read_only = True,
|
|
on_register = False,
|
|
hint = _('Entrez un nombre decimal'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^[0-9]*$'),
|
|
Field('numeroPAJE', N_('Numero PAJE'), read_only = True,
|
|
on_register = False,
|
|
hint = _('Entrez un nombre decimal'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^[0-9]*$'),
|
|
Field('numeroIRCEM', N_('Numero IRCEM'), read_only = True,
|
|
on_register = False,
|
|
hint = _('Entrez un nombre decimal'),
|
|
widget_class = 'ValidatedStringWidget',
|
|
regex = r'^[0-9]*$'),
|
|
Field('orgDn', N_('DN de l\'organisme d\'affiliation'), read_only =
|
|
True, multivalued = True, invisible = True, widget_class =
|
|
authentic.identities.IdentitiesStoreLdap.LdapDnWidget,
|
|
on_register = False),
|
|
]
|
|
def init(self):
|
|
authentic.identities.IdentitiesStoreLdap.init(self)
|
|
# Allow login using:
|
|
# uid
|
|
# mail
|
|
# numeroPassFormaAssMat
|
|
# numeroPassFormaSPE
|
|
self.uid_request_str = '(&(|(%(uid)s=%%(username)s)(mail=%%(username)s)(numeroPassFormaAssMat=%%(username)s)(numeroPassFormaSPE=%%(username)s))(objectclass=%(oc)s))' % {
|
|
'uid': self.ldap_object_uid, 'oc': self.ldap_object_class }
|
|
self.alpha_request_str = '(&(uid=%%s*)(objectclass=%(oc)s))' % \
|
|
{ 'oc': self.ldap_object_class }
|
|
|
|
def save(self, identity):
|
|
res = authentic.identities.IdentitiesStoreLdap.save(self, identity)
|
|
response = get_response()
|
|
try:
|
|
if response and res:
|
|
id = identity.accounts[0].username
|
|
action = callback.XmlRpcAction.create_ldap_update(
|
|
callback.XmlRpcAction.TYPE_PERSONNE, id)
|
|
response.add_after_job('''Send use information update to Ofbiz, \
|
|
id: %r''' % id, callback.BatchJob(action))
|
|
except Exception, e:
|
|
raise
|
|
return res
|
|
|
|
def remove(self, identity):
|
|
'''Call the parent method and notify Ofbiz'''
|
|
id = identity.accounts[0].username
|
|
action = callback.XmlRpcAction.create_ldap_update(
|
|
callback.XmlRpcAction.TYPE_DELETE, id)
|
|
response = get_response()
|
|
response.add_after_job('''Send removal to Ofbiz of account \
|
|
id: %r''' % id, callback.BatchJob(action))
|
|
return authentic.identities.IdentitiesStoreLdap.remove(self, identity)
|
|
|
|
|
|
# Utilise seulement des majuscules et des chiffres, sauf i,l et 1, O et 0
|
|
pwd_alphabet = 'ABCDEFGHJKMNPQRSTUVWXYZ23456789'
|
|
def create_password(self,for_account='inconnu'):
|
|
pwd_length = get_pwd_length()
|
|
password = ''.join([random.choice(self.pwd_alphabet)
|
|
for x in range(pwd_length)])
|
|
get_logger().debug('Generated new password %r for account %r' % (password, for_account))
|
|
return password
|
|
|
|
def get_identity_for_account(self, account):
|
|
if not isinstance(account, PasswordAccount):
|
|
return
|
|
self.connect_admin()
|
|
escaped_username = ldap.filter.escape_filter_chars(account.username)
|
|
result = self.ldap_conn.search_s(self.ldap_base,
|
|
ldap.SCOPE_SUBTREE,
|
|
self.uid_request_str % { 'username': escaped_username } )
|
|
if not result:
|
|
return
|
|
else:
|
|
uid = result[0][0]
|
|
try:
|
|
try:
|
|
self.ldap_conn.simple_bind_s(uid, account.password)
|
|
except ldap.INVALID_CREDENTIALS:
|
|
self.ldap_conn.simple_bind_s(uid, account.password.upper())
|
|
except ldap.INVALID_CREDENTIALS:
|
|
return
|
|
except ldap.SERVER_DOWN:
|
|
raise IdentityStoreException('LDAP server is down')
|
|
except IndexError:
|
|
return
|
|
identity = self.get_identity(uid)
|
|
# Workaroung in order to keep the password clear in memory.
|
|
identity.accounts[0].password = account.password
|
|
return identity
|
|
|
|
authentic.identities.stores['ifef'] = IdentitiesStoreIFEF
|