mirror of
https://github.com/zulip/zulip.git
synced 2025-11-16 03:41:58 +00:00
tests: Refactor query_ldap() and add complete test coverage.
This commit is contained in:
committed by
Tim Abbott
parent
13eaa49a42
commit
46d6541958
@@ -12,4 +12,6 @@ class Command(BaseCommand):
|
|||||||
help="email of user to query")
|
help="email of user to query")
|
||||||
|
|
||||||
def handle(self, *args: Any, **options: str) -> None:
|
def handle(self, *args: Any, **options: str) -> None:
|
||||||
query_ldap(**options)
|
values = query_ldap(**options)
|
||||||
|
for value in values:
|
||||||
|
print(value)
|
||||||
|
|||||||
@@ -3,7 +3,7 @@ from django.conf import settings
|
|||||||
from django.core import mail
|
from django.core import mail
|
||||||
from django.http import HttpResponse
|
from django.http import HttpResponse
|
||||||
from django.test import override_settings
|
from django.test import override_settings
|
||||||
from django_auth_ldap.backend import _LDAPUser
|
from django_auth_ldap.backend import LDAPBackend, _LDAPUser
|
||||||
from django.test.client import RequestFactory
|
from django.test.client import RequestFactory
|
||||||
from django.utils.timezone import now as timezone_now
|
from django.utils.timezone import now as timezone_now
|
||||||
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
from typing import Any, Callable, Dict, List, Optional, Set, Tuple
|
||||||
@@ -54,7 +54,7 @@ from zproject.backends import ZulipDummyBackend, EmailAuthBackend, \
|
|||||||
dev_auth_enabled, password_auth_enabled, github_auth_enabled, \
|
dev_auth_enabled, password_auth_enabled, github_auth_enabled, \
|
||||||
require_email_format_usernames, AUTH_BACKEND_NAME_MAP, \
|
require_email_format_usernames, AUTH_BACKEND_NAME_MAP, \
|
||||||
ZulipLDAPConfigurationError, ZulipLDAPExceptionOutsideDomain, \
|
ZulipLDAPConfigurationError, ZulipLDAPExceptionOutsideDomain, \
|
||||||
ZulipLDAPException, sync_user_from_ldap
|
ZulipLDAPException, query_ldap, sync_user_from_ldap
|
||||||
|
|
||||||
from zerver.views.auth import (maybe_send_to_registration,
|
from zerver.views.auth import (maybe_send_to_registration,
|
||||||
_subdomain_token_salt)
|
_subdomain_token_salt)
|
||||||
@@ -2898,6 +2898,64 @@ class TestZulipLDAPUserPopulator(ZulipLDAPTestCase):
|
|||||||
actual_value = CustomProfileFieldValue.objects.get(user_profile=hamlet, field=no_op_field).value
|
actual_value = CustomProfileFieldValue.objects.get(user_profile=hamlet, field=no_op_field).value
|
||||||
self.assertEqual(actual_value, expected_value)
|
self.assertEqual(actual_value, expected_value)
|
||||||
|
|
||||||
|
class TestQueryLDAP(ZulipLDAPTestCase):
|
||||||
|
class _LDAPUser:
|
||||||
|
attrs = {
|
||||||
|
'cn': ['King Hamlet', ],
|
||||||
|
'sn': ['Hamlet', ],
|
||||||
|
'thumbnailPhoto': [open(os.path.join(settings.STATIC_ROOT, "images/team/tim.png"), "rb").read()],
|
||||||
|
'birthDate': ['1990-01-01', ],
|
||||||
|
'twitter': ['@handle', ],
|
||||||
|
}
|
||||||
|
|
||||||
|
def __init__(self, backend: LDAPBackend, username: str) -> None:
|
||||||
|
super().__init__()
|
||||||
|
|
||||||
|
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.EmailAuthBackend',))
|
||||||
|
def test_ldap_not_configured(self) -> None:
|
||||||
|
values = query_ldap(self.example_email('hamlet'))
|
||||||
|
self.assertEqual(values, ['LDAP backend not configured on this server.'])
|
||||||
|
|
||||||
|
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
|
||||||
|
def test_user_not_present(self) -> None:
|
||||||
|
values = query_ldap(self.example_email('hamlet'))
|
||||||
|
self.assertEqual(values, ['No such user found'])
|
||||||
|
|
||||||
|
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
|
||||||
|
def test_normal_query(self) -> None:
|
||||||
|
with self.settings(AUTH_LDAP_USER_ATTR_MAP={'full_name': 'cn',
|
||||||
|
'short_name': 'sn',
|
||||||
|
'avatar': 'thumbnailPhoto',
|
||||||
|
'custom_profile_field__birthday': 'birthDate',
|
||||||
|
'custom_profile_field__phone_number': 'phoneNumber',
|
||||||
|
'custom_profile_field__twitter': 'twitter'}), \
|
||||||
|
mock.patch('zproject.backends._LDAPUser', self._LDAPUser, create=True):
|
||||||
|
values = query_ldap(self.example_email('hamlet'))
|
||||||
|
self.assertEqual(len(values), 6)
|
||||||
|
self.assertIn('full_name: King Hamlet', values)
|
||||||
|
self.assertIn('short_name: Hamlet', values)
|
||||||
|
self.assertIn('avatar: (An avatar image file)', values)
|
||||||
|
self.assertIn('custom_profile_field__birthday: 1990-01-01', values)
|
||||||
|
self.assertIn('custom_profile_field__phone_number: LDAP field not present', values)
|
||||||
|
self.assertIn('custom_profile_field__twitter: @handle', values)
|
||||||
|
|
||||||
|
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
|
||||||
|
def test_query_email_attr(self) -> None:
|
||||||
|
self._LDAPUser.attrs = {
|
||||||
|
'cn': ['King Hamlet', ],
|
||||||
|
'sn': ['Hamlet', ],
|
||||||
|
'email_attr': ['separate_email@zulip.com', ],
|
||||||
|
}
|
||||||
|
with self.settings(AUTH_LDAP_USER_ATTR_MAP={'full_name': 'cn',
|
||||||
|
'short_name': 'sn'},
|
||||||
|
LDAP_EMAIL_ATTR='email_attr'), \
|
||||||
|
mock.patch('zproject.backends._LDAPUser', self._LDAPUser, create=True):
|
||||||
|
values = query_ldap(self.example_email('hamlet'))
|
||||||
|
self.assertEqual(len(values), 3)
|
||||||
|
self.assertIn('full_name: King Hamlet', values)
|
||||||
|
self.assertIn('short_name: Hamlet', values)
|
||||||
|
self.assertIn('email: separate_email@zulip.com', values)
|
||||||
|
|
||||||
class TestZulipAuthMixin(ZulipTestCase):
|
class TestZulipAuthMixin(ZulipTestCase):
|
||||||
def test_get_user(self) -> None:
|
def test_get_user(self) -> None:
|
||||||
backend = ZulipAuthMixin()
|
backend = ZulipAuthMixin()
|
||||||
|
|||||||
@@ -505,22 +505,25 @@ def sync_user_from_ldap(user_profile: UserProfile) -> bool:
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
# Quick tool to test whether you're correctly authenticating to LDAP
|
# Quick tool to test whether you're correctly authenticating to LDAP
|
||||||
def query_ldap(**options: str) -> None:
|
def query_ldap(email: str) -> List[str]:
|
||||||
email = options['email']
|
values = []
|
||||||
for backend in get_backends():
|
backend = next((backend for backend in get_backends() if isinstance(backend, LDAPBackend)), None)
|
||||||
if isinstance(backend, LDAPBackend):
|
if backend is not None:
|
||||||
ldap_attrs = _LDAPUser(backend, backend.django_to_ldap_username(email)).attrs
|
ldap_attrs = _LDAPUser(backend, backend.django_to_ldap_username(email)).attrs
|
||||||
if ldap_attrs is None:
|
if ldap_attrs is None:
|
||||||
print("No such user found")
|
values.append("No such user found")
|
||||||
else:
|
else:
|
||||||
for django_field, ldap_field in settings.AUTH_LDAP_USER_ATTR_MAP.items():
|
for django_field, ldap_field in settings.AUTH_LDAP_USER_ATTR_MAP.items():
|
||||||
value = ldap_attrs.get(ldap_field, ["LDAP field not present", ])[0]
|
value = ldap_attrs.get(ldap_field, ["LDAP field not present", ])[0]
|
||||||
if django_field == "avatar":
|
if django_field == "avatar":
|
||||||
if isinstance(value, bytes):
|
if isinstance(value, bytes):
|
||||||
value = "(An avatar image file)"
|
value = "(An avatar image file)"
|
||||||
print("%s: %s" % (django_field, value))
|
values.append("%s: %s" % (django_field, value))
|
||||||
if settings.LDAP_EMAIL_ATTR is not None:
|
if settings.LDAP_EMAIL_ATTR is not None:
|
||||||
print("%s: %s" % ('email', ldap_attrs[settings.LDAP_EMAIL_ATTR]))
|
values.append("%s: %s" % ('email', ldap_attrs[settings.LDAP_EMAIL_ATTR][0]))
|
||||||
|
else:
|
||||||
|
values.append("LDAP backend not configured on this server.")
|
||||||
|
return values
|
||||||
|
|
||||||
class DevAuthBackend(ZulipAuthMixin):
|
class DevAuthBackend(ZulipAuthMixin):
|
||||||
# Allow logging in as any user without a password.
|
# Allow logging in as any user without a password.
|
||||||
|
|||||||
Reference in New Issue
Block a user