ldap: Allow users to login with just LDAP username.

We had an inconsistent behavior when `LDAP_APPEND_DOMAIN` was set
in that we allowed user to enter username instead of his email in
the auth form but later the workflow failed due to a small bug.

Fixes: #10917.
This commit is contained in:
Harshit Bansal 2019-01-09 16:58:39 +00:00 committed by Tim Abbott
parent 475108b784
commit a55e101bef
2 changed files with 47 additions and 6 deletions

View File

@ -57,7 +57,7 @@ from zproject.backends import ZulipDummyBackend, EmailAuthBackend, \
ZulipLDAPUserPopulator, DevAuthBackend, GitHubAuthBackend, ZulipAuthMixin, \
dev_auth_enabled, password_auth_enabled, github_auth_enabled, \
require_email_format_usernames, AUTH_BACKEND_NAME_MAP, \
ZulipLDAPConfigurationError
ZulipLDAPConfigurationError, ZulipLDAPExceptionOutsideDomain
from zerver.views.auth import (maybe_send_to_registration,
login_or_register_remote_user,
@ -2177,6 +2177,23 @@ class TestLDAP(ZulipTestCase):
assert(user_profile is not None)
self.assertEqual(user_profile.email, self.example_email("hamlet"))
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_login_success_with_username(self) -> 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", 'testing',
realm=get_realm('zulip'))
assert(user_profile is not None)
self.assertEqual(user_profile.email, self.example_email("hamlet"))
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_login_success_with_email_attr(self) -> None:
self.mock_ldap.directory = {
@ -2231,12 +2248,28 @@ class TestLDAP(ZulipTestCase):
self.assertTrue(backend.get_group_permissions(None, None) == set())
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_django_to_ldap_username(self) -> None:
def test_django_to_ldap_username_without_append_domain(self) -> None:
backend = self.backend
username = backend.django_to_ldap_username('"hamlet@test"@zulip.com')
self.assertEqual(username, '"hamlet@test"@zulip.com')
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_django_to_ldap_username_with_append_domain(self) -> 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"')
username = backend.django_to_ldap_username('"hamlet@test"@zulip')
self.assertEqual(username, '"hamlet@test"@zulip')
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_django_to_ldap_username_with_invalid_domain(self) -> None:
backend = self.backend
with self.settings(LDAP_APPEND_DOMAIN='zulip.com'), \
self.assertRaises(ZulipLDAPExceptionOutsideDomain):
backend.django_to_ldap_username('"hamlet@test"@test.com')
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',))
def test_ldap_to_django_username(self) -> None:
backend = self.backend

View File

@ -220,6 +220,13 @@ class ZulipRemoteUserBackend(RemoteUserBackend):
email = remote_user_to_email(remote_user)
return common_get_active_user(email, realm, return_data=return_data)
def is_valid_email(email: str) -> bool:
try:
validate_email(email)
except ValidationError:
return False
return True
def email_belongs_to_ldap(realm: Realm, email: str) -> bool:
if not ldap_auth_enabled(realm):
return False
@ -287,6 +294,7 @@ class ZulipLDAPAuthBackendBase(ZulipAuthMixin, LDAPBackend):
def django_to_ldap_username(self, username: str) -> str:
if settings.LDAP_APPEND_DOMAIN:
if is_valid_email(username):
if not username.endswith("@" + settings.LDAP_APPEND_DOMAIN):
raise ZulipLDAPExceptionOutsideDomain("Email %s does not match LDAP domain %s." % (
username, settings.LDAP_APPEND_DOMAIN))