mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-19 19:26:21 +00:00
feat: modelo de datos de activitypub #15109
This commit is contained in:
parent
b4117d7c34
commit
27c0ca655e
25 changed files with 435 additions and 1 deletions
33
app/models/activity_pub.rb
Normal file
33
app/models/activity_pub.rb
Normal file
|
@ -0,0 +1,33 @@
|
|||
# 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
|
||||
include AASM
|
||||
|
||||
belongs_to :site
|
||||
belongs_to :object, polymorphic: true
|
||||
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 deleted] }
|
||||
|
||||
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
|
||||
state :deleted
|
||||
end
|
||||
end
|
24
app/models/activity_pub/activity.rb
Normal file
24
app/models/activity_pub/activity.rb
Normal file
|
@ -0,0 +1,24 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Activity =
|
||||
#
|
||||
# Lleva un registro de las actividades que nos piden hacer remotamente.
|
||||
#
|
||||
# Las actividades pueden tener distintos destinataries (sitios/actores).
|
||||
#
|
||||
# @todo Obtener el contenido del objeto dinámicamente si no existe
|
||||
# localmente, por ejemplo cuando la actividad crea un objeto pero lo
|
||||
# envía como referencia en lugar de anidarlo.
|
||||
#
|
||||
# @see {https://www.w3.org/TR/activitypub/#client-to-server-interactions}
|
||||
class ActivityPub::Activity < ApplicationRecord
|
||||
include ActivityPub::Concerns::JsonLdConcern
|
||||
|
||||
belongs_to :activity_pub
|
||||
has_one :object, through: :activity_pub
|
||||
|
||||
validates :activity_pub_id, presence: true
|
||||
|
||||
# Siempre en orden descendiente para saber el último estado
|
||||
default_scope -> { order(created_at: :desc) }
|
||||
end
|
3
app/models/activity_pub/activity/create.rb
Normal file
3
app/models/activity_pub/activity/create.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::Create < ActivityPub::Activity; end
|
3
app/models/activity_pub/activity/delete.rb
Normal file
3
app/models/activity_pub/activity/delete.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::Delete < ActivityPub::Activity; end
|
3
app/models/activity_pub/activity/flag.rb
Normal file
3
app/models/activity_pub/activity/flag.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::Flag < ActivityPub::Activity; end
|
7
app/models/activity_pub/activity/follow.rb
Normal file
7
app/models/activity_pub/activity/follow.rb
Normal file
|
@ -0,0 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Follow =
|
||||
#
|
||||
# Una actividad de seguimiento se refiere siempre a une actore (el
|
||||
# sitio) y proviene de otre actore.
|
||||
class ActivityPub::Activity::Follow < ActivityPub::Activity; end
|
3
app/models/activity_pub/activity/generic.rb
Normal file
3
app/models/activity_pub/activity/generic.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::Generic < ActivityPub::Activity; end
|
8
app/models/activity_pub/activity/undo.rb
Normal file
8
app/models/activity_pub/activity/undo.rb
Normal file
|
@ -0,0 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Undo =
|
||||
#
|
||||
# Deshace una actividad, dependiendo de la actividad a la que se
|
||||
# refiere.
|
||||
class ActivityPub::Activity::Undo < ActivityPub::Activity
|
||||
end
|
3
app/models/activity_pub/activity/update.rb
Normal file
3
app/models/activity_pub/activity/update.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub::Activity::Update < ActivityPub::Activity; end
|
14
app/models/activity_pub/actor.rb
Normal file
14
app/models/activity_pub/actor.rb
Normal file
|
@ -0,0 +1,14 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Actor =
|
||||
#
|
||||
# Actor es la entidad que realiza acciones en ActivityPub
|
||||
#
|
||||
# @todo Obtener el perfil dinámicamente
|
||||
class ActivityPub::Actor < ApplicationRecord
|
||||
include ActivityPub::Concerns::JsonLdConcern
|
||||
|
||||
belongs_to :instance
|
||||
has_many :activity_pubs, as: :object
|
||||
has_many :objects
|
||||
end
|
32
app/models/activity_pub/concerns/json_ld_concern.rb
Normal file
32
app/models/activity_pub/concerns/json_ld_concern.rb
Normal file
|
@ -0,0 +1,32 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ActivityPub
|
||||
module Concerns
|
||||
module JsonLdConcern
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
included do
|
||||
validates :uri, presence: true, uniqueness: true
|
||||
|
||||
# Cuando asignamos contenido, obtener la URI si no lo hicimos ya
|
||||
before_save :uri_from_content!, unless: :uri?
|
||||
|
||||
# Obtiene un tipo de actividad a partir del tipo informado
|
||||
#
|
||||
# @param object [Hash]
|
||||
# @return [Activity]
|
||||
def self.type_from(object)
|
||||
"#{self.class.name}::#{object[:type].presence || 'Generic'}".constantize
|
||||
rescue NameError
|
||||
self.class::Generic
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def uri_from_content!
|
||||
self.uri = content[:id]
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
21
app/models/activity_pub/instance.rb
Normal file
21
app/models/activity_pub/instance.rb
Normal file
|
@ -0,0 +1,21 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Instance =
|
||||
#
|
||||
# Representa cada instancia del fediverso que interactúa con la Social
|
||||
# Inbox.
|
||||
class ActivityPub::Instance < ApplicationRecord
|
||||
include AASM
|
||||
|
||||
validates :aasm_state, presence: true, inclusion: { in: %w[paused allowed blocked] }
|
||||
validates :hostname, uniqueness: true, hostname: true
|
||||
|
||||
has_many :activity_pubs
|
||||
has_many :actors
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
state :allowed
|
||||
state :blocked
|
||||
end
|
||||
end
|
11
app/models/activity_pub/object.rb
Normal file
11
app/models/activity_pub/object.rb
Normal file
|
@ -0,0 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Almacena objetos de ActivityPub, como Note, Article, etc.
|
||||
class ActivityPub::Object < ApplicationRecord
|
||||
include ActivityPub::Concerns::JsonLdConcern
|
||||
|
||||
belongs_to :actor
|
||||
has_many :activity_pubs, as: :object
|
||||
|
||||
validates :actor_id, presence: true
|
||||
end
|
6
app/models/activity_pub/object/application.rb
Normal file
6
app/models/activity_pub/object/application.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Application =
|
||||
#
|
||||
# Una aplicación o instancia
|
||||
class ActivityPub::Object::Application < ActivityPub::Object; end
|
6
app/models/activity_pub/object/article.rb
Normal file
6
app/models/activity_pub/object/article.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Article =
|
||||
#
|
||||
# Representa artículos
|
||||
class ActivityPub::Object::Article < ActivityPub::Object; end
|
4
app/models/activity_pub/object/generic.rb
Normal file
4
app/models/activity_pub/object/generic.rb
Normal file
|
@ -0,0 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Generic =
|
||||
class ActivityPub::Object::Generic < ActivityPub::Object; end
|
6
app/models/activity_pub/object/note.rb
Normal file
6
app/models/activity_pub/object/note.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Note =
|
||||
#
|
||||
# Representa notas, el tipo más común de objeto del Fediverso.
|
||||
class ActivityPub::Object::Note < ActivityPub::Object; end
|
6
app/models/activity_pub/object/organization.rb
Normal file
6
app/models/activity_pub/object/organization.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Organization =
|
||||
#
|
||||
# Una organización
|
||||
class ActivityPub::Object::Organization < ActivityPub::Object; end
|
6
app/models/activity_pub/object/person.rb
Normal file
6
app/models/activity_pub/object/person.rb
Normal file
|
@ -0,0 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# = Person =
|
||||
#
|
||||
# Una persona, el perfil de une actore
|
||||
class ActivityPub::Object::Person < ActivityPub::Object; end
|
16
db/migrate/20240219153919_create_activity_pub_activities.rb
Normal file
16
db/migrate/20240219153919_create_activity_pub_activities.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Actividades. Se asocian a un objeto y a una cola de moderación
|
||||
class CreateActivityPubActivities < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :activity_pub_activities, id: :uuid do |t|
|
||||
t.timestamps
|
||||
|
||||
t.uuid :activity_pub_id, index: true, null: false
|
||||
|
||||
t.string :type, null: false
|
||||
t.string :uri, null: false
|
||||
t.jsonb :content, default: {}
|
||||
end
|
||||
end
|
||||
end
|
12
db/migrate/20240219175839_create_activity_pub_actors.rb
Normal file
12
db/migrate/20240219175839_create_activity_pub_actors.rb
Normal file
|
@ -0,0 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Almacena actores de ActivityPub y los relaciona con actividades
|
||||
class CreateActivityPubActors < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :activity_pub_actors, id: :uuid do |t|
|
||||
t.timestamps
|
||||
t.uuid :instance_id, index: true, null: false
|
||||
t.string :uri, index: true, unique: true, null: false
|
||||
end
|
||||
end
|
||||
end
|
18
db/migrate/20240219204011_create_activity_pubs.rb
Normal file
18
db/migrate/20240219204011_create_activity_pubs.rb
Normal file
|
@ -0,0 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Registro de actividades.
|
||||
class CreateActivityPubs < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :activity_pubs, id: :uuid do |t|
|
||||
t.timestamps
|
||||
|
||||
t.bigint :site_id, null: false
|
||||
t.uuid :object_id, null: false
|
||||
t.string :object_type, null: false
|
||||
|
||||
t.string :aasm_state, null: false
|
||||
|
||||
t.index %i[site_id object_id object_type], unique: true
|
||||
end
|
||||
end
|
||||
end
|
17
db/migrate/20240219204224_create_activity_pub_objects.rb
Normal file
17
db/migrate/20240219204224_create_activity_pub_objects.rb
Normal file
|
@ -0,0 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Almacena objetos de ActivityPub. Los objetos pueden estar compartidos
|
||||
# por toda la instancia.
|
||||
class CreateActivityPubObjects < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :activity_pub_objects, id: :uuid do |t|
|
||||
t.timestamps
|
||||
|
||||
t.uuid :actor_id, index: true, null: false
|
||||
|
||||
t.string :type, null: false
|
||||
t.string :uri, null: false, unique: true
|
||||
t.jsonb :content, default: {}
|
||||
end
|
||||
end
|
||||
end
|
13
db/migrate/20240220161414_create_activity_pub_instances.rb
Normal file
13
db/migrate/20240220161414_create_activity_pub_instances.rb
Normal file
|
@ -0,0 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Almacena las instancias
|
||||
class CreateActivityPubInstances < ActiveRecord::Migration[6.1]
|
||||
def change
|
||||
create_table :activity_pub_instances, id: :uuid do |t|
|
||||
t.timestamps
|
||||
t.string :hostname, index: true, unique: true, null: false
|
||||
t.string :aasm_state, null: false
|
||||
t.jsonb :content, default: {}
|
||||
end
|
||||
end
|
||||
end
|
161
db/structure.sql
161
db/structure.sql
|
@ -473,6 +473,78 @@ CREATE SEQUENCE public.active_storage_variant_records_id_seq
|
|||
ALTER SEQUENCE public.active_storage_variant_records_id_seq OWNED BY public.active_storage_variant_records.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_activities; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.activity_pub_activities (
|
||||
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,
|
||||
activity_pub_id uuid NOT NULL,
|
||||
type character varying NOT NULL,
|
||||
uri character varying NOT NULL,
|
||||
content jsonb DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_actors; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.activity_pub_actors (
|
||||
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,
|
||||
instance_id uuid NOT NULL,
|
||||
uri character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_instances; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.activity_pub_instances (
|
||||
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,
|
||||
hostname character varying NOT NULL,
|
||||
aasm_state character varying NOT NULL,
|
||||
content jsonb DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_objects; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.activity_pub_objects (
|
||||
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,
|
||||
actor_id uuid NOT NULL,
|
||||
type character varying NOT NULL,
|
||||
uri character varying NOT NULL,
|
||||
content jsonb DEFAULT '{}'::jsonb
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pubs; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.activity_pubs (
|
||||
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 NOT NULL,
|
||||
object_id uuid NOT NULL,
|
||||
object_type character varying NOT NULL,
|
||||
aasm_state character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: ar_internal_metadata; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1565,6 +1637,46 @@ ALTER TABLE ONLY public.active_storage_variant_records
|
|||
ADD CONSTRAINT active_storage_variant_records_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_activities activity_pub_activities_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.activity_pub_activities
|
||||
ADD CONSTRAINT activity_pub_activities_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_actors activity_pub_actors_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.activity_pub_actors
|
||||
ADD CONSTRAINT activity_pub_actors_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_instances activity_pub_instances_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.activity_pub_instances
|
||||
ADD CONSTRAINT activity_pub_instances_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pub_objects activity_pub_objects_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.activity_pub_objects
|
||||
ADD CONSTRAINT activity_pub_objects_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: activity_pubs activity_pubs_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.activity_pubs
|
||||
ADD CONSTRAINT activity_pubs_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: blazer_audits blazer_audits_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1865,6 +1977,48 @@ CREATE UNIQUE INDEX index_active_storage_blobs_on_key_and_service_name ON public
|
|||
CREATE UNIQUE INDEX index_active_storage_variant_records_uniqueness ON public.active_storage_variant_records USING btree (blob_id, variation_digest);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_activity_pub_activities_on_activity_pub_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_activity_pub_activities_on_activity_pub_id ON public.activity_pub_activities USING btree (activity_pub_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_activity_pub_actors_on_instance_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_activity_pub_actors_on_instance_id ON public.activity_pub_actors USING btree (instance_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_activity_pub_actors_on_uri; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_activity_pub_actors_on_uri ON public.activity_pub_actors USING btree (uri);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_activity_pub_instances_on_hostname; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_activity_pub_instances_on_hostname ON public.activity_pub_instances USING btree (hostname);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_activity_pub_objects_on_actor_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_activity_pub_objects_on_actor_id ON public.activity_pub_objects USING btree (actor_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_activity_pubs_on_site_id_and_object_id_and_object_type; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_activity_pubs_on_site_id_and_object_id_and_object_type ON public.activity_pubs USING btree (site_id, object_id, object_type);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_blazer_audits_on_query_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2320,6 +2474,11 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20230829204127'),
|
||||
('20230921155401'),
|
||||
('20230927153926'),
|
||||
('20240216170202');
|
||||
('20240216170202'),
|
||||
('20240219153919'),
|
||||
('20240219175839'),
|
||||
('20240219204011'),
|
||||
('20240219204224'),
|
||||
('20240220161414');
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue