mirror of https://github.com/zulip/zulip.git
registration: Populate LDAP users using invitation information.
Fixes: #11212.
This commit is contained in:
parent
3e3d8527b0
commit
fcf2ffe8db
|
@ -2125,10 +2125,11 @@ class ZulipLDAPTestCase(ZulipTestCase):
|
|||
self.mock_ldap = MockLDAP()
|
||||
self.mock_initialize.return_value = self.mock_ldap
|
||||
self.backend = ZulipLDAPAuthBackend()
|
||||
# Internally `_realm` attribute is automatically set by the
|
||||
# `authenticate()` method. But for testing the `get_or_build_user()`
|
||||
# method separately, we need to set it manually.
|
||||
# Internally `_realm` and `_prereg_user` attributes are automatically set
|
||||
# by the `authenticate()` method. But for testing the `get_or_build_user()`
|
||||
# method separately, we need to set them manually.
|
||||
self.backend._realm = get_realm('zulip')
|
||||
self.backend._prereg_user = None
|
||||
|
||||
def tearDown(self) -> None:
|
||||
self.mock_ldap.reset()
|
||||
|
|
|
@ -21,7 +21,7 @@ from confirmation.models import Confirmation, create_confirmation_link, Multiuse
|
|||
from confirmation import settings as confirmation_settings
|
||||
|
||||
from zerver.forms import HomepageForm, WRONG_SUBDOMAIN_ERROR, check_subdomain_available
|
||||
from zerver.lib.actions import do_change_password
|
||||
from zerver.lib.actions import do_change_password, get_default_streams_for_realm
|
||||
from zerver.lib.exceptions import CannotDeactivateLastUserError
|
||||
from zerver.lib.dev_ldap_directory import init_fakeldap
|
||||
from zerver.decorator import do_two_factor_login
|
||||
|
@ -59,6 +59,7 @@ from zerver.lib.mobile_auth_otp import xor_hex_strings, ascii_to_hex, \
|
|||
from zerver.lib.notifications import enqueue_welcome_emails, \
|
||||
followup_day2_email_delay
|
||||
from zerver.lib.subdomains import is_root_domain_available
|
||||
from zerver.lib.stream_subscription import get_stream_subscriptions_for_user
|
||||
from zerver.lib.test_helpers import find_key_by_email, queries_captured, \
|
||||
HostRequestMock, load_subdomain_token
|
||||
from zerver.lib.test_classes import (
|
||||
|
@ -2778,6 +2779,83 @@ class UserSignUpTest(ZulipTestCase):
|
|||
# Name comes from the POST request, not LDAP
|
||||
self.assertEqual(user_profile.full_name, 'Non-LDAP Full Name')
|
||||
|
||||
def ldap_invite_and_signup_as(self, invite_as: int, streams: List[str]=['Denmark']) -> None:
|
||||
ldap_user_attr_map = {'full_name': 'fn'}
|
||||
mock_directory = {
|
||||
'uid=newuser,ou=users,dc=zulip,dc=com': {
|
||||
'userPassword': ['testing'],
|
||||
'fn': ['LDAP Name'],
|
||||
}
|
||||
}
|
||||
init_fakeldap(mock_directory)
|
||||
|
||||
subdomain = 'zulip'
|
||||
email = self.nonreg_email('newuser')
|
||||
password = 'testing'
|
||||
|
||||
# Invite user.
|
||||
self.login(self.example_email('iago'))
|
||||
response = self.client_post("/json/invites",
|
||||
{"invitee_emails": [self.nonreg_email('newuser')],
|
||||
"stream": streams,
|
||||
"invite_as": invite_as})
|
||||
self.assert_json_success(response)
|
||||
self.logout()
|
||||
|
||||
with self.settings(
|
||||
POPULATE_PROFILE_VIA_LDAP=True,
|
||||
LDAP_APPEND_DOMAIN='zulip.com',
|
||||
AUTH_LDAP_BIND_PASSWORD='',
|
||||
AUTH_LDAP_USER_ATTR_MAP=ldap_user_attr_map,
|
||||
AUTH_LDAP_USER_DN_TEMPLATE='uid=%(user)s,ou=users,dc=zulip,dc=com'):
|
||||
|
||||
result = self.submit_reg_form_for_user(email,
|
||||
password,
|
||||
full_name="Ignore",
|
||||
from_confirmation="1",
|
||||
# Pass HTTP_HOST for the target subdomain
|
||||
HTTP_HOST=subdomain + ".testserver")
|
||||
self.assertEqual(result.status_code, 200)
|
||||
|
||||
result = self.submit_reg_form_for_user(email,
|
||||
password,
|
||||
full_name="Ignore",
|
||||
# Pass HTTP_HOST for the target subdomain
|
||||
HTTP_HOST=subdomain + ".testserver")
|
||||
self.assertEqual(result.status_code, 302)
|
||||
|
||||
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
|
||||
'zproject.backends.EmailAuthBackend'))
|
||||
def test_ldap_invite_user_as_admin(self) -> None:
|
||||
self.ldap_invite_and_signup_as(PreregistrationUser.INVITE_AS['REALM_ADMIN'])
|
||||
user_profile = UserProfile.objects.get(email=self.nonreg_email('newuser'))
|
||||
self.assertTrue(user_profile.is_realm_admin)
|
||||
|
||||
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
|
||||
'zproject.backends.EmailAuthBackend'))
|
||||
def test_ldap_invite_user_as_guest(self) -> None:
|
||||
self.ldap_invite_and_signup_as(PreregistrationUser.INVITE_AS['GUEST_USER'])
|
||||
user_profile = UserProfile.objects.get(email=self.nonreg_email('newuser'))
|
||||
self.assertTrue(user_profile.is_guest)
|
||||
|
||||
@override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipLDAPAuthBackend',
|
||||
'zproject.backends.EmailAuthBackend'))
|
||||
def test_ldap_invite_streams(self) -> None:
|
||||
stream_name = 'Rome'
|
||||
realm = get_realm('zulip')
|
||||
stream = get_stream(stream_name, realm)
|
||||
default_streams = get_default_streams_for_realm(realm)
|
||||
default_streams_name = [stream.name for stream in default_streams]
|
||||
self.assertNotIn(stream_name, default_streams_name)
|
||||
|
||||
# Invite user.
|
||||
self.ldap_invite_and_signup_as(PreregistrationUser.INVITE_AS['REALM_ADMIN'], streams=[stream_name])
|
||||
|
||||
user_profile = UserProfile.objects.get(email=self.nonreg_email('newuser'))
|
||||
self.assertTrue(user_profile.is_realm_admin)
|
||||
sub = get_stream_subscriptions_for_user(user_profile).filter(recipient__type_id=stream.id)
|
||||
self.assertEqual(len(sub), 1)
|
||||
|
||||
def test_registration_when_name_changes_are_disabled(self) -> None:
|
||||
"""
|
||||
Test `name_changes_disabled` when we are not running under LDAP.
|
||||
|
|
|
@ -244,6 +244,7 @@ def accounts_register(request: HttpRequest) -> HttpResponse:
|
|||
username=email,
|
||||
password=password,
|
||||
realm=realm,
|
||||
prereg_user=prereg_user,
|
||||
return_data=return_data)
|
||||
if auth_result is not None:
|
||||
# Since we'll have created a user, we now just log them in.
|
||||
|
|
|
@ -24,8 +24,9 @@ from zerver.lib.dev_ldap_directory import init_fakeldap
|
|||
from zerver.lib.request import JsonableError
|
||||
from zerver.lib.subdomains import user_matches_subdomain, get_subdomain
|
||||
from zerver.lib.users import check_full_name
|
||||
from zerver.models import UserProfile, Realm, get_user_profile_by_id, \
|
||||
remote_user_to_email, email_to_username, get_realm, get_user_by_delivery_email
|
||||
from zerver.models import PreregistrationUser, UserProfile, Realm, get_default_stream_groups, \
|
||||
get_user_profile_by_id, remote_user_to_email, email_to_username, get_realm, \
|
||||
get_user_by_delivery_email
|
||||
|
||||
def pad_method_dict(method_dict: Dict[str, bool]) -> Dict[str, bool]:
|
||||
"""Pads an authentication methods dict to contain all auth backends
|
||||
|
@ -364,10 +365,12 @@ class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase):
|
|||
REALM_IS_NONE_ERROR = 1
|
||||
|
||||
def authenticate(self, username: str, password: str, realm: Optional[Realm]=None,
|
||||
prereg_user: Optional[PreregistrationUser]=None,
|
||||
return_data: Optional[Dict[str, Any]]=None) -> Optional[UserProfile]:
|
||||
if realm is None:
|
||||
return None
|
||||
self._realm = realm
|
||||
self._prereg_user = prereg_user
|
||||
if not ldap_auth_enabled(realm):
|
||||
return None
|
||||
|
||||
|
@ -430,7 +433,15 @@ class ZulipLDAPAuthBackend(ZulipLDAPAuthBackendBase):
|
|||
except JsonableError as e:
|
||||
raise ZulipLDAPException(e.msg)
|
||||
|
||||
user_profile = do_create_user(username, None, self._realm, full_name, short_name)
|
||||
opts = {} # type: Dict[str, Any]
|
||||
if self._prereg_user:
|
||||
invited_as = self._prereg_user.invited_as
|
||||
opts['prereg_user'] = self._prereg_user
|
||||
opts['is_realm_admin'] = invited_as == PreregistrationUser.INVITE_AS['REALM_ADMIN']
|
||||
opts['is_guest'] = invited_as == PreregistrationUser.INVITE_AS['GUEST_USER']
|
||||
opts['default_stream_groups'] = get_default_stream_groups(self._realm)
|
||||
|
||||
user_profile = do_create_user(username, None, self._realm, full_name, short_name, **opts)
|
||||
self.sync_avatar_from_ldap(user_profile, ldap_user)
|
||||
|
||||
return user_profile, True
|
||||
|
|
Loading…
Reference in New Issue