"""
-This API is adapted for OpenLDAP.
-The file contains all LDAP classes and methods needed to:
- - Load the LDAP connection configuration file (login, address..) with
- LdapConfig
- - Connect to LDAP with ldap_co
- - Create a unique LDAP login and password for a user based on his email or
- last name and first name with LoginPassword.
- - Manage entries in LDAP using SFA records with LDAPapi
- (Search, Add, Delete, Modify)
+This API is adapted for OpenLDAP. The file contains all LDAP classes and methods
+needed to:
+- Load the LDAP connection configuration file (login, address..) with LdapConfig
+- Connect to LDAP with ldap_co
+- Create a unique LDAP login and password for a user based on his email or last
+name and first name with LoginPassword.
+- Manage entries in LDAP using SFA records with LDAPapi (Search, Add, Delete,
+Modify)
"""
import random
#rights to add objects
self.ldapserv.simple_bind_s(self.ldapAdminDN,
self.ldapAdminPassword)
+ return {'bool': True}
except ldap.LDAPError, error:
return {'bool': False, 'message': error}
- return {'bool': True}
+
def close(self):
- """ Close the LDAP connection.
+ """Close the LDAP connection.
Can throw an exception if the unbinding fails.
- :returns: dictionary with the bind status if fails.
- False if not and in this case the error message({'bool','message'})
+
+ :returns: dictionary with the bind status if the unbinding failed and
+ in this case the dict contains an error message. The dictionary keys
+ are : ({'bool','message'})
:rtype: dict or None
"""
return lower_first_name, lower_last_name
+ # XXX JORDAN: This function writes an error in the log but returns normally :))
def choose_sets_chars_for_login(self, lower_first_name, lower_last_name):
"""
logger.error("LDAP LdapGenerateUniqueLogin failed : \
impossible to generate unique login for %s %s"
% (lower_first_name, lower_last_name))
+ logger.debug("JORDAN choose_sets_chars_for_login %d %s" % (index, login))
return index, login
def generate_password(self):
class LDAPapi:
"""Defines functions to insert and search entries in the LDAP.
+ .. note:: class supposes the unix schema is used
+
"""
def __init__(self):
logger.setLevelDebug()
first name so that the user's login can be generated.
:param record: Record must contain first_name and last_name.
- :param record: dict
+ :type record: dict
:returns: the generated login for the user described with record if the
login generation is successful, None if it fails.
:rtype: string or None
if index >= 9:
logger.error("LoginException : Generation login error \
with minimum four characters")
+ break
else:
try:
login = \
lower_last_name[0:
self.login_pwd.login_max_length
- index]
+ logger.debug("JORDAN trying login: %r" % login)
login_filter = '(uid=' + login + ')'
except KeyError:
print "lower_first_name - lower_last_name too short"
:rtype: string
"""
+ logger.debug("JORDAN make_ldap_filters_from_record: %r" % record)
req_ldap = ''
req_ldapdict = {}
if record :
if record['first_name'] != record['last_name']:
req_ldapdict['cn'] = str(record['first_name'])+" "\
+ str(record['last_name'])
+ if 'uid' in record:
+ req_ldapdict['uid'] = record['uid']
if 'email' in record:
req_ldapdict['mail'] = record['email']
if 'mail' in record:
:rtype: dict
"""
+ logger.debug("JORDAN make_ldap_attributes_from_record: %r" % record)
attrs = {}
attrs['objectClass'] = ["top", "person", "inetOrgPerson",
return attrs
-
def LdapAddUser(self, record) :
"""Add SFA user to LDAP if it is not in LDAP yet.
:param record: dictionnary with the user's data.
:returns: a dictionary with the status (Fail= False, Success= True)
and the uid of the newly added user if successful, or the error
- meassage it is not. Dict has keys bool and message in case of
+ message it is not. Dict has keys bool and message in case of
failure, and bool uid in case of success.
:rtype: dict
.. seealso:: make_ldap_filters_from_record
"""
- logger.debug(" \r\n \t LDAP LdapAddUser \r\n\r\n ================\r\n ")
- user_ldap_attrs = self.make_ldap_attributes_from_record(record)
-
- #Check if user already in LDAP wih email, first name and last name
- filter_by = self.make_ldap_filters_from_record(user_ldap_attrs)
- user_exist = self.LdapSearch(filter_by)
- if user_exist:
- logger.warning(" \r\n \t LDAP LdapAddUser user %s %s \
- already exists" % (user_ldap_attrs['sn'],
- user_ldap_attrs['mail']))
- return {'bool': False}
-
- #Bind to the server
- result = self.conn.connect()
-
- if(result['bool']):
-
- # A dict to help build the "body" of the object
- logger.debug(" \r\n \t LDAP LdapAddUser attrs %s "
- % user_ldap_attrs)
-
- # The dn of our new entry/object
- dn = 'uid=' + user_ldap_attrs['uid'] + "," + self.baseDN
-
- try:
- ldif = modlist.addModlist(user_ldap_attrs)
- logger.debug("LDAPapi.py add attrs %s \r\n ldif %s"
- % (user_ldap_attrs, ldif))
- self.conn.ldapserv.add_s(dn, ldif)
-
- logger.info("Adding user %s login %s in LDAP"
- % (user_ldap_attrs['cn'], user_ldap_attrs['uid']))
- except ldap.LDAPError, error:
- logger.log_exc("LDAP Add Error %s" % error)
- return {'bool': False, 'message': error}
-
- self.conn.close()
- return {'bool': True, 'uid': user_ldap_attrs['uid']}
+ filter_by = self.make_ldap_filters_from_record({'email' : record['email']})
+ user = self.LdapSearch(filter_by)
+ if user:
+ logger.debug("LDAPapi.py user ldap exist \t%s" % user)
+ # user = [('uid=saint,ou=People,dc=senslab,dc=info', {'uid': ['saint'], 'givenName': ['Fred'], ...})]
+ return {'bool': True, 'uid': user[0][1]['uid'][0]}
else:
- return result
-
+ user_ldap_attrs = self.make_ldap_attributes_from_record(record)
+ result = self.conn.connect()
+ if(result['bool']):
+ logger.debug("LDAPapi.py user ldap doesn't exist \t%s" % user_ldap_attrs)
+ # The dn of our new entry/object
+ dn = 'uid=' + user_ldap_attrs['uid'] + "," + self.baseDN
+ try:
+ ldif = modlist.addModlist(user_ldap_attrs)
+ self.conn.ldapserv.add_s(dn, ldif)
+ self.conn.close()
+ return {'bool': True, 'uid': user_ldap_attrs['uid']}
+ except ldap.LDAPError, error:
+ logger.log_exc("LDAP Add Error %s" % error)
+ return {'bool': False, 'message': error}
+
+
+
+
def LdapDelete(self, person_dn):
"""Deletes a person in LDAP. Uses the dn of the user.
.. seealso:: make_ldap_filters_from_record for req_ldap format.
"""
+ logger.debug("JORDAN LdapSearch, req_ldap=%r, expected_fields=%r" % (req_ldap, expected_fields))
result = self.conn.connect(bind=False)
if (result['bool']):
logger.log_exc("LDAP LdapSearch Error %s" % error)
return []
- else:
- logger.error("LDAP.PY \t Connection Failed")
- return
+ else:
+ logger.error("LDAP.PY \t Connection Failed")
+ return []
def _process_ldap_info_for_all_users(self, result_data):
"""Process the data of all enabled users in LDAP.
parent_hrn = None
peer_authority = None
- if 'hrn' in record:
+ # If the user is coming from External authority (e.g. OneLab)
+ # Then hrn is None, it should be filled in by the creation of Ldap User
+ # XXX LOIC !!! What if a user email is in 2 authorities?
+ if 'hrn' in record and record['hrn'] is not None:
hrn = record['hrn']
parent_hrn = get_authority(hrn)
if parent_hrn != self.authname:
else:
hrn = None
- results = {
- 'type': 'user',
- 'pkey': ldapentry['sshPublicKey'],
- #'uid': ldapentry[1]['uid'][0],
- 'uid': tmpname,
- 'email': tmpemail,
- #'email': ldapentry[1]['mail'][0],
- 'first_name': ldapentry['givenName'][0],
- 'last_name': ldapentry['sn'][0],
- #'phone': 'none',
- 'serial': 'none',
- 'authority': parent_hrn,
- 'peer_authority': peer_authority,
- 'pointer': -1,
- 'hrn': hrn,
- }
+ if hrn is None:
+ results = {
+ 'type': 'user',
+ 'pkey': ldapentry['sshPublicKey'],
+ #'uid': ldapentry[1]['uid'][0],
+ 'uid': tmpname,
+ 'email': tmpemail,
+ #'email': ldapentry[1]['mail'][0],
+ 'first_name': ldapentry['givenName'][0],
+ 'last_name': ldapentry['sn'][0],
+ #'phone': 'none',
+ 'serial': 'none',
+ 'authority': parent_hrn,
+ 'peer_authority': peer_authority,
+ 'pointer': -1,
+ }
+ else:
+ #hrn = None
+ results = {
+ 'type': 'user',
+ 'pkey': ldapentry['sshPublicKey'],
+ #'uid': ldapentry[1]['uid'][0],
+ 'uid': tmpname,
+ 'email': tmpemail,
+ #'email': ldapentry[1]['mail'][0],
+ 'first_name': ldapentry['givenName'][0],
+ 'last_name': ldapentry['sn'][0],
+ #'phone': 'none',
+ 'serial': 'none',
+ 'authority': parent_hrn,
+ 'peer_authority': peer_authority,
+ 'pointer': -1,
+ 'hrn': hrn,
+ }
return results
def LdapFindUser(self, record=None, is_user_enabled=None,
:rtype: dict or list
"""
+ logger.debug("JORDAN LdapFindUser record=%r, is_user_enabled=%r, expected_fields=%r" % (record, is_user_enabled, expected_fields))
+
custom_record = {}
if is_user_enabled:
custom_record['enabled'] = is_user_enabled
return None
#Asked for a specific user
if record is not None:
+ logger.debug("LOIC - record = %s" % record)
results = self._process_ldap_info_for_one_user(record, result_data)
else:
#Asked for all users in ldap
results = self._process_ldap_info_for_all_users(result_data)
- return results
\ No newline at end of file
+ return results