diff --git a/frontend_tests/node_tests/settings_org.js b/frontend_tests/node_tests/settings_org.js
index bfc01e4b85..13eb78355a 100644
--- a/frontend_tests/node_tests/settings_org.js
+++ b/frontend_tests/node_tests/settings_org.js
@@ -816,11 +816,25 @@ run_test('misc', () => {
assert.equal($("#change_email .button").attr('disabled'), 'disabled');
page_params.realm_avatar_changes_disabled = false;
+ page_params.server_avatar_changes_disabled = false;
settings_account.update_avatar_change_display();
assert.equal($("#user_avatar_upload_button .button").attr('disabled'), false);
assert.equal($("#user_avatar_delete_button .button").attr('disabled'), false);
page_params.realm_avatar_changes_disabled = true;
+ page_params.server_avatar_changes_disabled = false;
+ settings_account.update_avatar_change_display();
+ assert.equal($("#user_avatar_upload_button .button").attr('disabled'), 'disabled');
+ assert.equal($("#user_avatar_delete_button .button").attr('disabled'), 'disabled');
+
+ page_params.realm_avatar_changes_disabled = false;
+ page_params.server_avatar_changes_disabled = true;
+ settings_account.update_avatar_change_display();
+ assert.equal($("#user_avatar_upload_button .button").attr('disabled'), 'disabled');
+ assert.equal($("#user_avatar_delete_button .button").attr('disabled'), 'disabled');
+
+ page_params.realm_avatar_changes_disabled = true;
+ page_params.server_avatar_changes_disabled = true;
settings_account.update_avatar_change_display();
assert.equal($("#user_avatar_upload_button .button").attr('disabled'), 'disabled');
assert.equal($("#user_avatar_delete_button .button").attr('disabled'), 'disabled');
diff --git a/static/js/settings_account.js b/static/js/settings_account.js
index 89b45e5625..aa3cc0261d 100644
--- a/static/js/settings_account.js
+++ b/static/js/settings_account.js
@@ -46,7 +46,9 @@ exports.update_email_change_display = function () {
};
exports.update_avatar_change_display = function () {
- if (page_params.realm_avatar_changes_disabled && !page_params.is_admin) {
+ if ((page_params.realm_avatar_changes_disabled ||
+ page_params.server_avatar_changes_disabled)
+ && !page_params.is_admin) {
$('#user_avatar_upload_button .button').attr('disabled', 'disabled');
$('#user_avatar_delete_button .button').attr('disabled', 'disabled');
} else {
diff --git a/static/templates/settings/account-settings.handlebars b/static/templates/settings/account-settings.handlebars
index c0bdbf56dc..f4ae8be09c 100644
--- a/static/templates/settings/account-settings.handlebars
+++ b/static/templates/settings/account-settings.handlebars
@@ -170,12 +170,12 @@
diff --git a/zerver/models.py b/zerver/models.py
index 7f9e91f48f..0f7ef87eac 100644
--- a/zerver/models.py
+++ b/zerver/models.py
@@ -491,7 +491,7 @@ def name_changes_disabled(realm: Optional[Realm]) -> bool:
return settings.NAME_CHANGES_DISABLED or realm.name_changes_disabled
def avatar_changes_disabled(realm: Realm) -> bool:
- return realm.avatar_changes_disabled
+ return settings.AVATAR_CHANGES_DISABLED or realm.avatar_changes_disabled
class RealmDomain(models.Model):
"""For an organization with emails_restricted_to_domains enabled, the list of
diff --git a/zerver/tests/test_home.py b/zerver/tests/test_home.py
index e55a1bd8b4..6434b3c3cd 100644
--- a/zerver/tests/test_home.py
+++ b/zerver/tests/test_home.py
@@ -184,6 +184,7 @@ class HomeTest(ZulipTestCase):
"root_domain_uri",
"save_stacktraces",
"search_pills_enabled",
+ "server_avatar_changes_disabled",
"server_generation",
"server_inline_image_preview",
"server_inline_url_embed_preview",
diff --git a/zerver/tests/test_settings.py b/zerver/tests/test_settings.py
index a8e7f1547c..a1fed4345b 100644
--- a/zerver/tests/test_settings.py
+++ b/zerver/tests/test_settings.py
@@ -9,7 +9,7 @@ from typing import Any, Dict
from zerver.lib.initial_password import initial_password
from zerver.lib.sessions import get_session_dict_user
from zerver.lib.test_classes import ZulipTestCase
-from zerver.lib.test_helpers import MockLDAP
+from zerver.lib.test_helpers import MockLDAP, get_test_image_file
from zerver.lib.users import get_all_api_keys
from zerver.models import get_realm, UserProfile, \
get_user_profile_by_api_key
@@ -313,6 +313,19 @@ class ChangeSettingsTest(ZulipTestCase):
result = self.do_change_emojiset(emojiset)
self.assert_json_success(result)
+ def test_avatar_changes_disabled(self) -> None:
+ user = self.example_user('hamlet')
+ email = user.email
+ self.login(email)
+
+ with self.settings(AVATAR_CHANGES_DISABLED=True):
+ result = self.client_delete("/json/users/me/avatar")
+ self.assert_json_error(result, "Avatar changes are disabled in this organization.", 400)
+
+ with self.settings(AVATAR_CHANGES_DISABLED=True):
+ with get_test_image_file('img.png') as fp1:
+ result = self.client_post("/json/users/me/avatar", {'f1': fp1})
+ self.assert_json_error(result, "Avatar changes are disabled in this organization.", 400)
class UserChangesTest(ZulipTestCase):
def test_update_api_key(self) -> None:
diff --git a/zerver/views/home.py b/zerver/views/home.py
index 11caaf8301..cfea7ebea7 100644
--- a/zerver/views/home.py
+++ b/zerver/views/home.py
@@ -203,6 +203,7 @@ def home_real(request: HttpRequest) -> HttpResponse:
password_min_guesses = settings.PASSWORD_MIN_GUESSES,
jitsi_server_url = settings.JITSI_SERVER_URL,
search_pills_enabled = settings.SEARCH_PILLS_ENABLED,
+ server_avatar_changes_disabled = settings.AVATAR_CHANGES_DISABLED,
# Misc. extra data.
have_initial_messages = user_has_messages,
diff --git a/zproject/prod_settings_template.py b/zproject/prod_settings_template.py
index 113c5bf0bf..e8ea365bbd 100644
--- a/zproject/prod_settings_template.py
+++ b/zproject/prod_settings_template.py
@@ -300,10 +300,16 @@ LOCAL_UPLOADS_DIR = "/home/zulip/uploads"
# uploads, so browsers will crash if you try uploading larger files.
MAX_FILE_UPLOAD_SIZE = 25
-# Controls whether name changes are completely disabled for this installation
-# This is useful in settings where you're syncing names from an integrated LDAP/Active Directory
+# Controls whether name changes are completely disabled for this
+# installation. This is useful when you're syncing names from an
+# integrated LDAP/Active Directory.
NAME_CHANGES_DISABLED = False
+# Controls whether avatar changes are completely disabled for this
+# installation. This is useful when you're syncing avatars from an
+# integrated LDAP/Active Directory.
+AVATAR_CHANGES_DISABLED = False
+
# Controls whether users who have not uploaded an avatar will receive an avatar
# from gravatar.com.
ENABLE_GRAVATAR = True
diff --git a/zproject/settings.py b/zproject/settings.py
index cac831c09a..adc101b4ce 100644
--- a/zproject/settings.py
+++ b/zproject/settings.py
@@ -225,6 +225,7 @@ DEFAULT_SETTINGS = {
'INLINE_IMAGE_PREVIEW': True,
'INLINE_URL_EMBED_PREVIEW': False,
'NAME_CHANGES_DISABLED': False,
+ 'AVATAR_CHANGES_DISABLED': False,
'PASSWORD_MIN_LENGTH': 6,
'PASSWORD_MIN_GUESSES': 10000,
'PUSH_NOTIFICATION_BOUNCER_URL': None,