Skip to content

Commit

Permalink
check domain blocks for outgoing deliveries
Browse files Browse the repository at this point in the history
  • Loading branch information
Floppy committed Nov 28, 2024
1 parent 3794679 commit 2698f84
Show file tree
Hide file tree
Showing 3 changed files with 52 additions and 6 deletions.
6 changes: 6 additions & 0 deletions config/initializers/extensions.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
require "fediverse/inbox"
require "federails/moderation/filtered_inbox"

Fediverse::Inbox.send(:include, Federails::Moderation::FilteredInbox)

require "fediverse/notifier"
require "federails/moderation/filtered_notifier"

Fediverse::Notifier.send(:include, Federails::Moderation::FilteredNotifier)
16 changes: 16 additions & 0 deletions lib/federails/moderation/filtered_notifier.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
module Federails::Moderation
module FilteredNotifier
extend ActiveSupport::Concern

included do
class <<self
def filter_post_to_inbox(to:, message:, from: nil)
filtered_post_to_inbox(to: to, message: message, from: from) unless DomainBlock.blocked?(to.server)
end

alias_method :filtered_post_to_inbox, :post_to_inbox
alias_method :post_to_inbox, :filter_post_to_inbox
end
end
end
end
36 changes: 30 additions & 6 deletions spec/requests/domain_block_spec.rb
Original file line number Diff line number Diff line change
@@ -1,33 +1,57 @@
RSpec.describe Federails::Moderation::DomainBlock do
let(:actor) { FactoryBot.create(:user).federails_actor }

describe 'with a blocked domain' do
context 'with a blocked domain' do
before do
described_class.create(domain: "example.com")
described_class.create(domain: "blocked.com")
end

it 'allows non-matching activities' do
payload = { "id" => "https://test.com/abc1234" }
payload = { "id" => "https://allowed.com/abc1234" }
expect(Fediverse::Inbox).to receive(:filtered_dispatch_request).with(payload)
Fediverse::Inbox.dispatch_request(payload)
end

it 'rejects activities with matching IDs' do
payload = { "id" => "https://example.com/abc1234" }
payload = { "id" => "https://blocked.com/abc1234" }
expect(Fediverse::Inbox).not_to receive(:filtered_dispatch_request)
Fediverse::Inbox.dispatch_request(payload)
end

it 'rejects activities with subdomain-matching IDs' do
payload = { "id" => "https://www.example.com/abc1234" }
payload = { "id" => "https://www.blocked.com/abc1234" }
expect(Fediverse::Inbox).not_to receive(:filtered_dispatch_request)
Fediverse::Inbox.dispatch_request(payload)
end

it 'rejects activities with matching actors' do
payload = { "actor" => "https://example.com/users/abc1234" }
payload = { "actor" => "https://blocked.com/users/abc1234" }
expect(Fediverse::Inbox).not_to receive(:filtered_dispatch_request)
Fediverse::Inbox.dispatch_request(payload)
end
end

context "when delivering" do
FakeActivity = Struct.new :id, :actor, :recipients, :action, :entity, keyword_init: true

let(:local_actor) { FactoryBot.create(:user).federails_actor }
let(:distant_target_actor) { FactoryBot.create :distant_actor }
let(:activity) { FakeActivity.new(actor: local_actor, recipients: [ distant_target_actor ]) }

before do
allow(Fediverse::Notifier).to receive(:payload).and_return("message")
end

it 'allows delivery to non-blocked domains' do
expect(Fediverse::Notifier).to receive(:filtered_post_to_inbox).
with(to: distant_target_actor, message: "message", from: local_actor).once
Fediverse::Notifier.post_to_inboxes(activity)
end

it 'blocks delivery to blocked domains' do
described_class.create(domain: distant_target_actor.server)
expect(Fediverse::Notifier).not_to receive(:filtered_post_to_inbox)
Fediverse::Notifier.post_to_inboxes(activity)
end
end
end

0 comments on commit 2698f84

Please sign in to comment.