settings: Improve error message when deactivating the last user.

This PR was originally started by Rishi Gupta (see #10383).
This commit is contained in:
Rishi Gupta
2018-08-20 23:14:46 -07:00
committed by Tim Abbott
parent 7fb674cc58
commit dd0126ff1b
5 changed files with 41 additions and 5 deletions

View File

@@ -440,8 +440,18 @@ exports.set_up = function () {
window.location.href = "/login";
},
error: function (xhr) {
var error_last_admin = i18n.t("Error: Cannot deactivate the only organization administrator.");
var error_last_user = i18n.t("Error: Cannot deactivate the only user. You can deactivate the whole organization though in your <a target=\"_blank\" href=\"/#organization/organization-profile\">Organization profile settings</a>.");
var rendered_error_msg;
if (xhr.responseJSON.code === "CANNOT_DEACTIVATE_LAST_USER") {
if (xhr.responseJSON.is_last_admin) {
rendered_error_msg = error_last_admin;
} else {
rendered_error_msg = error_last_user;
}
}
$("#deactivate_self_modal").modal("hide");
ui_report.error(i18n.t("Error deactivating account"), xhr, $('#account-settings-status').expectOne());
$("#account-settings-status").addClass("alert-error").html(rendered_error_msg).show();
},
});
}, 5000);

View File

@@ -93,6 +93,8 @@ IGNORED_PHRASES = [
r"was too large; the maximum file size is 25MiB.",
r"selected message",
r"a-z",
r"organization administrator",
r"user",
# SPECIAL CASES
# Enter is usually capitalized

View File

@@ -32,6 +32,7 @@ class ErrorCode(AbstractEnum):
BAD_IMAGE = ()
REALM_UPLOAD_QUOTA = ()
BAD_NARROW = ()
CANNOT_DEACTIVATE_LAST_USER = ()
MISSING_HTTP_EVENT_HEADER = ()
STREAM_DOES_NOT_EXIST = ()
UNAUTHORIZED_PRINCIPAL = ()
@@ -139,6 +140,18 @@ class StreamDoesNotExistError(JsonableError):
def msg_format() -> str:
return _("Stream '{stream}' does not exist")
class CannotDeactivateLastUserError(JsonableError):
code = ErrorCode.CANNOT_DEACTIVATE_LAST_USER
data_fields = ['is_last_admin', 'entity']
def __init__(self, is_last_admin: bool) -> None:
self.is_last_admin = is_last_admin
self.entity = _("organization administrator") if is_last_admin else _("user")
@staticmethod
def msg_format() -> str:
return _("Cannot deactivate the only {entity}.")
class RateLimited(PermissionDenied):
def __init__(self, msg: str="") -> None:
super().__init__(msg)

View File

@@ -23,6 +23,7 @@ from confirmation import settings as confirmation_settings
from zerver.forms import HomepageForm, WRONG_SUBDOMAIN_ERROR, check_subdomain_available
from zerver.lib.actions import do_change_password
from zerver.lib.exceptions import CannotDeactivateLastUserError
from zerver.decorator import do_two_factor_login
from zerver.views.auth import login_or_register_remote_user, \
redirect_and_log_into_subdomain, start_two_factor_auth
@@ -2886,7 +2887,7 @@ class DeactivateUserTest(ZulipTestCase):
user = self.example_user('iago')
self.assertTrue(user.is_active)
result = self.client_delete('/json/users/me')
self.assert_json_error(result, "Cannot deactivate the only organization administrator")
self.assert_json_error(result, "Cannot deactivate the only organization administrator.")
user = self.example_user('iago')
self.assertTrue(user.is_active)
self.assertTrue(user.is_realm_admin)
@@ -2898,6 +2899,14 @@ class DeactivateUserTest(ZulipTestCase):
self.assert_json_success(result)
do_change_is_admin(user, True)
def test_do_not_deactivate_final_user(self) -> None:
realm = get_realm('zulip')
UserProfile.objects.filter(realm=realm, is_realm_admin=False).update(is_active=False)
email = self.example_email("iago")
self.login(email)
result = self.client_delete('/json/users/me')
self.assert_json_error(result, "Cannot deactivate the only user.")
class TestLoginPage(ZulipTestCase):
def test_login_page_wrong_subdomain_error(self) -> None:
result = self.client_get("/login/?subdomain=1")

View File

@@ -22,7 +22,7 @@ from zerver.lib.actions import do_change_avatar_fields, do_change_bot_owner, \
do_update_user_custom_profile_data
from zerver.lib.avatar import avatar_url, get_gravatar_url, get_avatar_field
from zerver.lib.bot_config import set_bot_config
from zerver.lib.exceptions import JsonableError
from zerver.lib.exceptions import JsonableError, CannotDeactivateLastUserError
from zerver.lib.integrations import EMBEDDED_BOTS
from zerver.lib.request import has_request_variables, REQ
from zerver.lib.response import json_error, json_success
@@ -48,9 +48,11 @@ def deactivate_user_backend(request: HttpRequest, user_profile: UserProfile,
return _deactivate_user_profile_backend(request, user_profile, target)
def deactivate_user_own_backend(request: HttpRequest, user_profile: UserProfile) -> HttpResponse:
if UserProfile.objects.filter(realm=user_profile.realm, is_active=True).count() == 1:
raise CannotDeactivateLastUserError(is_last_admin=False)
if user_profile.is_realm_admin and check_last_admin(user_profile):
return json_error(_('Cannot deactivate the only organization administrator'))
raise CannotDeactivateLastUserError(is_last_admin=True)
do_deactivate_user(user_profile, acting_user=user_profile)
return json_success()