mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 11:16:22 +00:00
feat: enviar reportes remotos
This commit is contained in:
parent
6c61aec60e
commit
67d9731b1e
9 changed files with 146 additions and 16 deletions
|
@ -0,0 +1,27 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Api
|
||||||
|
module V1
|
||||||
|
module ActivityPub
|
||||||
|
# Devuelve los reportes remotos hechos
|
||||||
|
#
|
||||||
|
# @todo Verificar la firma. Por ahora no es necesario porque no es
|
||||||
|
# posible obtener remotamente todos los reportes y se identifican por
|
||||||
|
# UUIDv4.
|
||||||
|
class RemoteFlagsController < BaseController
|
||||||
|
skip_forgery_protection
|
||||||
|
|
||||||
|
def show
|
||||||
|
render json: (remote_flag&.content || {}), content_type: 'application/activity+json'
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
# @return [ActivityPub::RemoteFlag,nil]
|
||||||
|
def remote_flag
|
||||||
|
@remote_flag ||= ::ActivityPub::RemoteFlag.find(params[:id])
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
25
app/jobs/activity_pub/remote_flag_job.rb
Normal file
25
app/jobs/activity_pub/remote_flag_job.rb
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Envía un reporte directamente a la instancia remota
|
||||||
|
#
|
||||||
|
# @todo El panel debería ser su propia instancia y firmar sus propios
|
||||||
|
# mensajes.
|
||||||
|
# @todo Como la Social Inbox no soporta enviar actividades
|
||||||
|
# a destinataries que no sean seguidores, enviamos el reporte
|
||||||
|
# directamente a la instancia.
|
||||||
|
# @see {https://github.com/hyphacoop/social.distributed.press/issues/14}
|
||||||
|
class ActivityPub
|
||||||
|
class RemoteFlagJob < ApplicationJob
|
||||||
|
self.priority = 30
|
||||||
|
|
||||||
|
def perform(remote_flag:)
|
||||||
|
client = remote_flag.site.social_inbox.client_for(remote_flag.actor.content['inbox'])
|
||||||
|
response = client.post(endpoint: '', body: remote_flag.content)
|
||||||
|
|
||||||
|
raise 'No se pudo enviar el reporte' unless response.ok?
|
||||||
|
rescue Exception => e
|
||||||
|
ExceptionNotifier.notify_exception(e, data: { remote_flag: remote_flag.id, response: response.parsed_response })
|
||||||
|
raise
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -13,6 +13,7 @@ class ActivityPub
|
||||||
has_many :actor_moderation
|
has_many :actor_moderation
|
||||||
has_many :activity_pubs, as: :object
|
has_many :activity_pubs, as: :object
|
||||||
has_many :activities
|
has_many :activities
|
||||||
|
has_many :remote_flags
|
||||||
|
|
||||||
# Obtiene el nombre de la Actor como mención, solo si obtuvimos el
|
# Obtiene el nombre de la Actor como mención, solo si obtuvimos el
|
||||||
# contenido de antemano.
|
# contenido de antemano.
|
||||||
|
|
|
@ -58,13 +58,6 @@ class DeploySocialDistributedPress < Deploy
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Obtiene el hostname de la API de Sutty
|
|
||||||
#
|
|
||||||
# @return [String]
|
|
||||||
def api_hostname
|
|
||||||
Rails.application.routes.default_url_options[:host].sub('panel', 'api')
|
|
||||||
end
|
|
||||||
|
|
||||||
# Crea los hooks en la Social Inbox para que nos avise de actividades
|
# Crea los hooks en la Social Inbox para que nos avise de actividades
|
||||||
# nuevas
|
# nuevas
|
||||||
#
|
#
|
||||||
|
@ -80,7 +73,7 @@ class DeploySocialDistributedPress < Deploy
|
||||||
webhook_class.new.call({
|
webhook_class.new.call({
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
url: Rails.application.routes.url_helpers.public_send(
|
url: Rails.application.routes.url_helpers.public_send(
|
||||||
event_url, site_id: site.name, host: api_hostname
|
event_url, site_id: site.name, host: site.social_inbox_hostname
|
||||||
),
|
),
|
||||||
headers: {
|
headers: {
|
||||||
'X-Social-Inbox': rol.token
|
'X-Social-Inbox': rol.token
|
||||||
|
|
|
@ -15,6 +15,7 @@ class Site
|
||||||
has_many :actor_moderations
|
has_many :actor_moderations
|
||||||
has_many :fediblock_states
|
has_many :fediblock_states
|
||||||
has_many :instances, through: :instance_moderations
|
has_many :instances, through: :instance_moderations
|
||||||
|
has_many :remote_flags, class_name: 'ActivityPub::RemoteFlag'
|
||||||
|
|
||||||
before_save :generate_private_key_pem!, unless: :private_key_pem?
|
before_save :generate_private_key_pem!, unless: :private_key_pem?
|
||||||
|
|
||||||
|
@ -23,6 +24,13 @@ class Site
|
||||||
@social_inbox ||= SocialInbox.new(site: self)
|
@social_inbox ||= SocialInbox.new(site: self)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# Obtiene el hostname de la API de Sutty
|
||||||
|
#
|
||||||
|
# @return [String]
|
||||||
|
def social_inbox_hostname
|
||||||
|
Rails.application.routes.default_url_options[:host].sub('panel', 'api')
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
# Genera la llave privada y la almacena
|
# Genera la llave privada y la almacena
|
||||||
|
|
|
@ -37,8 +37,20 @@ class SocialInbox
|
||||||
|
|
||||||
# @return [DistributedPress::V1::Social::Client]
|
# @return [DistributedPress::V1::Social::Client]
|
||||||
def client
|
def client
|
||||||
@client ||= DistributedPress::V1::Social::Client.new(
|
@client ||= client_for site.config.dig('activity_pub', 'url')
|
||||||
url: site.config.dig('activity_pub', 'url'),
|
end
|
||||||
|
|
||||||
|
# Permite enviar mensajes directo a otro servidor
|
||||||
|
#
|
||||||
|
# @param url [String]
|
||||||
|
# @return [DistributedPress::V1::Social::Client]
|
||||||
|
def client_for(url)
|
||||||
|
raise "Falló generar un cliente" if url.blank?
|
||||||
|
|
||||||
|
@client_for ||= {}
|
||||||
|
@client_for[url] ||=
|
||||||
|
DistributedPress::V1::Social::Client.new(
|
||||||
|
url: url,
|
||||||
public_key_url: public_key_url,
|
public_key_url: public_key_url,
|
||||||
private_key_pem: site.private_key_pem,
|
private_key_pem: site.private_key_pem,
|
||||||
logger: Rails.logger,
|
logger: Rails.logger,
|
||||||
|
|
|
@ -11,6 +11,10 @@ Rails.application.routes.draw do
|
||||||
namespace :v1 do
|
namespace :v1 do
|
||||||
resources :csp_reports, only: %i[create]
|
resources :csp_reports, only: %i[create]
|
||||||
|
|
||||||
|
namespace :activity_pub do
|
||||||
|
resources :remote_flags, only: %i[show]
|
||||||
|
end
|
||||||
|
|
||||||
resources :sites, only: %i[index], constraints: { site_id: /[a-z0-9\-.]+/, id: /[a-z0-9\-.]+/ } do
|
resources :sites, only: %i[index], constraints: { site_id: /[a-z0-9\-.]+/, id: /[a-z0-9\-.]+/ } do
|
||||||
get :'invitades/cookie', to: 'invitades#cookie'
|
get :'invitades/cookie', to: 'invitades#cookie'
|
||||||
post :'posts/:layout', to: 'posts#create', as: :posts
|
post :'posts/:layout', to: 'posts#create', as: :posts
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
# Lleva el registro de reportes remotos
|
||||||
|
class CreateActivityPubRemoteFlags < ActiveRecord::Migration[6.1]
|
||||||
|
def change
|
||||||
|
create_table :activity_pub_remote_flags, id: :uuid do |t|
|
||||||
|
t.timestamps
|
||||||
|
t.belongs_to :site
|
||||||
|
t.uuid :actor_id, index: true
|
||||||
|
|
||||||
|
t.text :message
|
||||||
|
|
||||||
|
t.index %i[site_id actor_id], unique: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -546,6 +546,20 @@ CREATE TABLE public.activity_pub_objects (
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: activity_pub_remote_flags; Type: TABLE; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE TABLE public.activity_pub_remote_flags (
|
||||||
|
id uuid DEFAULT gen_random_uuid() NOT NULL,
|
||||||
|
created_at timestamp(6) without time zone NOT NULL,
|
||||||
|
updated_at timestamp(6) without time zone NOT NULL,
|
||||||
|
site_id bigint,
|
||||||
|
actor_id uuid,
|
||||||
|
message text
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: activity_pubs; Type: TABLE; Schema: public; Owner: -
|
-- Name: activity_pubs; Type: TABLE; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -1762,6 +1776,14 @@ ALTER TABLE ONLY public.activity_pub_objects
|
||||||
ADD CONSTRAINT activity_pub_objects_pkey PRIMARY KEY (id);
|
ADD CONSTRAINT activity_pub_objects_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: activity_pub_remote_flags activity_pub_remote_flags_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
ALTER TABLE ONLY public.activity_pub_remote_flags
|
||||||
|
ADD CONSTRAINT activity_pub_remote_flags_pkey PRIMARY KEY (id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: activity_pubs activity_pubs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
-- Name: activity_pubs activity_pubs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -2122,6 +2144,27 @@ CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USIN
|
||||||
CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname);
|
CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_activity_pub_remote_flags_on_actor_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_activity_pub_remote_flags_on_actor_id ON public.activity_pub_remote_flags USING btree (actor_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_activity_pub_remote_flags_on_site_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE INDEX index_activity_pub_remote_flags_on_site_id ON public.activity_pub_remote_flags USING btree (site_id);
|
||||||
|
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Name: index_activity_pub_remote_flags_on_site_id_and_actor_id; Type: INDEX; Schema: public; Owner: -
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE UNIQUE INDEX index_activity_pub_remote_flags_on_site_id_and_actor_id ON public.activity_pub_remote_flags USING btree (site_id, actor_id);
|
||||||
|
|
||||||
|
|
||||||
--
|
--
|
||||||
-- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: -
|
-- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: -
|
||||||
--
|
--
|
||||||
|
@ -2653,6 +2696,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
||||||
('20240227134845'),
|
('20240227134845'),
|
||||||
('20240227142019'),
|
('20240227142019'),
|
||||||
('20240228171335'),
|
('20240228171335'),
|
||||||
('20240228202830');
|
('20240228202830'),
|
||||||
|
('20240229201155');
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue