mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 18:56:21 +00:00
parent
522cef8c9a
commit
bf75d50cc3
10 changed files with 88 additions and 118 deletions
|
@ -27,7 +27,7 @@ class ActivityPubsController < ApplicationController
|
|||
authorize activity_pubs
|
||||
|
||||
action = params[:activity_pub_action].to_sym
|
||||
method = :"#{action}!"
|
||||
method = :"#{action}_all!"
|
||||
may = :"may_#{action}?"
|
||||
|
||||
redirect_to_moderation_queue!
|
||||
|
@ -35,36 +35,25 @@ class ActivityPubsController < ApplicationController
|
|||
return unless ActivityPub.events.include? action
|
||||
|
||||
# Crear una sola remote flag por autore
|
||||
if action == :report
|
||||
message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message)
|
||||
|
||||
activity_pubs.distinct.pluck(:actor_id).each do |actor_id|
|
||||
remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id)
|
||||
remote_flag.message = message
|
||||
# Lo estamos actualizando, con lo que lo vamos a volver a enviar
|
||||
remote_flag.requeue if remote_flag.persisted?
|
||||
remote_flag.save
|
||||
# XXX: Idealmente todas las ActivityPub que enviamos pueden
|
||||
# cambiar de estado, pero chequeamos de todas formas.
|
||||
remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) })
|
||||
end
|
||||
end
|
||||
|
||||
ActivityPub.transaction do
|
||||
activity_pubs.find_each do |activity_pub|
|
||||
next unless activity_pub.public_send(may)
|
||||
if action == :report
|
||||
message = remote_flag_params(activity_pubs.first).dig(:remote_flag_attributes, :message)
|
||||
|
||||
activity_pub.public_send(method)
|
||||
|
||||
flash[:success] = I18n.t('activity_pubs.action_on_several.success')
|
||||
rescue Exception => e
|
||||
ExceptionNotifier.notify_exception(e,
|
||||
data: { site: site.name, params: params.permit!.to_h,
|
||||
activity_pub: activity_pub.id })
|
||||
|
||||
flash.delete(:success)
|
||||
flash[:error] = I18n.t('activity_pubs.action_on_several.error')
|
||||
activity_pubs.distinct.pluck(:actor_id).each do |actor_id|
|
||||
remote_flag = ActivityPub::RemoteFlag.find_or_initialize_by(actor_id: actor_id, site_id: site.id)
|
||||
remote_flag.message = message
|
||||
# Lo estamos actualizando, con lo que lo vamos a volver a enviar
|
||||
remote_flag.requeue if remote_flag.persisted?
|
||||
remote_flag.save
|
||||
# XXX: Idealmente todas las ActivityPub que enviamos pueden
|
||||
# cambiar de estado, pero chequeamos de todas formas.
|
||||
remote_flag.activity_pubs << (activity_pubs.where(actor_id: actor_id).to_a.select { |a| a.public_send(may) })
|
||||
end
|
||||
end
|
||||
|
||||
message = activity_pubs.public_send(method) ? :success : :error
|
||||
|
||||
flash[message] = I18n.t("activity_pubs.action_on_several.#{message}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -37,7 +37,7 @@ class ActorModerationsController < ApplicationController
|
|||
authorize actor_moderations
|
||||
|
||||
action = params[:actor_moderation_action].to_sym
|
||||
method = :"#{action}!"
|
||||
method = :"#{action}_all!"
|
||||
may = :"may_#{action}?"
|
||||
|
||||
redirect_to_moderation_queue!
|
||||
|
@ -45,20 +45,17 @@ class ActorModerationsController < ApplicationController
|
|||
return unless ActorModeration.events.include? action
|
||||
|
||||
ActorModeration.transaction do
|
||||
actor_moderations.find_each do |actor_moderation|
|
||||
next unless actor_moderation.public_send(may)
|
||||
if action == :report
|
||||
actor_moderations.find_each do |actor_moderation|
|
||||
next unless actor_moderation.public_send(may)
|
||||
|
||||
actor_moderation.update(actor_moderation_params(actor_moderation)) if action == :report
|
||||
|
||||
actor_moderation.public_send(method)
|
||||
|
||||
flash[:success] = I18n.t('actor_moderations.action_on_several.success')
|
||||
rescue Exception => e
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h })
|
||||
|
||||
flash.delete(:success)
|
||||
flash[:error] = I18n.t('actor_moderations.action_on_several.error')
|
||||
actor_moderation.update(actor_moderation_params(actor_moderation))
|
||||
end
|
||||
end
|
||||
|
||||
message = actor_moderation.public_send(method) ? :success : :error
|
||||
|
||||
flash[message] = I18n.t("actor_moderations.action_on_several.#{message}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -10,6 +10,12 @@ class InstanceModerationsController < ApplicationController
|
|||
|
||||
instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?")
|
||||
|
||||
flash[:success] = I18n.t("instance_moderations.#{event}.success")
|
||||
rescue Exception => e
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h })
|
||||
|
||||
flash[:error] = I18n.t("instance_moderations.#{event}.error")
|
||||
ensure
|
||||
redirect_to_moderation_queue!
|
||||
end
|
||||
end
|
||||
|
@ -20,17 +26,16 @@ class InstanceModerationsController < ApplicationController
|
|||
authorize instance_moderations
|
||||
|
||||
action = params[:instance_moderation_action].to_sym
|
||||
method = :"#{action}!"
|
||||
may = :"may_#{action}?"
|
||||
method = :"#{action}_all!"
|
||||
|
||||
redirect_to_moderation_queue!
|
||||
|
||||
return unless InstanceModeration.events.include? action
|
||||
|
||||
InstanceModeration.transaction do
|
||||
instance_moderations.find_each do |instance_moderation|
|
||||
instance_moderation.public_send(method) if instance_moderation.public_send(may)
|
||||
end
|
||||
message = instance_moderations.public_send(method) ? :success : :error
|
||||
|
||||
flash[:message] = I18n.t("instance_moderations.action_on_several.#{message}")
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -14,7 +14,6 @@ class ActivityPub
|
|||
end
|
||||
|
||||
instances = ActivityPub::Instance.where(hostname: hostnames)
|
||||
success = true
|
||||
|
||||
Site.transaction do
|
||||
# Crea todas las moderaciones de instancia con un estado por
|
||||
|
@ -22,17 +21,11 @@ class ActivityPub
|
|||
instances.find_each do |instance|
|
||||
# Esto bloquea cada una individualmente en la Social Inbox,
|
||||
# idealmente son pocas instancias las que aparecen.
|
||||
site.instance_moderations.find_or_create_by(instance: instance).tap do |instance_moderation|
|
||||
instance_moderation.block! if instance_moderation.may_block?
|
||||
# Notificar todos los errores sin detener la ejecución
|
||||
rescue Exception => e
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, instance_moderation: instance_moderation.id })
|
||||
success = false
|
||||
end
|
||||
site.instance_moderations.find_or_create_by(instance: instance)
|
||||
end
|
||||
end
|
||||
|
||||
success
|
||||
site.instance_moderations.where(instance_id: instances.ids).block_all!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -38,28 +38,6 @@ class ActivityPub < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
# Permite todos los comentarios. No podemos hacer acciones en masa
|
||||
# sobre comentarios en la Social Inbox, con lo que tenemos que
|
||||
# comunicarnos individualmente.
|
||||
def self.allow_all!
|
||||
self.find_each do |activity_pub|
|
||||
activity_pub.allow! if activity_pub.may_allow?
|
||||
rescue Exception => e
|
||||
notify_exception!(e, activity_pub)
|
||||
end
|
||||
end
|
||||
|
||||
# Rechaza todos los comentarios. No podemos hacer acciones en masa
|
||||
# sobre comentarios en la Social Inbox, con lo que tenemos que
|
||||
# comunicarnos individualmente.
|
||||
def self.reject_all!
|
||||
self.find_each do |activity_pub|
|
||||
activity_pub.reject! if activity_pub.may_reject?
|
||||
rescue Exception => e
|
||||
notify_exception!(e, activity_pub)
|
||||
end
|
||||
end
|
||||
|
||||
aasm do
|
||||
# Todavía no hay una decisión sobre el objeto
|
||||
state :paused, initial: true
|
||||
|
|
|
@ -14,19 +14,6 @@ class ActorModeration < ApplicationRecord
|
|||
|
||||
accepts_nested_attributes_for :remote_flag
|
||||
|
||||
# Bloquea todes les Actores bloqueables
|
||||
def self.block_all!
|
||||
self.update_all(aasm_state: 'blocked', updated_at: Time.now)
|
||||
end
|
||||
|
||||
def self.pause_all!
|
||||
self.update_all(aasm_state: 'paused', updated_at: Time.now)
|
||||
end
|
||||
|
||||
def self.remove_all!
|
||||
self.update_all(aasm_state: 'removed', updated_at: Time.now)
|
||||
end
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
state :allowed
|
||||
|
|
|
@ -28,6 +28,26 @@ module AasmEventsConcern
|
|||
aasm.states.map(&:name) - self::IGNORED_STATES
|
||||
end
|
||||
|
||||
# Define un método que cambia el estado para todos los objetos del
|
||||
# scope actual.
|
||||
#
|
||||
# @return [Bool] Si hubo al menos un error, devuelve false.
|
||||
self.events.each do |event|
|
||||
define_singleton_method(:"#{event}_all!") do
|
||||
success = true
|
||||
|
||||
self.find_each do |object|
|
||||
object.public_send(:"#{event}!") if object.public_send(:"may_#{event}?")
|
||||
rescue Exception => e
|
||||
success = false
|
||||
|
||||
notify_exception! e, object
|
||||
end
|
||||
|
||||
success
|
||||
end
|
||||
end
|
||||
|
||||
# Envía notificación de errores
|
||||
#
|
||||
# @param exception [Exception]
|
||||
|
|
|
@ -39,12 +39,6 @@ class FediblockState < ApplicationRecord
|
|||
# Luego esta tarea crea las que falten e ignora las que ya se
|
||||
# bloquearon.
|
||||
ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames)
|
||||
|
||||
# Bloquear a todes les Actores de las instancias bloqueadas para
|
||||
# indicarle a le usuarie que les tiene que desbloquear
|
||||
# manualmente.
|
||||
actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids
|
||||
ActorModeration.where(actor_id: actor_ids).paused.block_all!
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -66,12 +60,6 @@ class FediblockState < ApplicationRecord
|
|||
# bloqueadas por otros fediblocks.
|
||||
instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids
|
||||
site.instance_moderations.where(instance_id: instance_ids).pause_all!
|
||||
|
||||
# Volver a pausar todes les actores de esta instancia que fueron
|
||||
# bloqueades, a menos que hayan sido bloqueades por otro
|
||||
# fediblock.
|
||||
actor_ids = ActivityPub::Actor.where(instance_id: instance_ids).ids
|
||||
ActorModeration.where(actor_id: actor_ids).blocked.pause_all!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -11,26 +11,13 @@ class InstanceModeration < ApplicationRecord
|
|||
belongs_to :site
|
||||
belongs_to :instance, class_name: 'ActivityPub::Instance'
|
||||
|
||||
# Traer todas las instancias bloqueables, según la máquina de estados,
|
||||
# todas las que no estén bloqueadas ya.
|
||||
scope :may_block, -> { where.not(aasm_state: 'blocked') }
|
||||
scope :may_pause, -> { where.not(aasm_state: 'paused') }
|
||||
|
||||
# Bloquear instancias en masa
|
||||
def self.block_all!
|
||||
self.may_block.update_all(aasm_state: 'blocked', updated_at: Time.now)
|
||||
end
|
||||
|
||||
# Pausar instancias en masa
|
||||
def self.pause_all!
|
||||
self.may_pause.update_all(aasm_state: 'paused', updated_at: Time.now)
|
||||
end
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
state :allowed
|
||||
state :blocked
|
||||
|
||||
# Al volver la instancia a pausa no cambiamos el estado de
|
||||
# moderación de actores pre-existente.
|
||||
event :pause do
|
||||
transitions from: %i[allowed blocked], to: :paused
|
||||
|
||||
|
@ -39,23 +26,36 @@ class InstanceModeration < ApplicationRecord
|
|||
end
|
||||
end
|
||||
|
||||
# Al permitir, también permitimos todes les actores que no hayan
|
||||
# tenido acciones de moderación.
|
||||
event :allow do
|
||||
transitions from: %i[paused blocked], to: :allowed
|
||||
|
||||
before do
|
||||
allow_remotely!
|
||||
|
||||
site.actor_moderations.paused.where(actor_id: actor_ids).allow_all!
|
||||
end
|
||||
end
|
||||
|
||||
# Al bloquear, también bloqueamos a todes les actores que no hayan
|
||||
# tenido acciones de moderación.
|
||||
event :block do
|
||||
transitions from: %i[paused allowed], to: :blocked
|
||||
|
||||
before do
|
||||
block_remotely!
|
||||
|
||||
site.actor_moderations.paused.where(actor_id: actor_ids).block_all!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Array<String>]
|
||||
def actor_ids
|
||||
ActivityPub::Actor.where(instance_id: self.instance_id).ids
|
||||
end
|
||||
|
||||
# Elimina la instancia de todas las listas
|
||||
#
|
||||
# @return [Boolean]
|
||||
|
|
|
@ -145,6 +145,19 @@ es:
|
|||
report:
|
||||
success: "Cuenta reportada a su instancia."
|
||||
error: "No se pudo reportar la cuenta. Hemos recibido el reporte y lo estaremos verificando."
|
||||
instance_moderations:
|
||||
action_on_several:
|
||||
success: "Se ha modificado el estado de moderación de varias instancias. Podés encontrarlas usando los filtros en la sección Instancias."
|
||||
error: "Hubo un error al modificar el estado de moderación de varias instancias. Hemos recibido el reporte y lo estaremos verificando."
|
||||
pause:
|
||||
success: "Instancia pausada. Todos los comentarios y cuentas de esta instancia necesitan ser aprobados manualmente. No se ha modificado el estado de moderación de cuentas y comentarios pre-existentes."
|
||||
error: "No se pudo pausar la instancia. Hemos recibido el reporte y lo estaremos verificando."
|
||||
allow:
|
||||
success: "Instancia permitida. Todos los comentarios y cuentas pendientes de moderación fueron aprobados y los próximos serán aprobados inmediatamente."
|
||||
error: "No se pudo permitir la instancia. Hemos recibido el reporte y lo estaremos verificando."
|
||||
block:
|
||||
success: "Instancia bloqueada. Todos los comentarios y cuentas serán rechazados inmediatamente. Todos los comentarios y cuentas pendientes de moderación fueron rechazados."
|
||||
error: "No se pudo bloquear la instancia. Hemos recibido el reporte y lo estaremos verificando."
|
||||
fediblock_states:
|
||||
action_on_several:
|
||||
success: "Se habilitaron las listas de bloqueo, podés encontrar las instancias filtrando por Bloqueadas. Todas las cuentas de estas instancias pendientes de moderación han sido bloqueadas. Podés activarlas individualmente en la sección Cuentas."
|
||||
|
|
Loading…
Reference in a new issue