|
@ -9,10 +9,10 @@ |
|
|
# Contribution : Joel Grand-Guillaume |
|
|
# Contribution : Joel Grand-Guillaume |
|
|
# |
|
|
# |
|
|
# WARNING: This program as such is intended to be used by professional |
|
|
# WARNING: This program as such is intended to be used by professional |
|
|
# programmers who take the whole responsability of assessing all potential |
|
|
|
|
|
|
|
|
# programmers who take the whole responsibility of assessing all potential |
|
|
# consequences resulting from its eventual inadequacies and bugs |
|
|
# consequences resulting from its eventual inadequacies and bugs |
|
|
# End users who are looking for a ready-to-use solution with commercial |
|
|
# End users who are looking for a ready-to-use solution with commercial |
|
|
# garantees and support are strongly adviced to contract a Free Software |
|
|
|
|
|
|
|
|
# guarantees and support are strongly advised to contract a Free Software |
|
|
# Service Company |
|
|
# Service Company |
|
|
# |
|
|
# |
|
|
# This program is Free Software; you can redistribute it and/or |
|
|
# This program is Free Software; you can redistribute it and/or |
|
@ -30,22 +30,24 @@ |
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
|
|
# |
|
|
# |
|
|
############################################################################## |
|
|
############################################################################## |
|
|
#TODO FInd why company parameter are cached |
|
|
|
|
|
|
|
|
# TODO Find why company parameter are cached |
|
|
|
|
|
|
|
|
import re |
|
|
import re |
|
|
import unicodedata |
|
|
import unicodedata |
|
|
import netsvc |
|
|
|
|
|
|
|
|
from openerp import netsvc |
|
|
try: |
|
|
try: |
|
|
import ldap |
|
|
import ldap |
|
|
import ldap.modlist |
|
|
import ldap.modlist |
|
|
except : |
|
|
|
|
|
print 'python ldap not installed please install it in order to use this module' |
|
|
|
|
|
|
|
|
except: |
|
|
|
|
|
print('python ldap not installed please install it in order to use this module') |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
from osv import osv, fields |
|
|
|
|
|
from tools.translate import _ |
|
|
|
|
|
|
|
|
from openerp.osv import orm, fields |
|
|
|
|
|
from openerp.tools.translate import _ |
|
|
|
|
|
|
|
|
logger = netsvc.Logger() |
|
|
logger = netsvc.Logger() |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LdapConnMApper(object): |
|
|
class LdapConnMApper(object): |
|
|
"""LdapConnMApper: push specific fields from the Terp Partner_contacts to the |
|
|
"""LdapConnMApper: push specific fields from the Terp Partner_contacts to the |
|
|
LDAP schema inetOrgPerson. Ldap bind options are stored in company.r""" |
|
|
LDAP schema inetOrgPerson. Ldap bind options are stored in company.r""" |
|
@ -61,7 +63,7 @@ class LdapConnMApper(object): |
|
|
self.connexion = '' |
|
|
self.connexion = '' |
|
|
self.ACTIVDIR = False |
|
|
self.ACTIVDIR = False |
|
|
|
|
|
|
|
|
#Reading ldap pref |
|
|
|
|
|
|
|
|
# Reading ldap pref |
|
|
user = osv_obj.pool.get('res.users').browse(cursor, uid, uid, context=context) |
|
|
user = osv_obj.pool.get('res.users').browse(cursor, uid, uid, context=context) |
|
|
company = osv_obj.pool.get('res.company').browse(cursor, |
|
|
company = osv_obj.pool.get('res.company').browse(cursor, |
|
|
uid, |
|
|
uid, |
|
@ -75,26 +77,26 @@ class LdapConnMApper(object): |
|
|
self.OU = company.ounit |
|
|
self.OU = company.ounit |
|
|
self.ACTIVDIR = company.is_activedir |
|
|
self.ACTIVDIR = company.is_activedir |
|
|
|
|
|
|
|
|
mand = (self.USER_DN, self.CONTACT_DN, self.LDAP_SERVER , self.PASS, self.OU) |
|
|
|
|
|
|
|
|
mand = (self.USER_DN, self.CONTACT_DN, self.LDAP_SERVER, self.PASS, self.OU) |
|
|
if company.ldap_active: |
|
|
if company.ldap_active: |
|
|
for param in mand: |
|
|
for param in mand: |
|
|
if not param: |
|
|
if not param: |
|
|
raise osv.except_osv(_('Warning !'), |
|
|
|
|
|
_('An LDAP parameter is missing for company %s') % (company.name,)) |
|
|
|
|
|
|
|
|
raise orm.except_orm(_('Warning !'), |
|
|
|
|
|
_('An LDAP parameter is missing for company %s') % (company.name, )) |
|
|
|
|
|
|
|
|
def get_connexion(self): |
|
|
def get_connexion(self): |
|
|
"""create a new ldap connexion""" |
|
|
"""create a new ldap connexion""" |
|
|
logger.notifyChannel("LDAP Address", netsvc.LOG_DEBUG, |
|
|
logger.notifyChannel("LDAP Address", netsvc.LOG_DEBUG, |
|
|
_('connecting to server ldap %s') % (self.LDAP_SERVER,)) |
|
|
|
|
|
if self.PORT : |
|
|
|
|
|
|
|
|
_('connecting to server ldap %s') % (self.LDAP_SERVER, )) |
|
|
|
|
|
if self.PORT: |
|
|
self.connexion = ldap.open(self.LDAP_SERVER, self.PORT) |
|
|
self.connexion = ldap.open(self.LDAP_SERVER, self.PORT) |
|
|
else : |
|
|
|
|
|
|
|
|
else: |
|
|
self.connexion = ldap.open(self.LDAP_SERVER) |
|
|
self.connexion = ldap.open(self.LDAP_SERVER) |
|
|
self.connexion.simple_bind_s(self.USER_DN, self.PASS) |
|
|
self.connexion.simple_bind_s(self.USER_DN, self.PASS) |
|
|
return self.connexion |
|
|
return self.connexion |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class LDAPAddress(osv.osv): |
|
|
|
|
|
|
|
|
class LDAPAddress(orm.Model): |
|
|
"""Override the CRUD of the objet in order to dynamically bind to ldap""" |
|
|
"""Override the CRUD of the objet in order to dynamically bind to ldap""" |
|
|
_inherit = 'res.partner.address' |
|
|
_inherit = 'res.partner.address' |
|
|
ldapMapper = None |
|
|
ldapMapper = None |
|
@ -108,7 +110,7 @@ class LDAPAddress(osv.osv): |
|
|
'column name to lastname ;')) |
|
|
'column name to lastname ;')) |
|
|
cr.execute('ALTER TABLE res_partner_address RENAME column name to lastname ;') |
|
|
cr.execute('ALTER TABLE res_partner_address RENAME column name to lastname ;') |
|
|
|
|
|
|
|
|
except Exception, e: |
|
|
|
|
|
|
|
|
except Exception: |
|
|
cr.rollback() |
|
|
cr.rollback() |
|
|
logger.notifyChannel(_('LDAP address init'), |
|
|
logger.notifyChannel(_('LDAP address init'), |
|
|
netsvc.LOG_INFO, |
|
|
netsvc.LOG_INFO, |
|
@ -119,7 +121,7 @@ class LDAPAddress(osv.osv): |
|
|
def _compute_name(self, firstname, lastname): |
|
|
def _compute_name(self, firstname, lastname): |
|
|
firstname = firstname or u'' |
|
|
firstname = firstname or u'' |
|
|
lastname = lastname or u'' |
|
|
lastname = lastname or u'' |
|
|
firstname = (u' '+ firstname).rstrip() |
|
|
|
|
|
|
|
|
firstname = (u' ' + firstname).rstrip() |
|
|
return u"%s%s" % (lastname, firstname) |
|
|
return u"%s%s" % (lastname, firstname) |
|
|
|
|
|
|
|
|
def _name_get_fnc(self, cursor, uid, ids, name, arg, context=None): |
|
|
def _name_get_fnc(self, cursor, uid, ids, name, arg, context=None): |
|
@ -129,37 +131,36 @@ class LDAPAddress(osv.osv): |
|
|
reads = self.read(cursor, uid, ids, ['lastname', 'firstname']) |
|
|
reads = self.read(cursor, uid, ids, ['lastname', 'firstname']) |
|
|
res = [] |
|
|
res = [] |
|
|
for record in reads: |
|
|
for record in reads: |
|
|
## We want to have " firstname" or "" |
|
|
|
|
|
|
|
|
# We want to have " firstname" or "" |
|
|
name = self._compute_name(record['firstname'], record['lastname']) |
|
|
name = self._compute_name(record['firstname'], record['lastname']) |
|
|
res.append((record['id'], name)) |
|
|
res.append((record['id'], name)) |
|
|
return dict(res) |
|
|
return dict(res) |
|
|
|
|
|
|
|
|
# TODO get the new version of name search not vulnerable to sql injections |
|
|
|
|
|
# def name_search(self, cursor, user, name, args=None, operator='ilike', context=None, limit=100): |
|
|
|
|
|
# if not context: context = {} |
|
|
|
|
|
# prep_name = '.*%s.*' %(name) |
|
|
|
|
|
# cursor.execute(("select id from res_partner_address where" |
|
|
|
|
|
# " (to_ascii(convert( lastname, 'UTF8', 'LATIN1'),'LATIN-1') ~* '%s'" |
|
|
|
|
|
# " or to_ascii(convert( firstname, 'UTF8', 'LATIN1'),'LATIN-1') ~* '%s')" |
|
|
|
|
|
# " limit %s") % (prep_name, prep_name, limit)) |
|
|
|
|
|
# res = cursor.fetchall() |
|
|
|
|
|
# if res: |
|
|
|
|
|
# res = [x[0] for x in res] |
|
|
|
|
|
# else: |
|
|
|
|
|
# res = [] |
|
|
|
|
|
# # search in partner name to know if we are searching partner... |
|
|
|
|
|
# partner_obj=self.pool.get('res.partner') |
|
|
|
|
|
# part_len = len(res)-limit |
|
|
|
|
|
# if part_len > 0: |
|
|
|
|
|
# partner_res = partner_obj.search(cursor, user, [('name', 'ilike', name)], |
|
|
|
|
|
# limit=part_len, context=context) |
|
|
|
|
|
# for p in partner_res: |
|
|
|
|
|
# addresses = partner_obj.browse(cursor, user, p).address |
|
|
|
|
|
# # Take each contact and add it to |
|
|
|
|
|
# for add in addresses: |
|
|
|
|
|
# res.append(add.id) |
|
|
|
|
|
# return self.name_get(cursor, user, res, context) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
# TODO get the new version of name search not vulnerable to sql injections |
|
|
|
|
|
# def name_search(self, cursor, user, name, args=None, operator='ilike', context=None, limit=100): |
|
|
|
|
|
# if not context: context = {} |
|
|
|
|
|
# prep_name = '.*%s.*' %(name) |
|
|
|
|
|
# cursor.execute(("select id from res_partner_address where" |
|
|
|
|
|
# " (to_ascii(convert( lastname, 'UTF8', 'LATIN1'),'LATIN-1') ~* '%s'" |
|
|
|
|
|
# " or to_ascii(convert( firstname, 'UTF8', 'LATIN1'),'LATIN-1') ~* '%s')" |
|
|
|
|
|
# " limit %s") % (prep_name, prep_name, limit)) |
|
|
|
|
|
# res = cursor.fetchall() |
|
|
|
|
|
# if res: |
|
|
|
|
|
# res = [x[0] for x in res] |
|
|
|
|
|
# else: |
|
|
|
|
|
# res = [] |
|
|
|
|
|
# # search in partner name to know if we are searching partner... |
|
|
|
|
|
# partner_obj=self.pool.get('res.partner') |
|
|
|
|
|
# part_len = len(res)-limit |
|
|
|
|
|
# if part_len > 0: |
|
|
|
|
|
# partner_res = partner_obj.search(cursor, user, [('name', 'ilike', name)], |
|
|
|
|
|
# limit=part_len, context=context) |
|
|
|
|
|
# for p in partner_res: |
|
|
|
|
|
# addresses = partner_obj.browse(cursor, user, p).address |
|
|
|
|
|
# # Take each contact and add it to |
|
|
|
|
|
# for add in addresses: |
|
|
|
|
|
# res.append(add.id) |
|
|
|
|
|
# return self.name_get(cursor, user, res, context) |
|
|
|
|
|
|
|
|
_columns = { |
|
|
_columns = { |
|
|
'firstname': fields.char('First name', size=256), |
|
|
'firstname': fields.char('First name', size=256), |
|
@ -169,7 +170,7 @@ class LDAPAddress(osv.osv): |
|
|
store=True, string='Contact Name', |
|
|
store=True, string='Contact Name', |
|
|
help='Name generated from the first name and last name', |
|
|
help='Name generated from the first name and last name', |
|
|
nodrop=True), |
|
|
nodrop=True), |
|
|
'private_phone':fields.char('Private phone', size=128), |
|
|
|
|
|
|
|
|
'private_phone': fields.char('Private phone', size=128), |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
def create(self, cursor, uid, vals, context={}): |
|
|
def create(self, cursor, uid, vals, context={}): |
|
@ -189,9 +190,9 @@ class LDAPAddress(osv.osv): |
|
|
ids = [ids] |
|
|
ids = [ids] |
|
|
if ids: |
|
|
if ids: |
|
|
self.validate_entries(vals, cursor, uid, ids) |
|
|
self.validate_entries(vals, cursor, uid, ids) |
|
|
if context.has_key('init_mode') and context['init_mode'] : |
|
|
|
|
|
|
|
|
if context.get('init_mode'): |
|
|
success = True |
|
|
success = True |
|
|
else : |
|
|
|
|
|
|
|
|
else: |
|
|
success = super(LDAPAddress, self).write(cursor, uid, ids, |
|
|
success = super(LDAPAddress, self).write(cursor, uid, ids, |
|
|
vals, context) |
|
|
vals, context) |
|
|
if self.ldaplinkactive(cursor, uid, context): |
|
|
if self.ldaplinkactive(cursor, uid, context): |
|
@ -200,7 +201,8 @@ class LDAPAddress(osv.osv): |
|
|
return success |
|
|
return success |
|
|
|
|
|
|
|
|
def unlink(self, cursor, uid, ids, context=None): |
|
|
def unlink(self, cursor, uid, ids, context=None): |
|
|
if not context: context = {} |
|
|
|
|
|
|
|
|
if context is None: |
|
|
|
|
|
context = {} |
|
|
if ids: |
|
|
if ids: |
|
|
self.getconn(cursor, uid, {}) |
|
|
self.getconn(cursor, uid, {}) |
|
|
if not isinstance(ids, list): |
|
|
if not isinstance(ids, list): |
|
@ -212,77 +214,76 @@ class LDAPAddress(osv.osv): |
|
|
|
|
|
|
|
|
def validate_entries(self, vals, cursor, uid, ids): |
|
|
def validate_entries(self, vals, cursor, uid, ids): |
|
|
"""Validate data of an address based on the inetOrgPerson schema""" |
|
|
"""Validate data of an address based on the inetOrgPerson schema""" |
|
|
for val in vals : |
|
|
|
|
|
try : |
|
|
|
|
|
|
|
|
for val in vals: |
|
|
|
|
|
try: |
|
|
if isinstance(vals[val], basestring): |
|
|
if isinstance(vals[val], basestring): |
|
|
vals[val] = unicode(vals[val].decode('utf8')) |
|
|
vals[val] = unicode(vals[val].decode('utf8')) |
|
|
except UnicodeError: |
|
|
except UnicodeError: |
|
|
logger.notifyChannel('LDAP encode', netsvc.LOG_DEBUG, |
|
|
logger.notifyChannel('LDAP encode', netsvc.LOG_DEBUG, |
|
|
'cannot unicode '+ vals[val]) |
|
|
|
|
|
|
|
|
'cannot unicode ' + vals[val]) |
|
|
pass |
|
|
pass |
|
|
|
|
|
|
|
|
if ids is not None: |
|
|
if ids is not None: |
|
|
if isinstance(ids, (int, long)): |
|
|
if isinstance(ids, (int, long)): |
|
|
ids = [ids] |
|
|
ids = [ids] |
|
|
if len(ids) == 1: |
|
|
if len(ids) == 1: |
|
|
self.addNeededFields(ids[0],vals,cursor,uid) |
|
|
|
|
|
|
|
|
self.addNeededFields(ids[0], vals, cursor, uid) |
|
|
email = vals.get('email', False) |
|
|
email = vals.get('email', False) |
|
|
phone = vals.get('phone', False) |
|
|
phone = vals.get('phone', False) |
|
|
fax = vals.get('fax', False) |
|
|
fax = vals.get('fax', False) |
|
|
mobile = vals.get('mobile', False) |
|
|
mobile = vals.get('mobile', False) |
|
|
lastname = vals.get('lastname', False) |
|
|
|
|
|
private_phone = vals.get('private_phone', False) |
|
|
private_phone = vals.get('private_phone', False) |
|
|
if email : |
|
|
|
|
|
|
|
|
if email: |
|
|
if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", |
|
|
if re.match("^.+\\@(\\[?)[a-zA-Z0-9\\-\\.]+\\.([a-zA-Z]{2,3}|[0-9]{1,3})(\\]?)$", |
|
|
email) is None: |
|
|
email) is None: |
|
|
raise osv.except_osv(_('Warning !'), |
|
|
|
|
|
|
|
|
raise orm.except_orm(_('Warning !'), |
|
|
_('Please enter a valid e-mail')) |
|
|
_('Please enter a valid e-mail')) |
|
|
phones = (('phone', phone), ('fax', fax), ('mobile', mobile), |
|
|
phones = (('phone', phone), ('fax', fax), ('mobile', mobile), |
|
|
('private_phone', private_phone)) |
|
|
('private_phone', private_phone)) |
|
|
for phone_tuple in phones: |
|
|
for phone_tuple in phones: |
|
|
phone_number = phone_tuple[1] |
|
|
phone_number = phone_tuple[1] |
|
|
if phone_number : |
|
|
|
|
|
|
|
|
if phone_number: |
|
|
if not phone_number.startswith('+'): |
|
|
if not phone_number.startswith('+'): |
|
|
raise osv.except_osv(_('Warning !'), |
|
|
|
|
|
|
|
|
raise orm.except_orm(_('Warning !'), |
|
|
_('Please enter a valid phone number in %s' |
|
|
_('Please enter a valid phone number in %s' |
|
|
' international format (i.e. leading +)') % phone_tuple[0]) |
|
|
' international format (i.e. leading +)') % phone_tuple[0]) |
|
|
|
|
|
|
|
|
def getVals(self, att_name, key, vals, dico, uid, ids, cursor, context=None): |
|
|
def getVals(self, att_name, key, vals, dico, uid, ids, cursor, context=None): |
|
|
"""map to values to dict""" |
|
|
"""map to values to dict""" |
|
|
if not context: context = {} |
|
|
|
|
|
## We explicitely test False value |
|
|
|
|
|
if vals.get(key, False) != False: |
|
|
|
|
|
|
|
|
if not context: |
|
|
|
|
|
context = {} |
|
|
|
|
|
# We explicitly test False value |
|
|
|
|
|
if vals.get(key, False) is not False: |
|
|
dico[att_name] = vals[key] |
|
|
dico[att_name] = vals[key] |
|
|
else : |
|
|
|
|
|
|
|
|
else: |
|
|
if context.get('init_mode'): |
|
|
if context.get('init_mode'): |
|
|
return False |
|
|
return False |
|
|
tmp = self.read(cursor, uid, ids, [key], context={}) |
|
|
tmp = self.read(cursor, uid, ids, [key], context={}) |
|
|
if tmp.get(key, False) : |
|
|
|
|
|
|
|
|
if tmp.get(key, False): |
|
|
dico[att_name] = tmp[key] |
|
|
dico[att_name] = tmp[key] |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def _un_unicodize_buf(self, in_buf): |
|
|
def _un_unicodize_buf(self, in_buf): |
|
|
if isinstance(in_buf, unicode) : |
|
|
|
|
|
|
|
|
if isinstance(in_buf, unicode): |
|
|
try: |
|
|
try: |
|
|
return in_buf.encode() |
|
|
return in_buf.encode() |
|
|
except Exception, e: |
|
|
|
|
|
return unicodedata.normalize("NFKD", in_buf).encode('ascii','ignore') |
|
|
|
|
|
|
|
|
except Exception: |
|
|
|
|
|
return unicodedata.normalize("NFKD", in_buf).encode('ascii', 'ignore') |
|
|
return in_buf |
|
|
return in_buf |
|
|
|
|
|
|
|
|
def unUnicodize(self, indict) : |
|
|
|
|
|
|
|
|
def unUnicodize(self, indict): |
|
|
"""remove unicode data of modlist as unicode is not supported |
|
|
"""remove unicode data of modlist as unicode is not supported |
|
|
by python-ldap librairy till version 2.7""" |
|
|
|
|
|
for key in indict : |
|
|
|
|
|
|
|
|
by python-ldap library till version 2.7 |
|
|
|
|
|
""" |
|
|
|
|
|
for key in indict: |
|
|
if not isinstance(indict[key], list): |
|
|
if not isinstance(indict[key], list): |
|
|
indict[key] = self._un_unicodize_buf(indict[key]) |
|
|
indict[key] = self._un_unicodize_buf(indict[key]) |
|
|
else: |
|
|
else: |
|
|
nonutfArray = [] |
|
|
nonutfArray = [] |
|
|
for val in indict[key] : |
|
|
|
|
|
|
|
|
for val in indict[key]: |
|
|
nonutfArray.append(self._un_unicodize_buf(val)) |
|
|
nonutfArray.append(self._un_unicodize_buf(val)) |
|
|
indict[key] = nonutfArray |
|
|
indict[key] = nonutfArray |
|
|
|
|
|
|
|
|
def addNeededFields(self, id, vals, cursor, uid): |
|
|
def addNeededFields(self, id, vals, cursor, uid): |
|
|
keys = vals.keys() |
|
|
|
|
|
previousvalue = self.browse(cursor, uid, [id])[0] |
|
|
previousvalue = self.browse(cursor, uid, [id])[0] |
|
|
if not vals.get('partner_id'): |
|
|
if not vals.get('partner_id'): |
|
|
vals['partner_id'] = previousvalue.partner_id.id |
|
|
vals['partner_id'] = previousvalue.partner_id.id |
|
@ -296,142 +297,141 @@ class LDAPAddress(osv.osv): |
|
|
"""Mapp ResPArtner adress to moddlist""" |
|
|
"""Mapp ResPArtner adress to moddlist""" |
|
|
self.addNeededFields(id, vals, cursor, uid) |
|
|
self.addNeededFields(id, vals, cursor, uid) |
|
|
conn = self.getconn(cursor, uid, {}) |
|
|
conn = self.getconn(cursor, uid, {}) |
|
|
keys = vals.keys() |
|
|
|
|
|
partner_obj=self.pool.get('res.partner') |
|
|
|
|
|
|
|
|
partner_obj = self.pool.get('res.partner') |
|
|
part_name = partner_obj.browse(cursor, uid, vals['partner_id']).name |
|
|
part_name = partner_obj.browse(cursor, uid, vals['partner_id']).name |
|
|
vals['partner'] = part_name |
|
|
vals['partner'] = part_name |
|
|
name = self._compute_name(vals.get('firstname'), vals.get('lastname')) |
|
|
name = self._compute_name(vals.get('firstname'), vals.get('lastname')) |
|
|
if name : |
|
|
|
|
|
|
|
|
if name: |
|
|
cn = name |
|
|
cn = name |
|
|
else: |
|
|
else: |
|
|
cn = part_name |
|
|
cn = part_name |
|
|
if not vals.get('lastname') : |
|
|
|
|
|
|
|
|
if not vals.get('lastname'): |
|
|
vals['lastname'] = part_name |
|
|
vals['lastname'] = part_name |
|
|
contact_obj = {'objectclass' : ['inetOrgPerson'], |
|
|
|
|
|
'uid': ['terp_'+str(id)], |
|
|
|
|
|
'ou':[conn.OU], |
|
|
|
|
|
'cn':[cn], |
|
|
|
|
|
'sn':[vals['lastname']]} |
|
|
|
|
|
|
|
|
contact_obj = {'objectclass': ['inetOrgPerson'], |
|
|
|
|
|
'uid': ['terp_' + str(id)], |
|
|
|
|
|
'ou': [conn.OU], |
|
|
|
|
|
'cn': [cn], |
|
|
|
|
|
'sn': [vals['lastname']]} |
|
|
if not vals.get('street'): |
|
|
if not vals.get('street'): |
|
|
vals['street'] = u'' |
|
|
vals['street'] = u'' |
|
|
if not vals.get('street2'): |
|
|
if not vals.get('street2'): |
|
|
vals['street2'] = u'' |
|
|
vals['street2'] = u'' |
|
|
street_key = 'street' |
|
|
street_key = 'street' |
|
|
if self.getconn(cursor, uid, {}).ACTIVDIR : |
|
|
|
|
|
|
|
|
if self.getconn(cursor, uid, {}).ACTIVDIR: |
|
|
# ENTERING THE M$ Realm and it is weird |
|
|
# ENTERING THE M$ Realm and it is weird |
|
|
# We manage the address |
|
|
# We manage the address |
|
|
street_key = 'streetAddress' |
|
|
street_key = 'streetAddress' |
|
|
contact_obj[street_key] = vals['street'] + "\r\n" + vals['street2'] |
|
|
contact_obj[street_key] = vals['street'] + "\r\n" + vals['street2'] |
|
|
#we modifiy the class |
|
|
|
|
|
contact_obj['objectclass'] = ['top','person','organizationalPerson','inetOrgPerson','user'] |
|
|
|
|
|
#we handle the country |
|
|
|
|
|
if vals.get('country_id') : |
|
|
|
|
|
country = self.browse(cursor, uid, id).country_id |
|
|
|
|
|
if country : |
|
|
|
|
|
|
|
|
# we modifiy the class |
|
|
|
|
|
contact_obj['objectclass'] = ['top', 'person', 'organizationalPerson', 'inetOrgPerson', 'user'] |
|
|
|
|
|
# we handle the country |
|
|
|
|
|
if vals.get('country_id'): |
|
|
|
|
|
country = self.browse(cursor, uid, id, context=context).country_id |
|
|
|
|
|
if country: |
|
|
vals['country_id'] = country.name |
|
|
vals['country_id'] = country.name |
|
|
vals['c'] = country.code |
|
|
vals['c'] = country.code |
|
|
else : |
|
|
|
|
|
|
|
|
else: |
|
|
vals['country_id'] = False |
|
|
vals['country_id'] = False |
|
|
vals['c'] = False |
|
|
vals['c'] = False |
|
|
if vals.get('country_id', False) : |
|
|
|
|
|
|
|
|
if vals.get('country_id', False): |
|
|
self.getVals('co', 'country_id', vals, contact_obj, uid, id, cursor, context) |
|
|
self.getVals('co', 'country_id', vals, contact_obj, uid, id, cursor, context) |
|
|
self.getVals('c', 'c', vals, contact_obj, uid, id, cursor, context) |
|
|
self.getVals('c', 'c', vals, contact_obj, uid, id, cursor, context) |
|
|
# we compute the display name |
|
|
# we compute the display name |
|
|
vals['display'] = '%s %s'%(vals['partner'], contact_obj['cn'][0]) |
|
|
|
|
|
|
|
|
vals['display'] = '%s %s' % (vals['partner'], contact_obj['cn'][0]) |
|
|
# we get the title |
|
|
# we get the title |
|
|
if self.browse(cursor, uid, id).function: |
|
|
if self.browse(cursor, uid, id).function: |
|
|
contact_obj['description'] = self.browse(cursor, uid, id).function.name |
|
|
contact_obj['description'] = self.browse(cursor, uid, id).function.name |
|
|
# we replace carriage return |
|
|
# we replace carriage return |
|
|
if vals.get('comment', False): |
|
|
if vals.get('comment', False): |
|
|
vals['comment'] = vals['comment'].replace("\n","\r\n") |
|
|
|
|
|
|
|
|
vals['comment'] = vals['comment'].replace("\n", "\r\n") |
|
|
# Active directory specific fields |
|
|
# Active directory specific fields |
|
|
self.getVals('company', 'partner' ,vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('info', 'comment' ,vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('displayName', 'partner' ,vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
## Web site management |
|
|
|
|
|
|
|
|
self.getVals('company', 'partner', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('info', 'comment', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('displayName', 'partner', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
# Web site management |
|
|
if self.browse(cursor, uid, id).partner_id.website: |
|
|
if self.browse(cursor, uid, id).partner_id.website: |
|
|
vals['website'] = self.browse(cursor, uid, id).partner_id.website |
|
|
vals['website'] = self.browse(cursor, uid, id).partner_id.website |
|
|
self.getVals('wWWHomePage', 'website', vals, contact_obj, uid, id, cursor, context) |
|
|
self.getVals('wWWHomePage', 'website', vals, contact_obj, uid, id, cursor, context) |
|
|
del(vals['website']) |
|
|
del(vals['website']) |
|
|
self.getVals('title', 'title', vals, contact_obj, uid, id, cursor, context) |
|
|
self.getVals('title', 'title', vals, contact_obj, uid, id, cursor, context) |
|
|
else : |
|
|
|
|
|
|
|
|
else: |
|
|
contact_obj[street_key] = vals['street'] + u"\n" + vals['street2'] |
|
|
contact_obj[street_key] = vals['street'] + u"\n" + vals['street2'] |
|
|
self.getVals('o','partner' ,vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
|
|
|
|
|
|
#Common attributes |
|
|
|
|
|
self.getVals('givenName', 'firstname',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('mail', 'email',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('telephoneNumber', 'phone',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('l', 'city',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('facsimileTelephoneNumber', 'fax',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('mobile', 'mobile',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('homePhone', 'private_phone',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('postalCode', 'zip',vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
|
|
|
self.getVals('o', 'partner', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
|
|
|
|
|
|
# Common attributes |
|
|
|
|
|
self.getVals('givenName', 'firstname', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('mail', 'email', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('telephoneNumber', 'phone', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('l', 'city', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('facsimileTelephoneNumber', 'fax', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('mobile', 'mobile', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('homePhone', 'private_phone', vals, contact_obj, uid, id, cursor, context) |
|
|
|
|
|
self.getVals('postalCode', 'zip', vals, contact_obj, uid, id, cursor, context) |
|
|
self.unUnicodize(contact_obj) |
|
|
self.unUnicodize(contact_obj) |
|
|
return contact_obj |
|
|
return contact_obj |
|
|
|
|
|
|
|
|
def saveLdapContact(self, id, vals, cursor, uid, context=None): |
|
|
def saveLdapContact(self, id, vals, cursor, uid, context=None): |
|
|
"""save openerp adress to ldap""" |
|
|
"""save openerp adress to ldap""" |
|
|
contact_obj = self.mappLdapObject(id,vals,cursor,uid,context) |
|
|
|
|
|
|
|
|
contact_obj = self.mappLdapObject(id, vals, cursor, uid, context) |
|
|
conn = self.connectToLdap(cursor, uid, context=context) |
|
|
conn = self.connectToLdap(cursor, uid, context=context) |
|
|
try: |
|
|
try: |
|
|
if self.getconn(cursor, uid, context).ACTIVDIR: |
|
|
if self.getconn(cursor, uid, context).ACTIVDIR: |
|
|
conn.connexion.add_s("CN=%s,OU=%s,%s"%(contact_obj['cn'][0], conn.OU, conn.CONTACT_DN), |
|
|
|
|
|
|
|
|
conn.connexion.add_s("CN=%s,OU=%s,%s" % (contact_obj['cn'][0], conn.OU, conn.CONTACT_DN), |
|
|
ldap.modlist.addModlist(contact_obj)) |
|
|
ldap.modlist.addModlist(contact_obj)) |
|
|
else: |
|
|
else: |
|
|
conn.connexion.add_s("uid=terp_%s,OU=%s,%s"%(str(id), conn.OU, conn.CONTACT_DN), |
|
|
|
|
|
ldap.modlist.addModlist(contact_obj)) |
|
|
|
|
|
except Exception, e: |
|
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
conn.connexion.add_s("uid=terp_%s,OU=%s,%s" % (str(id), conn.OU, conn.CONTACT_DN), |
|
|
|
|
|
ldap.modlist.addModlist(contact_obj)) |
|
|
|
|
|
except Exception: |
|
|
|
|
|
raise |
|
|
conn.connexion.unbind_s() |
|
|
conn.connexion.unbind_s() |
|
|
|
|
|
|
|
|
def updateLdapContact(self, id, vals, cursor, uid, context): |
|
|
def updateLdapContact(self, id, vals, cursor, uid, context): |
|
|
"""update an existing contact with the data of OpenERP""" |
|
|
"""update an existing contact with the data of OpenERP""" |
|
|
conn = self.connectToLdap(cursor,uid,context={}) |
|
|
|
|
|
|
|
|
conn = self.connectToLdap(cursor, uid, context={}) |
|
|
try: |
|
|
try: |
|
|
old_contatc_obj = self.getLdapContact(conn,id) |
|
|
|
|
|
|
|
|
old_contatc_obj = self.getLdapContact(conn, id) |
|
|
except ldap.NO_SUCH_OBJECT: |
|
|
except ldap.NO_SUCH_OBJECT: |
|
|
self.saveLdapContact(id,vals,cursor,uid,context) |
|
|
|
|
|
|
|
|
self.saveLdapContact(id, vals, cursor, uid, context) |
|
|
return |
|
|
return |
|
|
contact_obj = self.mappLdapObject(id,vals,cursor,uid,context) |
|
|
|
|
|
|
|
|
contact_obj = self.mappLdapObject(id, vals, cursor, uid, context) |
|
|
if conn.ACTIVDIR: |
|
|
if conn.ACTIVDIR: |
|
|
modlist = [] |
|
|
modlist = [] |
|
|
for key, val in contact_obj.items() : |
|
|
|
|
|
|
|
|
for key, val in contact_obj.items(): |
|
|
if key in ('cn', 'uid', 'objectclass'): |
|
|
if key in ('cn', 'uid', 'objectclass'): |
|
|
continue |
|
|
continue |
|
|
if isinstance(val, list): |
|
|
if isinstance(val, list): |
|
|
val = val[0] |
|
|
val = val[0] |
|
|
modlist.append((ldap.MOD_REPLACE, key, val)) |
|
|
modlist.append((ldap.MOD_REPLACE, key, val)) |
|
|
else : |
|
|
|
|
|
|
|
|
else: |
|
|
modlist = ldap.modlist.modifyModlist(old_contatc_obj[1], contact_obj) |
|
|
modlist = ldap.modlist.modifyModlist(old_contatc_obj[1], contact_obj) |
|
|
try: |
|
|
try: |
|
|
conn.connexion.modify_s(old_contatc_obj[0], modlist) |
|
|
conn.connexion.modify_s(old_contatc_obj[0], modlist) |
|
|
conn.connexion.unbind_s() |
|
|
conn.connexion.unbind_s() |
|
|
except Exception, e: |
|
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
except Exception: |
|
|
|
|
|
raise |
|
|
|
|
|
|
|
|
def removeLdapContact(self, id, cursor, uid): |
|
|
def removeLdapContact(self, id, cursor, uid): |
|
|
"""Remove a contact from ldap""" |
|
|
"""Remove a contact from ldap""" |
|
|
conn = self.connectToLdap(cursor,uid,context={}) |
|
|
|
|
|
|
|
|
conn = self.connectToLdap(cursor, uid, context={}) |
|
|
to_delete = None |
|
|
to_delete = None |
|
|
try: |
|
|
try: |
|
|
to_delete = self.getLdapContact(conn,id) |
|
|
|
|
|
|
|
|
to_delete = self.getLdapContact(conn, id) |
|
|
except ldap.NO_SUCH_OBJECT: |
|
|
except ldap.NO_SUCH_OBJECT: |
|
|
logger.notifyChannel("Warning", netsvc.LOG_INFO, |
|
|
logger.notifyChannel("Warning", netsvc.LOG_INFO, |
|
|
_("'no object to delete in ldap' %s") %(id)) |
|
|
|
|
|
except Exception, e : |
|
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
_("'no object to delete in ldap' %s") % (id)) |
|
|
|
|
|
except Exception: |
|
|
|
|
|
raise |
|
|
try: |
|
|
try: |
|
|
if to_delete : |
|
|
|
|
|
|
|
|
if to_delete: |
|
|
conn.connexion.delete_s(to_delete[0]) |
|
|
conn.connexion.delete_s(to_delete[0]) |
|
|
conn.connexion.unbind_s() |
|
|
conn.connexion.unbind_s() |
|
|
except Exception, e: |
|
|
|
|
|
raise e |
|
|
|
|
|
|
|
|
except Exception: |
|
|
|
|
|
raise |
|
|
|
|
|
|
|
|
def getLdapContact(self, conn, id): |
|
|
def getLdapContact(self, conn, id): |
|
|
result = conn.connexion.search_ext_s("ou=%s,%s"%(conn.OU,conn.CONTACT_DN), |
|
|
|
|
|
|
|
|
result = conn.connexion.search_ext_s("ou=%s, %s" % (conn.OU, conn.CONTACT_DN), |
|
|
ldap.SCOPE_SUBTREE, |
|
|
ldap.SCOPE_SUBTREE, |
|
|
"(&(objectclass=*)(uid=terp_"+str(id)+"))") |
|
|
|
|
|
|
|
|
"(&(objectclass=*)(uid=terp_" + str(id) + "))") |
|
|
if not result: |
|
|
if not result: |
|
|
raise ldap.NO_SUCH_OBJECT |
|
|
raise ldap.NO_SUCH_OBJECT |
|
|
return result[0] |
|
|
return result[0] |
|
@ -439,21 +439,19 @@ class LDAPAddress(osv.osv): |
|
|
def ldaplinkactive(self, cursor, uid, context=None): |
|
|
def ldaplinkactive(self, cursor, uid, context=None): |
|
|
"""Check if ldap is activated for this company""" |
|
|
"""Check if ldap is activated for this company""" |
|
|
user = self.pool.get('res.users').browse(cursor, uid, uid, context=context) |
|
|
user = self.pool.get('res.users').browse(cursor, uid, uid, context=context) |
|
|
company = self.pool.get('res.company').browse(cursor, uid,user.company_id.id, context=context) |
|
|
|
|
|
|
|
|
company = self.pool.get('res.company').browse(cursor, uid, user.company_id.id, context=context) |
|
|
return company.ldap_active |
|
|
return company.ldap_active |
|
|
|
|
|
|
|
|
def getconn(self, cursor, uid, context=None): |
|
|
def getconn(self, cursor, uid, context=None): |
|
|
"""LdapConnMApper""" |
|
|
"""LdapConnMApper""" |
|
|
if not self.ldapMapper : |
|
|
|
|
|
|
|
|
if not self.ldapMapper: |
|
|
self.ldapMapper = LdapConnMApper(cursor, uid, self) |
|
|
self.ldapMapper = LdapConnMApper(cursor, uid, self) |
|
|
return self.ldapMapper |
|
|
return self.ldapMapper |
|
|
|
|
|
|
|
|
def connectToLdap(self, cursor, uid, context=None): |
|
|
def connectToLdap(self, cursor, uid, context=None): |
|
|
"""Reinitialize ldap connection""" |
|
|
"""Reinitialize ldap connection""" |
|
|
#getting ldap pref |
|
|
|
|
|
if not self.ldapMapper : |
|
|
|
|
|
|
|
|
# getting ldap pref |
|
|
|
|
|
if not self.ldapMapper: |
|
|
self.getconn(cursor, uid, context) |
|
|
self.getconn(cursor, uid, context) |
|
|
self.ldapMapper.get_connexion() |
|
|
self.ldapMapper.get_connexion() |
|
|
return self.ldapMapper |
|
|
return self.ldapMapper |
|
|
|
|
|
|
|
|
LDAPAddress() |
|
|
|