# 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 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 state :enabled event :enable do transitions from: :disabled, to: :enabled before do enable_remotely! # Al actualizar el estado en masa garantizamos que las # instancias que ya existen queden sincronizadas con el bloqueo # en masa que acabamos de hacer. instance_moderations.block_all! # Luego esta tarea crea las que falten e ignora las que ya se # bloquearon. ActivityPub::InstanceModerationJob.perform_now(site: site, hostnames: fediblock.hostnames) end end # Al deshabilitar, las listas pasan a modo pausa. # # @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 before do disable_remotely! instance_moderations.pause_all! end end end private # Todas las instancias de moderación de este sitio def instance_moderations site.instance_moderations.where(instance_id: fediblock.instances.pluck(:id)) end # @return [Array] def list_names @list_names ||= fediblock.instances.map do |instance| "@*@#{instance}" end end # Al deshabilitar, las instancias pasan a ser analizadas caso por caso def disable_remotely! raise AASM::InvalidTransition unless site.social_inbox.blocklist.delete(list: list_names).ok? && site.social_inbox.allowlist.delete(list: list_names).ok? end # Al habilitar, se bloquean todas las instancias de la lista def enable_remotely! raise AASM::InvalidTransition unless site.social_inbox.blocklist.post(list: list_names).ok? && site.social_inbox.allowlist.delete(list: list_names).ok? end end