From 272ed9068590e575e09c5abaeffca48040164873 Mon Sep 17 00:00:00 2001 From: David Wood Date: Mon, 8 Apr 2019 18:23:00 +0100 Subject: [PATCH] settings: Create an explicit invite_to_stream_policy setting. This commit creates a new organization setting that determines whether a user can invite other users to streams. Previously this was linked to the waiting period threshold, but this was both not documented and overly limiting. With significant tweaks by tabbott to change the database model to not involve two threshhold fields, edit the tests, etc. This requires follow-up work to make the create stream policy setting work how this code implies it should. Fixes #12042. --- frontend_tests/casper_tests/10-admin.js | 3 +- frontend_tests/node_tests/dispatch.js | 10 +- frontend_tests/node_tests/settings_org.js | 24 +++- static/js/admin.js | 1 + static/js/server_events_dispatch.js | 7 ++ static/js/settings_org.js | 31 +++++ static/styles/settings.scss | 1 + .../organization-permissions-admin.handlebars | 13 +- .../configure-who-can-invite-to-streams.md | 28 +++++ .../zerver/help/include/sidebar_index.md | 1 + zerver/lib/events.py | 3 + .../0214_realm_invite_to_stream_policy.py | 29 +++++ zerver/models.py | 14 +++ zerver/openapi/zulip-2.0.yaml | 4 + zerver/tests/test_events.py | 1 + zerver/tests/test_home.py | 1 + zerver/tests/test_realm.py | 3 + zerver/tests/test_subs.py | 112 +++++++++++++++--- zerver/views/realm.py | 1 + zerver/views/streams.py | 9 +- 20 files changed, 268 insertions(+), 28 deletions(-) create mode 100644 templates/zerver/help/configure-who-can-invite-to-streams.md create mode 100644 zerver/migrations/0214_realm_invite_to_stream_policy.py diff --git a/frontend_tests/casper_tests/10-admin.js b/frontend_tests/casper_tests/10-admin.js index 3202b31783..be5a376206 100644 --- a/frontend_tests/casper_tests/10-admin.js +++ b/frontend_tests/casper_tests/10-admin.js @@ -123,14 +123,13 @@ casper.then(function () { }); casper.waitUntilVisible('#id_realm_create_stream_permission', function () { - // Test Setting was saved + // Test setting was saved casper.test.assertEval(function () { return $('input[type="text"][id="id_realm_waiting_period_threshold"]').val() === '6'; }, 'Waiting period threshold set to 6 days'); // Deactivate setting - casper.evaluate(function () { $("#id_realm_create_stream_permission").val("by_admins_only").change(); }); diff --git a/frontend_tests/node_tests/dispatch.js b/frontend_tests/node_tests/dispatch.js index d9365ce288..aa21cce5b1 100644 --- a/frontend_tests/node_tests/dispatch.js +++ b/frontend_tests/node_tests/dispatch.js @@ -200,11 +200,11 @@ var event_fixtures = { value: false, }, - realm__update__invite_by_admins_only: { + realm__update__invite_to_stream_policy: { type: 'realm', op: 'update', - property: 'invite_by_admins_only', - value: false, + property: 'invite_to_stream_policy', + value: 2, }, realm__update__invite_required: { @@ -875,8 +875,8 @@ with_overrides(function (override) { var event = event_fixtures.realm__update__create_stream_by_admins_only; test_realm_boolean(event, 'realm_create_stream_by_admins_only'); - event = event_fixtures.realm__update__invite_by_admins_only; - test_realm_boolean(event, 'realm_invite_by_admins_only'); + event = event_fixtures.realm__update__invite_to_stream_policy; + test_realm_boolean(event, 'realm_invite_to_stream_policy'); event = event_fixtures.realm__update__invite_required; test_realm_boolean(event, 'realm_invite_required'); diff --git a/frontend_tests/node_tests/settings_org.js b/frontend_tests/node_tests/settings_org.js index 2980b8f68d..54c93c65fc 100644 --- a/frontend_tests/node_tests/settings_org.js +++ b/frontend_tests/node_tests/settings_org.js @@ -234,6 +234,12 @@ function test_submit_settings_form(submit_form) { }; $("#id_realm_create_stream_permission").val("by_anyone"); $("#id_realm_add_emoji_by_admins_only").val("by_anyone"); + const invite_to_stream_policy_elem = $("#id_realm_invite_to_stream_policy"); + invite_to_stream_policy_elem.val("1"); + invite_to_stream_policy_elem.attr('id', 'id_realm_invite_to_stream_policy'); + invite_to_stream_policy_elem.data = () => { + return "integer"; + }; const bot_creation_policy_elem = $("#id_realm_bot_creation_policy"); bot_creation_policy_elem.val("1"); bot_creation_policy_elem.attr('id', 'id_realm_bot_creation_policy'); @@ -250,6 +256,7 @@ function test_submit_settings_form(submit_form) { let subsection_elem = $(`#org-${subsection}`); subsection_elem.set_find_results('.setting-widget', [ bot_creation_policy_elem, + invite_to_stream_policy_elem, email_address_visibility_elem, ]); @@ -259,6 +266,7 @@ function test_submit_settings_form(submit_form) { let expected_value = { bot_creation_policy: '1', + invite_to_stream_policy: '1', email_address_visibility: '1', add_emoji_by_admins_only: false, create_stream_by_admins_only: false, @@ -532,6 +540,18 @@ function test_sync_realm_settings() { assert.equal(waiting_period_input_parent.visible(), false); } + { + /* Test invite to stream policy settings sync */ + const property_elem = $('#id_realm_invite_to_stream_policy'); + property_elem.length = 1; + property_elem.attr('id', 'id_realm_invite_to_stream_policy'); + + page_params.realm_invite_to_stream_policy = 3; + + settings_org.sync_realm_settings('invite_to_stream_policy'); + assert.equal($("#id_realm_invite_to_stream_policy").val(), "by_members_with_waiting_period"); + } + { /* Test message content edit limit minutes sync */ const property_elem = $('#id_realm_message_content_edit_limit_minutes'); @@ -743,8 +763,8 @@ run_test('set_up', () => { $("#enable_digest_emails_label").set_parent($.create('')); $("#id_realm_msg_edit_limit_setting").change = noop; $('#id_realm_msg_delete_limit_setting').change = noop; - const parent_elem = $.create('waiting-period-parent-stub'); - $('#id_realm_waiting_period_threshold').set_parent(parent_elem); + const waiting_period_parent_elem = $.create('waiting-period-parent-stub'); + $('#id_realm_waiting_period_threshold').set_parent(waiting_period_parent_elem); $("#allowed_domains_label").set_parent($.create('')); const allow_topic_edit_label_parent = $.create('allow-topic-edit-label-parent'); diff --git a/static/js/admin.js b/static/js/admin.js index 0e9bb59fa9..ee57a512d3 100644 --- a/static/js/admin.js +++ b/static/js/admin.js @@ -32,6 +32,7 @@ exports.build_page = function () { server_inline_url_embed_preview: page_params.server_inline_url_embed_preview, realm_authentication_methods: page_params.realm_authentication_methods, realm_create_stream_by_admins_only: page_params.realm_create_stream_by_admins_only, + realm_invite_to_stream_by_admins_only: page_params.realm_invite_to_stream_by_admins_only, realm_name_changes_disabled: page_params.realm_name_changes_disabled, realm_email_changes_disabled: page_params.realm_email_changes_disabled, realm_add_emoji_by_admins_only: page_params.realm_add_emoji_by_admins_only, diff --git a/static/js/server_events_dispatch.js b/static/js/server_events_dispatch.js index 6ed6729e41..83d7555574 100644 --- a/static/js/server_events_dispatch.js +++ b/static/js/server_events_dispatch.js @@ -92,6 +92,7 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { allow_community_topic_editing: noop, bot_creation_policy: settings_bots.update_bot_permissions_ui, create_stream_by_admins_only: noop, + invite_to_stream_policy: noop, default_language: noop, default_twenty_four_hour_time: noop, description: noop, @@ -131,6 +132,12 @@ exports.dispatch_normal_event = function dispatch_normal_event(event) { page_params.can_create_streams = !page_params.realm_create_stream_by_admins_only; } + } else if (event.property === 'invite_to_stream_policy') { + if (!page_params.is_admin) { + // TODO: Add waiting_period_threshold logic here. + page_params.can_invite_to_stream = + page_params.realm_invite_to_stream_policy === 1; + } } else if (event.property === 'notifications_stream_id') { settings_org.render_notifications_stream_ui( page_params.realm_notifications_stream_id, diff --git a/static/js/settings_org.js b/static/js/settings_org.js index 024035fc26..44e1306626 100644 --- a/static/js/settings_org.js +++ b/static/js/settings_org.js @@ -83,6 +83,18 @@ function get_property_value(property_name) { return "by_admin_user_with_custom_time"; } + if (property_name === 'realm_invite_to_stream_policy') { + if (page_params.realm_invite_to_stream_policy === 1) { + return "by_members"; + } + if (page_params.realm_invite_to_stream_policy === 2) { + return "by_admins_only"; + } + if (page_params.realm_invite_to_stream_policy === 3) { + return "by_members_with_waiting_period"; + } + } + if (property_name === 'realm_add_emoji_by_admins_only') { if (page_params.realm_add_emoji_by_admins_only) { return "by_admins_only"; @@ -153,6 +165,11 @@ function set_create_stream_permission_dropdown() { } } +function set_invite_to_stream_policy_dropdown() { + var value = get_property_value("realm_invite_to_stream_policy"); + $("#id_realm_invite_to_stream_policy").val(value); +} + function set_add_emoji_permission_dropdown() { $("#id_realm_add_emoji_by_admins_only").val(get_property_value("realm_add_emoji_by_admins_only")); } @@ -392,6 +409,8 @@ exports.populate_signup_notifications_stream_dropdown = function (stream_list) { function update_dependent_subsettings(property_name) { if (property_name === 'realm_create_stream_permission' || property_name === 'realm_waiting_period_threshold') { set_create_stream_permission_dropdown(); + } else if (property_name === 'realm_invite_to_stream_policy') { + set_invite_to_stream_policy_dropdown(); } else if (property_name === 'realm_video_chat_provider' || property_name === 'realm_google_hangouts_domain' || property_name.startsWith('realm_zoom')) { @@ -438,6 +457,8 @@ exports.sync_realm_settings = function (property) { property = 'message_content_edit_limit_minutes'; } else if (property === 'create_stream_by_admins_only') { property = 'create_stream_permission'; + } else if (property === 'invite_to_stream_policy') { + property = 'invite_to_stream_policy'; } else if (property === 'allow_message_editing') { property = 'msg_edit_limit_setting'; } else if (property === 'emails_restricted_to_domains' || property === 'disallow_disposable_email_addresses') { @@ -566,6 +587,7 @@ exports.build_page = function () { } set_create_stream_permission_dropdown(); + set_invite_to_stream_policy_dropdown(); set_add_emoji_permission_dropdown(); set_video_chat_provider_dropdown(); set_msg_edit_limit_dropdown(); @@ -692,6 +714,7 @@ exports.build_page = function () { JSON.stringify(parseInt(new_message_retention_days, 10)) : null; } else if (subsection === 'other_permissions') { var create_stream_permission = $("#id_realm_create_stream_permission").val(); + var invite_to_stream_policy = $("#id_realm_invite_to_stream_policy").val(); var add_emoji_permission = $("#id_realm_add_emoji_by_admins_only").val(); if (add_emoji_permission === "by_admins_only") { @@ -712,6 +735,14 @@ exports.build_page = function () { data.create_stream_by_admins_only = false; data.waiting_period_threshold = 0; } + + if (invite_to_stream_policy === "by_admins_only") { + data.invite_to_stream_policy = 2; + } else if (invite_to_stream_policy === "by_members") { + data.invite_to_stream_policy = 1; + } else if (invite_to_stream_policy === "by_members_with_waiting_period") { + data.invite_to_stream_policy = 3; + } } else if (subsection === 'org_join') { var org_join_restrictions = $('#id_realm_org_join_restrictions').val(); if (org_join_restrictions === "only_selected_domain") { diff --git a/static/styles/settings.scss b/static/styles/settings.scss index cfdd14e082..d7861ff658 100644 --- a/static/styles/settings.scss +++ b/static/styles/settings.scss @@ -1546,6 +1546,7 @@ body:not(.night-mode) #account-settings .custom_user_field .datepicker { } #id_realm_create_stream_permission, +#id_realm_invite_to_stream_policy, #id_realm_org_join_restrictions, #id_realm_bot_creation_policy, #id_realm_user_invite_restriction { diff --git a/static/templates/settings/organization-permissions-admin.handlebars b/static/templates/settings/organization-permissions-admin.handlebars index 8661f4c2ae..63d005e4a7 100644 --- a/static/templates/settings/organization-permissions-admin.handlebars +++ b/static/templates/settings/organization-permissions-admin.handlebars @@ -64,8 +64,8 @@
@@ -76,6 +76,15 @@ value="{{ realm_waiting_period_threshold }}"/>
+
+ + +
+