FEATURE: Make allow_uploaded_avatars accept TL (#14091)
This gives admins more control over who can upload custom profile pictures.
This commit is contained in:
parent
eb6d66fe6f
commit
ff367e22fb
|
@ -83,10 +83,23 @@ export default Controller.extend(ModalFunctionality, {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@discourseComputed()
|
siteSettingMatches(value, user) {
|
||||||
allowAvatarUpload() {
|
switch (value) {
|
||||||
|
case "disabled":
|
||||||
|
return false;
|
||||||
|
case "staff":
|
||||||
|
return user.staff;
|
||||||
|
case "admin":
|
||||||
|
return user.admin;
|
||||||
|
default:
|
||||||
|
return user.trust_level >= parseInt(value, 10) || user.staff;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
@discourseComputed("siteSettings.allow_uploaded_avatars")
|
||||||
|
allowAvatarUpload(allowUploadedAvatars) {
|
||||||
return (
|
return (
|
||||||
this.siteSettings.allow_uploaded_avatars &&
|
this.siteSettingMatches(allowUploadedAvatars, this.currentUser) &&
|
||||||
allowsImages(this.currentUser.staff, this.siteSettings)
|
allowsImages(this.currentUser.staff, this.siteSettings)
|
||||||
);
|
);
|
||||||
},
|
},
|
||||||
|
|
|
@ -62,7 +62,7 @@ const ORIGINAL_SETTINGS = {
|
||||||
max_image_width: 690,
|
max_image_width: 690,
|
||||||
max_image_height: 500,
|
max_image_height: 500,
|
||||||
allow_profile_backgrounds: true,
|
allow_profile_backgrounds: true,
|
||||||
allow_uploaded_avatars: true,
|
allow_uploaded_avatars: "0",
|
||||||
tl1_requires_read_posts: 30,
|
tl1_requires_read_posts: 30,
|
||||||
enable_long_polling: true,
|
enable_long_polling: true,
|
||||||
polling_interval: 3000,
|
polling_interval: 3000,
|
||||||
|
|
|
@ -29,7 +29,7 @@ class UploadsController < ApplicationController
|
||||||
# 50 characters ought to be enough for the upload type
|
# 50 characters ought to be enough for the upload type
|
||||||
type = (params[:upload_type].presence || params[:type].presence).parameterize(separator: "_")[0..50]
|
type = (params[:upload_type].presence || params[:type].presence).parameterize(separator: "_")[0..50]
|
||||||
|
|
||||||
if type == "avatar" && !me.admin? && (SiteSetting.discourse_connect_overrides_avatar || !SiteSetting.allow_uploaded_avatars)
|
if type == "avatar" && !me.admin? && (SiteSetting.discourse_connect_overrides_avatar || !TrustLevelAndStaffAndDisabledSetting.matches?(SiteSetting.allow_uploaded_avatars, me))
|
||||||
return render json: failed_json, status: 422
|
return render json: failed_json, status: 422
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1138,7 +1138,7 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
if type.blank? || type == 'system'
|
if type.blank? || type == 'system'
|
||||||
upload_id = nil
|
upload_id = nil
|
||||||
elsif !SiteSetting.allow_uploaded_avatars
|
elsif !TrustLevelAndStaffAndDisabledSetting.matches?(SiteSetting.allow_uploaded_avatars, user)
|
||||||
return render json: failed_json, status: 422
|
return render json: failed_json, status: 422
|
||||||
else
|
else
|
||||||
upload_id = params[:upload_id]
|
upload_id = params[:upload_id]
|
||||||
|
|
|
@ -0,0 +1,32 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class TrustLevelAndStaffAndDisabledSetting < TrustLevelAndStaffSetting
|
||||||
|
def self.valid_value?(val)
|
||||||
|
valid_values.include?(val) || (val.to_i.to_s == val.to_s && valid_values.include?(val.to_i))
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.valid_values
|
||||||
|
['disabled'] + TrustLevel.valid_range.to_a + special_groups
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.translation(value)
|
||||||
|
if value == 'disabled'
|
||||||
|
I18n.t('site_settings.disabled')
|
||||||
|
else
|
||||||
|
super
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.matches?(value, user)
|
||||||
|
case value
|
||||||
|
when 'disabled'
|
||||||
|
false
|
||||||
|
when 'staff'
|
||||||
|
user.staff?
|
||||||
|
when 'admin'
|
||||||
|
user.admin?
|
||||||
|
else
|
||||||
|
user.has_trust_level?(value.to_i) || user.staff?
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1450,6 +1450,7 @@ en:
|
||||||
watched_word_regexp_error: "The regular expression for '%{action}' watched words is invalid. Please check your <a href='%{base_path}/admin/customize/watched_words'>Watched Word settings</a>, or disable the 'watched words regular expressions' site setting."
|
watched_word_regexp_error: "The regular expression for '%{action}' watched words is invalid. Please check your <a href='%{base_path}/admin/customize/watched_words'>Watched Word settings</a>, or disable the 'watched words regular expressions' site setting."
|
||||||
|
|
||||||
site_settings:
|
site_settings:
|
||||||
|
disabled: "disabled"
|
||||||
display_local_time_in_user_card: "Display the local time based on a user's timezone when their user card is opened."
|
display_local_time_in_user_card: "Display the local time based on a user's timezone when their user card is opened."
|
||||||
censored_words: "Words that will be automatically replaced with ■■■■"
|
censored_words: "Words that will be automatically replaced with ■■■■"
|
||||||
delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days."
|
delete_old_hidden_posts: "Auto-delete any hidden posts that stay hidden for more than 30 days."
|
||||||
|
|
|
@ -1365,7 +1365,8 @@ files:
|
||||||
automatically_download_gravatars: true
|
automatically_download_gravatars: true
|
||||||
allow_uploaded_avatars:
|
allow_uploaded_avatars:
|
||||||
client: true
|
client: true
|
||||||
default: true
|
default: "0"
|
||||||
|
enum: "TrustLevelAndStaffAndDisabledSetting"
|
||||||
default_avatars:
|
default_avatars:
|
||||||
default: ""
|
default: ""
|
||||||
type: url_list
|
type: url_list
|
||||||
|
|
|
@ -0,0 +1,19 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class ChangeAllowUploadedAvatars < ActiveRecord::Migration[6.1]
|
||||||
|
def up
|
||||||
|
execute <<~SQL
|
||||||
|
UPDATE site_settings
|
||||||
|
SET data_type = 7, value = (CASE WHEN value = 'f' THEN 'disabled' ELSE '0' END)
|
||||||
|
WHERE name = 'allow_uploaded_avatars'
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
|
||||||
|
def down
|
||||||
|
execute <<~SQL
|
||||||
|
UPDATE site_settings
|
||||||
|
SET data_type = 5, value = (CASE WHEN value = 'disabled' THEN 'f' ELSE 't' END)
|
||||||
|
WHERE name = 'allow_uploaded_avatars'
|
||||||
|
SQL
|
||||||
|
end
|
||||||
|
end
|
|
@ -78,7 +78,7 @@ class ComposerMessagesFinder
|
||||||
# - "disable avatar education message" is enabled
|
# - "disable avatar education message" is enabled
|
||||||
# - "sso overrides avatar" is enabled
|
# - "sso overrides avatar" is enabled
|
||||||
# - "allow uploaded avatars" is disabled
|
# - "allow uploaded avatars" is disabled
|
||||||
return if SiteSetting.disable_avatar_education_message || SiteSetting.discourse_connect_overrides_avatar || !SiteSetting.allow_uploaded_avatars
|
return if SiteSetting.disable_avatar_education_message || SiteSetting.discourse_connect_overrides_avatar || !TrustLevelAndStaffAndDisabledSetting.matches?(SiteSetting.allow_uploaded_avatars, @user)
|
||||||
|
|
||||||
# If we got this far, log that we've nagged them about the avatar
|
# If we got this far, log that we've nagged them about the avatar
|
||||||
UserHistory.create!(action: UserHistory.actions[:notified_about_avatar], target_user_id: @user.id)
|
UserHistory.create!(action: UserHistory.actions[:notified_about_avatar], target_user_id: @user.id)
|
||||||
|
|
|
@ -144,7 +144,7 @@ describe ComposerMessagesFinder do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't notify users if 'allow_uploaded_avatars' setting is disabled" do
|
it "doesn't notify users if 'allow_uploaded_avatars' setting is disabled" do
|
||||||
SiteSetting.allow_uploaded_avatars = false
|
SiteSetting.allow_uploaded_avatars = 'disabled'
|
||||||
expect(finder.check_avatar_notification).to be_blank
|
expect(finder.check_avatar_notification).to be_blank
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -126,7 +126,7 @@ describe UploadsController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'ensures allow_uploaded_avatars is enabled when uploading an avatar' do
|
it 'ensures allow_uploaded_avatars is enabled when uploading an avatar' do
|
||||||
SiteSetting.allow_uploaded_avatars = false
|
SiteSetting.allow_uploaded_avatars = 'disabled'
|
||||||
post "/uploads.json", params: { file: logo, type: "avatar" }
|
post "/uploads.json", params: { file: logo, type: "avatar" }
|
||||||
expect(response.status).to eq(422)
|
expect(response.status).to eq(422)
|
||||||
end
|
end
|
||||||
|
@ -139,7 +139,7 @@ describe UploadsController do
|
||||||
|
|
||||||
it 'always allows admins to upload avatars' do
|
it 'always allows admins to upload avatars' do
|
||||||
sign_in(Fabricate(:admin))
|
sign_in(Fabricate(:admin))
|
||||||
SiteSetting.allow_uploaded_avatars = false
|
SiteSetting.allow_uploaded_avatars = 'disabled'
|
||||||
|
|
||||||
post "/uploads.json", params: { file: logo, type: "avatar" }
|
post "/uploads.json", params: { file: logo, type: "avatar" }
|
||||||
expect(response.status).to eq(200)
|
expect(response.status).to eq(200)
|
||||||
|
|
|
@ -2483,7 +2483,7 @@ describe UsersController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is disabled" do
|
it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is disabled" do
|
||||||
SiteSetting.allow_uploaded_avatars = false
|
SiteSetting.allow_uploaded_avatars = 'disabled'
|
||||||
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
upload_id: upload.id, type: "custom"
|
upload_id: upload.id, type: "custom"
|
||||||
}
|
}
|
||||||
|
@ -2491,8 +2491,50 @@ describe UsersController do
|
||||||
expect(response.status).to eq(422)
|
expect(response.status).to eq(422)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is admin" do
|
||||||
|
SiteSetting.allow_uploaded_avatars = 'admin'
|
||||||
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
upload_id: upload.id, type: "custom"
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
|
||||||
|
user.update!(admin: true)
|
||||||
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
upload_id: upload.id, type: "custom"
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is staff" do
|
||||||
|
SiteSetting.allow_uploaded_avatars = 'staff'
|
||||||
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
upload_id: upload.id, type: "custom"
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
|
||||||
|
user.update!(moderator: true)
|
||||||
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
upload_id: upload.id, type: "custom"
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "raises an error when selecting the custom/uploaded avatar and allow_uploaded_avatars is a trust level" do
|
||||||
|
SiteSetting.allow_uploaded_avatars = '3'
|
||||||
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
upload_id: upload.id, type: "custom"
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(422)
|
||||||
|
|
||||||
|
user.update!(trust_level: 3)
|
||||||
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
upload_id: upload.id, type: "custom"
|
||||||
|
}
|
||||||
|
expect(response.status).to eq(200)
|
||||||
|
end
|
||||||
|
|
||||||
it 'ignores the upload if picking a system avatar' do
|
it 'ignores the upload if picking a system avatar' do
|
||||||
SiteSetting.allow_uploaded_avatars = false
|
SiteSetting.allow_uploaded_avatars = 'disabled'
|
||||||
another_upload = Fabricate(:upload)
|
another_upload = Fabricate(:upload)
|
||||||
|
|
||||||
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
@ -2504,7 +2546,7 @@ describe UsersController do
|
||||||
end
|
end
|
||||||
|
|
||||||
it 'raises an error if the type is invalid' do
|
it 'raises an error if the type is invalid' do
|
||||||
SiteSetting.allow_uploaded_avatars = false
|
SiteSetting.allow_uploaded_avatars = 'disabled'
|
||||||
another_upload = Fabricate(:upload)
|
another_upload = Fabricate(:upload)
|
||||||
|
|
||||||
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
put "/u/#{user.username}/preferences/avatar/pick.json", params: {
|
||||||
|
|
Loading…
Reference in New Issue