diff --git a/zerver/tests/test_auth_backends.py b/zerver/tests/test_auth_backends.py index 9aa35d5c6b..25e3bf546c 100644 --- a/zerver/tests/test_auth_backends.py +++ b/zerver/tests/test_auth_backends.py @@ -16,7 +16,7 @@ import re from zerver.forms import HomepageForm from zerver.lib.actions import do_deactivate_realm, do_deactivate_user, \ - do_reactivate_realm, do_reactivate_user + do_reactivate_realm, do_reactivate_user, do_set_realm_authentication_methods from zerver.lib.initial_password import initial_password from zerver.lib.sessions import get_session_dict_user from zerver.lib.test_classes import ( @@ -1011,6 +1011,65 @@ class FetchAuthBackends(ZulipTestCase): 'zulip_version': ZULIP_VERSION, }) + # Test subdomains cases + with self.settings(REALMS_HAVE_SUBDOMAINS=True, + SUBDOMAINS_HOMEPAGE=False): + result = self.client_get("/api/v1/get_auth_backends") + self.assert_json_success(result) + data = ujson.loads(result.content) + self.assertEqual(data, { + 'msg': '', + 'password': False, + 'google': True, + 'dev': True, + 'result': 'success', + 'zulip_version': ZULIP_VERSION, + }) + + # Verify invalid subdomain + result = self.client_get("/api/v1/get_auth_backends", + HTTP_HOST="invalid.testserver") + self.assert_json_error_contains(result, "Invalid subdomain", 400) + + # Verify correct behavior with a valid subdomain with + # some backends disabled for the realm + realm = get_realm("zulip") + do_set_realm_authentication_methods(realm, dict(Google=False, + Email=False, + Dev=True)) + result = self.client_get("/api/v1/get_auth_backends", + HTTP_HOST="zulip.testserver") + self.assert_json_success(result) + data = ujson.loads(result.content) + self.assertEqual(data, { + 'msg': '', + 'password': False, + 'google': False, + 'dev': True, + 'result': 'success', + 'zulip_version': ZULIP_VERSION, + }) + with self.settings(REALMS_HAVE_SUBDOMAINS=True, + SUBDOMAINS_HOMEPAGE=True): + # With SUBDOMAINS_HOMEPAGE, homepage fails + result = self.client_get("/api/v1/get_auth_backends", + HTTP_HOST="testserver") + self.assert_json_error_contains(result, "Subdomain required", 400) + + # With SUBDOMAINS_HOMEPAGE, subdomain pages succeed + result = self.client_get("/api/v1/get_auth_backends", + HTTP_HOST="zulip.testserver") + self.assert_json_success(result) + data = ujson.loads(result.content) + self.assertEqual(data, { + 'msg': '', + 'password': False, + 'google': False, + 'dev': True, + 'result': 'success', + 'zulip_version': ZULIP_VERSION, + }) + class TestDevAuthBackend(ZulipTestCase): def test_login_success(self): # type: () -> None diff --git a/zerver/views/auth.py b/zerver/views/auth.py index 9276cc24e9..6384d45503 100644 --- a/zerver/views/auth.py +++ b/zerver/views/auth.py @@ -459,11 +459,30 @@ def api_fetch_api_key(request, username=REQ(), password=REQ()): @csrf_exempt def api_get_auth_backends(request): # type: (HttpRequest) -> HttpResponse - # May return a false positive for password auth if it's been disabled - # for a specific realm. Currently only happens for zulip.com on prod - return json_success({"password": password_auth_enabled(None), - "dev": dev_auth_enabled(), - "google": google_auth_enabled(), + """Returns which authentication methods are enabled on the server""" + if settings.REALMS_HAVE_SUBDOMAINS: + subdomain = get_subdomain(request) + try: + realm = Realm.objects.get(string_id=subdomain) + except Realm.DoesNotExist: + # If not the root subdomain, this is an error + if subdomain != "": + return json_error(_("Invalid subdomain")) + # With the root subdomain, it's an error or not depending + # whether SUBDOMAINS_HOMEPAGE (which indicates whether + # there are some realms without subdomains on this server) + # is set. + if settings.SUBDOMAINS_HOMEPAGE: + return json_error(_("Subdomain required")) + else: + realm = None + else: + # Without subdomains, we just have to report what the server + # supports, since we don't know the realm. + realm = None + return json_success({"password": password_auth_enabled(realm), + "dev": dev_auth_enabled(realm), + "google": google_auth_enabled(realm), "zulip_version": ZULIP_VERSION, })