emails: Cover all LDAP cases when emailing login details.

This provides a nice user experience for folks where we do know what
their LDAP credentials are.

Though we need to fix #10917 before the content in the email with be
correct.
This commit is contained in:
Vishnu Ks 2018-11-29 21:02:17 +05:30 committed by Tim Abbott
parent 7a2d93ed6e
commit f3033207b9
4 changed files with 96 additions and 15 deletions

View File

@ -22,10 +22,14 @@
<p>
{{ _('Your account details:') }}
<li>{{ _('Organization URL:') }} {{ realm_uri }}<br/></li>
{% if ldap_username %}
<li>{{ _('Use your LDAP account to login') }}<br/></li>
{% if ldap %}
{% if ldap_username %}
<li>{{ _('Username:') }} {{ ldap_username }}<br/></li>
{% else %}
<li>{{ _('Use your LDAP account to login') }}<br/></li>
{% endif %}
{% else %}
<li>{{ _('Email:') }} {{ email }}<br/></li>
<li>{{ _('Email:') }} {{ email }}<br/></li>
{% endif %}
{% trans %}
(you'll need these to sign in to the <a href="https://zulipchat.com/apps">mobile and desktop</a> apps)

View File

@ -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 %}

View File

@ -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,

View File

@ -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")