Add LDAP tests.

This commit is contained in:
Umair Khan
2016-10-24 17:41:45 +05:00
committed by Tim Abbott
parent ccc1f3861f
commit 50422e775b
3 changed files with 207 additions and 1 deletions

View File

@@ -35,6 +35,7 @@ diff-match-patch==20121119
# Needed for LDAP support # Needed for LDAP support
django-auth-ldap==1.2.8 django-auth-ldap==1.2.8
git+https://github.com/umairwaheed/fakeldap.git@7e824313d98a96e52119c359a9b0233fe0b8e585#egg=fakeldap==0.5.1
# Django extension providing bitfield support # Django extension providing bitfield support
django-bitfield==1.8.0 django-bitfield==1.8.0

View File

@@ -5,6 +5,7 @@ from django.test import TestCase
from django_auth_ldap.backend import _LDAPUser from django_auth_ldap.backend import _LDAPUser
from django.test.client import RequestFactory from django.test.client import RequestFactory
from typing import Any, Callable, Dict from typing import Any, Callable, Dict
from builtins import object
import jwt import jwt
import mock import mock
@@ -33,6 +34,7 @@ from social.backends.github import GithubOrganizationOAuth2, GithubTeamOAuth2, \
from six import text_type from six import text_type
from six.moves import urllib from six.moves import urllib
import ujson import ujson
from fakeldap import MockLDAP
class AuthBackendTest(TestCase): class AuthBackendTest(TestCase):
def verify_backend(self, backend, good_args=None, def verify_backend(self, backend, good_args=None,
@@ -962,3 +964,206 @@ class TestJWTLogin(ZulipTestCase):
self.assertEqual(result.status_code, 302) self.assertEqual(result.status_code, 302)
user_profile = get_user_profile_by_email(email) user_profile = get_user_profile_by_email(email)
self.assertEqual(get_session_dict_user(self.client.session), user_profile.id) self.assertEqual(get_session_dict_user(self.client.session), user_profile.id)
class TestLDAP(ZulipTestCase):
def setUp(self):
# type: () -> None
email = "hamlet@zulip.com"
user_profile = get_user_profile_by_email(email)
self.setup_subdomain(user_profile)
ldap_patcher = mock.patch('django_auth_ldap.config.ldap.initialize')
self.mock_initialize = ldap_patcher.start()
self.mock_ldap = MockLDAP()
self.mock_initialize.return_value = self.mock_ldap
self.backend = ZulipLDAPAuthBackend()
def tearUp(self):
# type: () -> None
self.mock_ldap.reset()
self.mock_initialize.stop()
def setup_subdomain(self, user_profile):
# type: (UserProfile) -> None
realm = user_profile.realm
realm.subdomain = 'zulip'
realm.save()
def test_login_success(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
user_profile = self.backend.authenticate('hamlet@zulip.com', 'testing')
self.assertEqual(user_profile.email, 'hamlet@zulip.com')
def test_login_failure_due_to_wrong_password(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
with self.assertRaisesRegexp(self.mock_ldap.INVALID_CREDENTIALS,
'uid=hamlet,ou=users,dc=zulip,dc=com:wrong'):
self.backend.authenticate('hamlet@zulip.com', 'wrong')
def test_login_failure_due_to_nonexistent_user(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
with self.assertRaisesRegexp(self.mock_ldap.INVALID_CREDENTIALS,
'uid=nonexistent,ou=users,dc=zulip,dc=com:testing'):
self.backend.authenticate('nonexistent@zulip.com', 'testing')
def test_ldap_permissions(self):
# type: () -> None
backend = self.backend
self.assertFalse(backend.has_perm(None, None))
self.assertFalse(backend.has_module_perms(None, None))
self.assertTrue(backend.get_all_permissions(None, None) == set())
self.assertTrue(backend.get_group_permissions(None, None) == set())
def test_django_to_ldap_username(self):
# type: () -> None
backend = self.backend
with self.settings(LDAP_APPEND_DOMAIN='zulip.com'):
username = backend.django_to_ldap_username('"hamlet@test"@zulip.com')
self.assertEqual(username, '"hamlet@test"')
def test_ldap_to_django_username(self):
# type: () -> None
backend = self.backend
with self.settings(LDAP_APPEND_DOMAIN='zulip.com'):
username = backend.ldap_to_django_username('"hamlet@test"')
self.assertEqual(username, '"hamlet@test"@zulip.com')
def test_get_or_create_user_when_user_exists(self):
# type: () -> None
class _LDAPUser(object):
attrs = {'fn': ['Full Name'], 'sn': ['Short Name']}
backend = self.backend
email = 'hamlet@zulip.com'
user_profile, created = backend.get_or_create_user(email, _LDAPUser())
self.assertFalse(created)
self.assertEqual(user_profile.email, email)
def test_get_or_create_user_when_user_does_not_exist(self):
# type: () -> None
class _LDAPUser(object):
attrs = {'fn': ['Full Name'], 'sn': ['Short Name']}
ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
with self.settings(AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map):
backend = self.backend
email = 'nonexisting@zulip.com'
user_profile, created = backend.get_or_create_user(email, _LDAPUser())
self.assertTrue(created)
self.assertEqual(user_profile.email, email)
self.assertEqual(user_profile.full_name, 'Full Name')
def test_get_or_create_user_when_realm_is_deactivated(self):
# type: () -> None
class _LDAPUser(object):
attrs = {'fn': ['Full Name'], 'sn': ['Short Name']}
ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
with self.settings(AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map):
backend = self.backend
email = 'nonexisting@zulip.com'
realm = get_realm('zulip.com')
do_deactivate_realm(realm)
with self.assertRaisesRegexp(Exception, 'Realm has been deactivated'):
backend.get_or_create_user(email, _LDAPUser())
def test_django_to_ldap_username_when_domain_does_not_match(self):
# type: () -> None
backend = self.backend
email = 'hamlet@zulip.com'
with self.assertRaisesRegexp(Exception, 'Username does not match LDAP domain.'):
with self.settings(LDAP_APPEND_DOMAIN='acme.com'):
backend.django_to_ldap_username(email)
def test_login_failure_due_to_wrong_subdomain(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
REALMS_HAVE_SUBDOMAINS=True,
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
user_profile = self.backend.authenticate('hamlet@zulip.com', 'testing',
realm_subdomain='acme')
self.assertIs(user_profile, None)
def test_login_failure_due_to_empty_subdomain(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
REALMS_HAVE_SUBDOMAINS=True,
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
user_profile = self.backend.authenticate('hamlet@zulip.com', 'testing',
realm_subdomain='')
self.assertIs(user_profile, None)
def test_login_success_when_subdomain_is_none(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
REALMS_HAVE_SUBDOMAINS=True,
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
user_profile = self.backend.authenticate('hamlet@zulip.com', 'testing',
realm_subdomain=None)
self.assertEqual(user_profile.email, 'hamlet@zulip.com')
def test_login_success_with_valid_subdomain(self):
# type: () -> None
self.mock_ldap.directory = {
'uid=hamlet,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing'
}
}
with self.settings(
REALMS_HAVE_SUBDOMAINS=True,
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_BIND_PASSWORD='',
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
user_profile = self.backend.authenticate('hamlet@zulip.com', 'testing',
realm_subdomain='zulip')
self.assertEqual(user_profile.email, 'hamlet@zulip.com')

View File

@@ -281,7 +281,7 @@ class ZulipLDAPAuthBackendBase(ZulipAuthMixin, LDAPBackend):
class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase): class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase):
def authenticate(self, username, password, realm_subdomain=None, return_data=None): def authenticate(self, username, password, realm_subdomain=None, return_data=None):
# type: (text_type, str, Optional[text_type], Optional[Dict[str, Any]]) -> Optional[str] # type: (text_type, str, Optional[text_type], Optional[Dict[str, Any]]) -> Optional[UserProfile]
try: try:
username = self.django_to_ldap_username(username) username = self.django_to_ldap_username(username)
user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password) user_profile = ZulipLDAPAuthBackendBase.authenticate(self, username, password)