diff --git a/Gemfile b/Gemfile index d720a2d6..f4125f65 100644 --- a/Gemfile +++ b/Gemfile @@ -39,7 +39,7 @@ gem 'devise-i18n' gem 'devise_invitable' gem 'redis-client' gem 'hiredis-client' -gem 'distributed-press-api-client', '~> 0.4.0rc2' +gem 'distributed-press-api-client', '~> 0.4.0rc3' gem 'email_address', git: 'https://github.com/fauno/email_address', branch: 'i18n' gem 'exception_notification' gem 'fast_blank' diff --git a/Gemfile.lock b/Gemfile.lock index 72a30af1..366b58a5 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -166,12 +166,12 @@ GEM devise_invitable (2.0.9) actionmailer (>= 5.0) devise (>= 4.6) - distributed-press-api-client (0.4.0rc2) + distributed-press-api-client (0.4.0rc3) addressable (~> 2.3, >= 2.3.0) climate_control dry-schema httparty (~> 0.18) - httparty-cache (~> 0.0.4) + httparty-cache (~> 0.0.6) json (~> 2.1, >= 2.1.0) jwt (~> 2.6.0) dotenv (2.8.1) @@ -272,7 +272,7 @@ GEM httparty (0.21.0) mini_mime (>= 1.0.0) multi_xml (>= 0.5.2) - httparty-cache (0.0.5) + httparty-cache (0.0.6) httparty (~> 0.18) i18n (1.14.1) concurrent-ruby (~> 1.0) @@ -626,7 +626,7 @@ DEPENDENCIES devise devise-i18n devise_invitable - distributed-press-api-client (~> 0.4.0rc2) + distributed-press-api-client (~> 0.4.0rc3) dotenv-rails down ed25519 diff --git a/app/controllers/actor_moderations_controller.rb b/app/controllers/actor_moderations_controller.rb index f4637d70..7450835b 100644 --- a/app/controllers/actor_moderations_controller.rb +++ b/app/controllers/actor_moderations_controller.rb @@ -2,10 +2,13 @@ # Gestiona la cola de moderación de actores class ActorModerationsController < ApplicationController - ActorModeration.aasm.events.map(&:name).each do |actor_event| + ActorModeration.events.each do |actor_event| define_method(actor_event) do authorize actor_moderation + # Crea una RemoteFlag si se envían los parámetros adecuados + actor_moderation.update(actor_moderation_params) if actor_event == :report + actor_moderation.public_send(:"#{actor_event}!") if actor_moderation.public_send(:"may_#{actor_event}?") redirect_back fallback_location: site_moderation_queue_path(**(session[:moderation_queue_filters] || {})) @@ -22,4 +25,11 @@ class ActorModerationsController < ApplicationController def actor_moderation @actor_moderation ||= site.actor_moderations.find(params[:actor_moderation_id] || params[:id]) end + + def actor_moderation_params + params.require(:actor_moderation).permit(remote_flag_attributes: %i[message]).tap do |p| + p[:remote_flag_attributes][:site_id] = actor_moderation.site_id + p[:remote_flag_attributes][:actor_id] = actor_moderation.actor_id + end + end end diff --git a/app/models/activity_pub/remote_flag.rb b/app/models/activity_pub/remote_flag.rb new file mode 100644 index 00000000..b790c4b1 --- /dev/null +++ b/app/models/activity_pub/remote_flag.rb @@ -0,0 +1,20 @@ +# frozen_string_literal: true + +class ActivityPub + class RemoteFlag < ApplicationRecord + belongs_to :actor + belongs_to :site + + # Genera la actividad a enviar + def content + { + '@context' => 'https://www.w3.org/ns/activitystreams', + 'id' => Rails.application.routes.url_helpers.v1_activity_pub_remote_flag_url(self, host: site.social_inbox_hostname), + 'type' => 'Flag', + 'actor' => ENV.fetch('PANEL_ACTOR_ID') { "https://#{ENV['SUTTY']}/about.jsonld" }, + 'content' => message.to_s, + 'object' => [ actor.uri ] + } + end + end +end diff --git a/app/models/actor_moderation.rb b/app/models/actor_moderation.rb index 1d9bae5d..c6f8bfc0 100644 --- a/app/models/actor_moderation.rb +++ b/app/models/actor_moderation.rb @@ -5,8 +5,11 @@ class ActorModeration < ApplicationRecord include AASM belongs_to :site + belongs_to :remote_flag, class_name: 'ActivityPub::RemoteFlag' belongs_to :actor, class_name: 'ActivityPub::Actor' + accepts_nested_attributes_for :remote_flag + # Bloquea todes les Actores bloqueables def self.block_all! self.update_all(aasm_state: 'blocked', updated_at: Time.now) @@ -53,8 +56,14 @@ class ActorModeration < ApplicationRecord end end + # Al reportar, necesitamos asociar una RemoteFlag para poder + # enviarla. event :report do transitions from: %i[blocked], to: :reported + + before do + ActivityPub::RemoteFlagJob.perform_later(remote_flag: remote_flag) + end end end diff --git a/app/views/components/_profiles_btn_box.haml b/app/views/components/_profiles_btn_box.haml index bd994f84..3ec95e59 100644 --- a/app/views/components/_profiles_btn_box.haml +++ b/app/views/components/_profiles_btn_box.haml @@ -1,5 +1,13 @@ -# Componente Botonera de Moderación de Cuentas (Remote_profile) +- form_params = {} +- form_params[:report] = { actor_moderation: { remote_flag_attributes: { message: '' } } } +- I18n.available_locales.each do |locale| + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t(locale) + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += ': ' + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += t('.report_message', locale: locale, panel_actor_mention: ENV.fetch('PANEL_ACTOR_MENTION') { '@sutty@sutty.nl' }) + - form_params[:report][:actor_moderation][:remote_flag_attributes][:message] += '\n\n' + .d-flex.flex-row - btn_class = 'btn-secondary' - ActorModeration.events.each do |actor_event| @@ -7,4 +15,5 @@ text: t(".text_#{actor_event}"), path: public_send(:"site_actor_moderation_#{actor_event}_path", actor_moderation_id: actor_moderation), class: btn_class, - disabled: !actor_moderation.public_send(:"may_#{actor_event}?") + disabled: !actor_moderation.public_send(:"may_#{actor_event}?"), + params: form_params[actor_event] diff --git a/app/views/moderation_queue/_account.haml b/app/views/moderation_queue/_account.haml index cdcc0ad4..5e574c71 100644 --- a/app/views/moderation_queue/_account.haml +++ b/app/views/moderation_queue/_account.haml @@ -8,5 +8,6 @@ = sanitize profile['summary'].html_safe -# Botones de Moderación - .d-flex.pb-4 - = render 'components/profiles_btn_box', actor_moderation: actor_moderation + - cache actor_moderation do + .d-flex.pb-4 + = render 'components/profiles_btn_box', actor_moderation: actor_moderation diff --git a/config/locales/en.yml b/config/locales/en.yml index 62e9a1a7..4aea89f7 100644 --- a/config/locales/en.yml +++ b/config/locales/en.yml @@ -106,6 +106,7 @@ en: text_allow: Always approve text_block: Block text_report: Report + report_message: "Hi! Someone using Sutty CMS reported this account on your instance. We don't have support for customized report messages yet, but we will soon. You can reach us at %{panel_actor_mention}." actor_moderations: show: user: Username diff --git a/config/locales/es.yml b/config/locales/es.yml index 3dc68d98..7b033859 100644 --- a/config/locales/es.yml +++ b/config/locales/es.yml @@ -106,6 +106,7 @@ es: text_allow: Aprobar siempre text_block: Bloquear text_report: Reportar + report_message: "¡Hola! Une usuarie de Sutty CMS reportó esta cuenta en tu instancia. Todavía no tenemos soporte para mensajes personalizados. Podés contactarnos en %{panel_actor_mention}." actor_moderations: show: user: Nombre de usuarie diff --git a/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb b/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb new file mode 100644 index 00000000..63e4ce1b --- /dev/null +++ b/db/migrate/20240301181224_add_remote_flag_to_actor_moderation.rb @@ -0,0 +1,18 @@ +# frozen_string_literal: true + +# Las acciones de moderación pueden tener un reporte remoto asociado +class AddRemoteFlagToActorModeration < ActiveRecord::Migration[6.1] + def up + add_column :actor_moderations, :remote_flag_id, :uuid, null: true + + ActivityPub::RemoteFlag.all.find_each do |remote_flag| + actor_moderation = ActorModeration.find_by(actor_id: remote_flag.actor_id) + + actor_moderation&.update_column(:remote_flag_id, remote_flag.id) + end + end + + def down + remove_column :actor_moderations, :remote_flag_id + end +end diff --git a/db/structure.sql b/db/structure.sql index 6cdb49f1..38a56b46 100644 --- a/db/structure.sql +++ b/db/structure.sql @@ -586,7 +586,8 @@ CREATE TABLE public.actor_moderations ( updated_at timestamp(6) without time zone NOT NULL, site_id bigint, actor_id uuid, - aasm_state character varying NOT NULL + aasm_state character varying NOT NULL, + remote_flag_id uuid ); @@ -2697,6 +2698,7 @@ INSERT INTO "schema_migrations" (version) VALUES ('20240227142019'), ('20240228171335'), ('20240228202830'), -('20240229201155'); +('20240229201155'), +('20240301181224');