mirror of https://github.com/zulip/zulip.git
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:
parent
7a2d93ed6e
commit
f3033207b9
|
@ -22,10 +22,14 @@
|
||||||
<p>
|
<p>
|
||||||
{{ _('Your account details:') }}
|
{{ _('Your account details:') }}
|
||||||
<li>{{ _('Organization URL:') }} {{ realm_uri }}<br/></li>
|
<li>{{ _('Organization URL:') }} {{ realm_uri }}<br/></li>
|
||||||
{% if ldap_username %}
|
{% if ldap %}
|
||||||
<li>{{ _('Use your LDAP account to login') }}<br/></li>
|
{% if ldap_username %}
|
||||||
|
<li>{{ _('Username:') }} {{ ldap_username }}<br/></li>
|
||||||
|
{% else %}
|
||||||
|
<li>{{ _('Use your LDAP account to login') }}<br/></li>
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
<li>{{ _('Email:') }} {{ email }}<br/></li>
|
<li>{{ _('Email:') }} {{ email }}<br/></li>
|
||||||
{% endif %}
|
{% endif %}
|
||||||
{% trans %}
|
{% trans %}
|
||||||
(you'll need these to sign in to the <a href="https://zulipchat.com/apps">mobile and desktop</a> apps)
|
(you'll need these to sign in to the <a href="https://zulipchat.com/apps">mobile and desktop</a> apps)
|
||||||
|
|
|
@ -12,8 +12,12 @@ You've joined the Zulip organization {{ realm_name }}.
|
||||||
|
|
||||||
{{ _('Your account details:') }}
|
{{ _('Your account details:') }}
|
||||||
* {{ _('Organization URL:') }} {{ realm_uri }}
|
* {{ _('Organization URL:') }} {{ realm_uri }}
|
||||||
|
{% if ldap %}
|
||||||
{% if ldap_username %}
|
{% if ldap_username %}
|
||||||
* {{ _('LDAP username:') }} {{ ldap_username }}
|
* {{ _('Username:') }} {{ ldap_username }}
|
||||||
|
{% else %}
|
||||||
|
* {{ _('Use your LDAP account to login') }}
|
||||||
|
{% endif %}
|
||||||
{% else %}
|
{% else %}
|
||||||
* {{ _('Email:') }} {{ email }}
|
* {{ _('Email:') }} {{ email }}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
|
|
|
@ -523,8 +523,15 @@ def enqueue_welcome_emails(user: UserProfile, realm_creation: bool=False) -> Non
|
||||||
context['getting_started_link'] = "https://zulipchat.com"
|
context['getting_started_link'] = "https://zulipchat.com"
|
||||||
|
|
||||||
from zproject.backends import email_belongs_to_ldap, require_email_format_usernames
|
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(
|
send_future_email(
|
||||||
"zerver/emails/followup_day1", user.realm, to_user_id=user.id, from_name=from_name,
|
"zerver/emails/followup_day1", user.realm, to_user_id=user.id, from_name=from_name,
|
||||||
|
|
|
@ -3,11 +3,13 @@ import os
|
||||||
import random
|
import random
|
||||||
import re
|
import re
|
||||||
import ujson
|
import ujson
|
||||||
|
import ldap
|
||||||
|
|
||||||
from django.conf import settings
|
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.config import LDAPSearch
|
||||||
from email.utils import formataddr
|
from email.utils import formataddr
|
||||||
from mock import patch, MagicMock
|
from mock import patch, MagicMock
|
||||||
from typing import Any, Dict, List, Optional
|
from typing import Any, Dict, List, Optional
|
||||||
|
@ -52,12 +54,43 @@ class TestFollowupEmails(ZulipTestCase):
|
||||||
"http://zulip.testserver/help/getting-your-organization-started-with-zulip")
|
"http://zulip.testserver/help/getting-your-organization-started-with-zulip")
|
||||||
self.assertNotIn("ldap_username", email_data["context"])
|
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',
|
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
|
||||||
'zproject.backends.ZulipDummyBackend'))
|
'zproject.backends.ZulipDummyBackend'))
|
||||||
def test_day1_email_ldap_login_credentials(self) -> None:
|
def test_day1_email_ldap_case_a_login_credentials(self) -> None:
|
||||||
password = "testing"
|
ldap_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
|
||||||
email = "newuser@zulip.com"
|
|
||||||
|
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_user_attr_map = {'full_name': 'fn', 'short_name': 'sn'}
|
||||||
|
|
||||||
ldap_patcher = patch('django_auth_ldap.config.ldap.initialize')
|
ldap_patcher = patch('django_auth_ldap.config.ldap.initialize')
|
||||||
|
@ -65,11 +98,10 @@ class TestFollowupEmails(ZulipTestCase):
|
||||||
mock_ldap = MockLDAP()
|
mock_ldap = MockLDAP()
|
||||||
mock_initialize.return_value = mock_ldap
|
mock_initialize.return_value = mock_ldap
|
||||||
|
|
||||||
full_name = 'New LDAP fullname'
|
|
||||||
mock_ldap.directory = {
|
mock_ldap.directory = {
|
||||||
'uid=newuser,ou=users,dc=zulip,dc=com': {
|
'uid=newuser,ou=users,dc=zulip,dc=com': {
|
||||||
'userPassword': 'testing',
|
'userPassword': 'testing',
|
||||||
'fn': [full_name],
|
'fn': ['full_name'],
|
||||||
'sn': ['shortname'],
|
'sn': ['shortname'],
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -78,14 +110,48 @@ class TestFollowupEmails(ZulipTestCase):
|
||||||
LDAP_APPEND_DOMAIN='zulip.com',
|
LDAP_APPEND_DOMAIN='zulip.com',
|
||||||
AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map,
|
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_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)
|
scheduled_emails = ScheduledEmail.objects.filter(user=user)
|
||||||
|
|
||||||
self.assertEqual(len(scheduled_emails), 2)
|
self.assertEqual(len(scheduled_emails), 2)
|
||||||
email_data = ujson.loads(scheduled_emails[0].data)
|
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:
|
def test_followup_emails_count(self) -> None:
|
||||||
hamlet = self.example_user("hamlet")
|
hamlet = self.example_user("hamlet")
|
||||||
|
|
Loading…
Reference in New Issue