mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 16:06:23 +00:00
feat: no permitir entrar al evento si falla la request
This commit is contained in:
parent
8f91b748ff
commit
8ff5626e99
8 changed files with 88 additions and 110 deletions
|
@ -9,14 +9,16 @@ class ActivityPubsController < ApplicationController
|
|||
authorize activity_pub
|
||||
|
||||
activity_pub.update(remote_flag_params(activity_pub)) if event == :report
|
||||
activity_pub.public_send(:"#{event}!") if activity_pub.public_send(:"may_#{event}?")
|
||||
|
||||
flash[:success] = I18n.t("activity_pubs.#{event}.success")
|
||||
rescue Exception => e
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h })
|
||||
message =
|
||||
if activity_pub.public_send(:"may_#{event}?") && activity_pub.public_send(:"#{event}!")
|
||||
:success
|
||||
else
|
||||
:error
|
||||
end
|
||||
|
||||
flash[message] = I18n.t("activity_pubs.#{event}.#{message}")
|
||||
|
||||
flash[:error] = I18n.t("activity_pubs.#{event}.error")
|
||||
ensure
|
||||
redirect_to_moderation_queue!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -17,14 +17,15 @@ class ActorModerationsController < ApplicationController
|
|||
# Crea una RemoteFlag si se envían los parámetros adecuados
|
||||
actor_moderation.update(remote_flag_params(actor_moderation)) if actor_event == :report
|
||||
|
||||
actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?")
|
||||
message =
|
||||
if actor_moderation.public_send(:"may_#{actor_event}?") && actor_moderation.public_send(:"#{actor_event}!")
|
||||
:success
|
||||
else
|
||||
:error
|
||||
end
|
||||
|
||||
flash[:success] = I18n.t("actor_moderations.#{actor_event}.success")
|
||||
rescue Exception => e
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, params: params.permit!.to_h })
|
||||
flash[message] = I18n.t("actor_moderations.#{actor_event}.#{message}")
|
||||
|
||||
flash[:error] = I18n.t("actor_moderations.#{actor_event}.error")
|
||||
ensure
|
||||
redirect_to_moderation_queue!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -8,14 +8,15 @@ class InstanceModerationsController < ApplicationController
|
|||
define_method(event) do
|
||||
authorize instance_moderation
|
||||
|
||||
instance_moderation.public_send(:"#{event}!") if instance_moderation.public_send(:"may_#{event}?")
|
||||
message =
|
||||
if instance_moderation.public_send(:"may_#{event}?") && instance_moderation.public_send(:"#{event}!")
|
||||
:success
|
||||
else
|
||||
:error
|
||||
end
|
||||
|
||||
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[message] = I18n.t("instance_moderations.#{event}.#{message}")
|
||||
|
||||
flash[:error] = I18n.t("instance_moderations.#{event}.error")
|
||||
ensure
|
||||
redirect_to_moderation_queue!
|
||||
end
|
||||
end
|
||||
|
|
|
@ -47,14 +47,19 @@ class ActivityPub < ApplicationRecord
|
|||
# Todavía no hay una decisión sobre el objeto
|
||||
state :paused, initial: true
|
||||
# Le usuarie aprobó el objeto
|
||||
state :approved
|
||||
state :approved, before_enter: :allow_remotely!
|
||||
# Le usuarie rechazó el objeto
|
||||
state :rejected
|
||||
state :rejected, before_enter: :reject_remotely!
|
||||
# Le usuarie reportó el objeto
|
||||
state :reported
|
||||
# Le actore eliminó el objeto
|
||||
state :removed
|
||||
|
||||
# Gestionar todos los errores
|
||||
error_on_all_events do |e|
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, activity_pub: self.id, activity: activities.first.uri })
|
||||
end
|
||||
|
||||
# Se puede volver a pausa en caso de actualización remota, para
|
||||
# revisar los cambios.
|
||||
event :pause do
|
||||
|
@ -67,7 +72,7 @@ class ActivityPub < ApplicationRecord
|
|||
event :remove do
|
||||
transitions to: :removed
|
||||
|
||||
before do
|
||||
after do
|
||||
next if object.blank?
|
||||
|
||||
object.update(content: {}) unless object.content.empty?
|
||||
|
@ -79,26 +84,18 @@ class ActivityPub < ApplicationRecord
|
|||
# webhook a modo de confirmación.
|
||||
event :approve do
|
||||
transitions from: %i[paused], to: :approved
|
||||
|
||||
before do
|
||||
allow_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# La actividad fue rechazada
|
||||
event :reject do
|
||||
transitions from: %i[paused], to: :rejected
|
||||
|
||||
before do
|
||||
reject_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# Solo podemos reportarla luego de rechazarla
|
||||
event :report do
|
||||
transitions from: :rejected, to: :reported
|
||||
|
||||
before do
|
||||
after do
|
||||
ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting?
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
# Mantiene la relación entre Site y Actor
|
||||
class ActorModeration < ApplicationRecord
|
||||
IGNORED_EVENTS = %i[remove]
|
||||
IGNORED_STATES = %i[removed]
|
||||
IGNORED_EVENTS = %i[remove].freeze
|
||||
IGNORED_STATES = %i[removed].freeze
|
||||
|
||||
include AASM
|
||||
|
||||
|
@ -14,38 +14,30 @@ class ActorModeration < ApplicationRecord
|
|||
accepts_nested_attributes_for :remote_flag
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
state :allowed
|
||||
state :blocked
|
||||
state :paused, initial: true, before_enter: :pause_remotely!
|
||||
state :allowed, before_enter: :allow_remotely!
|
||||
state :blocked, before_enter: :block_remotely!
|
||||
state :reported
|
||||
state :removed
|
||||
|
||||
error_on_all_events do |e|
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, actor: actor.uri, actor_moderation: id })
|
||||
end
|
||||
|
||||
event :pause do
|
||||
transitions from: %i[allowed blocked reported], to: :paused
|
||||
|
||||
before do
|
||||
pause_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# Al permitir una cuenta no se permiten todos los comentarios
|
||||
# pendientes de moderación que ya hizo.
|
||||
event :allow do
|
||||
transitions from: %i[paused blocked reported], to: :allowed
|
||||
|
||||
before do
|
||||
allow_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# Al bloquear una cuenta no se bloquean todos los comentarios
|
||||
# pendientes de moderación que hizo.
|
||||
event :block do
|
||||
transitions from: %i[paused allowed], to: :blocked
|
||||
|
||||
before do
|
||||
block_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# Al reportar, necesitamos asociar una RemoteFlag para poder
|
||||
|
@ -53,7 +45,7 @@ class ActorModeration < ApplicationRecord
|
|||
event :report do
|
||||
transitions from: %i[blocked], to: :reported
|
||||
|
||||
before do
|
||||
after do
|
||||
ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting?
|
||||
end
|
||||
end
|
||||
|
@ -63,8 +55,8 @@ class ActorModeration < ApplicationRecord
|
|||
event :remove do
|
||||
transitions to: :removed
|
||||
|
||||
before do
|
||||
site.activity_pubs.where(actor_id: self.actor_id).remove_all!
|
||||
after do
|
||||
site.activity_pubs.where(actor_id: actor_id).remove_all!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -16,7 +16,7 @@ module AasmEventsConcern
|
|||
#
|
||||
# @return [Array<Symbol>]
|
||||
def self.transitionable_events(current_state)
|
||||
self.events.select do |event|
|
||||
events.select do |event|
|
||||
aasm.events.find { |x| x.name == event }.transitions_from_state? current_state
|
||||
end
|
||||
end
|
||||
|
@ -32,19 +32,15 @@ module AasmEventsConcern
|
|||
# scope actual.
|
||||
#
|
||||
# @return [Bool] Si hubo al menos un error, devuelve false.
|
||||
self.aasm.events.map(&:name).each do |event|
|
||||
aasm.events.map(&:name).each do |event|
|
||||
define_singleton_method(:"#{event}_all!") do
|
||||
success = true
|
||||
successes = []
|
||||
|
||||
self.find_each do |object|
|
||||
object.public_send(:"#{event}!") if object.public_send(:"may_#{event}?")
|
||||
rescue Exception => e
|
||||
success = false
|
||||
|
||||
notify_exception! e, object
|
||||
find_each do |object|
|
||||
successes << (object.public_send(:"may_#{event}?") && object.public_send(:"#{event}!"))
|
||||
end
|
||||
|
||||
success
|
||||
successes.all?
|
||||
end
|
||||
|
||||
# Ejecuta la transición del evento en la base de datos sin
|
||||
|
@ -53,20 +49,13 @@ module AasmEventsConcern
|
|||
#
|
||||
# @return [Integer] Registros modificados
|
||||
define_singleton_method(:"#{event}_all_without_callbacks!") do
|
||||
aasm_event = self.aasm.events.find { |e| e.name == event }
|
||||
aasm_event = aasm.events.find { |e| e.name == event }
|
||||
to_state = aasm_event.transitions.map(&:to).first
|
||||
from_states = aasm_event.transitions.map(&:from)
|
||||
|
||||
self.unscope(where: :aasm_state).where(aasm_state: from_states).update_all(aasm_state: to_state, updated_at: Time.now)
|
||||
unscope(where: :aasm_state).where(aasm_state: from_states).update_all(aasm_state: to_state,
|
||||
updated_at: Time.now)
|
||||
end
|
||||
end
|
||||
|
||||
# Envía notificación de errores
|
||||
#
|
||||
# @param exception [Exception]
|
||||
# @param record [ApplicationRecord]
|
||||
def self.notify_exception!(exception, record)
|
||||
ExceptionNotifier.notify_exception(exception, data: { record_type: record.class.name, record_id: record.id })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -20,20 +20,15 @@ class FediblockState < ApplicationRecord
|
|||
# Aunque queramos las listas habilitadas por defecto, tenemos que
|
||||
# habilitarlas luego de crearlas para poder generar la lista de
|
||||
# bloqueo en la Social Inbox.
|
||||
state :disabled, initial: true
|
||||
state :enabled
|
||||
state :disabled, initial: true, before_enter: :disable_remotely_and_pause_instances!
|
||||
state :enabled, before_enter: :enable_remotely_and_block_instances!
|
||||
|
||||
error_on_all_events do |e|
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, fediblock: id })
|
||||
end
|
||||
|
||||
event :enable do
|
||||
transitions from: :disabled, to: :enabled
|
||||
|
||||
before do
|
||||
# Bloquear todos las instancias de este Fediblock
|
||||
enable_remotely! list_names(fediblock.hostnames)
|
||||
|
||||
# Luego esta tarea crea las que falten e ignora las que ya se
|
||||
# bloquearon.
|
||||
ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames, perform_remotely: false)
|
||||
end
|
||||
end
|
||||
|
||||
# Al deshabilitar, las listas pasan a modo pausa, a menos que estén
|
||||
|
@ -44,22 +39,31 @@ class FediblockState < ApplicationRecord
|
|||
# de list_names
|
||||
event :disable do
|
||||
transitions from: :enabled, to: :disabled
|
||||
|
||||
before do
|
||||
# Deshabilitar todas las instancias que no estén habilitadas por
|
||||
# otros fediblocks
|
||||
disable_remotely! list_names(unique_hostnames)
|
||||
|
||||
# Pausar todas las moderaciones de las instancias que no estén
|
||||
# bloqueadas por otros fediblocks.
|
||||
instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids
|
||||
site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def enable_remotely_and_block_instances!
|
||||
# Bloquear todos las instancias de este Fediblock
|
||||
enable_remotely! list_names(fediblock.hostnames)
|
||||
|
||||
# Luego esta tarea crea las que falten e ignora las que ya se
|
||||
# bloquearon.
|
||||
ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames, perform_remotely: false)
|
||||
end
|
||||
|
||||
def disable_remotely_and_pause_instances!
|
||||
# Deshabilitar todas las instancias que no estén habilitadas por
|
||||
# otros fediblocks
|
||||
disable_remotely! list_names(unique_hostnames)
|
||||
|
||||
# Pausar todas las moderaciones de las instancias que no estén
|
||||
# bloqueadas por otros fediblocks.
|
||||
instance_ids = ActivityPub::Instance.where(hostname: unique_hostnames).ids
|
||||
site.instance_moderations.where(instance_id: instance_ids).pause_all_without_callbacks!
|
||||
end
|
||||
|
||||
# Devuelve los hostnames únicos a esta instancia.
|
||||
#
|
||||
# @return [Array<String>]
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
|
||||
# Mantiene el registro de relaciones entre sitios e instancias
|
||||
class InstanceModeration < ApplicationRecord
|
||||
IGNORED_EVENTS = []
|
||||
IGNORED_STATES = []
|
||||
IGNORED_EVENTS = [].freeze
|
||||
IGNORED_STATES = [].freeze
|
||||
|
||||
include AASM
|
||||
|
||||
|
@ -11,38 +11,30 @@ class InstanceModeration < ApplicationRecord
|
|||
belongs_to :instance, class_name: 'ActivityPub::Instance'
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
state :allowed
|
||||
state :blocked
|
||||
state :paused, initial: true, before_enter: :pause_remotely!
|
||||
state :allowed, before_enter: :allow_remotely!
|
||||
state :blocked, before_enter: :block_remotely!
|
||||
|
||||
error_on_all_events do |e|
|
||||
ExceptionNotifier.notify_exception(e, data: { site: site.name, instance: instance.hostname, instance_moderation: id })
|
||||
end
|
||||
|
||||
# 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
|
||||
|
||||
before do
|
||||
pause_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# Al permitir, solo bloqueamos la instancia, sin modificar el estado
|
||||
# de les actores y comentarios retroactivamente.
|
||||
event :allow do
|
||||
transitions from: %i[paused blocked], to: :allowed
|
||||
|
||||
before do
|
||||
allow_remotely!
|
||||
end
|
||||
end
|
||||
|
||||
# Al bloquear, solo bloqueamos la instancia, sin modificar el estado
|
||||
# de les actores y comentarios retroactivamente.
|
||||
event :block do
|
||||
transitions from: %i[paused allowed], to: :blocked
|
||||
|
||||
before do
|
||||
block_remotely!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -51,7 +43,7 @@ class InstanceModeration < ApplicationRecord
|
|||
|
||||
# @return [Array<String>]
|
||||
def actor_ids
|
||||
ActivityPub::Actor.where(instance_id: self.instance_id).ids
|
||||
ActivityPub::Actor.where(instance_id: instance_id).ids
|
||||
end
|
||||
|
||||
# Elimina la instancia de todas las listas
|
||||
|
|
Loading…
Reference in a new issue