mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-22 04: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 :activity_pubs, as: :object
|
||||
has_many :activities
|
||||
has_many :remote_flags
|
||||
|
||||
# Obtiene el nombre de la Actor como mención, solo si obtuvimos el
|
||||
# contenido de antemano.
|
||||
|
|
|
@ -58,13 +58,6 @@ class DeploySocialDistributedPress < Deploy
|
|||
|
||||
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
|
||||
# nuevas
|
||||
#
|
||||
|
@ -80,7 +73,7 @@ class DeploySocialDistributedPress < Deploy
|
|||
webhook_class.new.call({
|
||||
method: 'POST',
|
||||
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: {
|
||||
'X-Social-Inbox': rol.token
|
||||
|
|
|
@ -15,6 +15,7 @@ class Site
|
|||
has_many :actor_moderations
|
||||
has_many :fediblock_states
|
||||
has_many :instances, through: :instance_moderations
|
||||
has_many :remote_flags, class_name: 'ActivityPub::RemoteFlag'
|
||||
|
||||
before_save :generate_private_key_pem!, unless: :private_key_pem?
|
||||
|
||||
|
@ -23,6 +24,13 @@ class Site
|
|||
@social_inbox ||= SocialInbox.new(site: self)
|
||||
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
|
||||
|
||||
# Genera la llave privada y la almacena
|
||||
|
|
|
@ -37,13 +37,25 @@ class SocialInbox
|
|||
|
||||
# @return [DistributedPress::V1::Social::Client]
|
||||
def client
|
||||
@client ||= DistributedPress::V1::Social::Client.new(
|
||||
url: site.config.dig('activity_pub', 'url'),
|
||||
public_key_url: public_key_url,
|
||||
private_key_pem: site.private_key_pem,
|
||||
logger: Rails.logger,
|
||||
cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER'])
|
||||
)
|
||||
@client ||= client_for 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,
|
||||
private_key_pem: site.private_key_pem,
|
||||
logger: Rails.logger,
|
||||
cache_store: HTTParty::Cache::Store::Redis.new(redis_url: ENV['REDIS_SERVER'])
|
||||
)
|
||||
end
|
||||
|
||||
# @return [DistributedPress::V1::Social::Inbox]
|
||||
|
|
|
@ -11,6 +11,10 @@ Rails.application.routes.draw do
|
|||
namespace :v1 do
|
||||
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
|
||||
get :'invitades/cookie', to: 'invitades#cookie'
|
||||
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: -
|
||||
--
|
||||
|
@ -1762,6 +1776,14 @@ ALTER TABLE ONLY public.activity_pub_objects
|
|||
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: -
|
||||
--
|
||||
|
@ -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);
|
||||
|
||||
|
||||
--
|
||||
-- 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: -
|
||||
--
|
||||
|
@ -2653,6 +2696,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20240227134845'),
|
||||
('20240227142019'),
|
||||
('20240228171335'),
|
||||
('20240228202830');
|
||||
('20240228202830'),
|
||||
('20240229201155');
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue