def test_null_port(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         port=None)

        self.assertEqual(389, backend._port)

        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         port=None,
                                                         use_ssl=True)

        self.assertEqual(LDAPS_PORT, backend._port)

        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         port=9090,
                                                         use_ssl=True)

        self.assertEqual(9090, backend._port)
    def test_authenticatefailure_non_group_member_non_required_group(self):
        # User is member of a group which is not required
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR,
                                                         group_dns_check='and')

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertFalse(authenticated)

        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR,
                                                         group_dns_check='or')

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertFalse(authenticated)
    def test_authenticate_and_get_user_groups_caching_enabled(self):
        required_group_dns = ['cn=group1,dc=stackstorm,dc=net']

        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            required_group_dns,
            LDAP_HOST,
            id_attr=LDAP_ID_ATTR,
            group_dns_check='or',
            cache_user_groups_response=True)

        self.assertEqual(ldap.ldapobject.SimpleLDAPObject.search_s.call_count,
                         0)

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertTrue(authenticated)
        self.assertEqual(ldap.ldapobject.SimpleLDAPObject.search_s.call_count,
                         2)

        user_groups = backend.get_user_groups(username=LDAP_USER_UID)
        self.assertEqual(user_groups, ['cn=group1,dc=stackstorm,dc=net'])
        self.assertEqual(ldap.ldapobject.SimpleLDAPObject.search_s.call_count,
                         2)
        self.assertTrue(LDAP_USER_UID in backend._user_groups_cache)
    def test_get_groups_caching_cache_ttl(self):
        required_group_dns = [
            'cn=group3,dc=stackstorm,dc=net', 'cn=group4,dc=stackstorm,dc=net'
        ]

        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            required_group_dns,
            LDAP_HOST,
            id_attr=LDAP_ID_ATTR,
            group_dns_check='or',
            cache_user_groups_response=True,
            cache_user_groups_cache_ttl=1)
        user_groups = backend.get_user_groups(username=LDAP_USER_UID)
        self.assertEqual(user_groups, ['cn=group3,dc=stackstorm,dc=net'])
        self.assertTrue(LDAP_USER_UID in backend._user_groups_cache)
        self.assertEqual(backend._user_groups_cache[LDAP_USER_UID],
                         ['cn=group3,dc=stackstorm,dc=net'])

        # After 1 second, cache entry should expire and it should result in another search_s call
        # which returns group4
        time.sleep(1.5)

        user_groups = backend.get_user_groups(username=LDAP_USER_UID)
        self.assertEqual(user_groups, ['cn=group4,dc=stackstorm,dc=net'])
        self.assertTrue(LDAP_USER_UID in backend._user_groups_cache)
        self.assertEqual(backend._user_groups_cache[LDAP_USER_UID],
                         ['cn=group4,dc=stackstorm,dc=net'])

        # Cache should now be empty
        time.sleep(1.5)
        self.assertFalse(LDAP_USER_UID in backend._user_groups_cache)
 def test_and_is_default_group_dns_check_value(self):
     backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                      LDAP_BIND_PASSWORD,
                                                      LDAP_BASE_OU,
                                                      LDAP_GROUP_DNS,
                                                      LDAP_HOST,
                                                      id_attr=LDAP_ID_ATTR)
     self.assertEqual(backend._group_dns_check, 'and')
    def test_null_id_attr(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=None)

        self.assertEqual('uid', backend._id_attr)
    def test_get_user_multiple_results(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        user_info = backend.get_user(username=LDAP_USER_UID)
        self.assertIsNone(user_info)
    def test_authenticate_without_password(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        with self.assertRaises(ValueError):
            backend.authenticate(LDAP_USER_UID, '')
    def test_authenticate(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        authenticated = backend.authenticate(LDAP_USER_UID, LDAP_USER_PASSWD)
        self.assertTrue(authenticated)
    def test_authenticate_failure_bad_user_password(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertFalse(authenticated)
    def test_scope(self):
        for scope in ['base', 'onelevel', 'subtree']:
            backend = ldap_backend.LDAPAuthenticationBackend(
                LDAP_BIND_DN,
                LDAP_BIND_PASSWORD,
                LDAP_BASE_OU,
                LDAP_GROUP_DNS,
                LDAP_HOST,
                scope=scope)

            self.assertEqual(ldap_backend.SEARCH_SCOPES[scope], backend._scope)
    def test_tls_authenticate_validate_cert(self):
        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            LDAP_GROUP_DNS,
            LDAP_HOST,
            use_tls=True,
            cacert=LDAP_CACERT_REAL_PATH,
            id_attr=LDAP_ID_ATTR)

        authenticated = backend.authenticate(LDAP_USER_UID, LDAP_USER_PASSWD)
        self.assertTrue(authenticated)
    def test_ssl_authenticate_failure(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         port=LDAPS_PORT,
                                                         use_ssl=True,
                                                         id_attr=LDAP_ID_ATTR)

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertFalse(authenticated)
    def test_chase_referrals(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR,
                                                         chase_referrals=False)

        conn = backend._init_connection()
        self.assertFalse(conn.get_option(ldap.OPT_REFERRALS))

        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR,
                                                         chase_referrals=True)

        conn = backend._init_connection()
        self.assertTrue(conn.get_option(ldap.OPT_REFERRALS))
    def test_get_user(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        user_info = backend.get_user(username=LDAP_USER_UID)
        self.assertEqual(user_info['cn'], ['Tomaz Muraus'])
        self.assertEqual(user_info['displayName'], ['Tomaz Muraus'])
        self.assertEqual(user_info['givenName'], ['Tomaz'])
        self.assertEqual(user_info['primaryGroupID'], ['513'])
Example #16
0
    def test_id_attr_and_account_pattern(self):
        account_pattern = '(|(username={username})(mail={username}))'
        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            LDAP_GROUP_DNS,
            LDAP_HOST,
            id_attr='user',
            account_pattern=account_pattern,
        )

        self.assertEqual(account_pattern, backend._account_pattern)
    def test_authenticate_or_behavior_success_member_of_single_group_1(self):
        # User is a memeber of single of possible required groups
        required_group_dns = ['cn=group1,dc=stackstorm,dc=net']
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         required_group_dns,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR,
                                                         group_dns_check='or')

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertTrue(authenticated)
    def test_get_user_groups(self):
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        expected = [
            'cn=testers,dc=stackstorm,dc=net',
            'cn=stormers,dc=stackstorm,dc=net'
        ]

        groups = backend.get_user_groups(username=LDAP_USER_UID)
        self.assertEqual(groups, expected)
    def test_authenticate(self):
        ldap_group_dns = ['cn=testers,ou=groups,dc=stackstorm,dc=net']
        ldap_user_uid = 'stanley'
        ldap_user_passwd = 'stanl3y!'

        backend = ldap_backend.LDAPAuthenticationBackend(
            self.ldap_bind_dn,
            self.ldap_bind_pass,
            self.ldap_base_ou,
            ldap_group_dns,
            self.ldap_host,
            id_attr=self.ldap_id_attr)

        authenticated = backend.authenticate(ldap_user_uid, ldap_user_passwd)

        self.assertTrue(authenticated)
    def test_authenticate_and_behavior_failure_non_group_member_of_all_required_groups_2(
            self):
        # User is member of two of the groups, but none of them are required
        required_group_dns = [
            'cn=group7,dc=stackstorm,dc=net', 'cn=group8,dc=stackstorm,dc=net'
        ]
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         required_group_dns,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR,
                                                         group_dns_check='and')

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertFalse(authenticated)
    def test_get_user_groups_specifying_group_pattern(self):
        expected_user_dn = 'unique_userdn_1'
        expected_username = '******'
        required_group_dns = [
            'cn=group3,dc=stackstorm,dc=net', 'cn=group4,dc=stackstorm,dc=net'
        ]
        scope = 'subtree'
        scope_number = ldap_backend.SEARCH_SCOPES[scope]

        group_pattern = '''
        (|
          (&
            (objectClass=group)
            (|
              (memberUserdn={user_dn})
              (uniqueMemberUserdn={user_dn})
              (memberUid={username})
              (uniqueMemberUid={username})
            )
          )
        )
        '''.replace('\n', '').replace(' ', '')
        expected_group_pattern = group_pattern.format(
            user_dn=expected_user_dn,
            username=expected_username,
        )

        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            required_group_dns,
            LDAP_HOST,
            scope=scope,
            group_pattern=group_pattern,
            cache_user_groups_response=False,
        )
        connection = mock.MagicMock()
        backend._init_connection = mock.MagicMock(return_value=connection)
        backend._get_user_dn = mock.MagicMock(return_value=expected_user_dn)

        backend.get_user_groups(expected_username)
        connection.search_s.assert_called_with(LDAP_BASE_OU, scope_number,
                                               expected_group_pattern, [])
    def test_client_options(self):
        client_options = {
            ldap.OPT_RESTART: 0,
            ldap.OPT_SIZELIMIT: 2014,
            ldap.OPT_DIAGNOSTIC_MESSAGE: 'test',
            # Not using a constant, 20482 is OPT_TIMEOUT
            '20482': 9
        }

        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            LDAP_GROUP_DNS,
            LDAP_HOST,
            id_attr=LDAP_ID_ATTR,
            client_options=client_options)

        conn = backend._init_connection()
        for option_name, option_value in client_options.items():
            self.assertEqual(conn.get_option(int(option_name)), option_value)
    def test_authenticate_and_is_default_behavior_non_group_member_of_all_required_groups(
            self):
        # User is member of two of the required groups and two non-required, but not
        # all of the required groups
        # Verify "and" is a default group_dns_check_behavior
        required_group_dns = [
            'cn=group1,dc=stackstorm,dc=net',
            'cn=group2,dc=stackstorm,dc=net',
            'cn=group5,dc=stackstorm,dc=net',
            'cn=group6,dc=stackstorm,dc=net',
        ]
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         required_group_dns,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        authenticated = backend.authenticate(LDAP_USER_UID,
                                             LDAP_USER_BAD_PASSWD)
        self.assertFalse(authenticated)
    def test_get_groups_caching_no_cross_username_cache_polution(self):
        required_group_dns = [
            'cn=group3,dc=stackstorm,dc=net', 'cn=group4,dc=stackstorm,dc=net'
        ]
        # Test which verifies that cache items are correctly scoped per username
        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            required_group_dns,
            LDAP_HOST,
            id_attr=LDAP_ID_ATTR,
            group_dns_check='or',
            cache_user_groups_response=True)
        user_groups = backend.get_user_groups(username=LDAP_USER_UID)
        self.assertEqual(user_groups, ['cn=group3,dc=stackstorm,dc=net'])
        self.assertEqual(backend._user_groups_cache[LDAP_USER_UID],
                         ['cn=group3,dc=stackstorm,dc=net'])

        user_groups = backend.get_user_groups(username=LDAP_USER_UID_2)
        self.assertEqual(user_groups, ['cn=group4,dc=stackstorm,dc=net'])
        self.assertEqual(backend._user_groups_cache[LDAP_USER_UID_2],
                         ['cn=group4,dc=stackstorm,dc=net'])
    def test_special_characters_in_username_are_escaped(self):
        # User is not member of any of the required group
        backend = ldap_backend.LDAPAuthenticationBackend(LDAP_BIND_DN,
                                                         LDAP_BIND_PASSWORD,
                                                         LDAP_BASE_OU,
                                                         LDAP_GROUP_DNS,
                                                         LDAP_HOST,
                                                         id_attr=LDAP_ID_ATTR)

        values = [
            ('stanleyA', 'stanleyA'),
            ('stanley!@?.,&', 'stanley!@?.,&'),
            # Special characters () should be escaped
            ('(stanley)', '\\28stanley\\29'),
            # Special characters () should be escaped
            ('(stanley=)', '\\28stanley=\\29'),
        ]

        for actual_username, expected_username in values:
            authenticated = backend.authenticate(actual_username,
                                                 LDAP_USER_BAD_PASSWD)
            call_args_1 = ldap.ldapobject.SimpleLDAPObject.search_s.call_args_list[
                0][0]
            call_args_2 = ldap.ldapobject.SimpleLDAPObject.search_s.call_args_list[
                1][0]

            # First search_s call (find user by uid)
            filter_call_value = call_args_1[2]
            self.assertEqual(filter_call_value, 'uid=%s' % (expected_username))

            # Second search_s call (group membership test)
            filter_call_value = call_args_2[2]
            self.assertTrue('(memberUid=%s)' %
                            (expected_username) in filter_call_value)

            ldap.ldapobject.SimpleLDAPObject.search_s = mock.MagicMock(
                side_effect=[LDAP_USER_SEARCH_RESULT, []])
    def test_get_user_specifying_account_pattern(self):
        expected_username = '******'
        required_group_dns = [
            'cn=group3,dc=stackstorm,dc=net', 'cn=group4,dc=stackstorm,dc=net'
        ]
        scope = 'subtree'
        scope_number = ldap_backend.SEARCH_SCOPES[scope]

        account_pattern = '''
        (&
          (objectClass=person)
          (|
            (accountName={username})
            (mail={username})
          )
        )
        '''.replace('\n', '').replace(' ', '')
        expected_account_pattern = account_pattern.format(
            username=expected_username)

        backend = ldap_backend.LDAPAuthenticationBackend(
            LDAP_BIND_DN,
            LDAP_BIND_PASSWORD,
            LDAP_BASE_OU,
            required_group_dns,
            LDAP_HOST,
            scope=scope,
            account_pattern=account_pattern,
        )
        connection = mock.MagicMock()
        backend._init_connection = mock.MagicMock(return_value=connection)
        backend.get_user(expected_username)

        connection.search_s.assert_called_once_with(LDAP_BASE_OU, scope_number,
                                                    expected_account_pattern,
                                                    [])