diff --git a/templates/zerver/emails/followup_day1.source.html b/templates/zerver/emails/followup_day1.source.html
index e630dd49b2..ee989babd9 100644
--- a/templates/zerver/emails/followup_day1.source.html
+++ b/templates/zerver/emails/followup_day1.source.html
@@ -22,10 +22,14 @@
{{ _('Your account details:') }}
{{ _('Organization URL:') }} {{ realm_uri }}
- {% if ldap_username %}
- {{ _('Use your LDAP account to login') }}
+ {% if ldap %}
+ {% if ldap_username %}
+ {{ _('Username:') }} {{ ldap_username }}
+ {% else %}
+ {{ _('Use your LDAP account to login') }}
+ {% endif %}
{% else %}
- {{ _('Email:') }} {{ email }}
+ {{ _('Email:') }} {{ email }}
{% endif %}
{% trans %}
(you'll need these to sign in to the mobile and desktop apps)
diff --git a/templates/zerver/emails/followup_day1.txt b/templates/zerver/emails/followup_day1.txt
index a0b3109682..3394e5c3fb 100644
--- a/templates/zerver/emails/followup_day1.txt
+++ b/templates/zerver/emails/followup_day1.txt
@@ -12,8 +12,12 @@ You've joined the Zulip organization {{ realm_name }}.
{{ _('Your account details:') }}
* {{ _('Organization URL:') }} {{ realm_uri }}
+{% if ldap %}
{% if ldap_username %}
-* {{ _('LDAP username:') }} {{ ldap_username }}
+* {{ _('Username:') }} {{ ldap_username }}
+{% else %}
+* {{ _('Use your LDAP account to login') }}
+{% endif %}
{% else %}
* {{ _('Email:') }} {{ email }}
{% endif %}
diff --git a/zerver/lib/notifications.py b/zerver/lib/notifications.py
index 7baf19e025..178635cfbf 100644
--- a/zerver/lib/notifications.py
+++ b/zerver/lib/notifications.py
@@ -523,8 +523,15 @@ def enqueue_welcome_emails(user: UserProfile, realm_creation: bool=False) -> Non
context['getting_started_link'] = "https://zulipchat.com"
from zproject.backends import email_belongs_to_ldap, require_email_format_usernames
- if email_belongs_to_ldap(user.realm, user.email) and not require_email_format_usernames(user.realm):
- context["ldap_username"] = True
+
+ if email_belongs_to_ldap(user.realm, user.email):
+ context["ldap"] = True
+ if settings.LDAP_APPEND_DOMAIN:
+ for backend in get_backends():
+ if isinstance(backend, LDAPBackend):
+ context["ldap_username"] = backend.django_to_ldap_username(user.email)
+ elif not settings.LDAP_EMAIL_ATTR:
+ context["ldap_username"] = user.email
send_future_email(
"zerver/emails/followup_day1", user.realm, to_user_id=user.id, from_name=from_name,
diff --git a/zerver/tests/test_notifications.py b/zerver/tests/test_notifications.py
index aeb05a1559..d2206f6149 100644
--- a/zerver/tests/test_notifications.py
+++ b/zerver/tests/test_notifications.py
@@ -3,11 +3,13 @@ import os
import random
import re
import ujson
+import ldap
from django.conf import settings
from django.core import mail
from django.http import HttpResponse
from django.test import override_settings
+from django_auth_ldap.config import LDAPSearch
from email.utils import formataddr
from mock import patch, MagicMock
from typing import Any, Dict, List, Optional
@@ -52,12 +54,43 @@ class TestFollowupEmails(ZulipTestCase):
"http://zulip.testserver/help/getting-your-organization-started-with-zulip")
self.assertNotIn("ldap_username", email_data["context"])
+ # See https://zulip.readthedocs.io/en/latest/production/authentication-methods.html#ldap-including-active-directory
+ # for case details.
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
'zproject.backends.ZulipDummyBackend'))
- def test_day1_email_ldap_login_credentials(self) -> None:
- password = "testing"
- email = "newuser@zulip.com"
-
+ def test_day1_email_ldap_case_a_login_credentials(self) -> None:
+ ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
+
+ ldap_patcher = patch('django_auth_ldap.config.ldap.initialize')
+ mock_initialize = ldap_patcher.start()
+ mock_ldap = MockLDAP()
+ mock_initialize.return_value = mock_ldap
+
+ mock_ldap.directory = {
+ "uid=newuser@zulip.com,ou=users,dc=zulip,dc=com": {
+ 'userPassword': 'testing',
+ 'fn': ['full_name'],
+ 'sn': ['shortname'],
+ }
+ }
+
+ ldap_search = LDAPSearch("ou=users,dc=zulip,dc=com", ldap.SCOPE_SUBTREE, "(email=%(user)s)")
+ with self.settings(
+ AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map,
+ AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com',
+ AUTH_LDAP_USER_SEARCH=ldap_search):
+ self.login_with_return("newuser@zulip.com", "testing")
+ user = UserProfile.objects.get(email="newuser@zulip.com")
+ scheduled_emails = ScheduledEmail.objects.filter(user=user)
+
+ self.assertEqual(len(scheduled_emails), 2)
+ email_data = ujson.loads(scheduled_emails[0].data)
+ self.assertEqual(email_data["context"]["ldap"], True)
+ self.assertEqual(email_data["context"]["ldap_username"], "newuser@zulip.com")
+
+ @override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
+ 'zproject.backends.ZulipDummyBackend'))
+ def test_day1_email_ldap_case_b_login_credentials(self) -> None:
ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
ldap_patcher = patch('django_auth_ldap.config.ldap.initialize')
@@ -65,11 +98,10 @@ class TestFollowupEmails(ZulipTestCase):
mock_ldap = MockLDAP()
mock_initialize.return_value = mock_ldap
- full_name = 'New LDAP fullname'
mock_ldap.directory = {
'uid=newuser,ou=users,dc=zulip,dc=com': {
'userPassword': 'testing',
- 'fn': [full_name],
+ 'fn': ['full_name'],
'sn': ['shortname'],
}
}
@@ -78,14 +110,48 @@ class TestFollowupEmails(ZulipTestCase):
LDAP_APPEND_DOMAIN='zulip.com',
AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map,
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
- self.login_with_return(email, password)
- user = UserProfile.objects.get(email=email)
+ self.login_with_return("newuser@zulip.com", "testing")
+
+ user = UserProfile.objects.get(email="newuser@zulip.com")
scheduled_emails = ScheduledEmail.objects.filter(user=user)
self.assertEqual(len(scheduled_emails), 2)
email_data = ujson.loads(scheduled_emails[0].data)
- self.assertEqual(email_data["context"]["ldap_username"], True)
+ self.assertEqual(email_data["context"]["ldap"], True)
+ self.assertEqual(email_data["context"]["ldap_username"], "newuser")
+
+ @override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
+ 'zproject.backends.ZulipDummyBackend'))
+ def test_day1_email_ldap_case_c_login_credentials(self) -> None:
+ ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
+
+ ldap_patcher = patch('django_auth_ldap.config.ldap.initialize')
+ mock_initialize = ldap_patcher.start()
+ mock_ldap = MockLDAP()
+ mock_initialize.return_value = mock_ldap
+
+ mock_ldap.directory = {
+ 'uid=newuser,ou=users,dc=zulip,dc=com': {
+ 'userPassword': 'testing',
+ 'fn': ['full_name'],
+ 'sn': ['shortname'],
+ 'email': ['newuser_email@zulip.com'],
+ }
+ }
+
+ with self.settings(
+ LDAP_EMAIL_ATTR='email',
+ AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map,
+ AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
+ self.login_with_return("newuser", "testing")
+ user = UserProfile.objects.get(email="newuser_email@zulip.com")
+ scheduled_emails = ScheduledEmail.objects.filter(user=user)
+
+ self.assertEqual(len(scheduled_emails), 2)
+ email_data = ujson.loads(scheduled_emails[0].data)
+ self.assertEqual(email_data["context"]["ldap"], True)
+ self.assertNotIn("ldap_username", email_data["context"])
def test_followup_emails_count(self) -> None:
hamlet = self.example_user("hamlet")