Repository: zulip/zulip

Issue:
Complete follow-ups to convenient LDAP auth testing system
Continuing from #10181, I think there's some high-value follow-ups to this that we should do:
* Play a bit with the defaults for username/password; I think it's a mistake to have LDAP users like `ldap_iago@zulip.com` with a name "Iago".  Would be much better to have totally new names for these users.
* Once that's done, document this somewhere; I think my best concept for that is to expand https://zulip.readthedocs.io/en/latest/subsystems/oauth.html to talk about LDAP auth as well (and rename it to `auth.html`).





Discussion:
Hello @zulip/server-authentication members, this issue was labeled with the "area: authentication" label, so you may want to check it out!

<!-- areaLabelAddition -->

Resolving patch:
diff --git a/zproject/backends.py b/zproject/backends.py
--- a/zproject/backends.py
+++ b/zproject/backends.py
@@ -107,20 +107,11 @@ def common_get_active_user(email: str, realm: Realm,
         return None
     return user_profile
 
-def generate_dev_ldap_dir(mode: str, extra_users: int=0) -> Dict[str, Dict[str, Sequence[str]]]:
+def generate_dev_ldap_dir(mode: str, num_users: int=8) -> Dict[str, Dict[str, Sequence[str]]]:
     mode = mode.lower()
-    names = [
-        ("Zoe", "ldap_ZOE@zulip.com"),
-        ("Othello, the Moor of Venice", "ldap_othello@zulip.com"),
-        ("Iago", "ldap_iago@zulip.com"),
-        ("Prospero from The Tempest", "ldap_prospero@zulip.com"),
-        ("Cordelia Lear", "ldap_cordelia@zulip.com"),
-        ("King Hamlet", "ldap_hamlet@zulip.com"),
-        ("aaron", "ldap_AARON@zulip.com"),
-        ("Polonius", "ldap_polonius@zulip.com"),
-    ]
-    for i in range(extra_users):
-        names.append(('Extra User %d' % (i,), 'ldap_extrauser%d@zulip.com' % (i,)))
+    names = []
+    for i in range(1, num_users+1):
+        names.append(('LDAP User %d' % (i,), 'ldapuser%d@zulip.com' % (i,)))
 
     ldap_dir = {}
     if mode == 'a':
@@ -336,7 +327,7 @@ def __init__(self) -> None:
             self.mock_initialize.return_value = self.mock_ldap
 
             self.mock_ldap.directory = generate_dev_ldap_dir(settings.FAKE_LDAP_MODE,
-                                                             settings.FAKE_LDAP_EXTRA_USERS)
+                                                             settings.FAKE_LDAP_NUM_USERS)
 
     def authenticate(self, username: str, password: str, realm: Optional[Realm]=None,
                      return_data: Optional[Dict[str, Any]]=None) -> Optional[UserProfile]:
diff --git a/zproject/dev_settings.py b/zproject/dev_settings.py
--- a/zproject/dev_settings.py
+++ b/zproject/dev_settings.py
@@ -103,7 +103,7 @@
 # In any case, the LDAP user account data is available in:
 #    zerver/tests/fixtures/ldap_dir.json
 FAKE_LDAP_MODE = None  # type: Optional[str]
-FAKE_LDAP_EXTRA_USERS = 0
+# FAKE_LDAP_NUM_USERS = 8
 
 if FAKE_LDAP_MODE:
     LDAP_APPEND_DOMAIN = None
diff --git a/zproject/settings.py b/zproject/settings.py
--- a/zproject/settings.py
+++ b/zproject/settings.py
@@ -144,7 +144,7 @@ def get_secret(key: str, default_value: Optional[Any]=None,
     # support local development of LDAP auth without an LDAP server.
     # Detailed docs in zproject/dev_settings.py.
     'FAKE_LDAP_MODE': None,
-    'FAKE_LDAP_EXTRA_USERS': 0,
+    'FAKE_LDAP_NUM_USERS': 8,
 
     # Social auth; we support providing values for some of these
     # settings in zulip-secrets.conf instead of settings.py in development.


Test patch:
diff --git a/zerver/tests/test_auth_backends.py b/zerver/tests/test_auth_backends.py
--- a/zerver/tests/test_auth_backends.py
+++ b/zerver/tests/test_auth_backends.py
@@ -2110,21 +2110,21 @@ def setup_subdomain(self, user_profile: UserProfile) -> None:
         realm.save()
 
     def test_generate_dev_ldap_dir(self) -> None:
-        ldap_dir = generate_dev_ldap_dir('A', 2)
+        ldap_dir = generate_dev_ldap_dir('A', 10)
         self.assertEqual(len(ldap_dir), 10)
         regex = re.compile(r'(uid\=)+[a-zA-Z0-9_.+-]+@[a-zA-Z0-9-]+\.[a-zA-Z0-9-.]+(\,ou\=users\,dc\=zulip\,dc\=com)')
         for key, value in ldap_dir.items():
             self.assertTrue(regex.match(key))
             self.assertCountEqual(list(value.keys()), ['cn', 'userPassword'])
 
-        ldap_dir = generate_dev_ldap_dir('b', 1)
+        ldap_dir = generate_dev_ldap_dir('b', 9)
         self.assertEqual(len(ldap_dir), 9)
         regex = re.compile(r'(uid\=)+[a-zA-Z0-9_.+-]+(\,ou\=users\,dc\=zulip\,dc\=com)')
         for key, value in ldap_dir.items():
             self.assertTrue(regex.match(key))
             self.assertCountEqual(list(value.keys()), ['cn', 'userPassword'])
 
-        ldap_dir = generate_dev_ldap_dir('c', 0)
+        ldap_dir = generate_dev_ldap_dir('c', 8)
         self.assertEqual(len(ldap_dir), 8)
         regex = re.compile(r'(uid\=)+[a-zA-Z0-9_.+-]+(\,ou\=users\,dc\=zulip\,dc\=com)')
         for key, value in ldap_dir.items():