def _get_or_create_user(self, user_data): """ Returns a Django user for the given LDAP user data. If the user does not exist, then it will be created. """ User = get_user_model() attributes = user_data["attributes"] # Create the user data. user_fields = { field_name: attributes.get(attribute_name, ("",))[0] for field_name, attribute_name in settings.LDAP_AUTH_USER_FIELDS.items() } user_fields = import_func(settings.LDAP_AUTH_CLEAN_USER_DATA)(user_fields) # Create the user lookup. user_lookup = { field_name: user_fields.pop(field_name, "") for field_name in settings.LDAP_AUTH_USER_LOOKUP_FIELDS } # Update or create the user. user, created = User.objects.update_or_create( defaults = user_fields, **user_lookup ) # Update relations import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS)(user, attributes) # All done! return user
def _get_or_create_user(self, user_data): """ Returns a Django user for the given LDAP user data. If the user does not exist, then it will be created. """ attributes = user_data.get("attributes") if attributes is None: logger.warning("LDAP user attributes empty") return None User = get_user_model() # Create the user data. user_fields = { field_name: (attributes[attribute_name][0] if isinstance( attributes[attribute_name], (list, tuple)) else attributes[attribute_name]) for field_name, attribute_name in settings.LDAP_AUTH_USER_FIELDS.items() if attribute_name in attributes } user_fields = import_func( settings.LDAP_AUTH_CLEAN_USER_DATA)(user_fields) print(user_fields) # Create the user lookup. user_lookup = { field_name: user_fields.pop(field_name, "") for field_name in settings.LDAP_AUTH_USER_LOOKUP_FIELDS } print(user_lookup) # Added this to handle the fact that groups is a list that actually needs to stay as a list try: groups = attributes.get( settings.LDAP_AUTH_USER_FIELDS.get('groups')) logger.debug('Fetched groups list') user_fields.pop('groups', None) except: groups = None logger.debug('No groups found') # Update or create the user. user, created = User.objects.update_or_create(defaults=user_fields, **user_lookup) print(user, created) if groups: self._update_or_create_user_groups(user, groups) # If the user was created, set them an unusable password. if created: user.set_unusable_password() user.save() # Update relations import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS)(user, attributes) # All done! logger.info("LDAP user lookup succeeded") return user
def testImportFunc(self): self.assertIs(clean_ldap_name, import_func(clean_ldap_name)) self.assertIs(clean_ldap_name, import_func("django_python3_ldap.utils.clean_ldap_name")) self.assertTrue(callable(import_func("django.contrib.auth.get_user_model"))) self.assertRaises(AttributeError, import_func, 123) self.assertTrue(callable(import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS))) with self.settings(LDAP_AUTH_SYNC_USER_RELATIONS="django.contrib.auth.get_user_model"): self.assertTrue(callable(import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS)))
def testImportFunc(self): self.assertIs(clean_ldap_name, import_func(clean_ldap_name)) self.assertIs(clean_ldap_name, import_func('django_python3_ldap.utils.clean_ldap_name')) self.assertTrue(callable(import_func('django.contrib.auth.get_user_model'))) self.assertRaises(AttributeError, import_func, 123) self.assertTrue(callable(import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS))) with self.settings(LDAP_AUTH_SYNC_USER_RELATIONS='django.contrib.auth.get_user_model'): self.assertTrue(callable(import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS)))
def _get_or_create_user(self, user_data): """ Returns a Django user for the given LDAP user data. If the user does not exist, then it will be created. """ attributes = user_data.get("attributes") if attributes is None: logger.warning("LDAP user attributes empty") return None User = get_user_model() # Create the user data. user_fields = { field_name: (attributes[attribute_name][0] if isinstance( attributes[attribute_name], (list, tuple)) else attributes[attribute_name]) for field_name, attribute_name in settings.LDAP_AUTH_USER_FIELDS.items() if attribute_name in attributes } user_fields = import_func( settings.LDAP_AUTH_CLEAN_USER_DATA)(user_fields) # Create the user lookup. user_lookup = { field_name: user_fields.pop(field_name, "") for field_name in settings.LDAP_AUTH_USER_LOOKUP_FIELDS } # Update or create the user. # user, created = User.objects.update_or_create( # defaults=user_fields, # **user_lookup # ) user, created = User.objects.get_or_create(**user_lookup) # If the user was created, set them an unusable password. if created: user.set_unusable_password() for attr, value in user_fields.items(): setattr(user, attr, value) user.save() # Update relations import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS)(user, attributes) # All done! logger.info("LDAP user lookup succeeded") return user
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. username = None password = None if kwargs: password = kwargs.pop("password") username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME)(kwargs) # Make the connection. if username or password: if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS else: auto_bind = ldap3.AUTO_BIND_NONE try: with ldap3.Connection(ldap3.Server(settings.LDAP_AUTH_URL), user=username, password=password, auto_bind=auto_bind) as c: yield Connection(c) except (ldap3.LDAPBindError, ldap3.LDAPSASLPrepError): yield None
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. kwargs = {key: value for key, value in kwargs.items() if value} username = None password = None if kwargs: password = kwargs.pop("password") username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME)(kwargs) # Make the connection. if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS try: with ldap3.Connection( ldap3.Server(settings.LDAP_AUTH_URL, allowed_referral_hosts=[("*", True)]), user=username, password=password, auto_bind=auto_bind, raise_exceptions=True, ) as c: yield Connection(c) except LDAPException as ex: logger.info("LDAP connect failed: {ex}".format(ex=ex)) yield None
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. kwargs = { key: value for key, value in kwargs.items() if value } username = None password = None if kwargs: password = kwargs.pop("password") username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME)(kwargs) # Make the connection. if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS try: with ldap3.Connection(ldap3.Server(settings.LDAP_AUTH_URL), user=username, password=password, auto_bind=auto_bind) as c: yield Connection(c) except ldap3.LDAPBindError as ex: logger.info("LDAP login failed: {ex}".format(ex=ex)) yield None except ldap3.LDAPException as ex: logger.warn("LDAP connect failed: {ex}".format(ex=ex)) yield None
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. format_username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME) kwargs = {key: value for key, value in kwargs.items() if value} username = None password = None if kwargs: password = kwargs.pop("password") username = format_username(kwargs) # Configure the connection. if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS tls = ldap3.Tls(**settings.LDAP_AUTH_TLS_PARAMS) # Connect. try: c = ldap3.Connection( ldap3.Server( settings.LDAP_AUTH_URL, allowed_referral_hosts=[("*", True)], tls=tls, ), user=username, password=password, auto_bind=auto_bind, raise_exceptions=True, ) except LDAPException as ex: logger.info("LDAP connect failed: {ex}".format(ex=ex)) yield None return # If the settings specify an alternative username and password for querying, rebind as that. if ((settings.LDAP_AUTH_CONNECTION_USERNAME or settings.LDAP_AUTH_CONNECTION_PASSWORD) and (settings.LDAP_AUTH_CONNECTION_USERNAME != username or settings.LDAP_AUTH_CONNECTION_PASSWORD != password)): try: c.rebind( user=format_username( {"username": settings.LDAP_AUTH_CONNECTION_USERNAME}), password=settings.LDAP_AUTH_CONNECTION_PASSWORD, ) except LDAPException as ex: logger.info("LDAP rebind failed: {ex}".format(ex=ex)) yield None return # Return the connection. try: yield Connection(c) finally: c.unbind()
def handle(self, *args, **kwargs): verbosity = int(kwargs.get("verbosity", 1)) User = get_user_model() auth_kwargs = { User.USERNAME_FIELD: settings.LDAP_AUTH_CONNECTION_USERNAME, 'password': settings.LDAP_AUTH_CONNECTION_PASSWORD } list_users = [] with ldap.connection(**auth_kwargs) as connection: if connection is None: raise CommandError("Could not connect to LDAP server") for user in connection.iter_users(): list_users.append(user.username) if verbosity >= 1: self.stdout.write("Synced {user}".format( user=user, )) import_func(settings.LDAP_AUTH_AFTER_SYNC_COMMAND)(list_users)
def _get_or_create_user(self, user_data): """ Returns a Django user for the given LDAP user data. If the user does not exist, then it will be created. """ attributes = user_data.get("attributes") if attributes is None: return None User = get_user_model() # Create the user data. user_fields = { field_name: (attributes[attribute_name][0] if isinstance( attributes[attribute_name], (list, tuple)) else attributes[attribute_name]) for field_name, attribute_name in settings.LDAP_AUTH_USER_FIELDS.items() if attribute_name in attributes } user_fields = import_func( settings.LDAP_AUTH_CLEAN_USER_DATA)(user_fields) # Create the user lookup. user_lookup = { field_name: user_fields.pop(field_name, "") for field_name in settings.LDAP_AUTH_USER_LOOKUP_FIELDS } # Update or create the user. user, created = User.objects.update_or_create(defaults=user_fields, **user_lookup) # Update relations import_func(settings.LDAP_AUTH_SYNC_USER_RELATIONS)(user, attributes) # All done! return user
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. format_username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME) kwargs = {key: value for key, value in kwargs.items() if value} username = None password = None if kwargs: password = kwargs.pop("password") username = format_username(kwargs) # Connect. try: c = ldap3.Connection( ldap3.Server( settings.LDAP_AUTH_URL, allowed_referral_hosts=[("*", True)], get_info=ldap3.NONE, connect_timeout=settings.LDAP_AUTH_CONNECT_TIMEOUT, ), user=username, password=password, auto_bind=False, raise_exceptions=True, receive_timeout=settings.LDAP_AUTH_RECEIVE_TIMEOUT, ) except LDAPException as ex: logger.warning("LDAP connect failed: {ex}".format(ex=ex)) yield None return # Configure. try: # Start TLS, if requested. if settings.LDAP_AUTH_USE_TLS: c.start_tls(read_server_info=False) # Perform initial authentication bind. c.bind(read_server_info=True) # If the settings specify an alternative username and password for querying, rebind as that. if ((settings.LDAP_AUTH_CONNECTION_USERNAME or settings.LDAP_AUTH_CONNECTION_PASSWORD) and (settings.LDAP_AUTH_CONNECTION_USERNAME != username or settings.LDAP_AUTH_CONNECTION_PASSWORD != password)): User = get_user_model() c.rebind( user=format_username({ User.USERNAME_FIELD: settings.LDAP_AUTH_CONNECTION_USERNAME }), password=settings.LDAP_AUTH_CONNECTION_PASSWORD, ) # Return the connection. logger.info("LDAP connect succeeded") yield Connection(c) except LDAPException as ex: logger.warning("LDAP bind failed: {ex}".format(ex=ex)) yield None finally: c.unbind()
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. format_username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME) kwargs = { key: value for key, value in kwargs.items() if value } username = None password = None if kwargs: password = kwargs.pop("password") # username = format_username(kwargs) try: username = kwargs.pop("binddn") except: username = format_username(kwargs) # Configure the connection. if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS # Connect. try: c = ldap3.Connection( ldap3.Server( settings.LDAP_AUTH_URL, allowed_referral_hosts=[("*", True)], get_info=ldap3.NONE, connect_timeout=settings.LDAP_AUTH_CONNECT_TIMEOUT, ), #user=username, #password=password, user=settings.LDAP_AUTH_CONNECTION_USERNAME, password=settings.LDAP_AUTH_CONNECTION_PASSWORD, auto_bind=auto_bind, raise_exceptions=True, receive_timeout=settings.LDAP_AUTH_RECEIVE_TIMEOUT, ) except LDAPException as ex: logger.warning("LDAP connect failed: {ex}".format(ex=ex)) yield None return # Rebind as login user. if ( settings.LDAP_AUTH_CONNECTION_USERNAME != username ): # Search login user. if c.search( search_base=settings.LDAP_AUTH_SEARCH_BASE, search_filter=format_search_filter(kwargs), search_scope=ldap3.SUBTREE, size_limit=1, ): username=c.response[0]['dn'] #print username User = get_user_model() try: c.rebind( # user=format_username({User.USERNAME_FIELD: settings.LDAP_AUTH_CONNECTION_USERNAME}), # user=settings.LDAP_AUTH_CONNECTION_USERNAME, # password=settings.LDAP_AUTH_CONNECTION_PASSWORD, user=username, password=password, ) except LDAPException as ex: logger.warning("LDAP rebind failed: {ex}".format(ex=ex)) yield None return # Return the connection. logger.info("LDAP connect succeeded") try: yield Connection(c) finally: c.unbind()
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. format_username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME) kwargs = {key: value for key, value in kwargs.items() if value} username = None password = None domain = None if kwargs: password = kwargs.pop("password") domain = kwargs.get("domain") username = format_username(kwargs) # Configure the connection. if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS # Connect. if domain is not None: auth_url = settings.LDAP_AUTH_MULTIDOMAIN_URL.get(domain) else: auth_url = settings.LDAP_AUTH_URL try: c = ldap3.Connection( ldap3.Server( auth_url, allowed_referral_hosts=[("*", True)], get_info=ldap3.NONE, connect_timeout=settings.LDAP_AUTH_CONNECT_TIMEOUT, ), user=username, password=password, auto_bind=auto_bind, raise_exceptions=True, receive_timeout=settings.LDAP_AUTH_RECEIVE_TIMEOUT, ) except LDAPException as ex: logger.warning("LDAP connect failed: {ex}".format(ex=ex)) yield None return # If the settings specify an alternative username and password for querying, rebind as that. if ((settings.LDAP_AUTH_CONNECTION_USERNAME or settings.LDAP_AUTH_CONNECTION_PASSWORD) and (settings.LDAP_AUTH_CONNECTION_USERNAME != username or settings.LDAP_AUTH_CONNECTION_PASSWORD != password)): User = get_user_model() try: c.rebind( user=format_username({ User.USERNAME_FIELD: settings.LDAP_AUTH_CONNECTION_USERNAME }), password=settings.LDAP_AUTH_CONNECTION_PASSWORD, ) except LDAPException as ex: logger.warning("LDAP rebind failed: {ex}".format(ex=ex)) yield None return # Return the connection. logger.info("LDAP connect succeeded") try: yield Connection(c) finally: c.unbind()
def connection(**kwargs): """ Creates and returns a connection to the LDAP server. The user identifier, if given, should be keyword arguments matching the fields in settings.LDAP_AUTH_USER_LOOKUP_FIELDS, plus a `password` argument. """ # Format the DN for the username. format_username = import_func(settings.LDAP_AUTH_FORMAT_USERNAME) kwargs = {key: value for key, value in kwargs.items() if value} username = None password = None if kwargs: password = kwargs.pop("password") username = format_username(kwargs) # Configure the connection. if settings.LDAP_AUTH_USE_TLS: auto_bind = ldap3.AUTO_BIND_TLS_BEFORE_BIND else: auto_bind = ldap3.AUTO_BIND_NO_TLS # Connect. try: assert settings.LDAP_AUTH_LDIF if settings.LDAP_AUTH_LDIF: c = ldap3.Connection( "mock_server", user=username, password=password, client_strategy=ldap3.MOCK_SYNC, raise_exceptions=True, ) # Load entries from LDIF file parser = LDIFParser(open(settings.LDAP_AUTH_LDIF, "rb")) for dn, entry in parser.parse(): c.strategy.add_entry(dn, entry) # Per https://ldap3.readthedocs.io/mocking.html: # "You cannot use the auto_bind parameter because the DIT is populated after the creation of the Connection object." # Bind manually c.bind() else: c = ldap3.Connection( ldap3.Server( settings.LDAP_AUTH_URL, allowed_referral_hosts=[("*", True)], get_info=ldap3.NONE, connect_timeout=settings.LDAP_AUTH_CONNECT_TIMEOUT, ), user=username, password=password, auto_bind=auto_bind, raise_exceptions=True, receive_timeout=settings.LDAP_AUTH_RECEIVE_TIMEOUT, ) except LDAPException as ex: logger.warning("LDAP connect failed: {ex}".format(ex=ex)) yield None return # If the settings specify an alternative username and password for querying, rebind as that. if ((settings.LDAP_AUTH_CONNECTION_USERNAME or settings.LDAP_AUTH_CONNECTION_PASSWORD) and (settings.LDAP_AUTH_CONNECTION_USERNAME != username or settings.LDAP_AUTH_CONNECTION_PASSWORD != password)): User = get_user_model() try: c.rebind( user=format_username({ User.USERNAME_FIELD: settings.LDAP_AUTH_CONNECTION_USERNAME }), password=settings.LDAP_AUTH_CONNECTION_PASSWORD, ) except LDAPException as ex: logger.warning("LDAP rebind failed: {ex}".format(ex=ex)) yield None return # Return the connection. logger.info("LDAP connect succeeded") try: yield Connection(c) finally: c.unbind()