Add complete implementation of create_user

This commit is contained in:
PCoder 2019-02-23 21:27:23 +01:00
parent 0976d0dbcb
commit ac89df9254
1 changed files with 86 additions and 26 deletions

View File

@ -4,6 +4,9 @@ import random
import ldap3
from django.conf import settings
import logging
logger = logging.getLogger(__name__)
class LdapManager:
@ -67,38 +70,53 @@ class LdapManager:
return passwd
def create_user(self, loginname, displayname, mail, password):
"""
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.
"""
def create_user(self, user, password, firstname, lastname, email):
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:
conn.add(
("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=loginname),
["inetOrgPerson"],
("uid={uid}," + settings.LDAP_CUSTOMER_DN).format(uid=user),
["inetOrgPerson", "posixAccount", "ldapPublickey"],
{
"uid": [loginname],
"cn": [displayname],
"sn": ["XXX"],
"givenName": ["XXX"],
"mail": [mail],
"userpassword": [self._ssha_password(
"uid": [user.encode("utf-8")],
"sn": [lastname.encode("utf-8")],
"givenName": [firstname.encode("utf-8")],
"cn": ["{} {}".format(firstname, lastname).encode("utf-8")],
"displayName": ["{} {}".format(firstname, lastname).encode("utf-8")],
"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")
)]
}
)
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:
conn.unbind()
@ -124,21 +142,63 @@ class LdapManager:
conn.unbind()
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.
:param uid: str representing the user
:param is_customer: bool representing whether the current user is a
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
"""
conn = self.get_admin_conn()
try:
result = conn.search(
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:
conn.unbind()
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