diff --git a/web/src/server_events_dispatch.js b/web/src/server_events_dispatch.js index 06851b7c49..9123501e5f 100644 --- a/web/src/server_events_dispatch.js +++ b/web/src/server_events_dispatch.js @@ -50,6 +50,7 @@ import * as scheduled_messages_ui from "./scheduled_messages_ui"; import * as scroll_bar from "./scroll_bar"; import * as settings_account from "./settings_account"; import * as settings_bots from "./settings_bots"; +import * as settings_components from "./settings_components"; import * as settings_config from "./settings_config"; import * as settings_emoji from "./settings_emoji"; import * as settings_exports from "./settings_exports"; @@ -290,20 +291,7 @@ export function dispatch_normal_event(event) { switch (event.property) { case "default": for (const [key, value] of Object.entries(event.data)) { - if (key === "authentication_methods") { - for (const [auth_method, enabled] of Object.entries( - event.data.authentication_methods, - )) { - realm.realm_authentication_methods[auth_method].enabled = - enabled; - } - settings_org.populate_auth_methods( - event.data.authentication_methods, - ); - } else { - realm["realm_" + key] = value; - } - + realm["realm_" + key] = value; if (Object.hasOwn(realm_settings, key)) { settings_org.sync_realm_settings(key); } @@ -318,6 +306,11 @@ export function dispatch_normal_event(event) { message_live_update.rerender_messages_view(); } } + if (event.data.authentication_methods !== undefined) { + settings_org.populate_auth_methods( + settings_components.realm_authentication_methods_to_boolean_dict(), + ); + } break; case "icon": realm.realm_icon_url = event.data.icon_url; diff --git a/web/tests/lib/events.js b/web/tests/lib/events.js index 5369a32a58..bd6cde656f 100644 --- a/web/tests/lib/events.js +++ b/web/tests/lib/events.js @@ -389,7 +389,7 @@ exports.fixtures = { edit_topic_policy: 4, create_multiuse_invite_group: 3, authentication_methods: { - Google: true, + Google: {enabled: true, available: true}, }, }, }, diff --git a/zerver/actions/realm_settings.py b/zerver/actions/realm_settings.py index cceeaa1675..9e0df319a5 100644 --- a/zerver/actions/realm_settings.py +++ b/zerver/actions/realm_settings.py @@ -326,11 +326,16 @@ def do_set_realm_authentication_methods( }, ) + event_data = dict( + authentication_methods=get_realm_authentication_methods_for_page_params_api( + realm, updated_value + ) + ) event = dict( type="realm", op="update_dict", property="default", - data=dict(authentication_methods=updated_value), + data=event_data, ) send_event(realm, event, active_user_ids(realm.id)) diff --git a/zerver/lib/event_schema.py b/zerver/lib/event_schema.py index 3021d832ee..b2b5cbd458 100644 --- a/zerver/lib/event_schema.py +++ b/zerver/lib/event_schema.py @@ -965,13 +965,23 @@ def check_realm_default_update( assert isinstance(event["value"], prop_type) +authentication_method_dict = DictType( + required_keys=[ + ("enabled", bool), + ("available", bool), + ], + optional_keys=[ + ("unavailable_reason", str), + ], +) + authentication_dict = DictType( required_keys=[ - ("Google", bool), - ("Dev", bool), - ("LDAP", bool), - ("GitHub", bool), - ("Email", bool), + ("Google", authentication_method_dict), + ("Dev", authentication_method_dict), + ("LDAP", authentication_method_dict), + ("GitHub", authentication_method_dict), + ("Email", authentication_method_dict), ] ) diff --git a/zerver/lib/events.py b/zerver/lib/events.py index 4682a5bcf8..efc1dbe386 100644 --- a/zerver/lib/events.py +++ b/zerver/lib/events.py @@ -1198,19 +1198,15 @@ def apply_event( ) elif event["op"] == "update_dict": for key, value in event["data"].items(): + state["realm_" + key] = value + # It's a bit messy, but this is where we need to + # update the state for whether password authentication + # is enabled on this server. if key == "authentication_methods": - state_realm_authentication_methods = state["realm_authentication_methods"] - for auth_method, enabled in value.items(): - state_realm_authentication_methods[auth_method]["enabled"] = enabled - - # It's a bit messy, but this is where we need to - # update the state for whether password authentication - # is enabled on this server. - state["realm_password_auth_enabled"] = value["Email"] or value["LDAP"] - state["realm_email_auth_enabled"] = value["Email"] - - else: - state["realm_" + key] = value + state["realm_password_auth_enabled"] = ( + value["Email"]["enabled"] or value["LDAP"]["enabled"] + ) + state["realm_email_auth_enabled"] = value["Email"]["enabled"] elif event["op"] == "deactivated": # The realm has just been deactivated. If our request had # arrived a moment later, we'd have rendered the diff --git a/zerver/openapi/zulip.yaml b/zerver/openapi/zulip.yaml index 0db4580b6e..5d6b563477 100644 --- a/zerver/openapi/zulip.yaml +++ b/zerver/openapi/zulip.yaml @@ -4172,13 +4172,11 @@ paths: authentication_methods: type: object additionalProperties: - description: | - Boolean describing whether the authentication method (i.e. its key) - is enabled in this organization. - type: boolean + $ref: "#/components/schemas/RealmAuthenticationMethod" description: | - Dictionary of authentication method keys with boolean values that - describe whether the named authentication method is enabled for the + Dictionary of authentication method keys mapped to dictionaries that + describe the properties of the named authentication method for the + organization - its enabled status and availability for use by the organization. Clients should use this to implement server-settings UI to change which @@ -14529,29 +14527,7 @@ paths: realm_authentication_methods: type: object additionalProperties: - type: object - properties: - enabled: - type: boolean - description: | - Boolean describing whether the authentication method (i.e. its key) - is enabled in this organization. - available: - type: boolean - description: | - Boolean describing whether the authentication method is available for use. - If false, the organization is not eligible to enable the authentication - method. - unavailable_reason: - type: string - description: | - Reason why the authentication method is unavailable. This field is optional - and is only present when 'available' is false. - additionalProperties: false - description: | - Dictionary describing the properties of the named authentication method for the - organization - its enabled status and availability for use by the - organization. + $ref: "#/components/schemas/RealmAuthenticationMethod" description: | Present if `realm` is present in `fetch_event_types`. @@ -18992,6 +18968,30 @@ components: only when some specific event occurs. **Changes**: New in Zulip 8.0 (feature level 230). + RealmAuthenticationMethod: + type: object + properties: + enabled: + type: boolean + description: | + Boolean describing whether the authentication method (i.e. its key) + is enabled in this organization. + available: + type: boolean + description: | + Boolean describing whether the authentication method is available for use. + If false, the organization is not eligible to enable the authentication + method. + unavailable_reason: + type: string + description: | + Reason why the authentication method is unavailable. This field is optional + and is only present when 'available' is false. + additionalProperties: false + description: | + Dictionary describing the properties of an authentication method for the + organization - its enabled status and availability for use by the + organization. RealmEmoji: type: object additionalProperties: false