diff --git a/zerver/tests/test_auth_backends.py b/zerver/tests/test_auth_backends.py index 2dbf16dcd2..4e08811155 100644 --- a/zerver/tests/test_auth_backends.py +++ b/zerver/tests/test_auth_backends.py @@ -124,6 +124,14 @@ class AuthBackendTest(ZulipTestCase): index = getattr(user_profile.realm.authentication_methods, backend_name).number user_profile.realm.authentication_methods.set_bit(index, False) user_profile.realm.save() + if 'realm' in good_kwargs: + # Because this test is a little unfaithful to the ordering + # (i.e. we fetched the realm object before this function + # was called, when in fact it should be fetched after we + # changed the allowed authentication methods), we need to + # propagate the changes we just made to the actual realm + # object in good_kwargs. + good_kwargs['realm'] = user_profile.realm self.assertIsNone(backend.authenticate(**good_kwargs)) user_profile.realm.authentication_methods.set_bit(index, True) user_profile.realm.save() @@ -282,9 +290,19 @@ class AuthBackendTest(ZulipTestCase): username = self.get_username() self.verify_backend(ZulipRemoteUserBackend(), good_kwargs=dict(remote_user=username, - realm_subdomain='zulip'), + realm=get_realm('zulip')), bad_kwargs=dict(remote_user=username, - realm_subdomain='acme')) + realm=get_realm('zephyr'))) + + @override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipRemoteUserBackend',)) + def test_remote_user_backend_invalid_realm(self): + # type: () -> None + username = self.get_username() + self.verify_backend(ZulipRemoteUserBackend(), + good_kwargs=dict(remote_user=username, + realm=get_realm('zulip')), + bad_kwargs=dict(remote_user=username, + realm=None)) @override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.ZulipRemoteUserBackend',)) @override_settings(SSO_APPEND_DOMAIN='zulip.com') @@ -293,9 +311,9 @@ class AuthBackendTest(ZulipTestCase): username = self.get_username(email_to_username) self.verify_backend(ZulipRemoteUserBackend(), good_kwargs=dict(remote_user=username, - realm_subdomain='zulip'), + realm=get_realm("zulip")), bad_kwargs=dict(remote_user=username, - realm_subdomain='acme')) + realm=get_realm('zephyr'))) @override_settings(AUTHENTICATION_BACKENDS=('zproject.backends.GitHubAuthBackend',)) def test_github_backend(self): diff --git a/zerver/views/auth.py b/zerver/views/auth.py index 8b64ede456..d3fe4a1710 100644 --- a/zerver/views/auth.py +++ b/zerver/views/auth.py @@ -187,7 +187,11 @@ def remote_user_sso(request): # enabled. validate_login_email(remote_user_to_email(remote_user)) - user_profile = authenticate(remote_user=remote_user, realm_subdomain=get_subdomain(request)) + subdomain = get_subdomain(request) + realm = get_realm(subdomain) + # Since RemoteUserBackend will return None if Realm is None, we + # don't need to check whether `get_realm` returned None. + user_profile = authenticate(remote_user=remote_user, realm=realm) return login_or_register_remote_user(request, remote_user, user_profile) @csrf_exempt diff --git a/zproject/backends.py b/zproject/backends.py index 7223af5dcf..e5885df323 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -411,15 +411,17 @@ class ZulipRemoteUserBackend(RemoteUserBackend): create_unknown_user = False def authenticate(self, remote_user: Optional[str], - realm_subdomain: Optional[str]=None) -> Optional[UserProfile]: - if not remote_user: + realm: Optional[Realm]=None) -> Optional[UserProfile]: + if realm is None: + return None + if remote_user is None: return None email = remote_user_to_email(remote_user) user_profile = common_get_active_user_by_email(email) if user_profile is None: return None - if not user_matches_subdomain(realm_subdomain, user_profile): + if not user_matches_subdomain(realm.subdomain, user_profile): return None if not auth_enabled_helper(["RemoteUser"], user_profile.realm): return None