mirror of
https://github.com/mastodon/mastodon.git
synced 2026-09-12 12:07:51 -05:00
160 lines
6.9 KiB
Ruby
160 lines
6.9 KiB
Ruby
# frozen_string_literal: true
|
|
|
|
class Admin::ModerationSuggestionsController < Admin::BaseController
|
|
before_action :set_moderation_suggestion_targets, only: :index
|
|
before_action :set_moderation_suggestions_by_target, only: :index
|
|
before_action :set_moderation_advisories_by_target, only: :index
|
|
before_action :set_current_state_by_target, only: :index
|
|
before_action :set_moderation_suggestion, only: [:destroy, :apply]
|
|
|
|
def index
|
|
authorize :moderation_suggestion, :index?
|
|
end
|
|
|
|
def destroy
|
|
authorize @moderation_suggestion, :dismiss?
|
|
|
|
# TODO: log?
|
|
|
|
# Actually dismiss all of the suggestions for the same target
|
|
ModerationSuggestion.where(target_type: @moderation_suggestion.target_type, target_key: @moderation_suggestion.target_key).update_all(state: :dismissed)
|
|
|
|
redirect_to admin_moderation_suggestions_path, notice: I18n.t('admin.moderation_suggestions.destroyed_msg', target_key: @moderation_suggestion.target_key)
|
|
end
|
|
|
|
def apply
|
|
authorize @moderation_suggestion, :apply?
|
|
|
|
case [@moderation_suggestion.target_type, @moderation_suggestion.action]
|
|
when ['domain', 'accept']
|
|
domain_allow = @moderation_suggestion.to_domain_allow
|
|
|
|
ApplicationRecord.transaction do
|
|
# TODO: log
|
|
domain_allow.save!
|
|
@moderation_suggestion.mark_as_applied!
|
|
end
|
|
|
|
redirect_to admin_moderation_suggestions_path, notice: I18n.t('admin.moderation_suggestions.applied_msg', target_key: @moderation_suggestion.target_key)
|
|
when ['domain', 'reject'], ['domain', 'limit']
|
|
domain_block = @moderation_suggestion.to_domain_block
|
|
|
|
# TODO: factor with `DomainBlocksController#create`?
|
|
existing_domain_block = DomainBlock.rule_for(domain_block.domain)
|
|
|
|
# We can't create a laxer block for a subdomain than we have for a domain
|
|
if existing_domain_block.present? && existing_domain_block.domain != TagManager.instance.normalize_domain(domain_block.domain) && !domain_block.stricter_than?(existing_domain_block)
|
|
return redirect_to admin_moderation_suggestions_path,
|
|
alert: I18n.t('admin.moderation_suggestions.unable_to_apply_msg',
|
|
target_key: @moderation_suggestion.target_key)
|
|
end
|
|
|
|
update = false
|
|
|
|
# Allow transparently upgrading a domain block
|
|
if existing_domain_block.present? && existing_domain_block.domain == TagManager.instance.normalize_domain(domain_block.domain)
|
|
# Downgrading requires confirmation
|
|
return render :confirm_downgrade unless domain_block.stricter_than?(existing_domain_block) || params[:confirm_downgrade]
|
|
|
|
# Transparent upgrading is allowed
|
|
existing_domain_block.assign_attributes(domain_block.attributes.without('id', 'created_at', 'updated_at'))
|
|
domain_block = existing_domain_block
|
|
|
|
update = domain_block.severity_changed?
|
|
end
|
|
|
|
# Require explicit confirmation on block
|
|
return render :confirm_reject if requires_confirmation?(domain_block)
|
|
|
|
domain_block.save!
|
|
# TODO: is this the way we want to log it?
|
|
log_action (update ? :update : :create), domain_block, moderation_subscription_id: domain_block.moderation_subscription_id
|
|
DomainBlockWorker.perform_async(domain_block.id, update)
|
|
@moderation_suggestion.mark_as_applied!
|
|
|
|
redirect_to admin_moderation_suggestions_path, notice: I18n.t('admin.moderation_suggestions.applied_msg', target_key: @moderation_suggestion.target_key)
|
|
when ['domain', 'retract']
|
|
ApplicationRecord.transaction do
|
|
if Rails.configuration.x.mastodon.limited_federation_mode
|
|
domain_allow = DomainAllow.find_by(domain: @moderation_suggestion.target_key)
|
|
UnallowDomainService.new.call(domain_allow)
|
|
# TODO: is this the way we want to log it?
|
|
log_action :destroy, domain_allow, moderation_subscription_id: domain_block.moderation_subscription_id
|
|
else
|
|
domain_block = DomainBlock.find_by(domain: @moderation_suggestion.target_key)
|
|
UnblockDomainService.new.call(domain_block)
|
|
# TODO: is this the way we want to log it?
|
|
log_action :destroy, domain_block, moderation_subscription_id: domain_block.moderation_subscription_id
|
|
end
|
|
|
|
@moderation_suggestion.mark_as_applied!
|
|
end
|
|
|
|
redirect_to admin_moderation_suggestions_path, notice: I18n.t('admin.moderation_suggestions.retracted_msg', target_key: @moderation_suggestion.target_key)
|
|
end
|
|
end
|
|
|
|
private
|
|
|
|
def requires_confirmation?(domain_block)
|
|
domain_block.valid? && (domain_block.new_record? || domain_block.severity_changed?) && domain_block.suspend? && !params[:confirm]
|
|
end
|
|
|
|
def set_moderation_suggestion_targets
|
|
@moderation_suggestion_targets = ModerationSuggestion.where(state: ['new', 'mailed']).reorder([target_type: :asc, target_key: :asc]).distinct.pluck(:target_type, :target_key)
|
|
end
|
|
|
|
def set_moderation_suggestions_by_target
|
|
@moderation_suggestions_by_target = begin
|
|
@moderation_suggestion_targets.group_by(&:first).reduce(ModerationSuggestion.none) do |scope, (target_type, target_pairs)|
|
|
scope.or(ModerationSuggestion.where(target_type: target_type, target_key: target_pairs.map(&:second)))
|
|
end
|
|
end.group_by { |suggestion| [suggestion.target_type, suggestion.target_key] }
|
|
end
|
|
|
|
def set_moderation_advisories_by_target
|
|
@moderation_advisories_by_target = begin
|
|
@moderation_suggestion_targets.group_by(&:first).reduce(SubscribedAdvisory.none) do |scope, (target_type, target_pairs)|
|
|
scope.or(SubscribedAdvisory.joins(:moderation_subscription).where(target_type: target_type, target_key: target_pairs.map(&:second)))
|
|
end
|
|
end.group_by { |advisory| [advisory.target_type, advisory.target_key] }
|
|
|
|
@moderation_advisories_by_target.each_value do |advisories|
|
|
advisories.sort_by! { |advisory| advisory.moderation_subscription.priority }
|
|
end
|
|
|
|
@moderation_advisories_by_target
|
|
end
|
|
|
|
def set_current_state_by_target
|
|
# TODO: handle other target types
|
|
|
|
if Rails.configuration.x.mastodon.limited_federation_mode
|
|
@current_state_by_target = DomainAllow.where(domain: @moderation_suggestion_targets.filter_map { |type, key| key if type == 'domain' }).pluck(:domain).to_h { |domain| [['domain', domain], 'accept'] }
|
|
@current_state_by_target.default = 'reject'
|
|
else
|
|
@current_state_by_target = DomainBlock.where(domain: @moderation_suggestion_targets.filter_map { |type, key| key if type == 'domain' }).to_h do |domain_block|
|
|
action = begin
|
|
case domain_block.severity
|
|
when 'suspend'
|
|
'reject'
|
|
when 'silence'
|
|
'limit'
|
|
else
|
|
'accept'
|
|
end
|
|
end
|
|
|
|
[['domain', domain_block.domain], action]
|
|
end
|
|
|
|
@current_state_by_target.default = 'accept'
|
|
end
|
|
@current_state_by_target
|
|
end
|
|
|
|
def set_moderation_suggestion
|
|
@moderation_suggestion = ModerationSuggestion.find(params[:id])
|
|
end
|
|
end
|