mirror of
https://0xacab.org/sutty/sutty
synced 2024-11-21 22:56:22 +00:00
feat: cada sitio tiene un estado de moderación para la instancia
This commit is contained in:
parent
64cef8a13e
commit
dc11e6efc7
14 changed files with 200 additions and 11 deletions
|
@ -142,7 +142,8 @@ module Api
|
|||
end
|
||||
end
|
||||
|
||||
# Actor, si no hay instancia, la crea en el momento
|
||||
# Actor, si no hay instancia, la crea en el momento, junto con
|
||||
# su estado de moderación.
|
||||
#
|
||||
# @return [Actor]
|
||||
def actor
|
||||
|
@ -150,6 +151,8 @@ module Api
|
|||
unless a.instance
|
||||
a.instance = ActivityPub::Instance.find_or_create_by(hostname: URI.parse(a.uri).hostname)
|
||||
|
||||
site.instance_moderations.find_or_create_by(instance: a.instance)
|
||||
|
||||
ActivityPub::InstanceFetchJob.perform_later(site: site, instance: a.instance)
|
||||
end
|
||||
|
||||
|
|
35
app/controllers/instance_moderations_controller.rb
Normal file
35
app/controllers/instance_moderations_controller.rb
Normal file
|
@ -0,0 +1,35 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Actualiza la relación entre un sitio y una instancia
|
||||
class InstanceModerationsController < ApplicationController
|
||||
before_action :authorize_policy
|
||||
|
||||
def pause
|
||||
instance_moderation.pause!
|
||||
|
||||
redirect_to site_moderation_queue_path
|
||||
end
|
||||
|
||||
def allow
|
||||
instance_moderation.allow!
|
||||
|
||||
redirect_to site_moderation_queue_path
|
||||
end
|
||||
|
||||
def block
|
||||
instance_moderation.block!
|
||||
|
||||
redirect_to site_moderation_queue_path
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# @return [InstanceModeration]
|
||||
def instance_moderation
|
||||
@instance_moderation ||= site.instance_moderations.find(params[:instance_moderation_id])
|
||||
end
|
||||
|
||||
def authorize_policy
|
||||
authorize instance_moderation
|
||||
end
|
||||
end
|
|
@ -8,7 +8,7 @@ class ModerationQueueController < ApplicationController
|
|||
|
||||
# @todo cambiar el estado por query
|
||||
@activity_pubs = site.activity_pubs
|
||||
@instances = ActivityPub::Instance.where(id: @activity_pubs.distinct.pluck(:instance_id))
|
||||
@instance_moderations = site.instance_moderations
|
||||
end
|
||||
|
||||
# Perfil remoto de usuarie
|
||||
|
|
|
@ -13,6 +13,7 @@ class ActivityPub
|
|||
|
||||
has_many :activity_pubs
|
||||
has_many :actors
|
||||
has_many :instance_moderations
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
|
|
27
app/models/instance_moderation.rb
Normal file
27
app/models/instance_moderation.rb
Normal file
|
@ -0,0 +1,27 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Mantiene el registro de relaciones entre sitios e instancias
|
||||
class InstanceModeration < ApplicationRecord
|
||||
include AASM
|
||||
|
||||
belongs_to :site
|
||||
belongs_to :instance, class_name: 'ActivityPub::Instance'
|
||||
|
||||
aasm do
|
||||
state :paused, initial: true
|
||||
state :allowed
|
||||
state :blocked
|
||||
|
||||
event :pause do
|
||||
transitions from: %i[allowed blocked], to: :paused
|
||||
end
|
||||
|
||||
event :allow do
|
||||
transitions from: %i[paused blocked], to: :allowed
|
||||
end
|
||||
|
||||
event :block do
|
||||
transitions from: %i[paused allowed], to: :blocked
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,6 +11,7 @@ class Site
|
|||
has_encrypted :private_key_pem
|
||||
|
||||
has_many :activity_pubs
|
||||
has_many :instance_moderations
|
||||
|
||||
before_save :generate_private_key_pem!, unless: :private_key_pem?
|
||||
|
||||
|
|
16
app/policies/instance_moderation_policy.rb
Normal file
16
app/policies/instance_moderation_policy.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Solo les usuaries pueden moderar instancias
|
||||
InstanceModerationPolicy = Struct.new(:usuarie, :instance_moderation) do
|
||||
def pause?
|
||||
instance_moderation.site.usuarie? usuarie
|
||||
end
|
||||
|
||||
def allow?
|
||||
pause?
|
||||
end
|
||||
|
||||
def block?
|
||||
pause?
|
||||
end
|
||||
end
|
|
@ -1,3 +1,7 @@
|
|||
-# Componente Botón general Moderación
|
||||
|
||||
%button.btn{ href: href, class: local_assigns[:class] }= text
|
||||
- local_assigns[:method] ||= 'patch'
|
||||
- local_assigns[:class] = "btn #{local_assigns[:class]}"
|
||||
|
||||
-# @todo path es obligatorio
|
||||
= button_to text, local_assigns[:path], **local_assigns
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
-# Componente botonera de moderación de Instancias
|
||||
|
||||
- btn_class = 'btn btn-secondary'
|
||||
= render 'components/btn_base', text: t('.text_check'), class: btn_class, href: ''
|
||||
= render 'components/btn_base', text: t('.text_allow'), class: btn_class, href: ''
|
||||
= render 'components/btn_base', text: t('.text_deny'), class: btn_class, href: ''
|
||||
= render 'components/btn_base', path: site_instance_moderation_pause_path(instance_moderation_id: instance_moderation), text: t('.text_check'), class: btn_class, disabled: !instance_moderation.may_pause?
|
||||
= render 'components/btn_base', path: site_instance_moderation_allow_path(instance_moderation_id: instance_moderation), text: t('.text_allow'), class: btn_class, disabled: !instance_moderation.may_allow?
|
||||
= render 'components/btn_base', path: site_instance_moderation_block_path(instance_moderation_id: instance_moderation), text: t('.text_deny'), class: btn_class, disabled: !instance_moderation.may_block?
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
-# Filtros
|
||||
= render 'components/instances_filters'
|
||||
|
||||
- @instances.each do |instance|
|
||||
- instance_moderations.each do |instance_moderation|
|
||||
%hr
|
||||
= render 'moderation_queue/instance', instance: instance
|
||||
= render 'moderation_queue/instance', instance: instance_moderation.instance
|
||||
|
||||
-# Botones moderación
|
||||
.d-flex.pb-4
|
||||
= render 'components/instances_btn_box', instance: instance
|
||||
= render 'components/instances_btn_box', site: site, instance_moderation: instance_moderation
|
||||
|
||||
%hr
|
||||
%h3.mt-5= t('moderation_queue.instances.title')
|
||||
|
|
|
@ -5,7 +5,7 @@
|
|||
.col
|
||||
- summary = t('.instances')
|
||||
= render 'layouts/details', summary: summary do
|
||||
= render 'moderation_queue/instances', site: @site, post: @post, moderation_queue: @moderation_queue
|
||||
= render 'moderation_queue/instances', site: @site, instance_moderations: @instance_moderations
|
||||
%hr
|
||||
- summary = t('.accounts')
|
||||
= render 'layouts/details', summary: summary do
|
||||
|
|
|
@ -62,6 +62,12 @@ Rails.application.routes.draw do
|
|||
get 'remote_profile', to: 'moderation_queue#remote_profile'
|
||||
get 'instances', to: 'moderation_queue#instances'
|
||||
|
||||
resources :instance_moderations, only: [] do
|
||||
patch :pause, to: 'instance_moderations#pause'
|
||||
patch :allow, to: 'instance_moderations#allow'
|
||||
patch :block, to: 'instance_moderations#block'
|
||||
end
|
||||
|
||||
# Gestionar artículos según idioma
|
||||
nested do
|
||||
scope '/(:locale)', constraint: /[a-z]{2}(-[A-Z]{2})?/ do
|
||||
|
|
26
db/migrate/20240226134335_create_instance_moderation.rb
Normal file
26
db/migrate/20240226134335_create_instance_moderation.rb
Normal file
|
@ -0,0 +1,26 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# Como la instancia es única para todo el panel, necesitamos llevar
|
||||
# registro de su relación con cada sitio por separado.
|
||||
class CreateInstanceModeration < ActiveRecord::Migration[6.1]
|
||||
def up
|
||||
create_table :instance_moderations do |t|
|
||||
t.timestamps
|
||||
|
||||
t.belongs_to :site
|
||||
t.uuid :instance_id, index: true
|
||||
|
||||
t.string :aasm_state, null: false, default: 'paused'
|
||||
|
||||
t.index %i[site_id instance_id], unique: true
|
||||
end
|
||||
|
||||
ActivityPub.all.find_each do |activity_pub|
|
||||
InstanceModeration.find_or_create_by(site: activity_pub.site, instance: activity_pub.instance)
|
||||
end
|
||||
end
|
||||
|
||||
def down
|
||||
drop_table :instance_moderations
|
||||
end
|
||||
end
|
|
@ -950,6 +950,39 @@ CREATE TABLE public.indexed_posts (
|
|||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: instance_moderations; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE TABLE public.instance_moderations (
|
||||
id bigint NOT NULL,
|
||||
created_at timestamp(6) without time zone NOT NULL,
|
||||
updated_at timestamp(6) without time zone NOT NULL,
|
||||
site_id bigint,
|
||||
instance_id uuid,
|
||||
aasm_state character varying DEFAULT 'paused'::character varying NOT NULL
|
||||
);
|
||||
|
||||
|
||||
--
|
||||
-- Name: instance_moderations_id_seq; Type: SEQUENCE; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE SEQUENCE public.instance_moderations_id_seq
|
||||
START WITH 1
|
||||
INCREMENT BY 1
|
||||
NO MINVALUE
|
||||
NO MAXVALUE
|
||||
CACHE 1;
|
||||
|
||||
|
||||
--
|
||||
-- Name: instance_moderations_id_seq; Type: SEQUENCE OWNED BY; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER SEQUENCE public.instance_moderations_id_seq OWNED BY public.instance_moderations.id;
|
||||
|
||||
|
||||
--
|
||||
-- Name: licencias; Type: TABLE; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1514,6 +1547,13 @@ ALTER TABLE ONLY public.designs ALTER COLUMN id SET DEFAULT nextval('public.desi
|
|||
ALTER TABLE ONLY public.distributed_press_publishers ALTER COLUMN id SET DEFAULT nextval('public.distributed_press_publishers_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: instance_moderations id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.instance_moderations ALTER COLUMN id SET DEFAULT nextval('public.instance_moderations_id_seq'::regclass);
|
||||
|
||||
|
||||
--
|
||||
-- Name: licencias id; Type: DEFAULT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -1774,6 +1814,14 @@ ALTER TABLE ONLY public.indexed_posts
|
|||
ADD CONSTRAINT indexed_posts_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: instance_moderations instance_moderations_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
ALTER TABLE ONLY public.instance_moderations
|
||||
ADD CONSTRAINT instance_moderations_pkey PRIMARY KEY (id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: licencias licencias_pkey; Type: CONSTRAINT; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2139,6 +2187,27 @@ CREATE INDEX index_indexed_posts_on_locale ON public.indexed_posts USING btree (
|
|||
CREATE INDEX index_indexed_posts_on_site_id ON public.indexed_posts USING btree (site_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_instance_moderations_on_instance_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_instance_moderations_on_instance_id ON public.instance_moderations USING btree (instance_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_instance_moderations_on_site_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE INDEX index_instance_moderations_on_site_id ON public.instance_moderations USING btree (site_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_instance_moderations_on_site_id_and_instance_id; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
||||
CREATE UNIQUE INDEX index_instance_moderations_on_site_id_and_instance_id ON public.instance_moderations USING btree (site_id, instance_id);
|
||||
|
||||
|
||||
--
|
||||
-- Name: index_licencias_on_name; Type: INDEX; Schema: public; Owner: -
|
||||
--
|
||||
|
@ -2476,6 +2545,7 @@ INSERT INTO "schema_migrations" (version) VALUES
|
|||
('20240220161414'),
|
||||
('20240221184007'),
|
||||
('20240223170317'),
|
||||
('20240226133022');
|
||||
('20240226133022'),
|
||||
('20240226134335');
|
||||
|
||||
|
||||
|
|
Loading…
Reference in a new issue