diff --git a/zerver/lib/events.py b/zerver/lib/events.py index 2d48597b1b..aa18b09939 100644 --- a/zerver/lib/events.py +++ b/zerver/lib/events.py @@ -253,7 +253,8 @@ def fetch_initial_state_data( # Most state is handled via the property_types framework; # these manual entries are for those realm settings that don't # fit into that framework. - state["realm_authentication_methods"] = realm.authentication_methods_dict() + realm_authentication_methods_dict = realm.authentication_methods_dict() + state["realm_authentication_methods"] = realm_authentication_methods_dict # We pretend these features are disabled because anonymous # users can't access them. In the future, we may want to move @@ -297,8 +298,12 @@ def fetch_initial_state_data( state["realm_digest_emails_enabled"] = ( realm.digest_emails_enabled and settings.SEND_DIGEST_EMAILS ) - state["realm_email_auth_enabled"] = email_auth_enabled(realm) - state["realm_password_auth_enabled"] = password_auth_enabled(realm) + state["realm_email_auth_enabled"] = email_auth_enabled( + realm, realm_authentication_methods_dict + ) + state["realm_password_auth_enabled"] = password_auth_enabled( + realm, realm_authentication_methods_dict + ) state["server_generation"] = settings.SERVER_GENERATION state["realm_is_zephyr_mirror_realm"] = realm.is_zephyr_mirror_realm diff --git a/zerver/tests/test_event_system.py b/zerver/tests/test_event_system.py index d9ada23564..3e285f862b 100644 --- a/zerver/tests/test_event_system.py +++ b/zerver/tests/test_event_system.py @@ -1211,7 +1211,7 @@ class FetchQueriesTest(ZulipTestCase): self.login_user(user) flush_per_request_caches() - with self.assert_database_query_count(41): + with self.assert_database_query_count(38): with mock.patch("zerver.lib.events.always_want") as want_mock: fetch_initial_state_data(user) @@ -1226,7 +1226,7 @@ class FetchQueriesTest(ZulipTestCase): muted_topics=1, muted_users=1, presence=1, - realm=4, + realm=1, realm_bot=1, realm_domains=1, realm_embedded_bots=0, diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py index e2d6cfdbe7..b21fcbde61 100644 --- a/zerver/tests/test_home.py +++ b/zerver/tests/test_home.py @@ -248,7 +248,7 @@ class HomeTest(ZulipTestCase): # Verify succeeds once logged-in flush_per_request_caches() - with self.assert_database_query_count(51): + with self.assert_database_query_count(48): with patch("zerver.lib.cache.cache_set") as cache_mock: result = self._get_home_page(stream="Denmark") self.check_rendered_logged_in_app(result) @@ -439,7 +439,7 @@ class HomeTest(ZulipTestCase): # Verify number of queries for Realm admin isn't much higher than for normal users. self.login("iago") flush_per_request_caches() - with self.assert_database_query_count(48): + with self.assert_database_query_count(45): with patch("zerver.lib.cache.cache_set") as cache_mock: result = self._get_home_page() self.check_rendered_logged_in_app(result) @@ -471,7 +471,7 @@ class HomeTest(ZulipTestCase): # Then for the second page load, measure the number of queries. flush_per_request_caches() - with self.assert_database_query_count(46): + with self.assert_database_query_count(43): result = self._get_home_page() # Do a sanity check that our new streams were in the payload. diff --git a/zproject/backends.py b/zproject/backends.py index ade8e1252d..4b2c4939eb 100644 --- a/zproject/backends.py +++ b/zproject/backends.py @@ -133,9 +133,21 @@ def pad_method_dict(method_dict: Dict[str, bool]) -> Dict[str, bool]: return method_dict -def auth_enabled_helper(backends_to_check: List[str], realm: Optional[Realm]) -> bool: +def auth_enabled_helper( + backends_to_check: List[str], + realm: Optional[Realm], + realm_authentication_methods: Optional[Dict[str, bool]] = None, +) -> bool: + """ + realm_authentication_methods can be passed if already fetched to avoid + a database query. + """ if realm is not None: - enabled_method_dict = realm.authentication_methods_dict() + if realm_authentication_methods is not None: + # Copy the dict to avoid mutating the original if it was passed in as argument. + enabled_method_dict = realm_authentication_methods.copy() + else: + enabled_method_dict = realm.authentication_methods_dict() else: enabled_method_dict = {method: True for method in AUTH_BACKEND_NAME_MAP} @@ -148,40 +160,60 @@ def auth_enabled_helper(backends_to_check: List[str], realm: Optional[Realm]) -> return False -def ldap_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["LDAP"], realm) +def ldap_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["LDAP"], realm, realm_authentication_methods) -def email_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["Email"], realm) +def email_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["Email"], realm, realm_authentication_methods) -def password_auth_enabled(realm: Optional[Realm] = None) -> bool: - return ldap_auth_enabled(realm) or email_auth_enabled(realm) +def password_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return ldap_auth_enabled(realm, realm_authentication_methods) or email_auth_enabled( + realm, realm_authentication_methods + ) -def dev_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["Dev"], realm) +def dev_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["Dev"], realm, realm_authentication_methods) -def google_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["Google"], realm) +def google_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["Google"], realm, realm_authentication_methods) -def github_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["GitHub"], realm) +def github_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["GitHub"], realm, realm_authentication_methods) -def gitlab_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["GitLab"], realm) +def gitlab_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["GitLab"], realm, realm_authentication_methods) -def apple_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["Apple"], realm) +def apple_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["Apple"], realm, realm_authentication_methods) -def saml_auth_enabled(realm: Optional[Realm] = None) -> bool: - return auth_enabled_helper(["SAML"], realm) +def saml_auth_enabled( + realm: Optional[Realm] = None, realm_authentication_methods: Optional[Dict[str, bool]] = None +) -> bool: + return auth_enabled_helper(["SAML"], realm, realm_authentication_methods) def require_email_format_usernames(realm: Optional[Realm] = None) -> bool: