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!');
|
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();
|
common.then_log_out();
|
||||||
|
|
||||||
casper.run(function () {
|
casper.run(function () {
|
||||||
|
|
|
@ -216,6 +216,26 @@ function render(template_name, args) {
|
||||||
assert.equal(count.text(), 99);
|
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() {
|
(function bookend() {
|
||||||
// Do subscribed/unsubscribed cases here.
|
// Do subscribed/unsubscribed cases here.
|
||||||
var args = {
|
var args = {
|
||||||
|
|
|
@ -174,6 +174,20 @@ exports.reset_realm_default_language = function () {
|
||||||
$("#id_realm_default_language").val(page_params.realm_default_language);
|
$("#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() {
|
function _setup_page() {
|
||||||
var domains_string = stringify_list_with_conjunction(page_params.domains, "or");
|
var domains_string = stringify_list_with_conjunction(page_params.domains, "or");
|
||||||
var atdomains = page_params.domains.slice();
|
var atdomains = page_params.domains.slice();
|
||||||
|
@ -189,6 +203,7 @@ function _setup_page() {
|
||||||
realm_restricted_to_domain: page_params.realm_restricted_to_domain,
|
realm_restricted_to_domain: page_params.realm_restricted_to_domain,
|
||||||
realm_invite_required: page_params.realm_invite_required,
|
realm_invite_required: page_params.realm_invite_required,
|
||||||
realm_invite_by_admins_only: page_params.realm_invite_by_admins_only,
|
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_create_stream_by_admins_only: page_params.realm_create_stream_by_admins_only,
|
||||||
realm_allow_message_editing: page_params.realm_allow_message_editing,
|
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),
|
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-restricted-to-domain-status").expectOne().hide();
|
||||||
$("#admin-realm-invite-required-status").expectOne().hide();
|
$("#admin-realm-invite-required-status").expectOne().hide();
|
||||||
$("#admin-realm-invite-by-admins-only-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-create-stream-by-admins-only-status").expectOne().hide();
|
||||||
$("#admin-realm-message-editing-status").expectOne().hide();
|
$("#admin-realm-message-editing-status").expectOne().hide();
|
||||||
$("#admin-realm-default-language-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_streams_loading_indicator'));
|
||||||
loading.make_indicator($('#admin_page_deactivated_users_loading_indicator'));
|
loading.make_indicator($('#admin_page_deactivated_users_loading_indicator'));
|
||||||
loading.make_indicator($('#admin_page_emoji_loading_indicator'));
|
loading.make_indicator($('#admin_page_emoji_loading_indicator'));
|
||||||
|
loading.make_indicator($('#admin_page_auth_methods_loading_indicator'));
|
||||||
|
|
||||||
// Populate users and bots tables
|
// Populate users and bots tables
|
||||||
channel.get({
|
channel.get({
|
||||||
|
@ -234,6 +251,9 @@ function _setup_page() {
|
||||||
error: failed_listing_streams
|
error: failed_listing_streams
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// Populate authentication methods table
|
||||||
|
exports.populate_auth_methods(page_params.realm_authentication_methods);
|
||||||
|
|
||||||
// Populate emoji table
|
// Populate emoji table
|
||||||
exports.populate_emoji(page_params.realm_emoji);
|
exports.populate_emoji(page_params.realm_emoji);
|
||||||
exports.update_default_streams_table();
|
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 restricted_to_domain_status = $("#admin-realm-restricted-to-domain-status").expectOne();
|
||||||
var invite_required_status = $("#admin-realm-invite-required-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 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 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 message_editing_status = $("#admin-realm-message-editing-status").expectOne();
|
||||||
var default_language_status = $("#admin-realm-default-language-status").expectOne();
|
var default_language_status = $("#admin-realm-default-language-status").expectOne();
|
||||||
|
var auth_methods_table = $('.admin_auth_methods_table');
|
||||||
name_status.hide();
|
name_status.hide();
|
||||||
restricted_to_domain_status.hide();
|
restricted_to_domain_status.hide();
|
||||||
invite_required_status.hide();
|
invite_required_status.hide();
|
||||||
invite_by_admins_only_status.hide();
|
invite_by_admins_only_status.hide();
|
||||||
|
authentication_methods_status.hide();
|
||||||
create_stream_by_admins_only_status.hide();
|
create_stream_by_admins_only_status.hide();
|
||||||
message_editing_status.hide();
|
message_editing_status.hide();
|
||||||
default_language_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_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_message_content_edit_limit_minutes = $("#id_realm_message_content_edit_limit_minutes").val();
|
||||||
var new_default_language = $("#id_realm_default_language").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
|
// If allow_message_editing is unchecked, message_content_edit_limit_minutes
|
||||||
// is irrelevant. Hence if allow_message_editing is unchecked, and
|
// is irrelevant. Hence if allow_message_editing is unchecked, and
|
||||||
// message_content_edit_limit_minutes is poorly formed, we set the latter to
|
// 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),
|
restricted_to_domain: JSON.stringify(new_restricted),
|
||||||
invite_required: JSON.stringify(new_invite),
|
invite_required: JSON.stringify(new_invite),
|
||||||
invite_by_admins_only: JSON.stringify(new_invite_by_admins_only),
|
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),
|
create_stream_by_admins_only: JSON.stringify(new_create_stream_by_admins_only),
|
||||||
allow_message_editing: JSON.stringify(new_allow_message_editing),
|
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),
|
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);
|
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) {
|
if (response_data.allow_message_editing !== undefined) {
|
||||||
// We expect message_content_edit_limit_seconds was sent in the
|
// We expect message_content_edit_limit_seconds was sent in the
|
||||||
// response as well
|
// response as well
|
||||||
|
@ -515,7 +546,12 @@ function _setup_page() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error: function (xhr, error) {
|
error: function (xhr, error) {
|
||||||
ui.report_error(i18n.t("Failed!"), xhr, name_status);
|
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) {
|
$.each(event.data, function (key, value) {
|
||||||
page_params['realm_' + 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') {
|
} else if (event.op === 'update' && event.property === 'default_language') {
|
||||||
page_params.realm_default_language = event.value;
|
page_params.realm_default_language = event.value;
|
||||||
admin.reset_realm_default_language();
|
admin.reset_realm_default_language();
|
||||||
|
|
|
@ -49,7 +49,8 @@
|
||||||
"Narrow to private messages with __message.sender_full_name__": "Narrow to private messages with __message.sender_full_name__",
|
"Narrow to private messages with __message.sender_full_name__": "Narrow to private messages with __message.sender_full_name__",
|
||||||
"Pin stream to top<br /> of left sidebar": "Pin stream to top<br /> of left sidebar",
|
"Pin stream to top<br /> of left sidebar": "Pin stream to top<br /> of left sidebar",
|
||||||
"Password": "Password",
|
"Password": "Password",
|
||||||
"Any user may now invite new users!": "Any user may now invite new users!",
|
"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",
|
"Receive desktop <br />notifications": "Receive desktop <br />notifications",
|
||||||
"Please specify a stream": "Please specify a stream",
|
"Please specify a stream": "Please specify a stream",
|
||||||
"Delete Alert Word": "Delete Alert Word",
|
"Delete Alert Word": "Delete Alert Word",
|
||||||
|
|
|
@ -27,6 +27,7 @@
|
||||||
<div role="tabpanel" class="tab-pane active" id="organization">
|
<div role="tabpanel" class="tab-pane active" id="organization">
|
||||||
{{ partial "organization-settings-admin" }}
|
{{ partial "organization-settings-admin" }}
|
||||||
{{ partial "emoji-settings-admin" }}
|
{{ partial "emoji-settings-admin" }}
|
||||||
|
{{ partial "auth-methods-settings-admin" }}
|
||||||
</div>
|
</div>
|
||||||
<div role="tabpanel" class="tab-pane" id="users">
|
<div role="tabpanel" class="tab-pane" id="users">
|
||||||
{{ partial "user-list-admin" }}
|
{{ 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))
|
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):
|
def do_set_realm_create_stream_by_admins_only(realm, create_stream_by_admins_only):
|
||||||
# type: (Realm, bool) -> None
|
# type: (Realm, bool) -> None
|
||||||
realm.create_stream_by_admins_only = create_stream_by_admins_only
|
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_restricted_to_domain'] = user_profile.realm.restricted_to_domain
|
||||||
state['realm_invite_required'] = user_profile.realm.invite_required
|
state['realm_invite_required'] = user_profile.realm.invite_required
|
||||||
state['realm_invite_by_admins_only'] = user_profile.realm.invite_by_admins_only
|
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_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_allow_message_editing'] = user_profile.realm.allow_message_editing
|
||||||
state['realm_message_content_edit_limit_seconds'] = user_profile.realm.message_content_edit_limit_seconds
|
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, \
|
from zproject.backends import ZulipDummyBackend, EmailAuthBackend, \
|
||||||
GoogleMobileOauth2Backend, ZulipRemoteUserBackend, ZulipLDAPAuthBackend, \
|
GoogleMobileOauth2Backend, ZulipRemoteUserBackend, ZulipLDAPAuthBackend, \
|
||||||
ZulipLDAPUserPopulator, DevAuthBackend, GitHubAuthBackend, ZulipAuthMixin, \
|
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
|
from zerver.views.auth import maybe_send_to_registration
|
||||||
|
|
||||||
|
@ -1444,3 +1444,41 @@ class TestMaybeSendToRegistration(ZulipTestCase):
|
||||||
confirmation_key = confirmation.confirmation_key
|
confirmation_key = confirmation.confirmation_key
|
||||||
self.assertIn('do_confirm/' + confirmation_key, result.url)
|
self.assertIn('do_confirm/' + confirmation_key, result.url)
|
||||||
self.assertEqual(PreregistrationUser.objects.all().count(), 1)
|
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_invite_by_admins_only,
|
||||||
do_set_realm_message_editing,
|
do_set_realm_message_editing,
|
||||||
do_set_realm_default_language,
|
do_set_realm_default_language,
|
||||||
|
do_set_realm_authentication_methods,
|
||||||
do_update_message,
|
do_update_message,
|
||||||
do_update_pointer,
|
do_update_pointer,
|
||||||
do_change_twenty_four_hour_time,
|
do_change_twenty_four_hour_time,
|
||||||
|
@ -466,6 +467,28 @@ class EventsRegisterTest(ZulipTestCase):
|
||||||
error = schema_checker('events[0]', events[0])
|
error = schema_checker('events[0]', events[0])
|
||||||
self.assert_on_error(error)
|
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):
|
def test_change_realm_invite_by_admins_only(self):
|
||||||
# type: () -> None
|
# type: () -> None
|
||||||
schema_checker = check_dict([
|
schema_checker = check_dict([
|
||||||
|
|
|
@ -1825,6 +1825,7 @@ class HomeTest(ZulipTestCase):
|
||||||
"product_name",
|
"product_name",
|
||||||
"prompt_for_invites",
|
"prompt_for_invites",
|
||||||
"realm_allow_message_editing",
|
"realm_allow_message_editing",
|
||||||
|
"realm_authentication_methods",
|
||||||
"realm_create_stream_by_admins_only",
|
"realm_create_stream_by_admins_only",
|
||||||
"realm_default_language",
|
"realm_default_language",
|
||||||
"realm_default_streams",
|
"realm_default_streams",
|
||||||
|
|
|
@ -581,6 +581,7 @@ def home(request):
|
||||||
realm_name = register_ret['realm_name'],
|
realm_name = register_ret['realm_name'],
|
||||||
realm_invite_required = register_ret['realm_invite_required'],
|
realm_invite_required = register_ret['realm_invite_required'],
|
||||||
realm_invite_by_admins_only = register_ret['realm_invite_by_admins_only'],
|
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_create_stream_by_admins_only = register_ret['realm_create_stream_by_admins_only'],
|
||||||
realm_allow_message_editing = register_ret['realm_allow_message_editing'],
|
realm_allow_message_editing = register_ret['realm_allow_message_editing'],
|
||||||
realm_message_content_edit_limit_seconds = register_ret['realm_message_content_edit_limit_seconds'],
|
realm_message_content_edit_limit_seconds = register_ret['realm_message_content_edit_limit_seconds'],
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
from __future__ import absolute_import
|
from __future__ import absolute_import
|
||||||
|
|
||||||
from typing import Any, Optional
|
from typing import Any, Optional
|
||||||
|
|
||||||
from django.http import HttpRequest, HttpResponse
|
from django.http import HttpRequest, HttpResponse
|
||||||
from django.utils.translation import ugettext as _
|
from django.utils.translation import ugettext as _
|
||||||
|
|
||||||
|
@ -14,11 +13,12 @@ from zerver.lib.actions import (
|
||||||
do_set_realm_message_editing,
|
do_set_realm_message_editing,
|
||||||
do_set_realm_restricted_to_domain,
|
do_set_realm_restricted_to_domain,
|
||||||
do_set_realm_default_language,
|
do_set_realm_default_language,
|
||||||
|
do_set_realm_authentication_methods
|
||||||
)
|
)
|
||||||
from zerver.lib.i18n import get_available_language_codes
|
from zerver.lib.i18n import get_available_language_codes
|
||||||
from zerver.lib.request import has_request_variables, REQ, JsonableError
|
from zerver.lib.request import has_request_variables, REQ, JsonableError
|
||||||
from zerver.lib.response import json_success, json_error
|
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
|
from zerver.models import UserProfile
|
||||||
|
|
||||||
@require_realm_admin
|
@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),
|
create_stream_by_admins_only=REQ(validator=check_bool, default=None),
|
||||||
allow_message_editing=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),
|
message_content_edit_limit_seconds=REQ(converter=to_non_negative_int, default=None),
|
||||||
default_language=REQ(validator=check_string, 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
|
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
|
# Validation for default_language
|
||||||
if default_language is not None and default_language not in get_available_language_codes():
|
if default_language is not None and default_language not in get_available_language_codes():
|
||||||
raise JsonableError(_("Invalid language '%s'" % (default_language,)))
|
raise JsonableError(_("Invalid language '%s'" % (default_language,)))
|
||||||
|
|
||||||
realm = user_profile.realm
|
realm = user_profile.realm
|
||||||
data = {} # type: Dict[str, Any]
|
data = {} # type: Dict[str, Any]
|
||||||
if name is not None and realm.name != name:
|
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:
|
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)
|
do_set_realm_invite_by_admins_only(realm, invite_by_admins_only)
|
||||||
data['invite_by_admins_only'] = 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:
|
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)
|
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
|
data['create_stream_by_admins_only'] = create_stream_by_admins_only
|
||||||
|
|
Loading…
Reference in New Issue