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
it "returns the parents original audience, if author is local" do
expect(object_on_local_parent.subscribers.map(&:id)) expect(object_on_local_parent.subscribers.map(&:id))
.to match_array([local_leia.person, remote_raphael].map(&:id)) .to match_array([local_leia.person, remote_raphael].map(&:id))
end end
it "returns remote persons of the parents original audience, if the parent is local, but the author is remote" do it "returns remote persons of the parents original audience not on same pod as the author, if author is remote" do
expect(remote_object_on_local_parent.subscribers.map(&:id)).to match_array([remote_raphael].map(&:id)) 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 the author of parent and author of relayable (for local delivery), if the parent is not local" do context "parent is remote" do
it "returns the author of parent and author of relayable (for local delivery)" do
expect(object_on_remote_parent.subscribers.map(&:id)) expect(object_on_remote_parent.subscribers.map(&:id))
.to match_array([remote_raphael, local_luke.person].map(&:id)) .to match_array([remote_raphael, local_luke.person].map(&:id))
end end
end end
end
end end