ldap.py 4.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import ldap
  2. import os,hashlib
  3. from base64 import urlsafe_b64encode as encode
  4. from ldap.modlist import addModlist
  5. from django.conf import settings
  6. class LDAPOperations():
  7. def __init__(self):
  8. self.connect()
  9. def connect(self):
  10. if settings.AUTH_LDAP_PROTO == 'ldaps':
  11. ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
  12. self.con = ldap.initialize(settings.AUTH_LDAP_PROTO + '://' + settings.AUTH_LDAP_HOST + ':' + settings.AUTH_LDAP_PORT)
  13. try:
  14. self.con.simple_bind_s(settings.AUTH_LDAP_BIND_DN, settings.AUTH_LDAP_BIND_PASSWORD)
  15. except ldap.SERVER_DOWN:
  16. raise ldap.SERVER_DOWN('The LDAP library can’t contact the LDAP server. Contact the admin.')
  17. def check_attribute(self, attribute, value):
  18. """
  19. Takes an attribute and value and checks it against the LDAP server for existence/availability.
  20. This is mainly for checking unique attributes ie uid, mail, uidNumber
  21. :param attribute:
  22. :param value
  23. :return: tuple
  24. """
  25. query = "(" + attribute + "=" + value + ")"
  26. result = self.con.search_s(settings.AUTH_LDAP_BASE_DN, ldap.SCOPE_SUBTREE, query)
  27. return result
  28. def add_to_group(self, username, group):
  29. user_dn = "uid=%s,ou=users,%s" % (username, settings.AUTH_LDAP_BASE_DN,)
  30. group_dn = "cn=%s,ou=groups,%s" % (group, settings.AUTH_LDAP_BASE_DN,)
  31. return self.con.modify_s(
  32. group_dn,
  33. [
  34. (ldap.MOD_ADD, 'member', [user_dn.encode("utf-8")]),
  35. ],
  36. )
  37. def del_from_group(self, username, group):
  38. user_dn = "uid=%s,ou=users,%s" % (username, settings.AUTH_LDAP_BASE_DN,)
  39. group_dn = "cn=%s,ou=groups,%s" % (group, settings.AUTH_LDAP_BASE_DN,)
  40. return self.con.modify_s(
  41. group_dn,
  42. [
  43. (ldap.MOD_DELETE, 'member', [user_dn.encode("utf-8")]),
  44. ],
  45. )
  46. def add_user(self, user):
  47. modlist = {
  48. "objectClass": ["sharixAccount"],
  49. "uid": [user.id],
  50. "userPassword": ['{ARGON2}'+user.password[6:]],
  51. "sn": [user.last_name],
  52. "initials": [user.middle_name],
  53. "givenName": [user.first_name],
  54. "cn": [user.get_full_name()],
  55. "displayName": [user.get_full_name()],
  56. # "title": [user.title],
  57. "mail": [user.email],
  58. # "jpegPhoto": [user.avatar],
  59. # "employeeType": [user.designation],
  60. # "departmentNumber": [user.department],
  61. "telephoneNumber": [user.phone_number],
  62. # "registeredAddress": [user.address],
  63. # "homePhone": [user.phone],
  64. # "uidNumber": [uid_number],
  65. # "gidNumber": [settings.LDAP_GID],
  66. # "loginShell": ["/bin/bash"],
  67. # "homeDirectory": ["/home/users/" + user.username]
  68. }
  69. dn = 'uid=' + modlist['uid'][0] + ',ou=users,' + settings.AUTH_LDAP_BASE_DN
  70. # convert modlist to bytes form ie b'abc'
  71. modlist_bytes = {}
  72. for key in modlist.keys():
  73. modlist_bytes[key] = [i.encode('utf-8') for i in modlist[key] if i
  74. is not None]
  75. result = self.con.add_s(dn, addModlist(modlist_bytes))
  76. return result
  77. def set_password(self, username, password):
  78. """
  79. set user password
  80. :param username:
  81. :param password:
  82. :return: ldap result
  83. """
  84. dn = "uid=%s,ou=users,%s" % (username, settings.AUTH_LDAP_BASE_DN,)
  85. user_result = self.check_attribute('uid', username) # get user
  86. tmp_modlist = dict(user_result)
  87. old_value = {"userPassword": [tmp_modlist[dn]['userPassword'][0]]}
  88. new_value = {"userPassword": [('{ARGON2}'+password[6:]).encode()]}
  89. modlist = ldap.modlist.modifyModlist(old_value, new_value)
  90. result = self.con.modify_s(dn, modlist)
  91. return result
  92. def delete_user(self, username):
  93. dn = "uid=%s,%s" % (username, settings.AUTH_LDAP_BASE_DN,)
  94. response = self.con.delete_s(dn)
  95. return response