mirror of https://github.com/zulip/zulip.git
admin: Enable admins to toggle supported auth methods via UI.
Add a table to the administration page that will allow realm admins to activate and deactivate the supported authentication methods for that realm.
This commit is contained in:
parent
21c024fc29
commit
f4c621ffe3
|
@ -529,6 +529,52 @@ casper.waitUntilVisible('#admin-realm-default-language-status', function () {
|
|||
casper.test.assertSelectorHasText('#admin-realm-default-language-status', 'Default language changed!');
|
||||
});
|
||||
|
||||
// Test authentication methods setting
|
||||
casper.waitForSelector('input[type="checkbox"]', function () {
|
||||
casper.click(".method_row[data-method='Email'] input[type='checkbox']");
|
||||
casper.click('form.admin-realm-form input.button');
|
||||
});
|
||||
|
||||
// Test setting was activated--default is checked
|
||||
casper.then(function () {
|
||||
// Scroll to bottom so that casper snapshots show the auth methods table
|
||||
this.scrollToBottom();
|
||||
// Test setting was activated
|
||||
casper.waitUntilVisible('#admin-realm-authentication-methods-status', function () {
|
||||
casper.test.assertSelectorHasText('#admin-realm-authentication-methods-status', 'Authentication methods saved!');
|
||||
casper.test.assertEval(function () {
|
||||
return !(document.querySelector(".method_row[data-method='Email'] input[type='checkbox']").checked);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
casper.then(function () {
|
||||
// Leave the page and return
|
||||
casper.click('#settings-dropdown');
|
||||
casper.click('a[href^="#subscriptions"]');
|
||||
casper.click('#settings-dropdown');
|
||||
casper.click('a[href^="#administration"]');
|
||||
|
||||
casper.waitForSelector(".method_row[data-method='Email'] input[type='checkbox']", function () {
|
||||
// Test Setting was saved
|
||||
casper.test.assertEval(function () {
|
||||
return !(document.querySelector(".method_row[data-method='Email'] input[type='checkbox']").checked);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Deactivate setting--default is checked
|
||||
casper.then(function () {
|
||||
casper.click(".method_row[data-method='Email'] input[type='checkbox']");
|
||||
casper.click('form.admin-realm-form input.button');
|
||||
casper.waitUntilVisible('#admin-realm-authentication-methods-status', function () {
|
||||
casper.test.assertSelectorHasText('#admin-realm-authentication-methods-status', 'Authentication methods saved!');
|
||||
casper.test.assertEval(function () {
|
||||
return document.querySelector(".method_row[data-method='Email'] input[type='checkbox']").checked;
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
common.then_log_out();
|
||||
|
||||
casper.run(function () {
|
||||
|
|
|
@ -216,6 +216,26 @@ function render(template_name, args) {
|
|||
assert.equal(count.text(), 99);
|
||||
}());
|
||||
|
||||
(function admin_auth_methods_list() {
|
||||
var args = {
|
||||
method: {
|
||||
"method": "Email",
|
||||
"enabled": false
|
||||
}
|
||||
};
|
||||
|
||||
var html = '';
|
||||
html += '<tbody id="admin_auth_methods_table">';
|
||||
html += render('admin_auth_methods_list', args);
|
||||
html += '</tbody>';
|
||||
|
||||
global.write_test_output('admin_auth_methods_list.handlebars', html);
|
||||
|
||||
var method = $(html).find('tr.method_row:first span.method');
|
||||
assert.equal(method.text(), 'Email');
|
||||
assert.equal(method.is("checked"), false);
|
||||
}());
|
||||
|
||||
(function bookend() {
|
||||
// Do subscribed/unsubscribed cases here.
|
||||
var args = {
|
||||
|
|
|
@ -174,6 +174,20 @@ exports.reset_realm_default_language = function () {
|
|||
$("#id_realm_default_language").val(page_params.realm_default_language);
|
||||
};
|
||||
|
||||
exports.populate_auth_methods = function (auth_methods) {
|
||||
var auth_methods_table = $("#admin_auth_methods_table").expectOne();
|
||||
auth_methods_table.find('tr.method_row').remove();
|
||||
_.each(_.keys(auth_methods).sort(), function (key) {
|
||||
auth_methods_table.append(templates.render('admin_auth_methods_list', {
|
||||
method: {
|
||||
method: key,
|
||||
enabled: auth_methods[key]
|
||||
}
|
||||
}));
|
||||
});
|
||||
loading.destroy_indicator($('#admin_page_auth_methods_loading_indicator'));
|
||||
};
|
||||
|
||||
function _setup_page() {
|
||||
var domains_string = stringify_list_with_conjunction(page_params.domains, "or");
|
||||
var atdomains = page_params.domains.slice();
|
||||
|
@ -189,6 +203,7 @@ function _setup_page() {
|
|||
realm_restricted_to_domain: page_params.realm_restricted_to_domain,
|
||||
realm_invite_required: page_params.realm_invite_required,
|
||||
realm_invite_by_admins_only: page_params.realm_invite_by_admins_only,
|
||||
realm_authentication_methods: page_params.realm_authentication_methods,
|
||||
realm_create_stream_by_admins_only: page_params.realm_create_stream_by_admins_only,
|
||||
realm_allow_message_editing: page_params.realm_allow_message_editing,
|
||||
realm_message_content_edit_limit_minutes: Math.ceil(page_params.realm_message_content_edit_limit_seconds / 60),
|
||||
|
@ -202,6 +217,7 @@ function _setup_page() {
|
|||
$("#admin-realm-restricted-to-domain-status").expectOne().hide();
|
||||
$("#admin-realm-invite-required-status").expectOne().hide();
|
||||
$("#admin-realm-invite-by-admins-only-status").expectOne().hide();
|
||||
$("#admin-realm-authentication-methods-status").expectOne().hide();
|
||||
$("#admin-realm-create-stream-by-admins-only-status").expectOne().hide();
|
||||
$("#admin-realm-message-editing-status").expectOne().hide();
|
||||
$("#admin-realm-default-language-status").expectOne().hide();
|
||||
|
@ -215,6 +231,7 @@ function _setup_page() {
|
|||
loading.make_indicator($('#admin_page_streams_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_deactivated_users_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_emoji_loading_indicator'));
|
||||
loading.make_indicator($('#admin_page_auth_methods_loading_indicator'));
|
||||
|
||||
// Populate users and bots tables
|
||||
channel.get({
|
||||
|
@ -234,6 +251,9 @@ function _setup_page() {
|
|||
error: failed_listing_streams
|
||||
});
|
||||
|
||||
// Populate authentication methods table
|
||||
exports.populate_auth_methods(page_params.realm_authentication_methods);
|
||||
|
||||
// Populate emoji table
|
||||
exports.populate_emoji(page_params.realm_emoji);
|
||||
exports.update_default_streams_table();
|
||||
|
@ -406,14 +426,16 @@ function _setup_page() {
|
|||
var restricted_to_domain_status = $("#admin-realm-restricted-to-domain-status").expectOne();
|
||||
var invite_required_status = $("#admin-realm-invite-required-status").expectOne();
|
||||
var invite_by_admins_only_status = $("#admin-realm-invite-by-admins-only-status").expectOne();
|
||||
var authentication_methods_status = $("#admin-realm-authentication-methods-status").expectOne();
|
||||
var create_stream_by_admins_only_status = $("#admin-realm-create-stream-by-admins-only-status").expectOne();
|
||||
var message_editing_status = $("#admin-realm-message-editing-status").expectOne();
|
||||
var default_language_status = $("#admin-realm-default-language-status").expectOne();
|
||||
|
||||
var auth_methods_table = $('.admin_auth_methods_table');
|
||||
name_status.hide();
|
||||
restricted_to_domain_status.hide();
|
||||
invite_required_status.hide();
|
||||
invite_by_admins_only_status.hide();
|
||||
authentication_methods_status.hide();
|
||||
create_stream_by_admins_only_status.hide();
|
||||
message_editing_status.hide();
|
||||
default_language_status.hide();
|
||||
|
@ -429,7 +451,10 @@ function _setup_page() {
|
|||
var new_allow_message_editing = $("#id_realm_allow_message_editing").prop("checked");
|
||||
var new_message_content_edit_limit_minutes = $("#id_realm_message_content_edit_limit_minutes").val();
|
||||
var new_default_language = $("#id_realm_default_language").val();
|
||||
|
||||
var new_auth_methods = {};
|
||||
_.each($("#admin_auth_methods_table").find('tr.method_row'), function (method_row) {
|
||||
new_auth_methods[$(method_row).data('method')] = $(method_row).find('input').prop('checked');
|
||||
});
|
||||
// If allow_message_editing is unchecked, message_content_edit_limit_minutes
|
||||
// is irrelevant. Hence if allow_message_editing is unchecked, and
|
||||
// message_content_edit_limit_minutes is poorly formed, we set the latter to
|
||||
|
@ -448,6 +473,7 @@ function _setup_page() {
|
|||
restricted_to_domain: JSON.stringify(new_restricted),
|
||||
invite_required: JSON.stringify(new_invite),
|
||||
invite_by_admins_only: JSON.stringify(new_invite_by_admins_only),
|
||||
authentication_methods: JSON.stringify(new_auth_methods),
|
||||
create_stream_by_admins_only: JSON.stringify(new_create_stream_by_admins_only),
|
||||
allow_message_editing: JSON.stringify(new_allow_message_editing),
|
||||
message_content_edit_limit_seconds: JSON.stringify(parseInt(new_message_content_edit_limit_minutes, 10) * 60),
|
||||
|
@ -489,6 +515,11 @@ function _setup_page() {
|
|||
ui.report_success(i18n.t("Any user may now create new streams!"), create_stream_by_admins_only_status);
|
||||
}
|
||||
}
|
||||
if (response_data.authentication_methods !== undefined) {
|
||||
if (response_data.authentication_methods) {
|
||||
ui.report_success(i18n.t("Authentication methods saved!"), authentication_methods_status);
|
||||
}
|
||||
}
|
||||
if (response_data.allow_message_editing !== undefined) {
|
||||
// We expect message_content_edit_limit_seconds was sent in the
|
||||
// response as well
|
||||
|
@ -515,8 +546,13 @@ function _setup_page() {
|
|||
}
|
||||
},
|
||||
error: function (xhr, error) {
|
||||
var reason = $.parseJSON(xhr.responseText).reason;
|
||||
if (reason === "no authentication") {
|
||||
ui.report_error(i18n.t("Failed!"), xhr, authentication_methods_status);
|
||||
} else {
|
||||
ui.report_error(i18n.t("Failed!"), xhr, name_status);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -64,6 +64,9 @@ function dispatch_normal_event(event) {
|
|||
$.each(event.data, function (key, value) {
|
||||
page_params['realm_' + key] = value;
|
||||
});
|
||||
if (event.data.authentication_methods !== undefined) {
|
||||
admin.populate_auth_methods(event.data.authentication_methods);
|
||||
}
|
||||
} else if (event.op === 'update' && event.property === 'default_language') {
|
||||
page_params.realm_default_language = event.value;
|
||||
admin.reset_realm_default_language();
|
||||
|
|
|
@ -50,6 +50,7 @@
|
|||
"Pin stream to top<br /> of left sidebar": "Pin stream to top<br /> of left sidebar",
|
||||
"Password": "Password",
|
||||
"Any user may now invite new users!": "Any user may now invite new users!",
|
||||
"Authentication methods saved!":"Authentication methods saved!",
|
||||
"Receive desktop <br />notifications": "Receive desktop <br />notifications",
|
||||
"Please specify a stream": "Please specify a stream",
|
||||
"Delete Alert Word": "Delete Alert Word",
|
||||
|
|
|
@ -27,6 +27,7 @@
|
|||
<div role="tabpanel" class="tab-pane active" id="organization">
|
||||
{{ partial "organization-settings-admin" }}
|
||||
{{ partial "emoji-settings-admin" }}
|
||||
{{ partial "auth-methods-settings-admin" }}
|
||||
</div>
|
||||
<div role="tabpanel" class="tab-pane" id="users">
|
||||
{{ partial "user-list-admin" }}
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
<div id="organization-settings" class="settings-section">
|
||||
<div class="settings-section-title"><i class="icon-vector-lock settings-section-icon"></i>
|
||||
{{t "Authentication Methods" }}</div>
|
||||
<form class="form-horizontal admin-realm-form">
|
||||
<div class="alert" id="admin-realm-authentication-methods-status"></div>
|
||||
<div class="admin-table-wrapper">
|
||||
<p>{{#tr this}}Configure the authentication methods for the __domain__ organization.{{/tr}}</p>
|
||||
<table class="table table-condensed table-striped">
|
||||
<tbody id="admin_auth_methods_table" class=" admin_auth_methods_table">
|
||||
<th>{{t "Method" }}</th>
|
||||
<th>{{t "Enabled" }}</th>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
<div id="admin_page_auth_methods_loading_indicator"></div>
|
||||
<div class="input-group">
|
||||
<div class="organization-submission">
|
||||
<input type="submit" class="button" value="{{t 'Save changes' }}" />
|
||||
</div>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
|
@ -0,0 +1,11 @@
|
|||
{{#with method}}
|
||||
<tr class="method_row" data-method="{{method}}">
|
||||
<td>
|
||||
<span class="method">{{method}}</span>
|
||||
</td>
|
||||
<td>
|
||||
<input type="checkbox"
|
||||
{{#if enabled}}checked="checked"{{/if}} />
|
||||
</td>
|
||||
</tr>
|
||||
{{/with}}
|
|
@ -437,6 +437,20 @@ def do_set_realm_invite_by_admins_only(realm, invite_by_admins_only):
|
|||
)
|
||||
send_event(event, active_user_ids(realm))
|
||||
|
||||
def do_set_realm_authentication_methods(realm, authentication_methods):
|
||||
# type: (Realm, Dict[str, bool]) -> None
|
||||
for key, value in list(authentication_methods.items()):
|
||||
index = getattr(realm.authentication_methods, key).number
|
||||
realm.authentication_methods.set_bit(index, int(value))
|
||||
realm.save(update_fields=['authentication_methods'])
|
||||
event = dict(
|
||||
type="realm",
|
||||
op="update_dict",
|
||||
property='default',
|
||||
data=dict(authentication_methods=realm.authentication_methods_dict())
|
||||
)
|
||||
send_event(event, active_user_ids(realm))
|
||||
|
||||
def do_set_realm_create_stream_by_admins_only(realm, create_stream_by_admins_only):
|
||||
# type: (Realm, bool) -> None
|
||||
realm.create_stream_by_admins_only = create_stream_by_admins_only
|
||||
|
@ -2842,6 +2856,7 @@ def fetch_initial_state_data(user_profile, event_types, queue_id):
|
|||
state['realm_restricted_to_domain'] = user_profile.realm.restricted_to_domain
|
||||
state['realm_invite_required'] = user_profile.realm.invite_required
|
||||
state['realm_invite_by_admins_only'] = user_profile.realm.invite_by_admins_only
|
||||
state['realm_authentication_methods'] = user_profile.realm.authentication_methods_dict()
|
||||
state['realm_create_stream_by_admins_only'] = user_profile.realm.create_stream_by_admins_only
|
||||
state['realm_allow_message_editing'] = user_profile.realm.allow_message_editing
|
||||
state['realm_message_content_edit_limit_seconds'] = user_profile.realm.message_content_edit_limit_seconds
|
||||
|
|
|
@ -29,7 +29,7 @@ from confirmation.models import Confirmation
|
|||
from zproject.backends import ZulipDummyBackend, EmailAuthBackend, \
|
||||
GoogleMobileOauth2Backend, ZulipRemoteUserBackend, ZulipLDAPAuthBackend, \
|
||||
ZulipLDAPUserPopulator, DevAuthBackend, GitHubAuthBackend, ZulipAuthMixin, \
|
||||
password_auth_enabled, github_auth_enabled, AUTH_BACKEND_NAME_MAP
|
||||
dev_auth_enabled, password_auth_enabled, github_auth_enabled, AUTH_BACKEND_NAME_MAP
|
||||
|
||||
from zerver.views.auth import maybe_send_to_registration
|
||||
|
||||
|
@ -1444,3 +1444,41 @@ class TestMaybeSendToRegistration(ZulipTestCase):
|
|||
confirmation_key = confirmation.confirmation_key
|
||||
self.assertIn('do_confirm/' + confirmation_key, result.url)
|
||||
self.assertEqual(PreregistrationUser.objects.all().count(), 1)
|
||||
|
||||
class TestAdminSetBackends(ZulipTestCase):
|
||||
|
||||
def test_change_enabled_backends(self):
|
||||
# type: () -> None
|
||||
# Log in as admin
|
||||
self.login("iago@zulip.com")
|
||||
result = self.client_patch("/json/realm", {
|
||||
'authentication_methods': ujson.dumps({u'Email': False, u'Dev': True})})
|
||||
self.assert_json_success(result)
|
||||
realm = get_realm('zulip.com')
|
||||
self.assertFalse(password_auth_enabled(realm))
|
||||
self.assertTrue(dev_auth_enabled())
|
||||
|
||||
def test_disable_all_backends(self):
|
||||
# type: () -> None
|
||||
# Log in as admin
|
||||
self.login("iago@zulip.com")
|
||||
result = self.client_patch("/json/realm", {
|
||||
'authentication_methods' : ujson.dumps({u'Email': False, u'Dev': False})})
|
||||
self.assert_json_error(result, 'At least one authentication method must be enabled.', status_code=403)
|
||||
realm = get_realm('zulip.com')
|
||||
self.assertTrue(password_auth_enabled(realm))
|
||||
self.assertTrue(dev_auth_enabled())
|
||||
|
||||
def test_supported_backends_only_updated(self):
|
||||
# type: () -> None
|
||||
# Log in as admin
|
||||
self.login("iago@zulip.com")
|
||||
# Set some supported and unsupported backends
|
||||
result = self.client_patch("/json/realm", {
|
||||
'authentication_methods' : ujson.dumps({u'Email': False, u'Dev': True, u'GitHub': False})})
|
||||
self.assert_json_success(result)
|
||||
realm = get_realm('zulip.com')
|
||||
# Check that unsupported backend is not enabled
|
||||
self.assertFalse(github_auth_enabled(realm))
|
||||
self.assertTrue(dev_auth_enabled())
|
||||
self.assertFalse(password_auth_enabled(realm))
|
||||
|
|
|
@ -41,6 +41,7 @@ from zerver.lib.actions import (
|
|||
do_set_realm_invite_by_admins_only,
|
||||
do_set_realm_message_editing,
|
||||
do_set_realm_default_language,
|
||||
do_set_realm_authentication_methods,
|
||||
do_update_message,
|
||||
do_update_pointer,
|
||||
do_change_twenty_four_hour_time,
|
||||
|
@ -466,6 +467,28 @@ class EventsRegisterTest(ZulipTestCase):
|
|||
error = schema_checker('events[0]', events[0])
|
||||
self.assert_on_error(error)
|
||||
|
||||
def test_change_realm_authentication_methods(self):
|
||||
# type: () -> None
|
||||
schema_checker = check_dict([
|
||||
('type', equals('realm')),
|
||||
('op', equals('update_dict')),
|
||||
('property', equals('default')),
|
||||
('data', check_dict([])),
|
||||
])
|
||||
# Test transitions; any new backends should be tested with T/T/T/F/T
|
||||
for (auth_method_dict) in \
|
||||
({'Google': True, 'Email': True, 'GitHub': True, 'LDAP': False, 'Dev': False},
|
||||
{'Google': True, 'Email': True, 'GitHub': False, 'LDAP': False, 'Dev': False},
|
||||
{'Google': True, 'Email': False, 'GitHub': False, 'LDAP': False, 'Dev': False},
|
||||
{'Google': True, 'Email': False, 'GitHub': True, 'LDAP': False, 'Dev': False },
|
||||
{'Google': False, 'Email': False, 'GitHub': False, 'LDAP': False, 'Dev': True},
|
||||
{'Google': False, 'Email': False, 'GitHub': True, 'LDAP': False, 'Dev': True},
|
||||
{'Google': False, 'Email': True, 'GitHub': True, 'LDAP': True, 'Dev': False}):
|
||||
events = self.do_test(lambda: do_set_realm_authentication_methods(self.user_profile.realm,
|
||||
auth_method_dict))
|
||||
error = schema_checker('events[0]', events[0])
|
||||
self.assert_on_error(error)
|
||||
|
||||
def test_change_realm_invite_by_admins_only(self):
|
||||
# type: () -> None
|
||||
schema_checker = check_dict([
|
||||
|
|
|
@ -1825,6 +1825,7 @@ class HomeTest(ZulipTestCase):
|
|||
"product_name",
|
||||
"prompt_for_invites",
|
||||
"realm_allow_message_editing",
|
||||
"realm_authentication_methods",
|
||||
"realm_create_stream_by_admins_only",
|
||||
"realm_default_language",
|
||||
"realm_default_streams",
|
||||
|
|
|
@ -581,6 +581,7 @@ def home(request):
|
|||
realm_name = register_ret['realm_name'],
|
||||
realm_invite_required = register_ret['realm_invite_required'],
|
||||
realm_invite_by_admins_only = register_ret['realm_invite_by_admins_only'],
|
||||
realm_authentication_methods = register_ret['realm_authentication_methods'],
|
||||
realm_create_stream_by_admins_only = register_ret['realm_create_stream_by_admins_only'],
|
||||
realm_allow_message_editing = register_ret['realm_allow_message_editing'],
|
||||
realm_message_content_edit_limit_seconds = register_ret['realm_message_content_edit_limit_seconds'],
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
from __future__ import absolute_import
|
||||
|
||||
from typing import Any, Optional
|
||||
|
||||
from django.http import HttpRequest, HttpResponse
|
||||
from django.utils.translation import ugettext as _
|
||||
|
||||
|
@ -14,11 +13,12 @@ from zerver.lib.actions import (
|
|||
do_set_realm_message_editing,
|
||||
do_set_realm_restricted_to_domain,
|
||||
do_set_realm_default_language,
|
||||
do_set_realm_authentication_methods
|
||||
)
|
||||
from zerver.lib.i18n import get_available_language_codes
|
||||
from zerver.lib.request import has_request_variables, REQ, JsonableError
|
||||
from zerver.lib.response import json_success, json_error
|
||||
from zerver.lib.validator import check_string, check_list, check_bool
|
||||
from zerver.lib.validator import check_string, check_dict, check_bool
|
||||
from zerver.models import UserProfile
|
||||
|
||||
@require_realm_admin
|
||||
|
@ -30,12 +30,12 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
|
|||
create_stream_by_admins_only=REQ(validator=check_bool, default=None),
|
||||
allow_message_editing=REQ(validator=check_bool, default=None),
|
||||
message_content_edit_limit_seconds=REQ(converter=to_non_negative_int, default=None),
|
||||
default_language=REQ(validator=check_string, default=None)):
|
||||
# type: (HttpRequest, UserProfile, Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str]) -> HttpResponse
|
||||
default_language=REQ(validator=check_string, default=None),
|
||||
authentication_methods=REQ(validator=check_dict([]), default=None)):
|
||||
# type: (HttpRequest, UserProfile, Optional[str], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[bool], Optional[int], Optional[str], Optional[dict]) -> HttpResponse
|
||||
# Validation for default_language
|
||||
if default_language is not None and default_language not in get_available_language_codes():
|
||||
raise JsonableError(_("Invalid language '%s'" % (default_language,)))
|
||||
|
||||
realm = user_profile.realm
|
||||
data = {} # type: Dict[str, Any]
|
||||
if name is not None and realm.name != name:
|
||||
|
@ -50,6 +50,13 @@ def update_realm(request, user_profile, name=REQ(validator=check_string, default
|
|||
if invite_by_admins_only is not None and realm.invite_by_admins_only != invite_by_admins_only:
|
||||
do_set_realm_invite_by_admins_only(realm, invite_by_admins_only)
|
||||
data['invite_by_admins_only'] = invite_by_admins_only
|
||||
if authentication_methods is not None and realm.authentication_methods != authentication_methods:
|
||||
if True not in list(authentication_methods.values()):
|
||||
return json_error(_("At least one authentication method must be enabled."),
|
||||
data={"reason": "no authentication"}, status=403)
|
||||
else:
|
||||
do_set_realm_authentication_methods(realm, authentication_methods)
|
||||
data['authentication_methods'] = authentication_methods
|
||||
if create_stream_by_admins_only is not None and realm.create_stream_by_admins_only != create_stream_by_admins_only:
|
||||
do_set_realm_create_stream_by_admins_only(realm, create_stream_by_admins_only)
|
||||
data['create_stream_by_admins_only'] = create_stream_by_admins_only
|
||||
|
|
Loading…
Reference in New Issue