Add complete implementation of create_user

This commit is contained in:
PCoder 2019-02-23 21:27:23 +01:00
parent 0976d0dbcb
commit ac89df9254

View file

@ -4,6 +4,9 @@ import random
import ldap3 import ldap3
from django.conf import settings from django.conf import settings
import logging
logger = logging.getLogger(__name__)
class LdapManager: class LdapManager:
@ -67,38 +70,53 @@ class LdapManager:
return passwd return passwd
def create_user(self, loginname, displayname, mail, password): def create_user(self, user, password, firstname, lastname, email):
"""
Create a new user in the LDAP storage.
*loginname* must be a unique, valid user id. It is generally safe to
pass lower-case ascii letters here. The *loginname* of an account
cannot be changed.
*displayname* is the name which is shown to other users. This can be
changed in the future.
*mail* is a valid mail address of the user.
*password* is the initial plain text password for the user.
"""
conn = self.get_admin_conn() conn = self.get_admin_conn()
uidNumber = self._get_max_uid() + 1
logger.debug("uidNumber={uidNumber}".format(uidNumber=uidNumber))
results = True
while results:
results = self.check_user_exists(
"",
True,
'(&(objectClass=inetOrgPerson)(objectClass=posixAccount)'
'(objectClass=top)(uidNumber={uidNumber}))'.format(
uidNumber=uidNumber
)
)
if results:
logger.debug(
"{uid} exists. Trying next.".format(uid=uidNumber)
)
uidNumber += 1
logger.debug("{uid} does not exist. Using it".format(uid=uidNumber))
self._set_max_uid(uidNumber)
try: try:
conn.add( conn.add(
("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=loginname), ("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=user),
["inetOrgPerson"], ["inetOrgPerson", "posixAccount", "ldapPublickey"],
{ {
"uid": [loginname], "uid": [user.encode("utf-8")],
"cn": [displayname], "sn": [lastname.encode("utf-8")],
"sn": ["XXX"], "givenName": [firstname.encode("utf-8")],
"givenName": ["XXX"], "cn": ["{} {}".format(firstname, lastname).encode("utf-8")],
"mail": [mail], "displayName": ["{} {}".format(firstname, lastname).encode("utf-8")],
"userpassword": [self._ssha_password( "uidNumber": [str(uidNumber)],
"gidNumber": [str(settings.LDAP_CUSTOMER_GROUP_ID)],
"loginShell": ["/bin/bash"],
"homeDirectory": ["/home/{}".format(user).encode("utf-8")],
"mail": email.encode("utf-8"),
"userPassword": [self._ssha_password(
password.encode("utf-8") password.encode("utf-8")
)] )]
} }
) )
logger.debug('Created user %s %s' % (user.encode('utf-8'),
uidNumber))
except Exception as ex:
logger.debug('Could not create user %s' % user.encode('utf-8'))
logger.error("Exception: " + str(ex))
raise Exception(ex)
finally: finally:
conn.unbind() conn.unbind()
@ -124,21 +142,63 @@ class LdapManager:
conn.unbind() conn.unbind()
return return_val return return_val
def check_user_exists(self, uid, is_customer=True): def check_user_exists(self, uid, is_customer=True, search_filter=""):
""" """
Check if the user with the given uid exists in the customer group. Check if the user with the given uid exists in the customer group.
:param uid: str representing the user :param uid: str representing the user
:param is_customer: bool representing whether the current user is a :param is_customer: bool representing whether the current user is a
customer. By default, the user is a customer (assume) customer. By default, the user is a customer (assume)
:param search_filter: str representing the filter condition to find
users. If its empty, the search finds the user with
the given uid.
:return: True if the user exists otherwise return False :return: True if the user exists otherwise return False
""" """
conn = self.get_admin_conn() conn = self.get_admin_conn()
try: try:
result = conn.search( result = conn.search(
settings.LDAP_CUSTOMER_DN if is_customer else settings.LDAP_USERS_DN, settings.LDAP_CUSTOMER_DN if is_customer else settings.LDAP_USERS_DN,
search_filter='(uid={uid})'.format(uid=uid) search_filter=search_filter if len(search_filter)> 0 else
'(uid={uid})'.format(uid=uid)
) )
finally: finally:
conn.unbind() conn.unbind()
return result return result
def _set_max_uid(self, max_uid):
"""
a utility function to save max_uid value to a file
:param max_uid: an integer representing the max uid
:return:
"""
with open(settings.LDAP_MAX_UID_FILE_PATH, 'w+') as handler:
handler.write(str(max_uid))
def _get_max_uid(self):
"""
A utility function to read the max uid value that was previously set
:return: An integer representing the max uid value that was previously
set
"""
try:
with open(settings.LDAP_MAX_UID_FILE_PATH, 'r+') as handler:
try:
return_value = int(handler.read())
except ValueError as ve:
logger.error(
"Error reading int value from {}. {}"
"Returning default value {} instead".format(
settings.LDAP_MAX_UID_PATH,
str(ve),
settings.LDAP_DEFAULT_START_UID
)
)
return_value = settings.LDAP_DEFAULT_START_UID
return return_value
except FileNotFoundError as fnfe:
logger.error("File not found : " + str(fnfe))
return_value = settings.LDAP_DEFAULT_START_UID
logger.error("So, returning UID={}".format(return_value))
return return_value