mirror of
https://github.com/discourse/discourse.git
synced 2026-08-11 05:25:16 -05:00
DEV: Apply syntax_tree formatting to app/*
This commit is contained in:
@@ -7,5 +7,4 @@ class Admin::AdminController < ApplicationController
|
||||
def index
|
||||
render body: nil
|
||||
end
|
||||
|
||||
end
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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"))
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user