2019-03-16 10:23:22 +00:00
|
|
|
# frozen_string_literal: true
|
|
|
|
|
|
|
|
class Form::AccountBatch
|
|
|
|
include ActiveModel::Model
|
2019-04-06 15:53:45 +00:00
|
|
|
include Authorization
|
2021-12-05 20:48:39 +00:00
|
|
|
include AccountableConcern
|
2019-06-04 21:11:18 +00:00
|
|
|
include Payloadable
|
2019-03-16 10:23:22 +00:00
|
|
|
|
2022-08-25 21:33:34 +00:00
|
|
|
attr_accessor :account_ids, :action, :current_account,
|
|
|
|
:select_all_matching, :query
|
2019-03-16 10:23:22 +00:00
|
|
|
|
|
|
|
def save
|
|
|
|
case action
|
2020-11-12 15:58:00 +00:00
|
|
|
when 'follow'
|
|
|
|
follow!
|
2019-03-16 10:23:22 +00:00
|
|
|
when 'unfollow'
|
|
|
|
unfollow!
|
|
|
|
when 'remove_from_followers'
|
|
|
|
remove_from_followers!
|
2023-03-03 19:25:15 +00:00
|
|
|
when 'remove_domains_from_followers'
|
|
|
|
remove_domains_from_followers!
|
2019-04-06 15:53:45 +00:00
|
|
|
when 'approve'
|
|
|
|
approve!
|
|
|
|
when 'reject'
|
|
|
|
reject!
|
2021-04-12 10:37:14 +00:00
|
|
|
when 'suppress_follow_recommendation'
|
|
|
|
suppress_follow_recommendation!
|
|
|
|
when 'unsuppress_follow_recommendation'
|
|
|
|
unsuppress_follow_recommendation!
|
2021-12-05 20:48:39 +00:00
|
|
|
when 'suspend'
|
|
|
|
suspend!
|
2019-03-16 10:23:22 +00:00
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
private
|
|
|
|
|
2020-11-12 15:58:00 +00:00
|
|
|
def follow!
|
2023-03-03 19:36:18 +00:00
|
|
|
error = nil
|
|
|
|
|
2021-12-05 20:48:39 +00:00
|
|
|
accounts.each do |target_account|
|
2020-11-12 15:58:00 +00:00
|
|
|
FollowService.new.call(current_account, target_account)
|
2023-03-03 19:36:18 +00:00
|
|
|
rescue Mastodon::NotPermittedError, ActiveRecord::RecordNotFound => e
|
|
|
|
error ||= e
|
2020-11-12 15:58:00 +00:00
|
|
|
end
|
2023-03-03 19:36:18 +00:00
|
|
|
|
|
|
|
raise error if error.present?
|
2020-11-12 15:58:00 +00:00
|
|
|
end
|
|
|
|
|
2019-03-16 10:23:22 +00:00
|
|
|
def unfollow!
|
2021-12-05 20:48:39 +00:00
|
|
|
accounts.each do |target_account|
|
2019-03-16 10:23:22 +00:00
|
|
|
UnfollowService.new.call(current_account, target_account)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def remove_from_followers!
|
2021-10-18 10:02:35 +00:00
|
|
|
RemoveFromFollowersService.new.call(current_account, account_ids)
|
2019-03-16 10:23:22 +00:00
|
|
|
end
|
|
|
|
|
2023-03-03 19:25:15 +00:00
|
|
|
def remove_domains_from_followers!
|
|
|
|
RemoveDomainsFromFollowersService.new.call(current_account, account_domains)
|
2019-03-16 10:23:22 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def account_domains
|
2020-12-07 11:08:30 +00:00
|
|
|
accounts.group(:domain).pluck(:domain).compact
|
2019-03-16 10:23:22 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def accounts
|
2022-08-25 21:33:34 +00:00
|
|
|
if select_all_matching?
|
|
|
|
query
|
|
|
|
else
|
|
|
|
Account.where(id: account_ids)
|
|
|
|
end
|
2019-03-16 10:23:22 +00:00
|
|
|
end
|
|
|
|
|
2019-04-06 15:53:45 +00:00
|
|
|
def approve!
|
2021-12-05 20:48:39 +00:00
|
|
|
accounts.includes(:user).find_each do |account|
|
|
|
|
approve_account(account)
|
|
|
|
end
|
2019-04-06 15:53:45 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def reject!
|
2021-12-05 20:48:39 +00:00
|
|
|
accounts.includes(:user).find_each do |account|
|
|
|
|
reject_account(account)
|
|
|
|
end
|
|
|
|
end
|
2019-04-06 15:53:45 +00:00
|
|
|
|
2021-12-05 20:48:39 +00:00
|
|
|
def suspend!
|
|
|
|
accounts.find_each do |account|
|
|
|
|
if account.user_pending?
|
|
|
|
reject_account(account)
|
|
|
|
else
|
|
|
|
suspend_account(account)
|
|
|
|
end
|
|
|
|
end
|
2019-04-06 15:53:45 +00:00
|
|
|
end
|
2021-04-12 10:37:14 +00:00
|
|
|
|
|
|
|
def suppress_follow_recommendation!
|
|
|
|
authorize(:follow_recommendation, :suppress?)
|
|
|
|
|
2021-12-05 20:48:39 +00:00
|
|
|
accounts.find_each do |account|
|
2021-04-12 10:37:14 +00:00
|
|
|
FollowRecommendationSuppression.create(account: account)
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
def unsuppress_follow_recommendation!
|
|
|
|
authorize(:follow_recommendation, :unsuppress?)
|
|
|
|
|
|
|
|
FollowRecommendationSuppression.where(account_id: account_ids).destroy_all
|
|
|
|
end
|
2021-12-05 20:48:39 +00:00
|
|
|
|
|
|
|
def reject_account(account)
|
|
|
|
authorize(account.user, :reject?)
|
2022-08-25 18:39:40 +00:00
|
|
|
log_action(:reject, account.user)
|
2021-12-05 20:48:39 +00:00
|
|
|
account.suspend!(origin: :local)
|
2022-01-27 23:43:56 +00:00
|
|
|
AccountDeletionWorker.perform_async(account.id, { 'reserve_username' => false })
|
2021-12-05 20:48:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def suspend_account(account)
|
|
|
|
authorize(account, :suspend?)
|
|
|
|
log_action(:suspend, account)
|
|
|
|
account.suspend!(origin: :local)
|
2022-11-17 09:52:51 +00:00
|
|
|
account.strikes.create!(
|
|
|
|
account: current_account,
|
|
|
|
action: :suspend
|
|
|
|
)
|
2023-05-16 12:56:49 +00:00
|
|
|
|
2021-12-05 20:48:39 +00:00
|
|
|
Admin::SuspensionWorker.perform_async(account.id)
|
2023-05-16 12:56:49 +00:00
|
|
|
|
|
|
|
# Suspending a single account closes their associated reports, so
|
|
|
|
# mass-suspending would be consistent.
|
|
|
|
Report.where(target_account: account).unresolved.find_each do |report|
|
|
|
|
authorize(report, :update?)
|
|
|
|
log_action(:resolve, report)
|
|
|
|
report.resolve!(current_account)
|
|
|
|
rescue Mastodon::NotPermittedError
|
|
|
|
# This should not happen, but just in case, do not fail early
|
|
|
|
end
|
2021-12-05 20:48:39 +00:00
|
|
|
end
|
|
|
|
|
|
|
|
def approve_account(account)
|
|
|
|
authorize(account.user, :approve?)
|
|
|
|
log_action(:approve, account.user)
|
|
|
|
account.user.approve!
|
|
|
|
end
|
2022-08-25 21:33:34 +00:00
|
|
|
|
|
|
|
def select_all_matching?
|
|
|
|
select_all_matching == '1'
|
|
|
|
end
|
2019-03-16 10:23:22 +00:00
|
|
|
end
|