5
0
Fork 0
mirror of https://0xacab.org/sutty/sutty synced 2024-11-23 00:16:23 +00:00
panel/app/models/activity_pub.rb

115 lines
3.1 KiB
Ruby
Raw Normal View History

# frozen_string_literal: true
# = ActivityPub =
#
# El registro de actividades recibidas y su estado. Cuando recibimos
# una actividad, puede estar destinada a varies actores dentro de Sutty,
# con lo que generamos una cola para cada une.
#
# @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions}
class ActivityPub < ApplicationRecord
IGNORED_EVENTS = %i[pause remove].freeze
IGNORED_STATES = %i[removed].freeze
include AASM
belongs_to :instance
belongs_to :site
belongs_to :object, polymorphic: true
2024-03-04 14:59:29 +00:00
belongs_to :actor
2024-03-06 18:36:00 +00:00
belongs_to :remote_flag, optional: true, class_name: 'ActivityPub::RemoteFlag'
has_many :activities
validates :site_id, presence: true
validates :object_id, presence: true
validates :aasm_state, presence: true, inclusion: { in: %w[paused approved rejected reported removed] }
2024-03-05 17:18:06 +00:00
accepts_nested_attributes_for :remote_flag
# Encuentra la URI de un objeto
#
# @return [String, nil]
def self.uri_from_object(object)
case object
2024-03-01 20:29:08 +00:00
when Array then uri_from_object(object.first)
when String then object
2024-03-01 20:29:08 +00:00
when Hash then (object['id'] || object[:id])
end
end
aasm do
# Todavía no hay una decisión sobre el objeto
state :paused, initial: true
# Le usuarie aprobó el objeto
state :approved
# Le usuarie rechazó el objeto
state :rejected
# Le usuarie reportó el objeto
state :reported
# Le actore eliminó el objeto
2024-02-21 18:44:41 +00:00
state :removed
# Se puede volver a pausa en caso de actualización remota, para
# revisar los cambios.
event :pause do
transitions to: :paused
end
# Recibir una acción de eliminación, eliminar el contenido de la
# base de datos. Esto elimina el contenido para todos los sitios
# porque estamos respetando lo que pidió le actore.
2024-02-21 18:44:41 +00:00
event :remove do
transitions to: :removed
before do
next if object.blank?
2024-02-21 20:05:17 +00:00
object.update(content: {}) unless object.content.empty?
end
end
2024-03-04 19:46:43 +00:00
# La actividad se aprueba, informándole a la Social Inbox que está
# aprobada. También recibimos la aprobación via
# webhook a modo de confirmación.
event :approve do
transitions from: %i[paused], to: :approved
2024-03-04 19:46:43 +00:00
before do
allow_remotely!
2024-03-04 19:46:43 +00:00
end
end
# La actividad fue rechazada
event :reject do
transitions from: %i[paused approved], to: :rejected
2024-03-04 19:46:43 +00:00
before do
reject_remotely!
2024-03-04 19:46:43 +00:00
end
end
# Solo podemos reportarla luego de rechazarla
event :report do
transitions from: :rejected, to: :reported
2024-03-05 17:18:06 +00:00
before do
ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) if remote_flag.waiting?
2024-03-05 17:18:06 +00:00
end
end
end
2024-03-13 14:15:31 +00:00
# Definir eventos en masa
include AasmEventsConcern
# Lo que tenemos que aprobar o rechazar es la última actividad
# disponible, que según el scope por defecto, va a ser la primera de
# la lista.
def reject_remotely!
raise unless site.social_inbox.inbox.reject(id: activities.first.uri).ok?
end
def allow_remotely!
raise unless site.social_inbox.inbox.accept(id: activities.first.uri).ok?
end
end