Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- from django.conf import settings
- from django.contrib.auth.models import User, check_password
- from django.contrib.auth.backends import ModelBackend
- from django.contrib.auth import get_user_model
- import ldap
- class BlvsysBackend(ModelBackend):
- @staticmethod
- def is_ldap_up():
- # unauthenticated search
- try:
- # connect and authenticate
- l = ldap.initialize('ldaps://' + settings.AUTHENTICATION_LDAP_SERVER + '/')
- l.protocol_version = ldap.VERSION3
- l.simple_bind()
- except:
- return False
- return True
- @staticmethod
- def get_ldap_user(username, password):
- # authenticated search
- try:
- # init
- search_filter = settings.AUTHENTICATION_LDAP_SEARCHFILTER % username
- # authenticate
- l = ldap.initialize('ldaps://' + settings.AUTHENTICATION_LDAP_SERVER + '/')
- l.protocol_version = ldap.VERSION3
- l.simple_bind(settings.AUTHENTICATION_LDAP_USER % username, password)
- # search one ldap result (not less, not more)
- ldap_result_id = l.search(settings.AUTHENTICATION_LDAP_BASEDN, ldap.SCOPE_SUBTREE, search_filter, None)
- ldap_result = None
- while 1:
- result_type, result_data = l.result(ldap_result_id, 0)
- if not result_data:
- break
- if result_type != ldap.RES_SEARCH_ENTRY:
- continue
- if ldap_result:
- raise Exception('more than one matching result !')
- ldap_result = result_data
- if not ldap_result:
- raise Exception('no matching result (1) !')
- # checking structure
- if not isinstance(ldap_result, list) or len(ldap_result) != 1:
- raise Exception('invalid LDAP answer struct 1')
- ldap_result = ldap_result[0]
- if not isinstance(ldap_result, tuple) or len(ldap_result) != 2:
- raise Exception('invalid LDAP answer struct 2')
- # checking key
- if ldap_result[0] != settings.AUTHENTICATION_LDAP_USER % username:
- raise Exception('invalid response key/uid')
- ldap_result = ldap_result[1]
- # checking struct
- needed = ('uid', 'givenName', 'sn', 'objectClass', 'mail')
- for n in needed:
- if n not in ldap_result or not isinstance(ldap_result[n], list):
- raise Exception('invalid LDAP answer struct 3')
- # checking values
- if \
- len(ldap_result['uid']) != 1 or ldap_result['uid'][0] != username or \
- username + '@' + settings.AUTHENTICATION_LDAP_EMAILDOMAIN not in ldap_result['mail'] or \
- 'believeInfo' not in ldap_result['objectClass']:
- raise Exception('unable to check your account data !')
- return ldap_result
- except:
- return None
- # TODO review prototype of authenticate()
- def authenticate(self, username=None, password=None):
- # user and password must be provided
- if username is None or password is None:
- print ' None'
- return None
- # ldapnot bypassed ? and UP ?
- if settings.AUTHENTICATION_LDAP_BYPASS:
- is_ldap_up = False
- else:
- is_ldap_up = self.is_ldap_up()
- # user exist in LDAP ?
- ldap_user = None
- if is_ldap_up:
- ldap_user = self.get_ldap_user(username, password)
- # user exist in Django ?
- try:
- local_user = get_user_model().objects.get(username=username)
- except User.DoesNotExist:
- local_user = None
- # nowhere ?
- if not ldap_user and not local_user:
- return None
- # in Django only ? superuser can go ahead
- if not ldap_user and local_user.is_superuser and check_password(password, local_user.password):
- return local_user
- # LDAP is up, the user must have an active account on it
- if is_ldap_up and not ldap_user:
- return None
- # LDAP is down, we consider local user :
- if not is_ldap_up and local_user and check_password(password, local_user.password):
- return local_user
- # LDAP is up, and user exist in ldap and django, update password and go ahred
- if ldap_user and local_user:
- if local_user.password != password:
- local_user.set_password(password)
- local_user.save()
- return local_user
- # LDAP is up, user exist only in ldap
- if ldap_user and not local_user:
- local_user = get_user_model()(
- username=username,
- first_name=ldap_user['givenName'][0],
- last_name=ldap_user['sn'][0],
- email=username + '@' + settings.AUTHENTICATION_LDAP_EMAILDOMAIN,
- is_active=True,
- is_staff=False,
- is_superuser=False,
- )
- local_user.set_password(password)
- local_user.save()
- return local_user
- # something goes wrong
- return None
- def get_user(self, user_id):
- try:
- return get_user_model().objects.get(pk=user_id)
- except User.DoesNotExist:
- return None
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement