Send only Retractions

Related to diaspora/diaspora_federation#27
This commit is contained in:
Benjamin Neff 2017-04-30 04:59:42 +02:00
parent e907b3eb18
commit b6b0aac969
No known key found for this signature in database
GPG key ID: 971464C3F1A90194
8 changed files with 45 additions and 71 deletions

View file

@ -347,7 +347,7 @@ class User < ActiveRecord::Base
######### Posts and Such ############### ######### Posts and Such ###############
def retract(target) def retract(target)
retraction = Retraction.for(target, self) retraction = Retraction.for(target)
retraction.defer_dispatch(self) retraction.defer_dispatch(self)
retraction.perform retraction.perform
end end

View file

@ -14,17 +14,9 @@ class Retraction
@target = target @target = target
end end
def self.for(target, sender=nil) def self.for(target)
federation_retraction = case target federation_retraction_data = Diaspora::Federation::Entities.retraction_data_for(target)
when Diaspora::Relayable new(federation_retraction_data, target.subscribers.select(&:remote?), target)
Diaspora::Federation::Entities.relayable_retraction(target, sender)
when Post
Diaspora::Federation::Entities.signed_retraction(target, sender)
else
Diaspora::Federation::Entities.retraction_data_for(target)
end
new(federation_retraction, target.subscribers.select(&:remote?), target)
end end
def defer_dispatch(user, include_target_author=true) def defer_dispatch(user, include_target_author=true)

View file

@ -165,16 +165,6 @@ module Diaspora
) )
end end
# @deprecated
def self.relayable_retraction(target, sender)
DiasporaFederation::Entities::RelayableRetraction.new(
target_guid: target.guid,
target_type: Mappings.entity_name_for(target),
target: related_entity(target),
author: sender.diaspora_handle
).to_h
end
def self.reshare(reshare) def self.reshare(reshare)
DiasporaFederation::Entities::Reshare.new( DiasporaFederation::Entities::Reshare.new(
root_author: reshare.root_diaspora_id, root_author: reshare.root_diaspora_id,
@ -189,10 +179,6 @@ module Diaspora
def self.retraction(retraction) def self.retraction(retraction)
case retraction.data[:target_type] case retraction.data[:target_type]
when "Comment", "Like", "PollParticipation"
DiasporaFederation::Entities::RelayableRetraction.new(retraction.data)
when "Post"
DiasporaFederation::Entities::SignedRetraction.new(retraction.data)
when "Contact" when "Contact"
DiasporaFederation::Entities::Contact.new(retraction.data) DiasporaFederation::Entities::Contact.new(retraction.data)
else else
@ -214,16 +200,6 @@ module Diaspora
end end
end end
# @deprecated
def self.signed_retraction(target, sender)
DiasporaFederation::Entities::SignedRetraction.new(
target_guid: target.guid,
target_type: Mappings.entity_name_for(target),
target: related_entity(target),
author: sender.diaspora_handle
).to_h
end
def self.status_message(status_message) def self.status_message(status_message)
DiasporaFederation::Entities::StatusMessage.new( DiasporaFederation::Entities::StatusMessage.new(
author: status_message.diaspora_handle, author: status_message.diaspora_handle,

View file

@ -151,7 +151,7 @@ module Diaspora
when Diaspora::Relayable when Diaspora::Relayable
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)
retraction.defer_dispatch(parent_author, false) retraction.defer_dispatch(parent_author, false)
retraction.perform retraction.perform
else else
@ -265,7 +265,7 @@ module Diaspora
parent_author = relayable.parent.author.owner parent_author = relayable.parent.author.owner
return unless parent_author && parent_author.ignored_people.include?(relayable.author) return unless parent_author && parent_author.ignored_people.include?(relayable.author)
retraction = Retraction.for(relayable, parent_author) retraction = Retraction.for(relayable)
Diaspora::Federation::Dispatcher.build(parent_author, retraction, subscribers: [relayable.author]).dispatch Diaspora::Federation::Dispatcher.build(parent_author, retraction, subscribers: [relayable.author]).dispatch
raise Diaspora::Federation::AuthorIgnored raise Diaspora::Federation::AuthorIgnored

View file

@ -4,13 +4,13 @@
describe Retraction do describe Retraction do
let(:post) { alice.post(:status_message, text: "destroy!", public: true) } let(:post) { alice.post(:status_message, text: "destroy!", public: true) }
let(:retraction) { Retraction.for(post, alice) } let(:retraction) { Retraction.for(post) }
describe "#subscribers" do describe "#subscribers" do
it "contains all remote-subscribers of target object" do it "contains all remote-subscribers of target object" do
post = local_luke.post(:status_message, text: "destroy!", public: true) post = local_luke.post(:status_message, text: "destroy!", public: true)
retraction = Retraction.for(post, local_luke) retraction = Retraction.for(post)
expect(retraction.subscribers).to eq([remote_raphael]) expect(retraction.subscribers).to eq([remote_raphael])
end end
@ -18,25 +18,25 @@ describe Retraction do
describe "#data" do describe "#data" do
it "contains the hash with all data from the federation-retraction" do it "contains the hash with all data from the federation-retraction" do
federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, alice) federation_retraction_data = Diaspora::Federation::Entities.retraction_data_for(post)
expect(retraction.data).to eq(federation_retraction.to_h) expect(retraction.data).to eq(federation_retraction_data)
end end
end end
describe ".for" do describe ".for" do
it "creates a retraction for a post" do it "creates a retraction for a post" do
expect(Diaspora::Federation::Entities).to receive(:signed_retraction).with(post, alice) expect(Diaspora::Federation::Entities).to receive(:retraction_data_for).with(post)
Retraction.for(post, alice) Retraction.for(post)
end end
it "creates a retraction for a relayable" do it "creates a retraction for a relayable" do
comment = FactoryGirl.create(:comment, author: alice.person, post: post) comment = FactoryGirl.create(:comment, author: alice.person, post: post)
expect(Diaspora::Federation::Entities).to receive(:relayable_retraction).with(comment, alice) expect(Diaspora::Federation::Entities).to receive(:retraction_data_for).with(comment)
Retraction.for(comment, alice) Retraction.for(comment)
end end
it "creates a retraction for a contact" do it "creates a retraction for a contact" do
@ -44,20 +44,21 @@ describe Retraction do
expect(Diaspora::Federation::Entities).to receive(:retraction_data_for).with(contact) expect(Diaspora::Federation::Entities).to receive(:retraction_data_for).with(contact)
Retraction.for(contact, contact.user) Retraction.for(contact)
end end
end end
describe ".defer_dispatch" do describe ".defer_dispatch" do
it "queues a job to send the retraction later" do it "queues a job to send the retraction later" do
post = local_luke.post(:status_message, text: "destroy!", public: true) post = local_luke.post(:status_message, text: "destroy!", public: true)
federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, local_luke) retraction = Retraction.for(post)
federation_retraction = Diaspora::Federation::Entities.retraction(retraction)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [remote_raphael.id], service_types: [] local_luke.id, federation_retraction.to_h, [remote_raphael.id], service_types: []
) )
Retraction.for(post, local_luke).defer_dispatch(local_luke) retraction.defer_dispatch(local_luke)
end end
it "adds service metadata to queued job for deletion" do it "adds service metadata to queued job for deletion" do
@ -66,47 +67,50 @@ describe Retraction do
facebook = Services::Facebook.new(access_token: "facebook") facebook = Services::Facebook.new(access_token: "facebook")
alice.services << twitter << facebook alice.services << twitter << facebook
federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, alice) retraction = Retraction.for(post)
federation_retraction = Diaspora::Federation::Entities.retraction(retraction)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
alice.id, federation_retraction.to_h, [], service_types: ["Services::Twitter"], tweet_id: "123" alice.id, federation_retraction.to_h, [], service_types: ["Services::Twitter"], tweet_id: "123"
) )
Retraction.for(post, alice).defer_dispatch(alice) retraction.defer_dispatch(alice)
end end
it "queues also a job if subscribers is empty" do it "queues also a job if subscribers is empty" do
federation_retraction = Diaspora::Federation::Entities.signed_retraction(post, alice) retraction = Retraction.for(post)
federation_retraction = Diaspora::Federation::Entities.retraction(retraction)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
alice.id, federation_retraction.to_h, [], service_types: [] alice.id, federation_retraction.to_h, [], service_types: []
) )
Retraction.for(post, alice).defer_dispatch(alice) retraction.defer_dispatch(alice)
end end
it "queues a job with empty opts for non-StatusMessage" do it "queues a job with empty opts for non-StatusMessage" do
post = local_luke.post(:status_message, text: "hello", public: true) post = local_luke.post(:status_message, text: "hello", public: true)
comment = local_luke.comment!(post, "destroy!") comment = local_luke.comment!(post, "destroy!")
federation_retraction = Diaspora::Federation::Entities.relayable_retraction(comment, local_luke) retraction = Retraction.for(comment)
federation_retraction = Diaspora::Federation::Entities.retraction(retraction)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [remote_raphael.id], {} local_luke.id, federation_retraction.to_h, [remote_raphael.id], {}
) )
Retraction.for(comment, local_luke).defer_dispatch(local_luke) retraction.defer_dispatch(local_luke)
end end
it "uses the author of the target parent as sender for a comment-retraction if the parent is local" do it "uses the author of the target parent as sender for a comment-retraction if the parent is local" do
post = local_luke.post(:status_message, text: "hello", public: true) post = local_luke.post(:status_message, text: "hello", public: true)
comment = local_leia.comment!(post, "destroy!") comment = local_leia.comment!(post, "destroy!")
federation_retraction = Diaspora::Federation::Entities.relayable_retraction(comment, local_leia) federation_retraction = Diaspora::Federation::Entities.retraction(comment)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [remote_raphael.id], {} local_luke.id, federation_retraction.to_h, [remote_raphael.id], {}
) )
Retraction.for(comment, local_leia).defer_dispatch(local_leia) Retraction.for(comment).defer_dispatch(local_leia)
end end
context "relayable" do context "relayable" do
@ -114,23 +118,25 @@ describe Retraction do
let(:comment) { FactoryGirl.create(:comment, post: post, author: remote_raphael) } let(:comment) { FactoryGirl.create(:comment, post: post, author: remote_raphael) }
it "sends retraction to target author if deleted by parent author" do it "sends retraction to target author if deleted by parent author" do
federation_retraction = Diaspora::Federation::Entities.relayable_retraction(comment, local_luke) retraction = Retraction.for(comment)
federation_retraction = Diaspora::Federation::Entities.retraction(retraction)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [remote_raphael.id], {} local_luke.id, federation_retraction.to_h, [remote_raphael.id], {}
) )
Retraction.for(comment, local_luke).defer_dispatch(local_luke) retraction.defer_dispatch(local_luke)
end end
it "don't sends retraction back to target author if relayed by parent author" do 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) retraction = Retraction.for(comment)
federation_retraction = Diaspora::Federation::Entities.retraction(retraction)
expect(Workers::DeferredRetraction).to receive(:perform_async).with( expect(Workers::DeferredRetraction).to receive(:perform_async).with(
local_luke.id, federation_retraction.to_h, [], {} local_luke.id, federation_retraction.to_h, [], {}
) )
Retraction.for(comment, local_luke).defer_dispatch(local_luke, false) retraction.defer_dispatch(local_luke, false)
end end
end end
end end
@ -138,29 +144,29 @@ describe Retraction do
describe "#perform" do describe "#perform" do
it "destroys the target object" do it "destroys the target object" do
expect(post).to receive(:destroy!) expect(post).to receive(:destroy!)
Retraction.for(post, alice).perform Retraction.for(post).perform
end end
end end
describe "#public?" do describe "#public?" do
it "returns true for a public post" do it "returns true for a public post" do
expect(Retraction.for(post, alice).public?).to be_truthy expect(Retraction.for(post).public?).to be_truthy
end end
it "returns true for a public comment if parent post is local" do it "returns true for a public comment if parent post is local" do
comment = bob.comment!(post, "destroy!") comment = bob.comment!(post, "destroy!")
expect(Retraction.for(comment, bob).public?).to be_truthy expect(Retraction.for(comment).public?).to be_truthy
end end
it "returns false for a public comment if parent post is not local" do it "returns false for a public comment if parent post is not local" do
remote_post = FactoryGirl.create(:status_message, author: remote_raphael) remote_post = FactoryGirl.create(:status_message, author: remote_raphael)
comment = alice.comment!(remote_post, "destroy!") comment = alice.comment!(remote_post, "destroy!")
expect(Retraction.for(comment, alice).public?).to be_falsey expect(Retraction.for(comment).public?).to be_falsey
end end
it "returns false for a private target" do it "returns false for a private target" do
private_post = alice.post(:status_message, text: "destroy!", to: alice.aspects.first.id) private_post = alice.post(:status_message, text: "destroy!", to: alice.aspects.first.id)
expect(Retraction.for(private_post, alice).public?).to be_falsey expect(Retraction.for(private_post).public?).to be_falsey
end end
end end
end end

