Esempio n. 1
0
    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
Esempio n. 2
0
    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
Esempio n. 3
0
    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)))
Esempio n. 4
0
    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)))
Esempio n. 5
0
    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
Esempio n. 6
0
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
Esempio n. 7
0
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
Esempio n. 8
0
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
Esempio n. 9
0
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()
Esempio n. 10
0
    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)
Esempio n. 11
0
    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
Esempio n. 12
0
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()
Esempio n. 13
0
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()
Esempio n. 14
0
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()
Esempio n. 15
0
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()