5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-22 19:26:21 +00:00
panel/app/models/fediblock_state.rb

112 lines
3.5 KiB
Ruby
Raw Normal View History

2024-02-27 16:43:46 +00:00
# frozen_string_literal: true
# Relación entre Fediblocks y Sites.
#
# Cuando se habilita un Fediblock, tenemos que asociar todas sus
# instancias con el sitio y bloquearlas. Cuando se deshabilita, la
# relación ya está creada y se va actualizando.
#
# @see ActivityPub::FediblockUpdatedJob
2024-02-27 16:43:46 +00:00
class FediblockState < ApplicationRecord
include AASM
belongs_to :site
belongs_to :fediblock, class_name: 'ActivityPub::Fediblock'
# El efecto secundario de esta máquina de estados es modificar el
# estado de moderación de cada instancia en el sitio. Nos salteamos
# los hooks de los eventos individuales.
aasm do
# 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, 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
2024-02-27 16:43:46 +00:00
event :enable do
transitions from: :disabled, to: :enabled
end
# Al deshabilitar, las listas pasan a modo pausa, a menos que estén
# activas en otros listados.
2024-02-27 16:43:46 +00:00
#
# @todo No cambiar el estado si se habían habilitado manualmente,
# pero esto implica que tenemos que encontrar las que sí y quitarlas
# de list_names
event :disable do
transitions from: :enabled, to: :disabled
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>]
def unique_hostnames
@unique_hostnames ||=
begin
other_enabled_fediblock_ids =
site.fediblock_states.enabled.where.not(id: id).pluck(:fediblock_id)
other_enabled_hostnames =
ActivityPub::Fediblock
.where(id: other_enabled_fediblock_ids)
.pluck(:hostnames)
.flatten
.uniq
fediblock.hostnames - other_enabled_hostnames
end
2024-02-27 16:43:46 +00:00
end
# @param hostnames [Array<String>]
2024-02-27 16:43:46 +00:00
# @return [Array<String>]
def list_names(hostnames)
hostnames.map do |hostname|
2024-03-06 18:03:17 +00:00
"@*@#{hostname}"
2024-02-27 16:43:46 +00:00
end
end
# Al deshabilitar, las instancias pasan a ser analizadas caso por caso
#
# @param list [Array<String>]
def disable_remotely!(list)
2024-03-06 17:31:32 +00:00
raise unless
site.social_inbox.blocklist.delete(list: list).ok? &&
site.social_inbox.allowlist.delete(list: list).ok?
2024-02-27 16:43:46 +00:00
end
# Al habilitar, se bloquean todas las instancias de la lista
#
# @param list [Array<String>]
def enable_remotely!(list)
2024-03-06 17:31:32 +00:00
raise unless
site.social_inbox.blocklist.post(list: list).ok? &&
site.social_inbox.allowlist.delete(list: list).ok?
2024-02-27 16:43:46 +00:00
end
end