This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
ifef-registration/extra/modules/store.py

196 lines
8.6 KiB
Python

# -*- coding: utf-8 -*-
import random
import ldap
from qommon import get_logger
from quixote import get_response
from authentic.identities import Field, get_pwd_length, PasswordAccount, \
IdentityStoreException, IdentitiesStoreLdap, Identity
import callback
class IdentityIFEF(Identity):
def get_preferred_language(self):
return getattr(self, 'c', None) or None
class IdentitiesStoreIFEF(IdentitiesStoreLdap):
identity_class = IdentityIFEF
label = N_('IFEF Ldap Directory')
fields = [
# Identification
Field('personalTitle', N_('Personal Title'),
on_register=False,
size=4, widget_class='SingleSelectWidget',
options=[(None, None, '0'),
('Mme', N_('Miss'), '2'),
('M.', N_('Mister'), '1'),]),
Field('sn', N_('Last name'), required=True, admin_required=True),
Field('givenName', N_('First name'), required=True, admin_required=True),
Field('c', N_('Language'), widget_class='SingleSelectWidget',
options=[
('fr', N_('French')),
('it', N_('Italian')),
('en', N_('English')),
('ro', N_('Romanian')),
('lv', N_('Latvian')),
('es', N_('Spanish')),
], size=10),
Field('dateOfBirth', N_('Birth date'), hint=_('jj/mm/aaaa'),
on_register=True, widget_class='DateWidget', jquery=False),
Field('placeOfBirth', N_('Birth place')),
# Contact
Field('email', N_('Email'),
hint=_("example: john@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_('Professional address')),
Field('postalCode', N_('Professional postal code'), widget_class='ValidatedStringWidget',
regex=r'[0-9]{5}', hint=_('Only digits.')),
Field('l', N_('Professional city')),
Field('st', N_('Professional region'), on_register=False),
Field('department', N_('Professional department'), on_register=False),
Field('homeStreetAdddress', N_('Personnal address'), on_register=False),
Field('homePostalCode', N_('Personnal postal code'), widget_class='ValidatedStringWidget',
regex=r'[0-9]{5}', on_register=False, hint=_('Only digits.')),
Field('homeLocalityName', N_('Personnal city'), on_register=False),
Field('homeStateOrProvinceName', N_('Personnal region'), on_register=False),
Field('homeDepartment', N_('Personnal department'),
on_register=False),
Field('userClass', N_('User class'), 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_('Mobile phone'),
hint=_('Only numbers, dots or spaces.'),
widget_class='ValidatedStringWidget',
regex=r'^ *(|[0-9][0-9. ]*) *$', on_register=False),
Field('homePhone', N_('Telephone perso'),
hint=_('Only numbers, dots or spaces.'),
widget_class='ValidatedStringWidget',
regex=r'^ *(|[0-9][0-9. ]*) *$'),
Field('telephoneNumber', N_('Telephone pro'),
hint=_('Only numbers, dots or spaces.'),
widget_class='ValidatedStringWidget',
regex=r'^ *(|[0-9][0-9. ]*) *$', on_register=False),
# Web
Field('microBlogURL', N_('Twitter account'),
hint=_("example: @twitter, identica, etc.")),
Field('socialNetworkURL', N_('Social network account'),
hint=_("example: compte facebook, linkedin, viadeo, etc.")),
Field('labeledURI', N_('Personnal WEB page')),
Field('voipURI', N_("VoIP address"),
hint=_("example: skype, sip, gtalk"),
on_register=False),
# Attributs specificiques IFEF
Field('numeroPassFormaAssMat', N_('Pass assistant maternelle number'),
read_only=True, on_register=False,
hint=_('Only digits'),
widget_class='ValidatedStringWidget',
regex=r'^[0-9]*$'),
Field('numeroPassFormaSPE', N_('Pass SPE number'), read_only=True,
on_register=False,
hint=_('Only digits'),
widget_class='ValidatedStringWidget',
regex=r'^[0-9]*$'),
Field('numeroURSSAF', N_('URSSAF number'), read_only=True,
on_register=False,
hint=_('Only digits'),
widget_class='ValidatedStringWidget',
regex=r'^[0-9]*$'),
Field('numeroPAJE', N_('PAJE number'), read_only=True,
on_register=False,
hint=_('Only digits'),
widget_class='ValidatedStringWidget',
regex=r'^[0-9]*$'),
Field('numeroIRCEM', N_('IRCEM number'), read_only=True,
on_register=False,
hint=_('Only digits'),
widget_class='ValidatedStringWidget',
regex=r'^[0-9]*$'),
Field('orgDn', N_("Affiliated organisation's LDAP distinguished name"), read_only =
True, multivalued=True, invisible=True, widget_class =
IdentitiesStoreLdap.LdapDnWidget,
on_register=False),
]
def init(self):
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 = 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:
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 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)
# Workaround in order to keep the password clear in memory.
identity.accounts[0].password = account.password
return identity
import authentic.identities
authentic.identities.stores['ifef'] = IdentitiesStoreIFEF