discourse/app/services/site_setting/update.rb
Régis Hanol c519798c35
FEATURE: log admin's choice to backfill when updating a default site (#36296)
setting

When an admin changes one of the default_something site setting, we ask
them if they want to backfill the value to all existing users.

This ensures we log the admin's response in the staff action logs so it
can help diagnose any issues that might arise from the change.

Here's a "before / after", the bottom two rows are "before", and the top
two rows are "after"

<img width="1091" height="293" alt="Screenshot 2025-11-27 at 17 42 29"
src="https://github.com/user-attachments/assets/3c6c74bd-efc2-4210-ad49-6b74630a70a2"
/>


Internal ref - t/169321
2025-11-27 18:40:07 +01:00

115 lines
3 KiB
Ruby
Vendored

# frozen_string_literal: true
class SiteSetting::Update
include Service::Base
Setting = Struct.new(:name, :value, :backfill, :change)
options do
attribute :allow_changing_hidden, :array, default: []
attribute :overridden_setting_names, default: {}
end
policy :current_user_is_admin
params do
attribute :settings
before_validation do
dependent_order = SiteSetting.type_supervisor.dependencies.order
self.settings =
self
.settings
.to_a
.map do |setting|
Setting.new(
setting[:setting_name].to_sym,
setting[:value].to_s.strip,
!!setting[:backfill],
nil,
)
end
.sort_by { |s| dependent_order.index(s.name) }
end
validates :settings, presence: true
after_validation do
self.settings =
self.settings.map do |setting|
raw_value = setting.value
setting.value =
case SiteSetting.type_supervisor.get_type(setting.name)
when :integer
raw_value.tr("^-0-9", "").to_i
when :file_size_restriction
raw_value.tr("^0-9", "").to_i
when :uploaded_image_list
raw_value.blank? ? "" : Upload.get_from_urls(raw_value.split("|")).to_a
when :upload
Upload.get_from_url(raw_value) || ""
else
raw_value
end
setting
end
end
end
policy :settings_are_not_deprecated, class_name: SiteSetting::Policy::SettingsAreNotDeprecated
policy :settings_are_unshadowed_globally,
class_name: SiteSetting::Policy::SettingsAreUnshadowedGlobally
policy :settings_are_visible, class_name: SiteSetting::Policy::SettingsAreVisible
policy :settings_are_configurable, class_name: SiteSetting::Policy::SettingsAreConfigurable
try do
transaction do
step :save
step :backfill
end
end
private
def current_user_is_admin(guardian:)
guardian.is_admin?
end
def save(params:, options:, guardian:)
params.settings.each do |setting|
detailed_message =
if default_user_preference?(setting)
value =
setting.backfill ? I18n.t("csv_export.boolean_yes") : I18n.t("csv_export.boolean_no")
I18n.t("staff_action_logs.site_setting.update_existing_users", value:)
end
setting.change =
SiteSetting.set_and_log(
options.overridden_setting_names[setting.name] || setting.name,
setting.value,
guardian.user,
detailed_message,
)
end
end
def backfill(params:)
params.settings.each do |setting|
next if !setting.backfill || !default_user_preference?(setting)
SiteSettingUpdateExistingUsers.call(
setting.name.to_s,
setting.change.new_value,
setting.change.previous_value,
)
end
end
def default_user_preference?(setting)
SiteSetting::DEFAULT_USER_PREFERENCES.include?(setting.name.to_s)
end
end