don't send relayables back to sender pod

send retraction for relayable to target author if retracted by parent author
This commit is contained in:
Benjamin Neff 2016-06-18 21:33:46 +02:00
parent 9dfa8e1442
commit a81bdac38c
6 changed files with 54 additions and 14 deletions

View file

@ -27,7 +27,8 @@ class Retraction
new(federation_retraction.to_h, target.subscribers.select(&:remote?), target) new(federation_retraction.to_h, target.subscribers.select(&:remote?), target)
end end
def defer_dispatch(user) def defer_dispatch(user, include_target_author=true)
subscribers = dispatch_subscribers(include_target_author)
Workers::DeferredRetraction.perform_async(user.id, data, subscribers.map(&:id), service_opts(user)) Workers::DeferredRetraction.perform_async(user.id, data, subscribers.map(&:id), service_opts(user))
end end
@ -46,6 +47,11 @@ class Retraction
attr_reader :target attr_reader :target
def dispatch_subscribers(include_target_author)
subscribers << target.author if target.is_a?(Diaspora::Relayable) && include_target_author && target.author.remote?
subscribers
end
def service_opts(user) def service_opts(user)
return {} unless target.is_a?(StatusMessage) return {} unless target.is_a?(StatusMessage)

View file

@ -143,7 +143,7 @@ module Diaspora
if object.parent.author.local? if object.parent.author.local?
parent_author = object.parent.author.owner parent_author = object.parent.author.owner
retraction = Retraction.for(object, parent_author) retraction = Retraction.for(object, parent_author)
retraction.defer_dispatch(parent_author) retraction.defer_dispatch(parent_author, false)
retraction.perform retraction.perform
else else
object.destroy! object.destroy!

View file

@ -33,7 +33,7 @@ module Diaspora
if author.local? if author.local?
parent.subscribers parent.subscribers
else else
parent.subscribers.select(&:remote?) parent.subscribers.select(&:remote?).reject {|person| person.pod_id == author.pod_id }
end end
else else
[parent.author, author] [parent.author, author]

View file

@ -98,6 +98,31 @@ describe Retraction do
Retraction.for(comment, local_luke).defer_dispatch(local_luke) Retraction.for(comment, local_luke).defer_dispatch(local_luke)
end end
context "relayable" do
let(:post) { local_luke.post(:status_message, text: "hello", public: true) }
let(:comment) { FactoryGirl.create(:comment, post: post, author: remote_raphael) }
it "sends retraction to target author if deleted by parent author" do
federation_retraction = Diaspora::Federation::Entities.relayable_retraction(comment, local_luke)
expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [remote_raphael.id], {}
)
Retraction.for(comment, local_luke).defer_dispatch(local_luke)
end
it "don't sends retraction back to target author if relayed by parent author" do
federation_retraction = Diaspora::Federation::Entities.relayable_retraction(comment, local_luke)
expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [], {}
)
Retraction.for(comment, local_luke).defer_dispatch(local_luke, false)
end
end
end end
describe "#perform" do describe "#perform" do

View file

@ -468,7 +468,7 @@ describe Diaspora::Federation::Receive do
comment_retraction = Retraction.for(remote_comment, alice) comment_retraction = Retraction.for(remote_comment, alice)
expect(Retraction).to receive(:for).with(instance_of(Comment), alice).and_return(comment_retraction) expect(Retraction).to receive(:for).with(instance_of(Comment), alice).and_return(comment_retraction)
expect(comment_retraction).to receive(:defer_dispatch).with(alice) expect(comment_retraction).to receive(:defer_dispatch).with(alice, false)
expect(comment_retraction).to receive(:perform).and_call_original expect(comment_retraction).to receive(:perform).and_call_original
expect_any_instance_of(Comment).to receive(:destroy!).and_call_original expect_any_instance_of(Comment).to receive(:destroy!).and_call_original

View file

@ -45,18 +45,27 @@ shared_examples_for "it is relayable" do
end end
describe "#subscribers" do describe "#subscribers" do
it "returns the parents original audience, if the parent is local" do context "parent is local" do
expect(object_on_local_parent.subscribers.map(&:id)) it "returns the parents original audience, if author is local" do
.to match_array([local_leia.person, remote_raphael].map(&:id)) expect(object_on_local_parent.subscribers.map(&:id))
.to match_array([local_leia.person, remote_raphael].map(&:id))
end
it "returns remote persons of the parents original audience not on same pod as the author, if author is remote" do
person1 = FactoryGirl.create(:person, pod: remote_raphael.pod)
person2 = FactoryGirl.create(:person, pod: FactoryGirl.create(:pod))
local_luke.share_with(person1, local_luke.aspects.first)
local_luke.share_with(person2, local_luke.aspects.first)
expect(remote_object_on_local_parent.subscribers.map(&:id)).to match_array([person2].map(&:id))
end
end end
it "returns remote persons of the parents original audience, if the parent is local, but the author is remote" do context "parent is remote" do
expect(remote_object_on_local_parent.subscribers.map(&:id)).to match_array([remote_raphael].map(&:id)) it "returns the author of parent and author of relayable (for local delivery)" do
end expect(object_on_remote_parent.subscribers.map(&:id))
.to match_array([remote_raphael, local_luke.person].map(&:id))
it "returns the author of parent and author of relayable (for local delivery), if the parent is not local" do end
expect(object_on_remote_parent.subscribers.map(&:id))
.to match_array([remote_raphael, local_luke.person].map(&:id))
end end
end end
end end