DEV: Apply syntax_tree formatting to app/*

This commit is contained in:
David Taylor
2023-01-09 14:14:59 +00:00
parent a641ce4b62
commit 5a003715d3
696 changed files with 18447 additions and 15481 deletions
@@ -7,5 +7,4 @@ class Admin::AdminController < ApplicationController
def index
render body: nil
end
end
+35 -34
View File
@@ -8,40 +8,40 @@ class Admin::ApiController < Admin::AdminController
offset = (params[:offset] || 0).to_i
limit = (params[:limit] || 50).to_i.clamp(1, 50)
keys = ApiKey
.where(hidden: false)
.includes(:user, :api_key_scopes)
# Sort revoked keys by revoked_at and active keys by created_at
.order("revoked_at DESC NULLS FIRST, created_at DESC")
.offset(offset)
.limit(limit)
keys =
ApiKey
.where(hidden: false)
.includes(:user, :api_key_scopes)
# Sort revoked keys by revoked_at and active keys by created_at
.order("revoked_at DESC NULLS FIRST, created_at DESC")
.offset(offset)
.limit(limit)
render_json_dump(
keys: serialize_data(keys, ApiKeySerializer),
offset: offset,
limit: limit
)
render_json_dump(keys: serialize_data(keys, ApiKeySerializer), offset: offset, limit: limit)
end
def show
api_key = ApiKey.includes(:api_key_scopes).find_by!(id: params[:id])
render_serialized(api_key, ApiKeySerializer, root: 'key')
render_serialized(api_key, ApiKeySerializer, root: "key")
end
def scopes
scopes = ApiKeyScope.scope_mappings.reduce({}) do |memo, (resource, actions)|
memo.tap do |m|
m[resource] = actions.map do |k, v|
{
scope_id: "#{resource}:#{k}",
key: k,
name: k.to_s.gsub('_', ' '),
params: v[:params],
urls: v[:urls]
}
scopes =
ApiKeyScope
.scope_mappings
.reduce({}) do |memo, (resource, actions)|
memo.tap do |m|
m[resource] = actions.map do |k, v|
{
scope_id: "#{resource}:#{k}",
key: k,
name: k.to_s.gsub("_", " "),
params: v[:params],
urls: v[:urls],
}
end
end
end
end
end
render json: { scopes: scopes }
end
@@ -52,7 +52,7 @@ class Admin::ApiController < Admin::AdminController
api_key.update!(update_params)
log_api_key(api_key, UserHistory.actions[:api_key_update], changes: api_key.saved_changes)
end
render_serialized(api_key, ApiKeySerializer, root: 'key')
render_serialized(api_key, ApiKeySerializer, root: "key")
end
def destroy
@@ -76,7 +76,7 @@ class Admin::ApiController < Admin::AdminController
api_key.save!
log_api_key(api_key, UserHistory.actions[:api_key_create], changes: api_key.saved_changes)
end
render_serialized(api_key, ApiKeySerializer, root: 'key')
render_serialized(api_key, ApiKeySerializer, root: "key")
end
def undo_revoke_key
@@ -105,7 +105,7 @@ class Admin::ApiController < Admin::AdminController
def build_scopes
params.require(:key)[:scopes].to_a.map do |scope_params|
resource, action = scope_params[:scope_id].split(':')
resource, action = scope_params[:scope_id].split(":")
mapping = ApiKeyScope.scope_mappings.dig(resource.to_sym, action.to_sym)
raise Discourse::InvalidParameters if mapping.nil? # invalid mapping
@@ -113,7 +113,7 @@ class Admin::ApiController < Admin::AdminController
ApiKeyScope.new(
resource: resource,
action: action,
allowed_parameters: build_params(scope_params, mapping[:params])
allowed_parameters: build_params(scope_params, mapping[:params]),
)
end
end
@@ -121,11 +121,13 @@ class Admin::ApiController < Admin::AdminController
def build_params(scope_params, params)
return if params.nil?
scope_params.slice(*params).tap do |allowed_params|
allowed_params.each do |k, v|
v.blank? ? allowed_params.delete(k) : allowed_params[k] = v.split(',')
scope_params
.slice(*params)
.tap do |allowed_params|
allowed_params.each do |k, v|
v.blank? ? allowed_params.delete(k) : allowed_params[k] = v.split(",")
end
end
end
end
def update_params
@@ -146,5 +148,4 @@ class Admin::ApiController < Admin::AdminController
def log_api_key_restore(*args)
StaffActionLogger.new(current_user).log_api_key_restore(*args)
end
end
+39 -13
View File
@@ -7,7 +7,7 @@ class Admin::BackupsController < Admin::AdminController
include ExternalUploadHelpers
before_action :ensure_backups_enabled
skip_before_action :check_xhr, only: [:index, :show, :logs, :check_backup_chunk, :upload_backup_chunk]
skip_before_action :check_xhr, only: %i[index show logs check_backup_chunk upload_backup_chunk]
def index
respond_to do |format|
@@ -62,7 +62,7 @@ class Admin::BackupsController < Admin::AdminController
Jobs.enqueue(
:download_backup_email,
user_id: current_user.id,
backup_file_path: url_for(controller: 'backups', action: 'show')
backup_file_path: url_for(controller: "backups", action: "show"),
)
render body: nil
@@ -73,8 +73,8 @@ class Admin::BackupsController < Admin::AdminController
def show
if !EmailBackupToken.compare(current_user.id, params.fetch(:token))
@error = I18n.t('download_backup_mailer.no_token')
return render layout: 'no_ember', status: 422, formats: [:html]
@error = I18n.t("download_backup_mailer.no_token")
return render layout: "no_ember", status: 422, formats: [:html]
end
store = BackupRestore::BackupStore.create
@@ -86,7 +86,7 @@ class Admin::BackupsController < Admin::AdminController
if store.remote?
redirect_to backup.source
else
headers['Content-Length'] = File.size(backup.source).to_s
headers["Content-Length"] = File.size(backup.source).to_s
send_file backup.source
end
else
@@ -170,9 +170,15 @@ class Admin::BackupsController < Admin::AdminController
identifier = params.fetch(:resumableIdentifier)
raise Discourse::InvalidParameters.new(:resumableIdentifier) unless valid_filename?(identifier)
return render status: 415, plain: I18n.t("backup.backup_file_should_be_tar_gz") unless valid_extension?(filename)
return render status: 415, plain: I18n.t("backup.not_enough_space_on_disk") unless has_enough_space_on_disk?(total_size)
return render status: 415, plain: I18n.t("backup.invalid_filename") unless valid_filename?(filename)
unless valid_extension?(filename)
return render status: 415, plain: I18n.t("backup.backup_file_should_be_tar_gz")
end
unless has_enough_space_on_disk?(total_size)
return render status: 415, plain: I18n.t("backup.not_enough_space_on_disk")
end
unless valid_filename?(filename)
return render status: 415, plain: I18n.t("backup.invalid_filename")
end
file = params.fetch(:file)
chunk_number = params.fetch(:resumableChunkNumber).to_i
@@ -187,7 +193,13 @@ class Admin::BackupsController < Admin::AdminController
uploaded_file_size = previous_chunk_number * chunk_size
if uploaded_file_size + current_chunk_size >= total_size
# merge all the chunks in a background thread
Jobs.enqueue_in(5.seconds, :backup_chunks_merger, filename: filename, identifier: identifier, chunks: chunk_number)
Jobs.enqueue_in(
5.seconds,
:backup_chunks_merger,
filename: filename,
identifier: identifier,
chunks: chunk_number,
)
end
render body: nil
@@ -197,7 +209,9 @@ class Admin::BackupsController < Admin::AdminController
params.require(:filename)
filename = params.fetch(:filename)
return render_json_error(I18n.t("backup.backup_file_should_be_tar_gz")) unless valid_extension?(filename)
unless valid_extension?(filename)
return render_json_error(I18n.t("backup.backup_file_should_be_tar_gz"))
end
return render_json_error(I18n.t("backup.invalid_filename")) unless valid_filename?(filename)
store = BackupRestore::BackupStore.create
@@ -236,8 +250,16 @@ class Admin::BackupsController < Admin::AdminController
end
def validate_before_create_multipart(file_name:, file_size:, upload_type:)
raise ExternalUploadHelpers::ExternalUploadValidationError.new(I18n.t("backup.backup_file_should_be_tar_gz")) unless valid_extension?(file_name)
raise ExternalUploadHelpers::ExternalUploadValidationError.new(I18n.t("backup.invalid_filename")) unless valid_filename?(file_name)
unless valid_extension?(file_name)
raise ExternalUploadHelpers::ExternalUploadValidationError.new(
I18n.t("backup.backup_file_should_be_tar_gz"),
)
end
unless valid_filename?(file_name)
raise ExternalUploadHelpers::ExternalUploadValidationError.new(
I18n.t("backup.invalid_filename"),
)
end
end
def self.serialize_upload(_upload)
@@ -248,7 +270,11 @@ class Admin::BackupsController < Admin::AdminController
begin
yield
rescue BackupRestore::BackupStore::StorageError => err
message = debug_upload_error(err, I18n.t("upload.create_multipart_failure", additional_detail: err.message))
message =
debug_upload_error(
err,
I18n.t("upload.create_multipart_failure", additional_detail: err.message),
)
raise ExternalUploadHelpers::ExternalUploadValidationError.new(message)
rescue BackupRestore::BackupStore::BackupFileExists
raise ExternalUploadHelpers::ExternalUploadValidationError.new(I18n.t("backup.file_exists"))
+58 -42
View File
@@ -1,6 +1,6 @@
# frozen_string_literal: true
require 'csv'
require "csv"
class Admin::BadgesController < Admin::AdminController
MAX_CSV_LINES = 50_000
@@ -10,25 +10,29 @@ class Admin::BadgesController < Admin::AdminController
data = {
badge_types: BadgeType.all.order(:id).to_a,
badge_groupings: BadgeGrouping.all.order(:position).to_a,
badges: Badge.includes(:badge_grouping)
.includes(:badge_type, :image_upload)
.references(:badge_grouping)
.order('badge_groupings.position, badge_type_id, badges.name').to_a,
badges:
Badge
.includes(:badge_grouping)
.includes(:badge_type, :image_upload)
.references(:badge_grouping)
.order("badge_groupings.position, badge_type_id, badges.name")
.to_a,
protected_system_fields: Badge.protected_system_fields,
triggers: Badge.trigger_hash
triggers: Badge.trigger_hash,
}
render_serialized(OpenStruct.new(data), AdminBadgesSerializer)
end
def preview
unless SiteSetting.enable_badge_sql
return render json: "preview not allowed", status: 403
end
return render json: "preview not allowed", status: 403 unless SiteSetting.enable_badge_sql
render json: BadgeGranter.preview(params[:sql],
target_posts: params[:target_posts] == "true",
explain: params[:explain] == "true",
trigger: params[:trigger].to_i)
render json:
BadgeGranter.preview(
params[:sql],
target_posts: params[:target_posts] == "true",
explain: params[:explain] == "true",
trigger: params[:trigger].to_i,
)
end
def new
@@ -47,18 +51,21 @@ class Admin::BadgesController < Admin::AdminController
if !badge.enabled?
render_json_error(
I18n.t('badges.mass_award.errors.badge_disabled', badge_name: badge.display_name),
status: 422
I18n.t("badges.mass_award.errors.badge_disabled", badge_name: badge.display_name),
status: 422,
)
return
end
replace_badge_owners = params[:replace_badge_owners] == 'true'
ensure_users_have_badge_once = params[:grant_existing_holders] != 'true'
replace_badge_owners = params[:replace_badge_owners] == "true"
ensure_users_have_badge_once = params[:grant_existing_holders] != "true"
if !ensure_users_have_badge_once && !badge.multiple_grant?
render_json_error(
I18n.t('badges.mass_award.errors.cant_grant_multiple_times', badge_name: badge.display_name),
status: 422
I18n.t(
"badges.mass_award.errors.cant_grant_multiple_times",
badge_name: badge.display_name,
),
status: 422,
)
return
end
@@ -72,7 +79,7 @@ class Admin::BadgesController < Admin::AdminController
line_number += 1
if line.present?
if line.include?('@')
if line.include?("@")
emails << line
else
usernames << line
@@ -80,26 +87,35 @@ class Admin::BadgesController < Admin::AdminController
end
if emails.size + usernames.size > MAX_CSV_LINES
return render_json_error I18n.t('badges.mass_award.errors.too_many_csv_entries', count: MAX_CSV_LINES), status: 400
return(
render_json_error I18n.t(
"badges.mass_award.errors.too_many_csv_entries",
count: MAX_CSV_LINES,
),
status: 400
)
end
end
end
BadgeGranter.revoke_all(badge) if replace_badge_owners
results = BadgeGranter.enqueue_mass_grant_for_users(
badge,
emails: emails,
usernames: usernames,
ensure_users_have_badge_once: ensure_users_have_badge_once
)
results =
BadgeGranter.enqueue_mass_grant_for_users(
badge,
emails: emails,
usernames: usernames,
ensure_users_have_badge_once: ensure_users_have_badge_once,
)
render json: {
unmatched_entries: results[:unmatched_entries].first(100),
matched_users_count: results[:matched_users_count],
unmatched_entries_count: results[:unmatched_entries_count]
}, status: :ok
unmatched_entries: results[:unmatched_entries].first(100),
matched_users_count: results[:matched_users_count],
unmatched_entries_count: results[:unmatched_entries_count],
},
status: :ok
rescue CSV::MalformedCSVError
render_json_error I18n.t('badges.mass_award.errors.invalid_csv', line_number: line_number), status: 400
render_json_error I18n.t("badges.mass_award.errors.invalid_csv", line_number: line_number),
status: 400
end
def badge_types
@@ -119,9 +135,7 @@ class Admin::BadgesController < Admin::AdminController
group.save
end
badge_groupings.each do |g|
g.destroy unless g.system? || ids.include?(g.id)
end
badge_groupings.each { |g| g.destroy unless g.system? || ids.include?(g.id) }
badge_groupings = BadgeGrouping.all.order(:position).to_a
render_serialized(badge_groupings, BadgeGroupingSerializer, root: "badge_groupings")
@@ -173,21 +187,23 @@ class Admin::BadgesController < Admin::AdminController
def update_badge_from_params(badge, opts = {})
errors = []
Badge.transaction do
allowed = Badge.column_names.map(&:to_sym)
allowed -= [:id, :created_at, :updated_at, :grant_count]
allowed = Badge.column_names.map(&:to_sym)
allowed -= %i[id created_at updated_at grant_count]
allowed -= Badge.protected_system_fields if badge.system?
allowed -= [:query] unless SiteSetting.enable_badge_sql
params.permit(*allowed)
allowed.each do |key|
badge.public_send("#{key}=" , params[key]) if params[key]
end
allowed.each { |key| badge.public_send("#{key}=", params[key]) if params[key] }
# Badge query contract checks
begin
if SiteSetting.enable_badge_sql
BadgeGranter.contract_checks!(badge.query, target_posts: badge.target_posts, trigger: badge.trigger)
BadgeGranter.contract_checks!(
badge.query,
target_posts: badge.target_posts,
trigger: badge.trigger,
)
end
rescue => e
errors << e.message
@@ -203,7 +219,7 @@ class Admin::BadgesController < Admin::AdminController
:bulk_user_title_update,
new_title: badge.name,
granted_badge_id: badge.id,
action: Jobs::BulkUserTitleUpdate::UPDATE_ACTION
action: Jobs::BulkUserTitleUpdate::UPDATE_ACTION,
)
end
@@ -1,11 +1,13 @@
# frozen_string_literal: true
class Admin::ColorSchemesController < Admin::AdminController
before_action :fetch_color_scheme, only: [:update, :destroy]
before_action :fetch_color_scheme, only: %i[update destroy]
def index
render_serialized(ColorScheme.base_color_schemes + ColorScheme.order('id ASC').all.to_a, ColorSchemeSerializer)
render_serialized(
ColorScheme.base_color_schemes + ColorScheme.order("id ASC").all.to_a,
ColorSchemeSerializer,
)
end
def create
@@ -38,6 +40,8 @@ class Admin::ColorSchemesController < Admin::AdminController
end
def color_scheme_params
params.permit(color_scheme: [:base_scheme_id, :name, :user_selectable, colors: [:name, :hex]])[:color_scheme]
params.permit(color_scheme: [:base_scheme_id, :name, :user_selectable, colors: %i[name hex]])[
:color_scheme
]
end
end
@@ -11,9 +11,12 @@ class Admin::DashboardController < Admin::StaffController
render json: data
end
def moderation; end
def security; end
def reports; end
def moderation
end
def security
end
def reports
end
def general
render json: AdminDashboardGeneralData.fetch_cached_stats
@@ -33,7 +36,7 @@ class Admin::DashboardController < Admin::StaffController
data = {
new_features: new_features,
has_unseen_features: DiscourseUpdates.has_unseen_features?(current_user.id),
release_notes_link: AdminDashboardGeneralData.fetch_cached_stats["release_notes_link"]
release_notes_link: AdminDashboardGeneralData.fetch_cached_stats["release_notes_link"],
}
render json: data
end
+68 -48
View File
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::EmailController < Admin::AdminController
def index
data = { delivery_method: delivery_method, settings: delivery_settings }
render_json_dump(data)
@@ -35,29 +34,22 @@ class Admin::EmailController < Admin::AdminController
else
email_logs.where(
"replace(post_reply_keys.reply_key::VARCHAR, '-', '') ILIKE ?",
"%#{reply_key}%"
"%#{reply_key}%",
)
end
end
email_logs = email_logs.to_a
tuples = email_logs.map do |email_log|
[email_log.post_id, email_log.user_id]
end
tuples = email_logs.map { |email_log| [email_log.post_id, email_log.user_id] }
reply_keys = {}
if tuples.present?
PostReplyKey
.where(
"(post_id,user_id) IN (#{(['(?)'] * tuples.size).join(', ')})",
*tuples
)
.where("(post_id,user_id) IN (#{(["(?)"] * tuples.size).join(", ")})", *tuples)
.pluck(:post_id, :user_id, "reply_key::text")
.each do |post_id, user_id, key|
reply_keys[[post_id, user_id]] = key
end
.each { |post_id, user_id, key| reply_keys[[post_id, user_id]] = key }
end
render_serialized(email_logs, EmailLogSerializer, reply_keys: reply_keys)
@@ -96,14 +88,10 @@ class Admin::EmailController < Admin::AdminController
def advanced_test
params.require(:email)
receiver = Email::Receiver.new(params['email'])
receiver = Email::Receiver.new(params["email"])
text, elided, format = receiver.select_body
render json: success_json.merge!(
text: text,
elided: elided,
format: format
)
render json: success_json.merge!(text: text, elided: elided, format: format)
end
def send_digest
@@ -112,9 +100,8 @@ class Admin::EmailController < Admin::AdminController
params.require(:email)
user = User.find_by_username(params[:username])
message, skip_reason = UserNotifications.public_send(:digest, user,
since: params[:last_seen_at]
)
message, skip_reason =
UserNotifications.public_send(:digest, user, since: params[:last_seen_at])
if message
message.to = params[:email]
@@ -134,9 +121,16 @@ class Admin::EmailController < Admin::AdminController
params.require(:to)
# These strings aren't localized; they are sent to an anonymous SMTP user.
if !User.with_email(Email.downcase(params[:from])).exists? && !SiteSetting.enable_staged_users
render json: { reject: true, reason: "Mail from your address is not accepted. Do you have an account here?" }
render json: {
reject: true,
reason: "Mail from your address is not accepted. Do you have an account here?",
}
elsif Email::Receiver.check_address(Email.downcase(params[:to])).nil?
render json: { reject: true, reason: "Mail to this address is not accepted. Check the address and try to send again?" }
render json: {
reject: true,
reason:
"Mail to this address is not accepted. Check the address and try to send again?",
}
else
render json: { reject: false }
end
@@ -157,10 +151,15 @@ class Admin::EmailController < Admin::AdminController
retry_count = 0
begin
Jobs.enqueue(:process_email, mail: email_raw, retry_on_rate_limit: true, source: "handle_mail")
Jobs.enqueue(
:process_email,
mail: email_raw,
retry_on_rate_limit: true,
source: "handle_mail",
)
rescue JSON::GeneratorError, Encoding::UndefinedConversionError => e
if retry_count == 0
email_raw = email_raw.force_encoding('iso-8859-1').encode("UTF-8")
email_raw = email_raw.force_encoding("iso-8859-1").encode("UTF-8")
retry_count += 1
retry
else
@@ -171,7 +170,8 @@ class Admin::EmailController < Admin::AdminController
# TODO: 2022-05-01 Remove this route once all sites have migrated over
# to using the new email_encoded param.
if deprecated_email_param_used
render plain: "warning: the email parameter is deprecated. all POST requests to this route should be sent with a base64 strict encoded email_encoded parameter instead. email has been received and is queued for processing"
render plain:
"warning: the email parameter is deprecated. all POST requests to this route should be sent with a base64 strict encoded email_encoded parameter instead. email has been received and is queued for processing"
else
render plain: "email has been received and is queued for processing"
end
@@ -204,15 +204,15 @@ class Admin::EmailController < Admin::AdminController
end
if incoming_email.nil?
email_local_part, email_domain = SiteSetting.notification_email.split('@')
email_local_part, email_domain = SiteSetting.notification_email.split("@")
bounced_to_address = "#{email_local_part}+verp-#{email_log.bounce_key}@#{email_domain}"
incoming_email = IncomingEmail.find_by(to_addresses: bounced_to_address)
end
# Temporary fix until all old format of emails has been purged via lib/email/cleaner.rb
if incoming_email.nil?
email_local_part, email_domain = SiteSetting.reply_by_email_address.split('@')
subdomain, root_domain, extension = email_domain&.split('.')
email_local_part, email_domain = SiteSetting.reply_by_email_address.split("@")
subdomain, root_domain, extension = email_domain&.split(".")
bounced_to_address = "#{subdomain}+verp-#{email_log.bounce_key}@#{root_domain}.#{extension}"
incoming_email = IncomingEmail.find_by(to_addresses: bounced_to_address)
end
@@ -231,41 +231,61 @@ class Admin::EmailController < Admin::AdminController
def filter_logs(logs, params)
table_name = logs.table_name
logs = logs.includes(:user, post: :topic)
.references(:user)
.order(created_at: :desc)
.offset(params[:offset] || 0)
.limit(50)
logs =
logs
.includes(:user, post: :topic)
.references(:user)
.order(created_at: :desc)
.offset(params[:offset] || 0)
.limit(50)
logs = logs.where("users.username ILIKE ?", "%#{params[:user]}%") if params[:user].present?
logs = logs.where("#{table_name}.to_address ILIKE ?", "%#{params[:address]}%") if params[:address].present?
logs = logs.where("#{table_name}.email_type ILIKE ?", "%#{params[:type]}%") if params[:type].present?
logs = logs.where("#{table_name}.to_address ILIKE ?", "%#{params[:address]}%") if params[
:address
].present?
logs = logs.where("#{table_name}.email_type ILIKE ?", "%#{params[:type]}%") if params[
:type
].present?
if table_name == "email_logs" && params[:smtp_transaction_response].present?
logs = logs.where("#{table_name}.smtp_transaction_response ILIKE ?", "%#{params[:smtp_transaction_response]}%")
logs =
logs.where(
"#{table_name}.smtp_transaction_response ILIKE ?",
"%#{params[:smtp_transaction_response]}%",
)
end
logs
end
def filter_incoming_emails(incoming_emails, params)
incoming_emails = incoming_emails.includes(:user, post: :topic)
.order(created_at: :desc)
.offset(params[:offset] || 0)
.limit(50)
incoming_emails =
incoming_emails
.includes(:user, post: :topic)
.order(created_at: :desc)
.offset(params[:offset] || 0)
.limit(50)
incoming_emails = incoming_emails.where("from_address ILIKE ?", "%#{params[:from]}%") if params[:from].present?
incoming_emails = incoming_emails.where("to_addresses ILIKE :to OR cc_addresses ILIKE :to", to: "%#{params[:to]}%") if params[:to].present?
incoming_emails = incoming_emails.where("subject ILIKE ?", "%#{params[:subject]}%") if params[:subject].present?
incoming_emails = incoming_emails.where("error ILIKE ?", "%#{params[:error]}%") if params[:error].present?
incoming_emails = incoming_emails.where("from_address ILIKE ?", "%#{params[:from]}%") if params[
:from
].present?
incoming_emails =
incoming_emails.where(
"to_addresses ILIKE :to OR cc_addresses ILIKE :to",
to: "%#{params[:to]}%",
) if params[:to].present?
incoming_emails = incoming_emails.where("subject ILIKE ?", "%#{params[:subject]}%") if params[
:subject
].present?
incoming_emails = incoming_emails.where("error ILIKE ?", "%#{params[:error]}%") if params[
:error
].present?
incoming_emails
end
def delivery_settings
action_mailer_settings
.reject { |k, _| k == :password }
.map { |k, v| { name: k, value: v } }
action_mailer_settings.reject { |k, _| k == :password }.map { |k, v| { name: k, value: v } }
end
def delivery_method
@@ -1,70 +1,69 @@
# frozen_string_literal: true
class Admin::EmailTemplatesController < Admin::AdminController
def self.email_keys
@email_keys ||= [
"custom_invite_forum_mailer",
"custom_invite_mailer",
"invite_forum_mailer",
"invite_mailer",
"invite_password_instructions",
"new_version_mailer",
"new_version_mailer_with_notes",
"system_messages.backup_failed",
"system_messages.backup_succeeded",
"system_messages.bulk_invite_failed",
"system_messages.bulk_invite_succeeded",
"system_messages.csv_export_failed",
"system_messages.csv_export_succeeded",
"system_messages.download_remote_images_disabled",
"system_messages.email_error_notification",
"system_messages.email_reject_auto_generated",
"system_messages.email_reject_bad_destination_address",
"system_messages.email_reject_empty",
"system_messages.email_reject_invalid_access",
"system_messages.email_reject_parsing",
"system_messages.email_reject_reply_key",
"system_messages.email_reject_screened_email",
"system_messages.email_reject_topic_closed",
"system_messages.email_reject_topic_not_found",
"system_messages.email_reject_unrecognized_error",
"system_messages.email_reject_user_not_found",
"system_messages.email_revoked",
"system_messages.pending_users_reminder",
"system_messages.post_hidden",
"system_messages.post_hidden_again",
"system_messages.queued_posts_reminder",
"system_messages.restore_failed",
"system_messages.restore_succeeded",
"system_messages.silenced_by_staff",
"system_messages.spam_post_blocked",
"system_messages.too_many_spam_flags",
"system_messages.unsilenced",
"system_messages.user_automatically_silenced",
"system_messages.welcome_invite",
"system_messages.welcome_user",
"system_messages.welcome_staff",
"test_mailer",
"user_notifications.account_created",
"user_notifications.admin_login",
"user_notifications.confirm_new_email",
"user_notifications.email_login",
"user_notifications.forgot_password",
"user_notifications.notify_old_email",
"user_notifications.set_password",
"user_notifications.signup",
"user_notifications.signup_after_approval",
"user_notifications.suspicious_login",
"user_notifications.user_invited_to_private_message_pm",
"user_notifications.user_invited_to_private_message_pm_group",
"user_notifications.user_invited_to_topic",
"user_notifications.user_linked",
"user_notifications.user_mentioned",
"user_notifications.user_posted",
"user_notifications.user_posted_pm",
"user_notifications.user_quoted",
"user_notifications.user_replied",
@email_keys ||= %w[
custom_invite_forum_mailer
custom_invite_mailer
invite_forum_mailer
invite_mailer
invite_password_instructions
new_version_mailer
new_version_mailer_with_notes
system_messages.backup_failed
system_messages.backup_succeeded
system_messages.bulk_invite_failed
system_messages.bulk_invite_succeeded
system_messages.csv_export_failed
system_messages.csv_export_succeeded
system_messages.download_remote_images_disabled
system_messages.email_error_notification
system_messages.email_reject_auto_generated
system_messages.email_reject_bad_destination_address
system_messages.email_reject_empty
system_messages.email_reject_invalid_access
system_messages.email_reject_parsing
system_messages.email_reject_reply_key
system_messages.email_reject_screened_email
system_messages.email_reject_topic_closed
system_messages.email_reject_topic_not_found
system_messages.email_reject_unrecognized_error
system_messages.email_reject_user_not_found
system_messages.email_revoked
system_messages.pending_users_reminder
system_messages.post_hidden
system_messages.post_hidden_again
system_messages.queued_posts_reminder
system_messages.restore_failed
system_messages.restore_succeeded
system_messages.silenced_by_staff
system_messages.spam_post_blocked
system_messages.too_many_spam_flags
system_messages.unsilenced
system_messages.user_automatically_silenced
system_messages.welcome_invite
system_messages.welcome_user
system_messages.welcome_staff
test_mailer
user_notifications.account_created
user_notifications.admin_login
user_notifications.confirm_new_email
user_notifications.email_login
user_notifications.forgot_password
user_notifications.notify_old_email
user_notifications.set_password
user_notifications.signup
user_notifications.signup_after_approval
user_notifications.suspicious_login
user_notifications.user_invited_to_private_message_pm
user_notifications.user_invited_to_private_message_pm_group
user_notifications.user_invited_to_topic
user_notifications.user_linked
user_notifications.user_mentioned
user_notifications.user_posted
user_notifications.user_posted_pm
user_notifications.user_quoted
user_notifications.user_replied
]
end
@@ -91,9 +90,18 @@ class Admin::EmailTemplatesController < Admin::AdminController
log_site_text_change(subject_result)
log_site_text_change(body_result)
render_serialized(key, AdminEmailTemplateSerializer, root: 'email_template', rest_serializer: true)
render_serialized(
key,
AdminEmailTemplateSerializer,
root: "email_template",
rest_serializer: true,
)
else
TranslationOverride.upsert!(I18n.locale, "#{key}.subject_template", subject_result[:old_value])
TranslationOverride.upsert!(
I18n.locale,
"#{key}.subject_template",
subject_result[:old_value],
)
TranslationOverride.upsert!(I18n.locale, "#{key}.text_body_template", body_result[:old_value])
render_json_error(error_messages)
@@ -105,11 +113,22 @@ class Admin::EmailTemplatesController < Admin::AdminController
raise Discourse::NotFound unless self.class.email_keys.include?(params[:id])
revert_and_log("#{key}.subject_template", "#{key}.text_body_template")
render_serialized(key, AdminEmailTemplateSerializer, root: 'email_template', rest_serializer: true)
render_serialized(
key,
AdminEmailTemplateSerializer,
root: "email_template",
rest_serializer: true,
)
end
def index
render_serialized(self.class.email_keys, AdminEmailTemplateSerializer, root: 'email_templates', rest_serializer: true, overridden_keys: overridden_keys)
render_serialized(
self.class.email_keys,
AdminEmailTemplateSerializer,
root: "email_templates",
rest_serializer: true,
overridden_keys: overridden_keys,
)
end
private
@@ -121,11 +140,7 @@ class Admin::EmailTemplatesController < Admin::AdminController
translation_override = TranslationOverride.upsert!(I18n.locale, key, value)
end
{
key: key,
old_value: old_value,
error_messages: translation_override&.errors&.full_messages
}
{ key: key, old_value: old_value, error_messages: translation_override&.errors&.full_messages }
end
def revert_and_log(*keys)
@@ -144,7 +159,10 @@ class Admin::EmailTemplatesController < Admin::AdminController
def log_site_text_change(update_result)
new_value = I18n.t(update_result[:key])
StaffActionLogger.new(current_user).log_site_text_change(
update_result[:key], new_value, update_result[:old_value])
update_result[:key],
new_value,
update_result[:old_value],
)
end
def format_error_message(update_result, attribute_key)
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::EmbeddableHostsController < Admin::AdminController
def create
save_host(EmbeddableHost.new, :create)
end
@@ -14,7 +13,10 @@ class Admin::EmbeddableHostsController < Admin::AdminController
def destroy
host = EmbeddableHost.where(id: params[:id]).first
host.destroy
StaffActionLogger.new(current_user).log_embeddable_host(host, UserHistory.actions[:embeddable_host_destroy])
StaffActionLogger.new(current_user).log_embeddable_host(
host,
UserHistory.actions[:embeddable_host_destroy],
)
render json: success_json
end
@@ -23,17 +25,25 @@ class Admin::EmbeddableHostsController < Admin::AdminController
def save_host(host, action)
host.host = params[:embeddable_host][:host]
host.allowed_paths = params[:embeddable_host][:allowed_paths]
host.class_name = params[:embeddable_host][:class_name]
host.class_name = params[:embeddable_host][:class_name]
host.category_id = params[:embeddable_host][:category_id]
host.category_id = SiteSetting.uncategorized_category_id if host.category_id.blank?
if host.save
changes = host.saved_changes if action == :update
StaffActionLogger.new(current_user).log_embeddable_host(host, UserHistory.actions[:"embeddable_host_#{action}"], changes: changes)
render_serialized(host, EmbeddableHostSerializer, root: 'embeddable_host', rest_serializer: true)
StaffActionLogger.new(current_user).log_embeddable_host(
host,
UserHistory.actions[:"embeddable_host_#{action}"],
changes: changes,
)
render_serialized(
host,
EmbeddableHostSerializer,
root: "embeddable_host",
rest_serializer: true,
)
else
render_json_error(host)
end
end
end
@@ -1,25 +1,22 @@
# frozen_string_literal: true
class Admin::EmbeddingController < Admin::AdminController
before_action :fetch_embedding
def show
render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true)
render_serialized(@embedding, EmbeddingSerializer, root: "embedding", rest_serializer: true)
end
def update
if params[:embedding][:embed_by_username].blank?
return render_json_error(I18n.t('site_settings.embed_username_required'))
return render_json_error(I18n.t("site_settings.embed_username_required"))
end
Embedding.settings.each do |s|
@embedding.public_send("#{s}=", params[:embedding][s])
end
Embedding.settings.each { |s| @embedding.public_send("#{s}=", params[:embedding][s]) }
if @embedding.save
fetch_embedding
render_serialized(@embedding, EmbeddingSerializer, root: 'embedding', rest_serializer: true)
render_serialized(@embedding, EmbeddingSerializer, root: "embedding", rest_serializer: true)
else
render_json_error(@embedding)
end
+5 -10
View File
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::EmojisController < Admin::AdminController
def index
render_serialized(Emoji.custom, EmojiSerializer, root: false)
end
@@ -17,15 +16,12 @@ class Admin::EmojisController < Admin::AdminController
hijack do
# fix the name
name = File.basename(name, ".*")
name = name.gsub(/[^a-z0-9]+/i, '_')
.gsub(/_{2,}/, '_')
.downcase
name = name.gsub(/[^a-z0-9]+/i, "_").gsub(/_{2,}/, "_").downcase
upload = UploadCreator.new(
file.tempfile,
file.original_filename,
type: 'custom_emoji'
).create_for(current_user.id)
upload =
UploadCreator.new(file.tempfile, file.original_filename, type: "custom_emoji").create_for(
current_user.id,
)
good = true
@@ -61,5 +57,4 @@ class Admin::EmojisController < Admin::AdminController
render json: success_json
end
end
+32 -42
View File
@@ -7,27 +7,19 @@ class Admin::GroupsController < Admin::StaffController
attributes = group_params.to_h.except(:owner_usernames, :usernames)
group = Group.new(attributes)
unless group_params[:allow_membership_requests]
group.membership_request_template = nil
end
group.membership_request_template = nil unless group_params[:allow_membership_requests]
if group_params[:owner_usernames].present?
owner_ids = User.where(
username: group_params[:owner_usernames].split(",")
).pluck(:id)
owner_ids = User.where(username: group_params[:owner_usernames].split(",")).pluck(:id)
owner_ids.each do |user_id|
group.group_users.build(user_id: user_id, owner: true)
end
owner_ids.each { |user_id| group.group_users.build(user_id: user_id, owner: true) }
end
if group_params[:usernames].present?
user_ids = User.where(username: group_params[:usernames].split(",")).pluck(:id)
user_ids -= owner_ids if owner_ids
user_ids.each do |user_id|
group.group_users.build(user_id: user_id)
end
user_ids.each { |user_id| group.group_users.build(user_id: user_id) }
end
if group.save
@@ -140,45 +132,43 @@ class Admin::GroupsController < Admin::StaffController
protected
def can_not_modify_automatic
render_json_error(I18n.t('groups.errors.can_not_modify_automatic'))
render_json_error(I18n.t("groups.errors.can_not_modify_automatic"))
end
private
def group_params
permitted = [
:name,
:mentionable_level,
:messageable_level,
:visibility_level,
:members_visibility_level,
:automatic_membership_email_domains,
:title,
:primary_group,
:grant_trust_level,
:incoming_email,
:flair_icon,
:flair_upload_id,
:flair_bg_color,
:flair_color,
:bio_raw,
:public_admission,
:public_exit,
:allow_membership_requests,
:full_name,
:default_notification_level,
:membership_request_template,
:owner_usernames,
:usernames,
:publish_read_state,
:notify_users
permitted = %i[
name
mentionable_level
messageable_level
visibility_level
members_visibility_level
automatic_membership_email_domains
title
primary_group
grant_trust_level
incoming_email
flair_icon
flair_upload_id
flair_bg_color
flair_color
bio_raw
public_admission
public_exit
allow_membership_requests
full_name
default_notification_level
membership_request_template
owner_usernames
usernames
publish_read_state
notify_users
]
custom_fields = DiscoursePluginRegistry.editable_group_custom_fields
permitted << { custom_fields: custom_fields } unless custom_fields.blank?
if guardian.can_associate_groups?
permitted << { associated_group_ids: [] }
end
permitted << { associated_group_ids: [] } if guardian.can_associate_groups?
permitted = permitted | DiscoursePluginRegistry.group_params
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::ImpersonateController < Admin::AdminController
def create
params.require(:username_or_email)
@@ -18,5 +17,4 @@ class Admin::ImpersonateController < Admin::AdminController
render body: nil
end
end
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::PermalinksController < Admin::AdminController
before_action :fetch_permalink, only: [:destroy]
def index
@@ -20,7 +19,8 @@ class Admin::PermalinksController < Admin::AdminController
params[:permalink_type_value] = Tag.find_by_name(params[:permalink_type_value])&.id
end
permalink = Permalink.new(:url => params[:url], params[:permalink_type] => params[:permalink_type_value])
permalink =
Permalink.new(:url => params[:url], params[:permalink_type] => params[:permalink_type_value])
if permalink.save
render_serialized(permalink, PermalinkSerializer)
else
@@ -38,5 +38,4 @@ class Admin::PermalinksController < Admin::AdminController
def fetch_permalink
@permalink = Permalink.find(params[:id])
end
end
+1 -3
View File
@@ -1,9 +1,7 @@
# frozen_string_literal: true
class Admin::PluginsController < Admin::StaffController
def index
render_serialized(Discourse.visible_plugins, AdminPluginSerializer, root: 'plugins')
render_serialized(Discourse.visible_plugins, AdminPluginSerializer, root: "plugins")
end
end
+44 -46
View File
@@ -2,24 +2,28 @@
class Admin::ReportsController < Admin::StaffController
def index
reports_methods = ['page_view_total_reqs'] +
ApplicationRequest.req_types.keys
.select { |r| r =~ /^page_view_/ && r !~ /mobile/ }
.map { |r| r + "_reqs" } +
Report.singleton_methods.grep(/^report_(?!about|storage_stats)/)
reports_methods =
["page_view_total_reqs"] +
ApplicationRequest
.req_types
.keys
.select { |r| r =~ /^page_view_/ && r !~ /mobile/ }
.map { |r| r + "_reqs" } +
Report.singleton_methods.grep(/^report_(?!about|storage_stats)/)
reports = reports_methods.map do |name|
type = name.to_s.gsub('report_', '')
description = I18n.t("reports.#{type}.description", default: '')
description_link = I18n.t("reports.#{type}.description_link", default: '')
reports =
reports_methods.map do |name|
type = name.to_s.gsub("report_", "")
description = I18n.t("reports.#{type}.description", default: "")
description_link = I18n.t("reports.#{type}.description_link", default: "")
{
type: type,
title: I18n.t("reports.#{type}.title"),
description: description.presence ? description : nil,
description_link: description_link.presence ? description_link : nil
}
end
{
type: type,
title: I18n.t("reports.#{type}.title"),
description: description.presence ? description : nil,
description_link: description_link.presence ? description_link : nil,
}
end
render_json_dump(reports: reports.sort_by { |report| report[:title] })
end
@@ -32,18 +36,14 @@ class Admin::ReportsController < Admin::StaffController
args = parse_params(report_params)
report = nil
if (report_params[:cache])
report = Report.find_cached(report_type, args)
end
report = Report.find_cached(report_type, args) if (report_params[:cache])
if report
reports << report
else
report = Report.find(report_type, args)
if (report_params[:cache]) && report
Report.cache(report)
end
Report.cache(report) if (report_params[:cache]) && report
if report.blank?
report = Report._get(report_type, args)
@@ -66,22 +66,16 @@ class Admin::ReportsController < Admin::StaffController
args = parse_params(params)
report = nil
if (params[:cache])
report = Report.find_cached(report_type, args)
end
report = Report.find_cached(report_type, args) if (params[:cache])
if report
return render_json_dump(report: report)
end
return render_json_dump(report: report) if report
hijack do
report = Report.find(report_type, args)
raise Discourse::NotFound if report.blank?
if (params[:cache])
Report.cache(report)
end
Report.cache(report) if (params[:cache])
render_json_dump(report: report)
end
@@ -91,16 +85,28 @@ class Admin::ReportsController < Admin::StaffController
def parse_params(report_params)
begin
start_date = (report_params[:start_date].present? ? Time.parse(report_params[:start_date]).to_date : 1.days.ago).beginning_of_day
end_date = (report_params[:end_date].present? ? Time.parse(report_params[:end_date]).to_date : start_date + 30.days).end_of_day
start_date =
(
if report_params[:start_date].present?
Time.parse(report_params[:start_date]).to_date
else
1.days.ago
end
).beginning_of_day
end_date =
(
if report_params[:end_date].present?
Time.parse(report_params[:end_date]).to_date
else
start_date + 30.days
end
).end_of_day
rescue ArgumentError => e
raise Discourse::InvalidParameters.new(e.message)
end
facets = nil
if Array === report_params[:facets]
facets = report_params[:facets].map { |s| s.to_s.to_sym }
end
facets = report_params[:facets].map { |s| s.to_s.to_sym } if Array === report_params[:facets]
limit = nil
if report_params.has_key?(:limit) && report_params[:limit].to_i > 0
@@ -108,16 +114,8 @@ class Admin::ReportsController < Admin::StaffController
end
filters = nil
if report_params.has_key?(:filters)
filters = report_params[:filters]
end
filters = report_params[:filters] if report_params.has_key?(:filters)
{
start_date: start_date,
end_date: end_date,
filters: filters,
facets: facets,
limit: limit
}
{ start_date: start_date, end_date: end_date, filters: filters, facets: facets, limit: limit }
end
end
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::RobotsTxtController < Admin::AdminController
def show
render json: { robots_txt: current_robots_txt, overridden: @overridden }
end
@@ -1,9 +1,8 @@
# frozen_string_literal: true
class Admin::ScreenedEmailsController < Admin::StaffController
def index
screened_emails = ScreenedEmail.limit(200).order('last_match_at desc').to_a
screened_emails = ScreenedEmail.limit(200).order("last_match_at desc").to_a
render_serialized(screened_emails, ScreenedEmailSerializer)
end
@@ -12,5 +11,4 @@ class Admin::ScreenedEmailsController < Admin::StaffController
screen.destroy!
render json: success_json
end
end
@@ -1,16 +1,19 @@
# frozen_string_literal: true
class Admin::ScreenedIpAddressesController < Admin::StaffController
before_action :fetch_screened_ip_address, only: [:update, :destroy]
before_action :fetch_screened_ip_address, only: %i[update destroy]
def index
filter = params[:filter]
filter = IPAddr.handle_wildcards(filter)
screened_ip_addresses = ScreenedIpAddress
screened_ip_addresses = screened_ip_addresses.where("cidr :filter >>= ip_address OR ip_address >>= cidr :filter", filter: filter) if filter.present?
screened_ip_addresses = screened_ip_addresses.limit(200).order('match_count desc')
screened_ip_addresses =
screened_ip_addresses.where(
"cidr :filter >>= ip_address OR ip_address >>= cidr :filter",
filter: filter,
) if filter.present?
screened_ip_addresses = screened_ip_addresses.limit(200).order("match_count desc")
begin
screened_ip_addresses = screened_ip_addresses.to_a
@@ -54,5 +57,4 @@ class Admin::ScreenedIpAddressesController < Admin::StaffController
def fetch_screened_ip_address
@screened_ip_address = ScreenedIpAddress.find(params[:id])
end
end
@@ -1,10 +1,15 @@
# frozen_string_literal: true
class Admin::ScreenedUrlsController < Admin::StaffController
def index
screened_urls = ScreenedUrl.select("domain, sum(match_count) as match_count, max(last_match_at) as last_match_at, min(created_at) as created_at").group(:domain).order('last_match_at DESC').to_a
screened_urls =
ScreenedUrl
.select(
"domain, sum(match_count) as match_count, max(last_match_at) as last_match_at, min(created_at) as created_at",
)
.group(:domain)
.order("last_match_at DESC")
.to_a
render_serialized(screened_urls, GroupedScreenedUrlSerializer)
end
end
@@ -1,7 +1,6 @@
# frozen_string_literal: true
class Admin::SearchLogsController < Admin::StaffController
def index
period = params[:period] || "all"
search_type = params[:search_type] || "all"
@@ -22,5 +21,4 @@ class Admin::SearchLogsController < Admin::StaffController
details[:search_result] = serialize_data(result, GroupedSearchResultSerializer, result: result)
render_json_dump(term: details)
end
end
+107 -51
View File
@@ -6,10 +6,7 @@ class Admin::SiteSettingsController < Admin::AdminController
end
def index
render_json_dump(
site_settings: SiteSetting.all_settings,
diags: SiteSetting.diags
)
render_json_dump(site_settings: SiteSetting.all_settings, diags: SiteSetting.diags)
end
def update
@@ -18,15 +15,17 @@ class Admin::SiteSettingsController < Admin::AdminController
value = params[id]
value.strip! if value.is_a?(String)
new_setting_name = SiteSettings::DeprecatedSettings::SETTINGS.find do |old_name, new_name, override, _|
if old_name == id
if !override
raise Discourse::InvalidParameters, "You cannot change this site setting because it is deprecated, use #{new_name} instead."
end
new_setting_name =
SiteSettings::DeprecatedSettings::SETTINGS.find do |old_name, new_name, override, _|
if old_name == id
if !override
raise Discourse::InvalidParameters,
"You cannot change this site setting because it is deprecated, use #{new_name} instead."
end
break new_name
break new_name
end
end
end
id = new_setting_name if new_setting_name
@@ -36,9 +35,7 @@ class Admin::SiteSettingsController < Admin::AdminController
value = Upload.get_from_urls(value.split("|")).to_a
end
if SiteSetting.type_supervisor.get_type(id) == :upload
value = Upload.get_from_url(value) || ""
end
value = Upload.get_from_url(value) || "" if SiteSetting.type_supervisor.get_type(id) == :upload
update_existing_users = params[:update_existing_user].present?
previous_value = value_or_default(SiteSetting.public_send(id)) if update_existing_users
@@ -68,22 +65,40 @@ class Admin::SiteSettingsController < Admin::AdminController
notification_level = category_notification_level(id)
categories_to_unwatch = previous_category_ids - new_category_ids
CategoryUser.where(category_id: categories_to_unwatch, notification_level: notification_level).delete_all
CategoryUser.where(
category_id: categories_to_unwatch,
notification_level: notification_level,
).delete_all
TopicUser
.joins(:topic)
.where(notification_level: TopicUser.notification_levels[:watching],
notifications_reason_id: TopicUser.notification_reasons[:auto_watch_category],
topics: { category_id: categories_to_unwatch })
.where(
notification_level: TopicUser.notification_levels[:watching],
notifications_reason_id: TopicUser.notification_reasons[:auto_watch_category],
topics: {
category_id: categories_to_unwatch,
},
)
.update_all(notification_level: TopicUser.notification_levels[:regular])
(new_category_ids - previous_category_ids).each do |category_id|
skip_user_ids = CategoryUser.where(category_id: category_id).pluck(:user_id)
User.real.where(staged: false).where.not(id: skip_user_ids).select(:id).find_in_batches do |users|
category_users = []
users.each { |user| category_users << { category_id: category_id, user_id: user.id, notification_level: notification_level } }
CategoryUser.insert_all!(category_users)
end
User
.real
.where(staged: false)
.where.not(id: skip_user_ids)
.select(:id)
.find_in_batches do |users|
category_users = []
users.each do |user|
category_users << {
category_id: category_id,
user_id: user.id,
notification_level: notification_level,
}
end
CategoryUser.insert_all!(category_users)
end
end
elsif id.start_with?("default_tags_")
previous_tag_ids = Tag.where(name: previous_value.split("|")).pluck(:id)
@@ -92,19 +107,40 @@ class Admin::SiteSettingsController < Admin::AdminController
notification_level = tag_notification_level(id)
TagUser.where(tag_id: (previous_tag_ids - new_tag_ids), notification_level: notification_level).delete_all
TagUser.where(
tag_id: (previous_tag_ids - new_tag_ids),
notification_level: notification_level,
).delete_all
(new_tag_ids - previous_tag_ids).each do |tag_id|
skip_user_ids = TagUser.where(tag_id: tag_id).pluck(:user_id)
User.real.where(staged: false).where.not(id: skip_user_ids).select(:id).find_in_batches do |users|
tag_users = []
users.each { |user| tag_users << { tag_id: tag_id, user_id: user.id, notification_level: notification_level, created_at: now, updated_at: now } }
TagUser.insert_all!(tag_users)
end
User
.real
.where(staged: false)
.where.not(id: skip_user_ids)
.select(:id)
.find_in_batches do |users|
tag_users = []
users.each do |user|
tag_users << {
tag_id: tag_id,
user_id: user.id,
notification_level: notification_level,
created_at: now,
updated_at: now,
}
end
TagUser.insert_all!(tag_users)
end
end
elsif is_sidebar_default_setting?(id)
Jobs.enqueue(:backfill_sidebar_site_settings, setting_name: id, previous_value: previous_value, new_value: new_value)
Jobs.enqueue(
:backfill_sidebar_site_settings,
setting_name: id,
previous_value: previous_value,
new_value: new_value,
)
end
end
@@ -135,15 +171,26 @@ class Admin::SiteSettingsController < Admin::AdminController
notification_level = category_notification_level(id)
user_ids = CategoryUser.where(category_id: previous_category_ids - new_category_ids, notification_level: notification_level).distinct.pluck(:user_id)
user_ids += User
.real
.joins("CROSS JOIN categories c")
.joins("LEFT JOIN category_users cu ON users.id = cu.user_id AND c.id = cu.category_id")
.where(staged: false)
.where("c.id IN (?) AND cu.notification_level IS NULL", new_category_ids - previous_category_ids)
.distinct
.pluck("users.id")
user_ids =
CategoryUser
.where(
category_id: previous_category_ids - new_category_ids,
notification_level: notification_level,
)
.distinct
.pluck(:user_id)
user_ids +=
User
.real
.joins("CROSS JOIN categories c")
.joins("LEFT JOIN category_users cu ON users.id = cu.user_id AND c.id = cu.category_id")
.where(staged: false)
.where(
"c.id IN (?) AND cu.notification_level IS NULL",
new_category_ids - previous_category_ids,
)
.distinct
.pluck("users.id")
json[:user_count] = user_ids.uniq.count
elsif id.start_with?("default_tags_")
@@ -152,19 +199,28 @@ class Admin::SiteSettingsController < Admin::AdminController
notification_level = tag_notification_level(id)
user_ids = TagUser.where(tag_id: previous_tag_ids - new_tag_ids, notification_level: notification_level).distinct.pluck(:user_id)
user_ids += User
.real
.joins("CROSS JOIN tags t")
.joins("LEFT JOIN tag_users tu ON users.id = tu.user_id AND t.id = tu.tag_id")
.where(staged: false)
.where("t.id IN (?) AND tu.notification_level IS NULL", new_tag_ids - previous_tag_ids)
.distinct
.pluck("users.id")
user_ids =
TagUser
.where(tag_id: previous_tag_ids - new_tag_ids, notification_level: notification_level)
.distinct
.pluck(:user_id)
user_ids +=
User
.real
.joins("CROSS JOIN tags t")
.joins("LEFT JOIN tag_users tu ON users.id = tu.user_id AND t.id = tu.tag_id")
.where(staged: false)
.where("t.id IN (?) AND tu.notification_level IS NULL", new_tag_ids - previous_tag_ids)
.distinct
.pluck("users.id")
json[:user_count] = user_ids.uniq.count
elsif is_sidebar_default_setting?(id)
json[:user_count] = SidebarSiteSettingsBackfiller.new(id, previous_value: previous_value, new_value: new_value).number_of_users_to_backfill
json[:user_count] = SidebarSiteSettingsBackfiller.new(
id,
previous_value: previous_value,
new_value: new_value,
).number_of_users_to_backfill
end
render json: json
@@ -173,7 +229,7 @@ class Admin::SiteSettingsController < Admin::AdminController
private
def is_sidebar_default_setting?(setting_name)
%w{default_sidebar_categories default_sidebar_tags}.include?(setting_name.to_s)
%w[default_sidebar_categories default_sidebar_tags].include?(setting_name.to_s)
end
def user_options
@@ -198,7 +254,7 @@ class Admin::SiteSettingsController < Admin::AdminController
default_include_tl0_in_digests: "include_tl0_in_digests",
default_text_size: "text_size_key",
default_title_count_mode: "title_count_mode_key",
default_hide_profile_and_presence: "hide_profile_and_presence"
default_hide_profile_and_presence: "hide_profile_and_presence",
}
end
+38 -34
View File
@@ -1,22 +1,25 @@
# frozen_string_literal: true
class Admin::SiteTextsController < Admin::AdminController
def self.preferred_keys
['system_messages.usage_tips.text_body_template',
'education.new-topic',
'education.new-reply',
'login_required.welcome_message']
%w[
system_messages.usage_tips.text_body_template
education.new-topic
education.new-reply
login_required.welcome_message
]
end
def self.restricted_keys
['user_notifications.confirm_old_email.title',
'user_notifications.confirm_old_email.subject_template',
'user_notifications.confirm_old_email.text_body_template']
%w[
user_notifications.confirm_old_email.title
user_notifications.confirm_old_email.subject_template
user_notifications.confirm_old_email.text_body_template
]
end
def index
overridden = params[:overridden] == 'true'
overridden = params[:overridden] == "true"
extras = {}
query = params[:q] || ""
@@ -61,7 +64,7 @@ class Admin::SiteTextsController < Admin::AdminController
render_serialized(
results[first..last - 1],
SiteTextSerializer,
root: 'site_texts',
root: "site_texts",
rest_serializer: true,
extras: extras,
overridden_keys: overridden,
@@ -71,7 +74,7 @@ class Admin::SiteTextsController < Admin::AdminController
def show
locale = fetch_locale(params[:locale])
site_text = find_site_text(locale)
render_serialized(site_text, SiteTextSerializer, root: 'site_text', rest_serializer: true)
render_serialized(site_text, SiteTextSerializer, root: "site_text", rest_serializer: true)
end
def update
@@ -92,14 +95,14 @@ class Admin::SiteTextsController < Admin::AdminController
:bulk_user_title_update,
new_title: value,
granted_badge_id: system_badge_id,
action: Jobs::BulkUserTitleUpdate::UPDATE_ACTION
action: Jobs::BulkUserTitleUpdate::UPDATE_ACTION,
)
end
render_serialized(site_text, SiteTextSerializer, root: 'site_text', rest_serializer: true)
render_serialized(site_text, SiteTextSerializer, root: "site_text", rest_serializer: true)
else
render json: failed_json.merge(
message: translation_override.errors.full_messages.join("\n\n")
), status: 422
render json:
failed_json.merge(message: translation_override.errors.full_messages.join("\n\n")),
status: 422
end
end
@@ -118,31 +121,27 @@ class Admin::SiteTextsController < Admin::AdminController
Jobs.enqueue(
:bulk_user_title_update,
granted_badge_id: system_badge_id,
action: Jobs::BulkUserTitleUpdate::RESET_ACTION
action: Jobs::BulkUserTitleUpdate::RESET_ACTION,
)
end
render_serialized(site_text, SiteTextSerializer, root: 'site_text', rest_serializer: true)
render_serialized(site_text, SiteTextSerializer, root: "site_text", rest_serializer: true)
end
def get_reseed_options
render_json_dump(
categories: SeedData::Categories.with_default_locale.reseed_options,
topics: SeedData::Topics.with_default_locale.reseed_options
topics: SeedData::Topics.with_default_locale.reseed_options,
)
end
def reseed
hijack do
if params[:category_ids].present?
SeedData::Categories.with_default_locale.update(
site_setting_names: params[:category_ids]
)
SeedData::Categories.with_default_locale.update(site_setting_names: params[:category_ids])
end
if params[:topic_ids].present?
SeedData::Topics.with_default_locale.update(
site_setting_names: params[:topic_ids]
)
SeedData::Topics.with_default_locale.update(site_setting_names: params[:topic_ids])
end
render json: success_json
@@ -152,8 +151,8 @@ class Admin::SiteTextsController < Admin::AdminController
protected
def is_badge_title?(id = "")
badge_parts = id.split('.')
badge_parts[0] == 'badges' && badge_parts[2] == 'name'
badge_parts = id.split(".")
badge_parts[0] == "badges" && badge_parts[2] == "name"
end
def record_for(key:, value: nil, locale:)
@@ -165,10 +164,15 @@ class Admin::SiteTextsController < Admin::AdminController
def find_site_text(locale)
if self.class.restricted_keys.include?(params[:id])
raise Discourse::InvalidAccess.new(nil, nil, custom_message: 'email_template_cant_be_modified')
raise Discourse::InvalidAccess.new(
nil,
nil,
custom_message: "email_template_cant_be_modified",
)
end
if I18n.exists?(params[:id], locale) || TranslationOverride.exists?(locale: locale, translation_key: params[:id])
if I18n.exists?(params[:id], locale) ||
TranslationOverride.exists?(locale: locale, translation_key: params[:id])
return record_for(key: params[:id], locale: locale)
end
@@ -182,9 +186,7 @@ class Admin::SiteTextsController < Admin::AdminController
def find_translations(query, overridden, locale)
translations = Hash.new { |hash, key| hash[key] = {} }
search_results = I18n.with_locale(locale) do
I18n.search(query, only_overridden: overridden)
end
search_results = I18n.with_locale(locale) { I18n.search(query, only_overridden: overridden) }
search_results.each do |key, value|
if PLURALIZED_REGEX.match(key)
@@ -205,7 +207,9 @@ class Admin::SiteTextsController < Admin::AdminController
plural_value = plural[1]
results << record_for(
key: "#{key}.#{plural_key}", value: plural_value, locale: plural.last
key: "#{key}.#{plural_key}",
value: plural_value,
locale: plural.last,
)
end
else
@@ -218,7 +222,7 @@ class Admin::SiteTextsController < Admin::AdminController
def fix_plural_keys(key, value, locale)
value = value.with_indifferent_access
plural_keys = I18n.with_locale(locale) { I18n.t('i18n.plural.keys') }
plural_keys = I18n.with_locale(locale) { I18n.t("i18n.plural.keys") }
return value if value.keys.size == plural_keys.size && plural_keys.all? { |k| value.key?(k) }
fallback_value = I18n.t(key, locale: :en, default: {})
@@ -1,9 +1,8 @@
# frozen_string_literal: true
class Admin::StaffActionLogsController < Admin::StaffController
def index
filters = params.slice(*UserHistory.staff_filters + [:page, :limit])
filters = params.slice(*UserHistory.staff_filters + %i[page limit])
page = (params[:page] || 0).to_i
page_size = (params[:limit] || 200).to_i.clamp(1, 200)
@@ -20,8 +19,8 @@ class Admin::StaffActionLogsController < Admin::StaffController
total_rows_staff_action_logs: count,
load_more_staff_action_logs: admin_staff_action_logs_path(load_more_params),
extras: {
user_history_actions: staff_available_actions
}
user_history_actions: staff_available_actions,
},
)
end
@@ -37,16 +36,10 @@ class Admin::StaffActionLogsController < Admin::StaffController
output = +"<h2>#{CGI.escapeHTML(cur&.dig("name").to_s)}</h2><p></p>"
diff_fields["name"] = {
prev: prev&.dig("name").to_s,
cur: cur&.dig("name").to_s,
}
diff_fields["name"] = { prev: prev&.dig("name").to_s, cur: cur&.dig("name").to_s }
["default", "user_selectable"].each do |f|
diff_fields[f] = {
prev: (!!prev&.dig(f)).to_s,
cur: (!!cur&.dig(f)).to_s
}
%w[default user_selectable].each do |f|
diff_fields[f] = { prev: (!!prev&.dig(f)).to_s, cur: (!!cur&.dig(f)).to_s }
end
diff_fields["color scheme"] = {
@@ -54,10 +47,7 @@ class Admin::StaffActionLogsController < Admin::StaffController
cur: cur&.dig("color_scheme", "name").to_s,
}
diff_fields["included themes"] = {
prev: child_themes(prev),
cur: child_themes(cur)
}
diff_fields["included themes"] = { prev: child_themes(prev), cur: child_themes(cur) }
load_diff(diff_fields, :cur, cur)
load_diff(diff_fields, :prev, prev)
@@ -94,10 +84,7 @@ class Admin::StaffActionLogsController < Admin::StaffController
def staff_available_actions
UserHistory.staff_actions.sort.map do |name|
{
id: name,
action_id: UserHistory.actions[name] || UserHistory.actions[:custom_staff],
}
{ id: name, action_id: UserHistory.actions[name] || UserHistory.actions[:custom_staff] }
end
end
end
+71 -66
View File
@@ -1,10 +1,9 @@
# frozen_string_literal: true
require 'base64'
require "base64"
class Admin::ThemesController < Admin::AdminController
skip_before_action :check_xhr, only: [:show, :preview, :export]
skip_before_action :check_xhr, only: %i[show preview export]
before_action :ensure_admin
def preview
@@ -15,7 +14,6 @@ class Admin::ThemesController < Admin::AdminController
end
def upload_asset
ban_in_allowlist_mode!
path = params[:file].path
@@ -34,32 +32,30 @@ class Admin::ThemesController < Admin::AdminController
end
def generate_key_pair
require 'sshkey'
require "sshkey"
k = SSHKey.generate
Discourse.redis.setex("ssh_key_#{k.ssh_public_key}", 1.hour, k.private_key)
render json: { public_key: k.ssh_public_key }
end
THEME_CONTENT_TYPES ||= %w{
THEME_CONTENT_TYPES ||= %w[
application/gzip
application/x-gzip
application/x-zip-compressed
application/zip
}
]
def import
@theme = nil
if params[:theme] && params[:theme].content_type == "application/json"
ban_in_allowlist_mode!
# .dcstyle.json import. Deprecated, but still available to allow conversion
json = JSON::parse(params[:theme].read)
theme = json['theme']
json = JSON.parse(params[:theme].read)
theme = json["theme"]
@theme = Theme.new(name: theme["name"], user_id: theme_user.id, auto_update: false)
theme["theme_fields"]&.each do |field|
if field["raw_upload"]
begin
tmp = Tempfile.new
@@ -79,7 +75,7 @@ class Admin::ThemesController < Admin::AdminController
name: field["name"],
value: field["value"],
type_id: field["type_id"],
upload_id: field["upload_id"]
upload_id: field["upload_id"],
)
end
@@ -93,17 +89,22 @@ class Admin::ThemesController < Admin::AdminController
begin
guardian.ensure_allowed_theme_repo_import!(remote.strip)
rescue Discourse::InvalidAccess
render_json_error I18n.t("themes.import_error.not_allowed_theme", { repo: remote.strip }), status: :forbidden
render_json_error I18n.t("themes.import_error.not_allowed_theme", { repo: remote.strip }),
status: :forbidden
return
end
hijack do
begin
branch = params[:branch] ? params[:branch] : nil
private_key = params[:public_key] ? Discourse.redis.get("ssh_key_#{params[:public_key]}") : nil
return render_json_error I18n.t("themes.import_error.ssh_key_gone") if params[:public_key].present? && private_key.blank?
private_key =
params[:public_key] ? Discourse.redis.get("ssh_key_#{params[:public_key]}") : nil
if params[:public_key].present? && private_key.blank?
return render_json_error I18n.t("themes.import_error.ssh_key_gone")
end
@theme = RemoteTheme.import_theme(remote, theme_user, private_key: private_key, branch: branch)
@theme =
RemoteTheme.import_theme(remote, theme_user, private_key: private_key, branch: branch)
render json: @theme, status: :created
rescue RemoteTheme::ImportError => e
if params[:force]
@@ -125,8 +126,8 @@ class Admin::ThemesController < Admin::AdminController
end
end
end
elsif params[:bundle] || (params[:theme] && THEME_CONTENT_TYPES.include?(params[:theme].content_type))
elsif params[:bundle] ||
(params[:theme] && THEME_CONTENT_TYPES.include?(params[:theme].content_type))
ban_in_allowlist_mode!
# params[:bundle] used by theme CLI. params[:theme] used by admin UI
@@ -135,21 +136,23 @@ class Admin::ThemesController < Admin::AdminController
update_components = params[:components]
match_theme_by_name = !!params[:bundle] && !params.key?(:theme_id) # Old theme CLI behavior, match by name. Remove Jan 2020
begin
@theme = RemoteTheme.update_zipped_theme(
bundle.path,
bundle.original_filename,
match_theme: match_theme_by_name,
user: theme_user,
theme_id: theme_id,
update_components: update_components
)
@theme =
RemoteTheme.update_zipped_theme(
bundle.path,
bundle.original_filename,
match_theme: match_theme_by_name,
user: theme_user,
theme_id: theme_id,
update_components: update_components,
)
log_theme_change(nil, @theme)
render json: @theme, status: :created
rescue RemoteTheme::ImportError => e
render_json_error e.message
end
else
render_json_error I18n.t("themes.import_error.unknown_file_type"), status: :unprocessable_entity
render_json_error I18n.t("themes.import_error.unknown_file_type"),
status: :unprocessable_entity
end
end
@@ -160,24 +163,25 @@ class Admin::ThemesController < Admin::AdminController
payload = {
themes: ActiveModel::ArraySerializer.new(@themes, each_serializer: ThemeSerializer),
extras: {
color_schemes: ActiveModel::ArraySerializer.new(@color_schemes, each_serializer: ColorSchemeSerializer)
}
color_schemes:
ActiveModel::ArraySerializer.new(@color_schemes, each_serializer: ColorSchemeSerializer),
},
}
respond_to do |format|
format.json { render json: payload }
end
respond_to { |format| format.json { render json: payload } }
end
def create
ban_in_allowlist_mode!
@theme = Theme.new(name: theme_params[:name],
user_id: theme_user.id,
user_selectable: theme_params[:user_selectable] || false,
color_scheme_id: theme_params[:color_scheme_id],
component: [true, "true"].include?(theme_params[:component]))
@theme =
Theme.new(
name: theme_params[:name],
user_id: theme_user.id,
user_selectable: theme_params[:user_selectable] || false,
color_scheme_id: theme_params[:color_scheme_id],
component: [true, "true"].include?(theme_params[:component]),
)
set_fields
respond_to do |format|
@@ -199,10 +203,8 @@ class Admin::ThemesController < Admin::AdminController
disables_component = [false, "false"].include?(theme_params[:enabled])
enables_component = [true, "true"].include?(theme_params[:enabled])
[:name, :color_scheme_id, :user_selectable, :enabled, :auto_update].each do |field|
if theme_params.key?(field)
@theme.public_send("#{field}=", theme_params[field])
end
%i[name color_scheme_id user_selectable enabled auto_update].each do |field|
@theme.public_send("#{field}=", theme_params[field]) if theme_params.key?(field)
end
if theme_params.key?(:child_theme_ids)
@@ -218,13 +220,9 @@ class Admin::ThemesController < Admin::AdminController
update_translations
handle_switch
if params[:theme][:remote_check]
@theme.remote_theme.update_remote_version
end
@theme.remote_theme.update_remote_version if params[:theme][:remote_check]
if params[:theme][:remote_update]
@theme.remote_theme.update_from_remote
end
@theme.remote_theme.update_from_remote if params[:theme][:remote_update]
respond_to do |format|
if @theme.save
@@ -245,7 +243,7 @@ class Admin::ThemesController < Admin::AdminController
error = I18n.t("themes.bad_color_scheme") if @theme.errors[:color_scheme].present?
error ||= I18n.t("themes.other_error")
render json: { errors: [ error ] }, status: :unprocessable_entity
render json: { errors: [error] }, status: :unprocessable_entity
end
end
end
@@ -260,9 +258,7 @@ class Admin::ThemesController < Admin::AdminController
StaffActionLogger.new(current_user).log_theme_destroy(@theme)
@theme.destroy
respond_to do |format|
format.json { head :no_content }
end
respond_to { |format| format.json { head :no_content } }
end
def show
@@ -279,10 +275,10 @@ class Admin::ThemesController < Admin::AdminController
exporter = ThemeStore::ZipExporter.new(@theme)
file_path = exporter.package_filename
headers['Content-Length'] = File.size(file_path).to_s
headers["Content-Length"] = File.size(file_path).to_s
send_data File.read(file_path),
filename: File.basename(file_path),
content_type: "application/zip"
filename: File.basename(file_path),
content_type: "application/zip"
ensure
exporter.cleanup!
end
@@ -330,9 +326,7 @@ class Admin::ThemesController < Admin::AdminController
end
end
Theme.where(id: expected).each do |theme|
@theme.add_relative_theme!(kind, theme)
end
Theme.where(id: expected).each { |theme| @theme.add_relative_theme!(kind, theme) }
end
def update_default_theme
@@ -361,11 +355,13 @@ class Admin::ThemesController < Admin::AdminController
:component,
:enabled,
:auto_update,
settings: {},
translations: {},
theme_fields: [:name, :target, :value, :upload_id, :type_id],
settings: {
},
translations: {
},
theme_fields: %i[name target value upload_id type_id],
child_theme_ids: [],
parent_theme_ids: []
parent_theme_ids: [],
)
end
end
@@ -382,7 +378,7 @@ class Admin::ThemesController < Admin::AdminController
name: field[:name],
value: field[:value],
type_id: field[:type_id],
upload_id: field[:upload_id]
upload_id: field[:upload_id],
)
end
end
@@ -408,7 +404,12 @@ class Admin::ThemesController < Admin::AdminController
end
def log_theme_setting_change(setting_name, previous_value, new_value)
StaffActionLogger.new(current_user).log_theme_setting_change(setting_name, previous_value, new_value, @theme)
StaffActionLogger.new(current_user).log_theme_setting_change(
setting_name,
previous_value,
new_value,
@theme,
)
end
def log_theme_component_disabled
@@ -422,10 +423,14 @@ class Admin::ThemesController < Admin::AdminController
def handle_switch
param = theme_params[:component]
if param.to_s == "false" && @theme.component?
raise Discourse::InvalidParameters.new(:component) if @theme.id == SiteSetting.default_theme_id
if @theme.id == SiteSetting.default_theme_id
raise Discourse::InvalidParameters.new(:component)
end
@theme.switch_to_theme!
elsif param.to_s == "true" && !@theme.component?
raise Discourse::InvalidParameters.new(:component) if @theme.id == SiteSetting.default_theme_id
if @theme.id == SiteSetting.default_theme_id
raise Discourse::InvalidParameters.new(:component)
end
@theme.switch_to_component!
end
end
+15 -10
View File
@@ -1,9 +1,18 @@
# frozen_string_literal: true
class Admin::UserFieldsController < Admin::AdminController
def self.columns
%i(name field_type editable description required show_on_profile show_on_user_card position searchable)
%i[
name
field_type
editable
description
required
show_on_profile
show_on_user_card
position
searchable
]
end
def create
@@ -13,14 +22,12 @@ class Admin::UserFieldsController < Admin::AdminController
field.required = params[:user_field][:required] == "true"
update_options(field)
json_result(field, serializer: UserFieldSerializer) do
field.save
end
json_result(field, serializer: UserFieldSerializer) { field.save }
end
def index
user_fields = UserField.all.includes(:user_field_options).order(:position)
render_serialized(user_fields, UserFieldSerializer, root: 'user_fields')
render_serialized(user_fields, UserFieldSerializer, root: "user_fields")
end
def update
@@ -28,9 +35,7 @@ class Admin::UserFieldsController < Admin::AdminController
field = UserField.where(id: params.require(:id)).first
Admin::UserFieldsController.columns.each do |col|
unless field_params[col].nil?
field.public_send("#{col}=", field_params[col])
end
field.public_send("#{col}=", field_params[col]) unless field_params[col].nil?
end
update_options(field)
@@ -38,7 +43,7 @@ class Admin::UserFieldsController < Admin::AdminController
if !field.show_on_profile && !field.show_on_user_card
DirectoryColumn.where(user_field_id: field.id).destroy_all
end
render_serialized(field, UserFieldSerializer, root: 'user_field')
render_serialized(field, UserFieldSerializer, root: "user_field")
else
render_json_error(field)
end
+153 -119
View File
@@ -3,28 +3,31 @@
class Admin::UsersController < Admin::StaffController
MAX_SIMILAR_USERS = 10
before_action :fetch_user, only: [:suspend,
:unsuspend,
:log_out,
:revoke_admin,
:revoke_moderation,
:grant_moderation,
:approve,
:activate,
:deactivate,
:silence,
:unsilence,
:trust_level,
:trust_level_lock,
:add_group,
:remove_group,
:primary_group,
:anonymize,
:merge,
:reset_bounce_score,
:disable_second_factor,
:delete_posts_batch,
:sso_record]
before_action :fetch_user,
only: %i[
suspend
unsuspend
log_out
revoke_admin
revoke_moderation
grant_moderation
approve
activate
deactivate
silence
unsilence
trust_level
trust_level_lock
add_group
remove_group
primary_group
anonymize
merge
reset_bounce_score
disable_second_factor
delete_posts_batch
sso_record
]
def index
users = ::AdminUserIndexQuery.new(params).find_users
@@ -42,9 +45,7 @@ class Admin::UsersController < Admin::StaffController
@user = User.find_by(id: params[:id])
raise Discourse::NotFound unless @user
similar_users = User.real
.where.not(id: @user.id)
.where(ip_address: @user.ip_address)
similar_users = User.real.where.not(id: @user.id).where(ip_address: @user.ip_address)
render_serialized(
@user,
@@ -64,7 +65,6 @@ class Admin::UsersController < Admin::StaffController
# DELETE action to delete penalty history for a user
def penalty_history
# We don't delete any history, we merely remove the action type
# with a removed type. It can still be viewed in the logs but
# will not affect TL3 promotions.
@@ -87,16 +87,19 @@ class Admin::UsersController < Admin::StaffController
DB.exec(
sql,
UserHistory.actions.slice(
:silence_user,
:suspend_user,
:unsilence_user,
:unsuspend_user,
:removed_silence_user,
:removed_unsilence_user,
:removed_suspend_user,
:removed_unsuspend_user
).merge(user_id: params[:user_id].to_i)
UserHistory
.actions
.slice(
:silence_user,
:suspend_user,
:unsilence_user,
:unsuspend_user,
:removed_silence_user,
:removed_unsilence_user,
:removed_suspend_user,
:removed_unsuspend_user,
)
.merge(user_id: params[:user_id].to_i),
)
render json: success_json
@@ -107,14 +110,21 @@ class Admin::UsersController < Admin::StaffController
if @user.suspended?
suspend_record = @user.suspend_record
message = I18n.t("user.already_suspended",
staff: suspend_record.acting_user.username,
time_ago: FreedomPatches::Rails4.time_ago_in_words(suspend_record.created_at, true, scope: :'datetime.distance_in_words_verbose')
)
message =
I18n.t(
"user.already_suspended",
staff: suspend_record.acting_user.username,
time_ago:
FreedomPatches::Rails4.time_ago_in_words(
suspend_record.created_at,
true,
scope: :"datetime.distance_in_words_verbose",
),
)
return render json: failed_json.merge(message: message), status: 409
end
params.require([:suspend_until, :reason])
params.require(%i[suspend_until reason])
all_users = [@user]
if Array === params[:other_user_ids]
@@ -133,12 +143,13 @@ class Admin::UsersController < Admin::StaffController
User.transaction do
user.save!
user_history = StaffActionLogger.new(current_user).log_user_suspend(
user,
params[:reason],
message: message,
post_id: params[:post_id]
)
user_history =
StaffActionLogger.new(current_user).log_user_suspend(
user,
params[:reason],
message: message,
post_id: params[:post_id],
)
end
user.logged_out
@@ -147,7 +158,7 @@ class Admin::UsersController < Admin::StaffController
:critical_user_email,
type: "account_suspended",
user_id: user.id,
user_history_id: user_history.id
user_history_id: user_history.id,
)
end
@@ -159,7 +170,7 @@ class Admin::UsersController < Admin::StaffController
user_history: user_history,
post_id: params[:post_id],
suspended_till: params[:suspend_until],
suspended_at: DateTime.now
suspended_at: DateTime.now,
)
end
@@ -171,8 +182,8 @@ class Admin::UsersController < Admin::StaffController
full_suspend_reason: user_history.try(:details),
suspended_till: @user.suspended_till,
suspended_at: @user.suspended_at,
suspended_by: BasicUserSerializer.new(current_user, root: false).as_json
}
suspended_by: BasicUserSerializer.new(current_user, root: false).as_json,
},
)
end
@@ -185,12 +196,7 @@ class Admin::UsersController < Admin::StaffController
DiscourseEvent.trigger(:user_unsuspended, user: @user)
render_json_dump(
suspension: {
suspended_till: nil,
suspended_at: nil
}
)
render_json_dump(suspension: { suspended_till: nil, suspended_at: nil })
end
def log_out
@@ -199,7 +205,7 @@ class Admin::UsersController < Admin::StaffController
@user.logged_out
render json: success_json
else
render json: { error: I18n.t('admin_js.admin.users.id_not_found') }, status: 404
render json: { error: I18n.t("admin_js.admin.users.id_not_found") }, status: 404
end
end
@@ -237,7 +243,7 @@ class Admin::UsersController < Admin::StaffController
group = Group.find(params[:group_id].to_i)
raise Discourse::NotFound unless group
return render_json_error(I18n.t('groups.errors.can_not_modify_automatic')) if group.automatic
return render_json_error(I18n.t("groups.errors.can_not_modify_automatic")) if group.automatic
guardian.ensure_can_edit!(group)
group.add(@user)
@@ -250,7 +256,7 @@ class Admin::UsersController < Admin::StaffController
group = Group.find(params[:group_id].to_i)
raise Discourse::NotFound unless group
return render_json_error(I18n.t('groups.errors.can_not_modify_automatic')) if group.automatic
return render_json_error(I18n.t("groups.errors.can_not_modify_automatic")) if group.automatic
guardian.ensure_can_edit!(group)
if group.remove(@user)
@@ -266,9 +272,7 @@ class Admin::UsersController < Admin::StaffController
if group = Group.find(primary_group_id)
guardian.ensure_can_change_primary_group!(@user, group)
if group.user_ids.include?(@user.id)
@user.primary_group_id = primary_group_id
end
@user.primary_group_id = primary_group_id if group.user_ids.include?(@user.id)
end
else
@user.primary_group_id = nil
@@ -304,9 +308,7 @@ class Admin::UsersController < Admin::StaffController
guardian.ensure_can_change_trust_level!(@user)
new_lock = params[:locked].to_s
unless new_lock =~ /true|false/
return render_json_error I18n.t('errors.invalid_boolean')
end
return render_json_error I18n.t("errors.invalid_boolean") unless new_lock =~ /true|false/
@user.manual_locked_trust_level = (new_lock == "true") ? @user.trust_level : nil
@user.save
@@ -320,31 +322,38 @@ class Admin::UsersController < Admin::StaffController
def approve
guardian.ensure_can_approve!(@user)
reviewable = ReviewableUser.find_by(target: @user) ||
Jobs::CreateUserReviewable.new.execute(user_id: @user.id).reviewable
reviewable =
ReviewableUser.find_by(target: @user) ||
Jobs::CreateUserReviewable.new.execute(user_id: @user.id).reviewable
reviewable.perform(current_user, :approve_user)
render body: nil
end
def approve_bulk
Reviewable.bulk_perform_targets(current_user, :approve_user, 'ReviewableUser', params[:users])
Reviewable.bulk_perform_targets(current_user, :approve_user, "ReviewableUser", params[:users])
render body: nil
end
def activate
guardian.ensure_can_activate!(@user)
# ensure there is an active email token
@user.email_tokens.create!(email: @user.email, scope: EmailToken.scopes[:signup]) if !@user.email_tokens.active.exists?
if !@user.email_tokens.active.exists?
@user.email_tokens.create!(email: @user.email, scope: EmailToken.scopes[:signup])
end
@user.activate
StaffActionLogger.new(current_user).log_user_activate(@user, I18n.t('user.activated_by_staff'))
StaffActionLogger.new(current_user).log_user_activate(@user, I18n.t("user.activated_by_staff"))
render json: success_json
end
def deactivate
guardian.ensure_can_deactivate!(@user)
@user.deactivate(current_user)
StaffActionLogger.new(current_user).log_user_deactivate(@user, I18n.t('user.deactivated_by_staff'), params.slice(:context))
StaffActionLogger.new(current_user).log_user_deactivate(
@user,
I18n.t("user.deactivated_by_staff"),
params.slice(:context),
)
refresh_browser @user
render json: success_json
end
@@ -354,10 +363,17 @@ class Admin::UsersController < Admin::StaffController
if @user.silenced?
silenced_record = @user.silenced_record
message = I18n.t("user.already_silenced",
staff: silenced_record.acting_user.username,
time_ago: FreedomPatches::Rails4.time_ago_in_words(silenced_record.created_at, true, scope: :'datetime.distance_in_words_verbose')
)
message =
I18n.t(
"user.already_silenced",
staff: silenced_record.acting_user.username,
time_ago:
FreedomPatches::Rails4.time_ago_in_words(
silenced_record.created_at,
true,
scope: :"datetime.distance_in_words_verbose",
),
)
return render json: failed_json.merge(message: message), status: 409
end
@@ -370,15 +386,16 @@ class Admin::UsersController < Admin::StaffController
user_history = nil
all_users.each do |user|
silencer = UserSilencer.new(
user,
current_user,
silenced_till: params[:silenced_till],
reason: params[:reason],
message_body: params[:message],
keep_posts: true,
post_id: params[:post_id]
)
silencer =
UserSilencer.new(
user,
current_user,
silenced_till: params[:silenced_till],
reason: params[:reason],
message_body: params[:message],
keep_posts: true,
post_id: params[:post_id],
)
if silencer.silence
user_history = silencer.user_history
@@ -386,7 +403,7 @@ class Admin::UsersController < Admin::StaffController
:critical_user_email,
type: "account_silenced",
user_id: user.id,
user_history_id: user_history.id
user_history_id: user_history.id,
)
end
end
@@ -399,8 +416,8 @@ class Admin::UsersController < Admin::StaffController
silence_reason: user_history.try(:details),
silenced_till: @user.silenced_till,
silenced_at: @user.silenced_at,
silenced_by: BasicUserSerializer.new(current_user, root: false).as_json
}
silenced_by: BasicUserSerializer.new(current_user, root: false).as_json,
},
)
end
@@ -413,8 +430,8 @@ class Admin::UsersController < Admin::StaffController
silenced: false,
silence_reason: nil,
silenced_till: nil,
silenced_at: nil
}
silenced_at: nil,
},
)
end
@@ -428,11 +445,7 @@ class Admin::UsersController < Admin::StaffController
user_security_key.destroy_all
StaffActionLogger.new(current_user).log_disable_second_factor_auth(@user)
Jobs.enqueue(
:critical_user_email,
type: "account_second_factor_disabled",
user_id: @user.id
)
Jobs.enqueue(:critical_user_email, type: "account_second_factor_disabled", user_id: @user.id)
render json: success_json
end
@@ -442,7 +455,7 @@ class Admin::UsersController < Admin::StaffController
guardian.ensure_can_delete_user!(user)
options = params.slice(:context, :delete_as_spammer)
[:delete_posts, :block_email, :block_urls, :block_ip].each do |param_name|
%i[delete_posts block_email block_urls block_ip].each do |param_name|
options[param_name] = ActiveModel::Type::Boolean.new.cast(params[param_name])
end
options[:prepare_for_destroy] = true
@@ -453,15 +466,21 @@ class Admin::UsersController < Admin::StaffController
render json: { deleted: true }
else
render json: {
deleted: false,
user: AdminDetailedUserSerializer.new(user, root: false).as_json
}
deleted: false,
user: AdminDetailedUserSerializer.new(user, root: false).as_json,
}
end
rescue UserDestroyer::PostsExistError
render json: {
deleted: false,
message: I18n.t("user.cannot_delete_has_posts", username: user.username, count: user.posts.joins(:topic).count),
}, status: 403
deleted: false,
message:
I18n.t(
"user.cannot_delete_has_posts",
username: user.username,
count: user.posts.joins(:topic).count,
),
},
status: 403
end
end
end
@@ -482,9 +501,16 @@ class Admin::UsersController < Admin::StaffController
return render body: nil, status: 404 unless SiteSetting.enable_discourse_connect
begin
sso = DiscourseConnect.parse("sso=#{params[:sso]}&sig=#{params[:sig]}", secure_session: secure_session)
sso =
DiscourseConnect.parse(
"sso=#{params[:sso]}&sig=#{params[:sig]}",
secure_session: secure_session,
)
rescue DiscourseConnect::ParseError
return render json: failed_json.merge(message: I18n.t("discourse_connect.login_error")), status: 422
return(
render json: failed_json.merge(message: I18n.t("discourse_connect.login_error")),
status: 422
)
end
begin
@@ -494,7 +520,8 @@ class Admin::UsersController < Admin::StaffController
rescue ActiveRecord::RecordInvalid => ex
render json: failed_json.merge(message: ex.message), status: 403
rescue DiscourseConnect::BlankExternalId => ex
render json: failed_json.merge(message: I18n.t('discourse_connect.blank_id_error')), status: 422
render json: failed_json.merge(message: I18n.t("discourse_connect.blank_id_error")),
status: 422
end
end
@@ -510,12 +537,13 @@ class Admin::UsersController < Admin::StaffController
block_urls: true,
block_ip: true,
delete_as_spammer: true,
context: I18n.t("user.destroy_reasons.same_ip_address", ip_address: params[:ip])
context: I18n.t("user.destroy_reasons.same_ip_address", ip_address: params[:ip]),
}
AdminUserIndexQuery.new(params).find_users(50).each do |user|
user_destroyer.destroy(user, options)
end
AdminUserIndexQuery
.new(params)
.find_users(50)
.each { |user| user_destroyer.destroy(user, options) }
render json: success_json
end
@@ -536,7 +564,8 @@ class Admin::UsersController < Admin::StaffController
if user = UserAnonymizer.new(@user, current_user, opts).make_anonymous
render json: success_json.merge(username: user.username)
else
render json: failed_json.merge(user: AdminDetailedUserSerializer.new(user, root: false).as_json)
render json:
failed_json.merge(user: AdminDetailedUserSerializer.new(user, root: false).as_json)
end
end
@@ -547,7 +576,12 @@ class Admin::UsersController < Admin::StaffController
guardian.ensure_can_merge_users!(@user, target_user)
Jobs.enqueue(:merge_user, user_id: @user.id, target_user_id: target_user.id, current_user_id: current_user.id)
Jobs.enqueue(
:merge_user,
user_id: @user.id,
target_user_id: target_user.id,
current_user_id: current_user.id,
)
render json: success_json
end
@@ -566,24 +600,25 @@ class Admin::UsersController < Admin::StaffController
private
def perform_post_action
return unless params[:post_id].present? &&
params[:post_action].present?
return unless params[:post_id].present? && params[:post_action].present?
if post = Post.where(id: params[:post_id]).first
case params[:post_action]
when 'delete'
when "delete"
PostDestroyer.new(current_user, post).destroy if guardian.can_delete_post_or_topic?(post)
when "delete_replies"
PostDestroyer.delete_with_replies(current_user, post) if guardian.can_delete_post_or_topic?(post)
when 'edit'
if guardian.can_delete_post_or_topic?(post)
PostDestroyer.delete_with_replies(current_user, post)
end
when "edit"
revisor = PostRevisor.new(post)
# Take what the moderator edited in as gospel
revisor.revise!(
current_user,
{ raw: params[:post_edit] },
{ raw: params[:post_edit] },
skip_validations: true,
skip_revision: true
skip_revision: true,
)
end
end
@@ -597,5 +632,4 @@ class Admin::UsersController < Admin::StaffController
def refresh_browser(user)
MessageBus.publish "/file-change", ["refresh"], user_ids: [user.id]
end
end
@@ -1,13 +1,14 @@
# frozen_string_literal: true
require 'csv'
require "csv"
class Admin::WatchedWordsController < Admin::StaffController
skip_before_action :check_xhr, only: [:download]
def index
watched_words = WatchedWord.by_action
watched_words = watched_words.where.not(action: WatchedWord.actions[:tag]) if !SiteSetting.tagging_enabled
watched_words =
watched_words.where.not(action: WatchedWord.actions[:tag]) if !SiteSetting.tagging_enabled
render_json_dump WatchedWordListSerializer.new(watched_words, scope: guardian, root: false)
end
@@ -38,19 +39,20 @@ class Admin::WatchedWordsController < Admin::StaffController
begin
CSV.foreach(file.tempfile, encoding: "bom|utf-8") do |row|
if row[0].present? && (!has_replacement || row[1].present?)
watched_word = WatchedWord.create_or_update_word(
word: row[0],
replacement: has_replacement ? row[1] : nil,
action_key: action_key,
case_sensitive: "true" == row[2]&.strip&.downcase
)
watched_word =
WatchedWord.create_or_update_word(
word: row[0],
replacement: has_replacement ? row[1] : nil,
action_key: action_key,
case_sensitive: "true" == row[2]&.strip&.downcase,
)
if watched_word.valid?
StaffActionLogger.new(current_user).log_watched_words_creation(watched_word)
end
end
end
data = { url: '/ok' }
data = { url: "/ok" }
rescue => e
data = failed_json.merge(errors: [e.message])
end
@@ -73,10 +75,10 @@ class Admin::WatchedWordsController < Admin::StaffController
content = content.pluck(:word).join("\n")
end
headers['Content-Length'] = content.bytesize.to_s
headers["Content-Length"] = content.bytesize.to_s
send_data content,
filename: "#{Discourse.current_hostname}-watched-words-#{name}.csv",
content_type: "text/csv"
filename: "#{Discourse.current_hostname}-watched-words-#{name}.csv",
content_type: "text/csv"
end
def clear_all
@@ -85,10 +87,12 @@ class Admin::WatchedWordsController < Admin::StaffController
action = WatchedWord.actions[name]
raise Discourse::NotFound if !action
WatchedWord.where(action: action).find_each do |watched_word|
watched_word.destroy!
StaffActionLogger.new(current_user).log_watched_words_deletion(watched_word)
end
WatchedWord
.where(action: action)
.find_each do |watched_word|
watched_word.destroy!
StaffActionLogger.new(current_user).log_watched_words_deletion(watched_word)
end
WordWatcher.clear_cache!
render json: success_json
end
+57 -27
View File
@@ -1,17 +1,19 @@
# frozen_string_literal: true
class Admin::WebHooksController < Admin::AdminController
before_action :fetch_web_hook, only: %i(show update destroy list_events bulk_events ping)
before_action :fetch_web_hook, only: %i[show update destroy list_events bulk_events ping]
def index
limit = 50
offset = params[:offset].to_i
web_hooks = WebHook.limit(limit)
.offset(offset)
.includes(:web_hook_event_types)
.includes(:categories)
.includes(:groups)
web_hooks =
WebHook
.limit(limit)
.offset(offset)
.includes(:web_hook_event_types)
.includes(:categories)
.includes(:groups)
json = {
web_hooks: serialize_data(web_hooks, AdminWebHookSerializer),
@@ -19,29 +21,34 @@ class Admin::WebHooksController < Admin::AdminController
event_types: WebHookEventType.active,
default_event_types: WebHook.default_event_types,
content_types: WebHook.content_types.map { |name, id| { id: id, name: name } },
delivery_statuses: WebHook.last_delivery_statuses.map { |name, id| { id: id, name: name.to_s } },
delivery_statuses:
WebHook.last_delivery_statuses.map { |name, id| { id: id, name: name.to_s } },
},
total_rows_web_hooks: WebHook.count,
load_more_web_hooks: admin_web_hooks_path(limit: limit, offset: offset + limit, format: :json)
load_more_web_hooks:
admin_web_hooks_path(limit: limit, offset: offset + limit, format: :json),
}
render json: MultiJson.dump(json), status: 200
end
def show
render_serialized(@web_hook, AdminWebHookSerializer, root: 'web_hook')
render_serialized(@web_hook, AdminWebHookSerializer, root: "web_hook")
end
def edit
render_serialized(@web_hook, AdminWebHookSerializer, root: 'web_hook')
render_serialized(@web_hook, AdminWebHookSerializer, root: "web_hook")
end
def create
web_hook = WebHook.new(web_hook_params)
if web_hook.save
StaffActionLogger.new(current_user).log_web_hook(web_hook, UserHistory.actions[:web_hook_create])
render_serialized(web_hook, AdminWebHookSerializer, root: 'web_hook')
StaffActionLogger.new(current_user).log_web_hook(
web_hook,
UserHistory.actions[:web_hook_create],
)
render_serialized(web_hook, AdminWebHookSerializer, root: "web_hook")
else
render_json_error web_hook.errors.full_messages
end
@@ -49,8 +56,12 @@ class Admin::WebHooksController < Admin::AdminController
def update
if @web_hook.update(web_hook_params)
StaffActionLogger.new(current_user).log_web_hook(@web_hook, UserHistory.actions[:web_hook_update], changes: @web_hook.saved_changes)
render_serialized(@web_hook, AdminWebHookSerializer, root: 'web_hook')
StaffActionLogger.new(current_user).log_web_hook(
@web_hook,
UserHistory.actions[:web_hook_update],
changes: @web_hook.saved_changes,
)
render_serialized(@web_hook, AdminWebHookSerializer, root: "web_hook")
else
render_json_error @web_hook.errors.full_messages
end
@@ -58,7 +69,10 @@ class Admin::WebHooksController < Admin::AdminController
def destroy
@web_hook.destroy!
StaffActionLogger.new(current_user).log_web_hook(@web_hook, UserHistory.actions[:web_hook_destroy])
StaffActionLogger.new(current_user).log_web_hook(
@web_hook,
UserHistory.actions[:web_hook_destroy],
)
render json: success_json
end
@@ -67,12 +81,17 @@ class Admin::WebHooksController < Admin::AdminController
offset = params[:offset].to_i
json = {
web_hook_events: serialize_data(@web_hook.web_hook_events.limit(limit).offset(offset), AdminWebHookEventSerializer),
web_hook_events:
serialize_data(
@web_hook.web_hook_events.limit(limit).offset(offset),
AdminWebHookEventSerializer,
),
total_rows_web_hook_events: @web_hook.web_hook_events.count,
load_more_web_hook_events: web_hook_events_admin_api_index_path(limit: limit, offset: offset + limit, format: :json),
load_more_web_hook_events:
web_hook_events_admin_api_index_path(limit: limit, offset: offset + limit, format: :json),
extras: {
web_hook_id: @web_hook.id
}
web_hook_id: @web_hook.id,
},
}
render json: MultiJson.dump(json), status: 200
@@ -91,26 +110,37 @@ class Admin::WebHooksController < Admin::AdminController
web_hook = web_hook_event.web_hook
emitter = WebHookEmitter.new(web_hook, web_hook_event)
emitter.emit!(headers: MultiJson.load(web_hook_event.headers), body: web_hook_event.payload)
render_serialized(web_hook_event, AdminWebHookEventSerializer, root: 'web_hook_event')
render_serialized(web_hook_event, AdminWebHookEventSerializer, root: "web_hook_event")
else
render json: failed_json
end
end
def ping
Jobs.enqueue(:emit_web_hook_event, web_hook_id: @web_hook.id, event_type: 'ping', event_name: 'ping')
Jobs.enqueue(
:emit_web_hook_event,
web_hook_id: @web_hook.id,
event_type: "ping",
event_name: "ping",
)
render json: success_json
end
private
def web_hook_params
params.require(:web_hook).permit(:payload_url, :content_type, :secret,
:wildcard_web_hook, :active, :verify_certificate,
web_hook_event_type_ids: [],
group_ids: [],
tag_names: [],
category_ids: [])
params.require(:web_hook).permit(
:payload_url,
:content_type,
:secret,
:wildcard_web_hook,
:active,
:verify_certificate,
web_hook_event_type_ids: [],
group_ids: [],
tag_names: [],
category_ids: [],
)
end
def fetch_web_hook