mirror of
https://github.com/discourse/discourse.git
synced 2025-05-30 04:18:27 +08:00
DEV: Use Service::Base
for suspend and silence actions (#28459)
This commit moves the business logic in the `Admin::UsersController#suspend` and `Admin::UsersController#silence` actions to dedicated service classes. There's no functional changes in this commit. Internal topic: t/130014.
This commit is contained in:
@ -1,8 +1,6 @@
|
||||
# frozen_string_literal: true
|
||||
|
||||
class Admin::UsersController < Admin::StaffController
|
||||
MAX_SIMILAR_USERS = 10
|
||||
|
||||
before_action :fetch_user,
|
||||
only: %i[
|
||||
suspend
|
||||
@ -62,7 +60,7 @@ class Admin::UsersController < Admin::StaffController
|
||||
{
|
||||
users:
|
||||
ActiveModel::ArraySerializer.new(
|
||||
@user.similar_users.limit(MAX_SIMILAR_USERS),
|
||||
@user.similar_users.limit(User::MAX_SIMILAR_USERS),
|
||||
each_serializer: SimilarAdminUserSerializer,
|
||||
scope: guardian,
|
||||
root: false,
|
||||
@ -121,70 +119,41 @@ class Admin::UsersController < Admin::StaffController
|
||||
end
|
||||
|
||||
def suspend
|
||||
guardian.ensure_can_suspend!(@user)
|
||||
reason = params[:reason]
|
||||
|
||||
if reason && (!reason.is_a?(String) || reason.size > 300)
|
||||
raise Discourse::InvalidParameters.new(:reason)
|
||||
end
|
||||
|
||||
if @user.suspended?
|
||||
suspend_record = @user.suspend_record
|
||||
message =
|
||||
I18n.t(
|
||||
"user.already_suspended",
|
||||
staff: suspend_record.acting_user.username,
|
||||
time_ago:
|
||||
AgeWords.time_ago_in_words(
|
||||
suspend_record.created_at,
|
||||
true,
|
||||
scope: :"datetime.distance_in_words_verbose",
|
||||
),
|
||||
with_service(SuspendUser, user: @user) do
|
||||
on_success do
|
||||
render_json_dump(
|
||||
suspension: {
|
||||
suspend_reason: result.reason,
|
||||
full_suspend_reason: result.user_history&.details,
|
||||
suspended_till: @user.suspended_till,
|
||||
suspended_at: @user.suspended_at,
|
||||
suspended_by: BasicUserSerializer.new(current_user, root: false).as_json,
|
||||
},
|
||||
)
|
||||
return render json: failed_json.merge(message: message), status: 409
|
||||
end
|
||||
|
||||
params.require(%i[suspend_until reason])
|
||||
|
||||
all_users = [@user]
|
||||
if Array === params[:other_user_ids]
|
||||
if params[:other_user_ids].size > MAX_SIMILAR_USERS
|
||||
raise Discourse::InvalidParameters.new(:other_user_ids)
|
||||
end
|
||||
|
||||
all_users.concat(User.where(id: params[:other_user_ids]).to_a)
|
||||
all_users.uniq!
|
||||
on_failed_policy(:can_suspend) { raise Discourse::InvalidAccess.new }
|
||||
|
||||
on_failed_policy(:not_suspended_already) do
|
||||
suspend_record = @user.suspend_record
|
||||
message =
|
||||
I18n.t(
|
||||
"user.already_suspended",
|
||||
staff: suspend_record.acting_user.username,
|
||||
time_ago:
|
||||
AgeWords.time_ago_in_words(
|
||||
suspend_record.created_at,
|
||||
true,
|
||||
scope: :"datetime.distance_in_words_verbose",
|
||||
),
|
||||
)
|
||||
render json: failed_json.merge(message: message), status: 409
|
||||
end
|
||||
|
||||
on_failed_contract do |contract|
|
||||
render json: failed_json.merge(errors: contract.errors.full_messages), status: 400
|
||||
end
|
||||
end
|
||||
|
||||
user_history = nil
|
||||
|
||||
all_users.each { |user| raise Discourse::InvalidAccess.new if !guardian.can_suspend?(user) }
|
||||
|
||||
all_users.each do |user|
|
||||
suspender =
|
||||
UserSuspender.new(
|
||||
user,
|
||||
suspended_till: params[:suspend_until],
|
||||
reason: params[:reason],
|
||||
by_user: current_user,
|
||||
message: params[:message],
|
||||
post_id: params[:post_id],
|
||||
)
|
||||
suspender.suspend
|
||||
user_history = suspender.user_history
|
||||
end
|
||||
|
||||
perform_post_action
|
||||
|
||||
render_json_dump(
|
||||
suspension: {
|
||||
suspend_reason: params[:reason],
|
||||
full_suspend_reason: user_history&.details,
|
||||
suspended_till: @user.suspended_till,
|
||||
suspended_at: @user.suspended_at,
|
||||
suspended_by: BasicUserSerializer.new(current_user, root: false).as_json,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
def unsuspend
|
||||
@ -359,78 +328,41 @@ class Admin::UsersController < Admin::StaffController
|
||||
end
|
||||
|
||||
def silence
|
||||
reason = params[:reason]
|
||||
|
||||
if reason && (!reason.is_a?(String) || reason.size > 300)
|
||||
raise Discourse::InvalidParameters.new(:reason)
|
||||
end
|
||||
|
||||
if @user.silenced?
|
||||
silenced_record = @user.silenced_record
|
||||
message =
|
||||
I18n.t(
|
||||
"user.already_silenced",
|
||||
staff: silenced_record.acting_user.username,
|
||||
time_ago:
|
||||
AgeWords.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
|
||||
|
||||
all_users = [@user]
|
||||
if Array === params[:other_user_ids]
|
||||
if params[:other_user_ids].size > MAX_SIMILAR_USERS
|
||||
raise Discourse::InvalidParameters.new(:other_user_ids)
|
||||
end
|
||||
|
||||
all_users.concat(User.where(id: params[:other_user_ids]).to_a)
|
||||
all_users.uniq!
|
||||
end
|
||||
|
||||
user_history = nil
|
||||
|
||||
all_users.each do |user|
|
||||
raise Discourse::InvalidAccess.new if !guardian.can_silence_user?(user)
|
||||
end
|
||||
|
||||
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],
|
||||
)
|
||||
|
||||
if silencer.silence
|
||||
user_history = silencer.user_history
|
||||
Jobs.enqueue(
|
||||
:critical_user_email,
|
||||
type: "account_silenced",
|
||||
user_id: user.id,
|
||||
user_history_id: user_history.id,
|
||||
with_service(SilenceUser, user: @user) do
|
||||
on_success do
|
||||
render_json_dump(
|
||||
silence: {
|
||||
silenced: true,
|
||||
silence_reason: result.user_history&.details,
|
||||
silenced_till: @user.silenced_till,
|
||||
silenced_at: @user.silenced_at,
|
||||
silenced_by: BasicUserSerializer.new(current_user, root: false).as_json,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
on_failed_policy(:can_silence) { raise Discourse::InvalidAccess.new }
|
||||
|
||||
on_failed_policy(:not_silenced_already) do
|
||||
silenced_record = @user.silenced_record
|
||||
message =
|
||||
I18n.t(
|
||||
"user.already_silenced",
|
||||
staff: silenced_record.acting_user.username,
|
||||
time_ago:
|
||||
AgeWords.time_ago_in_words(
|
||||
silenced_record.created_at,
|
||||
true,
|
||||
scope: :"datetime.distance_in_words_verbose",
|
||||
),
|
||||
)
|
||||
render json: failed_json.merge(message: message), status: 409
|
||||
end
|
||||
|
||||
on_failed_contract do |contract|
|
||||
render json: failed_json.merge(errors: contract.errors.full_messages), status: 400
|
||||
end
|
||||
end
|
||||
|
||||
perform_post_action
|
||||
|
||||
render_json_dump(
|
||||
silence: {
|
||||
silenced: true,
|
||||
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,
|
||||
},
|
||||
)
|
||||
end
|
||||
|
||||
def unsilence
|
||||
@ -612,31 +544,6 @@ class Admin::UsersController < Admin::StaffController
|
||||
|
||||
private
|
||||
|
||||
def perform_post_action
|
||||
return if params[:post_id].blank? || params[:post_action].blank?
|
||||
|
||||
if post = Post.where(id: params[:post_id]).first
|
||||
case params[:post_action]
|
||||
when "delete"
|
||||
PostDestroyer.new(current_user, post).destroy if guardian.can_delete_post_or_topic?(post)
|
||||
when "delete_replies"
|
||||
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] },
|
||||
skip_validations: true,
|
||||
skip_revision: true,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def fetch_user
|
||||
@user = User.find_by(id: params[:user_id])
|
||||
raise Discourse::NotFound unless @user
|
||||
|
Reference in New Issue
Block a user