View file

@ -507,9 +507,9 @@ describe Diaspora::Federation::Receive do
target_type: "Comment" target_type: "Comment"
) )
comment_retraction = Retraction.for(remote_comment, alice) comment_retraction = Retraction.for(remote_comment)
expect(Retraction).to receive(:for).with(instance_of(Comment), alice).and_return(comment_retraction) expect(Retraction).to receive(:for).with(instance_of(Comment)).and_return(comment_retraction)
expect(comment_retraction).to receive(:defer_dispatch).with(alice, false) 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

@ -778,7 +778,7 @@ describe User, :type => :model do
context "posts" do context "posts" do
it "sends a retraction" do it "sends a retraction" do
expect(Retraction).to receive(:for).with(post, bob).and_return(retraction) expect(Retraction).to receive(:for).with(post).and_return(retraction)
expect(retraction).to receive(:defer_dispatch).with(bob) expect(retraction).to receive(:defer_dispatch).with(bob)
expect(retraction).to receive(:perform) expect(retraction).to receive(:perform)

View file

@ -17,7 +17,7 @@ shared_examples "a dispatcher" do
opts = {service_types: "Services::Twitter", tweet_id: "123"} opts = {service_types: "Services::Twitter", tweet_id: "123"}
expect(Workers::DeletePostFromService).to receive(:perform_async).with(twitter.id, opts) expect(Workers::DeletePostFromService).to receive(:perform_async).with(twitter.id, opts)
retraction = Retraction.for(post, alice) retraction = Retraction.for(post)
Diaspora::Federation::Dispatcher.build(alice, retraction, opts).dispatch Diaspora::Federation::Dispatcher.build(alice, retraction, opts).dispatch
end end
@ -35,7 +35,7 @@ shared_examples "a dispatcher" do
it "does not deliver a Retraction of a Comment to services" do it "does not deliver a Retraction of a Comment to services" do
expect(Workers::DeletePostFromService).not_to receive(:perform_async) expect(Workers::DeletePostFromService).not_to receive(:perform_async)
retraction = Retraction.for(comment, alice) retraction = Retraction.for(comment)
Diaspora::Federation::Dispatcher.build(alice, retraction).dispatch Diaspora::Federation::Dispatcher.build(alice, retraction).dispatch
end end
end end