Advertisement
Guest User

Untitled

a guest
Nov 17th, 2016
104
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 5.44 KB | None | 0 0
  1. from django.conf import settings
  2. from django.contrib.auth.models import User, check_password
  3. from django.contrib.auth.backends import ModelBackend
  4. from django.contrib.auth import get_user_model
  5. import ldap
  6.  
  7.  
  8. class BlvsysBackend(ModelBackend):
  9.  
  10. @staticmethod
  11. def is_ldap_up():
  12. # unauthenticated search
  13. try:
  14. # connect and authenticate
  15. l = ldap.initialize('ldaps://' + settings.AUTHENTICATION_LDAP_SERVER + '/')
  16. l.protocol_version = ldap.VERSION3
  17. l.simple_bind()
  18.  
  19. except:
  20. return False
  21. return True
  22.  
  23. @staticmethod
  24. def get_ldap_user(username, password):
  25. # authenticated search
  26. try:
  27. # init
  28. search_filter = settings.AUTHENTICATION_LDAP_SEARCHFILTER % username
  29.  
  30. # authenticate
  31. l = ldap.initialize('ldaps://' + settings.AUTHENTICATION_LDAP_SERVER + '/')
  32. l.protocol_version = ldap.VERSION3
  33. l.simple_bind(settings.AUTHENTICATION_LDAP_USER % username, password)
  34.  
  35. # search one ldap result (not less, not more)
  36. ldap_result_id = l.search(settings.AUTHENTICATION_LDAP_BASEDN, ldap.SCOPE_SUBTREE, search_filter, None)
  37. ldap_result = None
  38. while 1:
  39. result_type, result_data = l.result(ldap_result_id, 0)
  40. if not result_data:
  41. break
  42. if result_type != ldap.RES_SEARCH_ENTRY:
  43. continue
  44. if ldap_result:
  45. raise Exception('more than one matching result !')
  46. ldap_result = result_data
  47. if not ldap_result:
  48. raise Exception('no matching result (1) !')
  49.  
  50. # checking structure
  51. if not isinstance(ldap_result, list) or len(ldap_result) != 1:
  52. raise Exception('invalid LDAP answer struct 1')
  53. ldap_result = ldap_result[0]
  54. if not isinstance(ldap_result, tuple) or len(ldap_result) != 2:
  55. raise Exception('invalid LDAP answer struct 2')
  56.  
  57. # checking key
  58. if ldap_result[0] != settings.AUTHENTICATION_LDAP_USER % username:
  59. raise Exception('invalid response key/uid')
  60. ldap_result = ldap_result[1]
  61.  
  62. # checking struct
  63. needed = ('uid', 'givenName', 'sn', 'objectClass', 'mail')
  64. for n in needed:
  65. if n not in ldap_result or not isinstance(ldap_result[n], list):
  66. raise Exception('invalid LDAP answer struct 3')
  67.  
  68. # checking values
  69. if \
  70. len(ldap_result['uid']) != 1 or ldap_result['uid'][0] != username or \
  71. username + '@' + settings.AUTHENTICATION_LDAP_EMAILDOMAIN not in ldap_result['mail'] or \
  72. 'believeInfo' not in ldap_result['objectClass']:
  73. raise Exception('unable to check your account data !')
  74.  
  75. return ldap_result
  76.  
  77. except:
  78. return None
  79.  
  80. # TODO review prototype of authenticate()
  81. def authenticate(self, username=None, password=None):
  82.  
  83. # user and password must be provided
  84. if username is None or password is None:
  85. print ' None'
  86. return None
  87.  
  88. # ldapnot bypassed ? and UP ?
  89. if settings.AUTHENTICATION_LDAP_BYPASS:
  90. is_ldap_up = False
  91. else:
  92. is_ldap_up = self.is_ldap_up()
  93.  
  94. # user exist in LDAP ?
  95. ldap_user = None
  96. if is_ldap_up:
  97. ldap_user = self.get_ldap_user(username, password)
  98.  
  99. # user exist in Django ?
  100. try:
  101. local_user = get_user_model().objects.get(username=username)
  102. except User.DoesNotExist:
  103. local_user = None
  104. # nowhere ?
  105. if not ldap_user and not local_user:
  106. return None
  107.  
  108. # in Django only ? superuser can go ahead
  109. if not ldap_user and local_user.is_superuser and check_password(password, local_user.password):
  110. return local_user
  111.  
  112. # LDAP is up, the user must have an active account on it
  113. if is_ldap_up and not ldap_user:
  114. return None
  115.  
  116. # LDAP is down, we consider local user :
  117. if not is_ldap_up and local_user and check_password(password, local_user.password):
  118. return local_user
  119.  
  120. # LDAP is up, and user exist in ldap and django, update password and go ahred
  121. if ldap_user and local_user:
  122. if local_user.password != password:
  123. local_user.set_password(password)
  124. local_user.save()
  125. return local_user
  126.  
  127. # LDAP is up, user exist only in ldap
  128. if ldap_user and not local_user:
  129. local_user = get_user_model()(
  130. username=username,
  131. first_name=ldap_user['givenName'][0],
  132. last_name=ldap_user['sn'][0],
  133. email=username + '@' + settings.AUTHENTICATION_LDAP_EMAILDOMAIN,
  134. is_active=True,
  135. is_staff=False,
  136. is_superuser=False,
  137. )
  138. local_user.set_password(password)
  139. local_user.save()
  140. return local_user
  141.  
  142. # something goes wrong
  143. return None
  144.  
  145. def get_user(self, user_id):
  146. try:
  147. return get_user_model().objects.get(pk=user_id)
  148. except User.DoesNotExist:
  149. return None
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement