From e907b3eb18ede79988b0741d0b645956f853e01f Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Sun, 30 Apr 2017 14:15:21 +0200 Subject: [PATCH] Send Contact entity for start/stop sharing Related to diaspora/diaspora_federation#32 --- app/models/user/connecting.rb | 1 + lib/diaspora/federated/retraction.rb | 4 +- lib/diaspora/federation/entities.rb | 48 +++---- lib/diaspora/federation/mappings.rb | 2 +- lib/diaspora/federation/receive.rb | 2 +- .../federation/attack_vectors_spec.rb | 5 +- .../receive_federation_messages_spec.rb | 4 +- .../lib/diaspora/federated/retraction_spec.rb | 2 +- spec/lib/diaspora/federation/entities_spec.rb | 126 +++++++----------- spec/lib/diaspora/federation/receive_spec.rb | 2 +- spec/models/user/connecting_spec.rb | 1 + 11 files changed, 80 insertions(+), 117 deletions(-) diff --git a/app/models/user/connecting.rb b/app/models/user/connecting.rb index 0781745f4..558cb7de4 100644 --- a/app/models/user/connecting.rb +++ b/app/models/user/connecting.rb @@ -34,6 +34,7 @@ class User if contact.person.local? contact.person.owner.disconnected_by(contact.user.person) else + contact.receiving = false Retraction.for(contact).defer_dispatch(self) end diff --git a/lib/diaspora/federated/retraction.rb b/lib/diaspora/federated/retraction.rb index 642c93898..a68fcccfa 100644 --- a/lib/diaspora/federated/retraction.rb +++ b/lib/diaspora/federated/retraction.rb @@ -21,10 +21,10 @@ class Retraction when Post Diaspora::Federation::Entities.signed_retraction(target, sender) else - Diaspora::Federation::Entities.retraction(target) + Diaspora::Federation::Entities.retraction_data_for(target) end - new(federation_retraction.to_h, target.subscribers.select(&:remote?), target) + new(federation_retraction, target.subscribers.select(&:remote?), target) end def defer_dispatch(user, include_target_author=true) diff --git a/lib/diaspora/federation/entities.rb b/lib/diaspora/federation/entities.rb index da8e0bb33..bab9624b7 100644 --- a/lib/diaspora/federation/entities.rb +++ b/lib/diaspora/federation/entities.rb @@ -5,17 +5,6 @@ module Diaspora public_send(Mappings.builder_for(entity.class), entity) end - def self.build_retraction(retraction) - case retraction.data[:target_type] - when "Comment", "Like", "PollParticipation" - DiasporaFederation::Entities::RelayableRetraction.new(retraction.data) - when "Post" - DiasporaFederation::Entities::SignedRetraction.new(retraction.data) - else - DiasporaFederation::Entities::Retraction.new(retraction.data) - end - end - def self.post(post) case post when StatusMessage @@ -50,10 +39,11 @@ module Diaspora end def self.contact(contact) - # TODO: use DiasporaFederation::Entities::Contact - DiasporaFederation::Entities::Request.new( + DiasporaFederation::Entities::Contact.new( author: contact.user.diaspora_handle, - recipient: contact.person.diaspora_handle + recipient: contact.person.diaspora_handle, + sharing: contact.receiving, + following: contact.receiving ) end @@ -182,7 +172,7 @@ module Diaspora target_type: Mappings.entity_name_for(target), target: related_entity(target), author: sender.diaspora_handle - ) + ).to_h end def self.reshare(reshare) @@ -197,24 +187,30 @@ module Diaspora ) end - def self.retraction(target) + def self.retraction(retraction) + 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" + DiasporaFederation::Entities::Contact.new(retraction.data) + else + DiasporaFederation::Entities::Retraction.new(retraction.data) + end + end + + def self.retraction_data_for(target) case target when Contact - # TODO: deprecated - author = target.user.diaspora_handle - DiasporaFederation::Entities::Retraction.new( - target_guid: target.user.guid, - target_type: "Person", - target: DiasporaFederation::Entities::RelatedEntity.new(author: author, local: true), - author: author - ) + contact(target).to_h.tap {|data| data[:target_type] = "Contact" } else DiasporaFederation::Entities::Retraction.new( target_guid: target.guid, target_type: Mappings.entity_name_for(target), target: related_entity(target), author: target.diaspora_handle - ) + ).to_h end end @@ -225,7 +221,7 @@ module Diaspora target_type: Mappings.entity_name_for(target), target: related_entity(target), author: sender.diaspora_handle - ) + ).to_h end def self.status_message(status_message) diff --git a/lib/diaspora/federation/mappings.rb b/lib/diaspora/federation/mappings.rb index 2b761b697..46e0ff969 100644 --- a/lib/diaspora/federation/mappings.rb +++ b/lib/diaspora/federation/mappings.rb @@ -49,7 +49,7 @@ module Diaspora PollParticipation => :poll_participation, Profile => :profile, Reshare => :reshare, - Retraction => :build_retraction, + Retraction => :retraction, StatusMessage => :status_message }.freeze diff --git a/lib/diaspora/federation/receive.rb b/lib/diaspora/federation/receive.rb index 18c642fd7..15c3d2caf 100644 --- a/lib/diaspora/federation/receive.rb +++ b/lib/diaspora/federation/receive.rb @@ -25,7 +25,7 @@ module Diaspora def self.contact(entity) recipient = Person.find_by(diaspora_handle: entity.recipient).owner - if entity.sharing.to_s == "true" + if entity.sharing Contact.create_or_update_sharing_contact(recipient, author_of(entity)) else recipient.disconnected_by(author_of(entity)) diff --git a/spec/integration/federation/attack_vectors_spec.rb b/spec/integration/federation/attack_vectors_spec.rb index e345420ef..c5a802647 100644 --- a/spec/integration/federation/attack_vectors_spec.rb +++ b/spec/integration/federation/attack_vectors_spec.rb @@ -49,9 +49,10 @@ describe "attack vectors", type: :request do it "should not receive retractions where the retractor and the salmon author do not match" do original_message = eve.post(:status_message, text: "store this!", to: eves_aspect.id) + retraction = Retraction.for(original_message) expect { - post_message(generate_xml(Diaspora::Federation::Entities.retraction(original_message), alice, bob), bob) + post_message(generate_xml(Diaspora::Federation::Entities.retraction(retraction), alice, bob), bob) }.to_not change { bob.visible_shareables(Post).count(:all) } end @@ -61,7 +62,7 @@ describe "attack vectors", type: :request do contact = bob.contacts(true).find_by(person_id: eve.person.id) expect(contact).to be_sharing - post_message(generate_xml(Diaspora::Federation::Entities.retraction(contact), alice, bob), bob) + post_message(generate_xml(Diaspora::Federation::Entities.retraction(Retraction.for(contact)), alice, bob), bob) expect(bob.contacts(true).find_by(person_id: eve.person.id)).to be_sharing end diff --git a/spec/integration/federation/receive_federation_messages_spec.rb b/spec/integration/federation/receive_federation_messages_spec.rb index 4a017cedf..d532b3c71 100644 --- a/spec/integration/federation/receive_federation_messages_spec.rb +++ b/spec/integration/federation/receive_federation_messages_spec.rb @@ -73,8 +73,8 @@ describe "Receive federation messages feature" do context "with private receive" do let(:recipient) { alice } - it "treats sharing request recive correctly" do - entity = Fabricate(:request_entity, author: sender_id, recipient: alice.diaspora_handle) + it "treats sharing request receive correctly" do + entity = Fabricate(:contact_entity, author: sender_id, recipient: alice.diaspora_handle) expect(Workers::ReceiveLocal).to receive(:perform_async).and_call_original diff --git a/spec/lib/diaspora/federated/retraction_spec.rb b/spec/lib/diaspora/federated/retraction_spec.rb index 3f7b9f39b..ee5e0f485 100644 --- a/spec/lib/diaspora/federated/retraction_spec.rb +++ b/spec/lib/diaspora/federated/retraction_spec.rb @@ -42,7 +42,7 @@ describe Retraction do it "creates a retraction for a contact" do contact = FactoryGirl.create(:contact) - expect(Diaspora::Federation::Entities).to receive(:retraction).with(contact) + expect(Diaspora::Federation::Entities).to receive(:retraction_data_for).with(contact) Retraction.for(contact, contact.user) end diff --git a/spec/lib/diaspora/federation/entities_spec.rb b/spec/lib/diaspora/federation/entities_spec.rb index 428990bcd..5263ff599 100644 --- a/spec/lib/diaspora/federation/entities_spec.rb +++ b/spec/lib/diaspora/federation/entities_spec.rb @@ -36,13 +36,15 @@ describe Diaspora::Federation::Entities do expect(federation_entity.additional_data).to eq(diaspora_entity.signature.additional_data) end - it "builds a contact (request)" do - diaspora_entity = FactoryGirl.build(:contact) + it "builds a contact" do + diaspora_entity = FactoryGirl.build(:contact, receiving: true) federation_entity = described_class.build(diaspora_entity) - expect(federation_entity).to be_instance_of(DiasporaFederation::Entities::Request) + expect(federation_entity).to be_instance_of(DiasporaFederation::Entities::Contact) expect(federation_entity.author).to eq(diaspora_entity.user.diaspora_handle) expect(federation_entity.recipient).to eq(diaspora_entity.person.diaspora_handle) + expect(federation_entity.sharing).to be_truthy + expect(federation_entity.following).to be_truthy end context "Conversation" do @@ -205,6 +207,31 @@ describe Diaspora::Federation::Entities do expect(federation_entity.provider_display_name).to eq(diaspora_entity.provider_display_name) end + context "Retraction" do + it "builds a Retraction entity for a Photo retraction" do + target = FactoryGirl.create(:photo, author: alice.person) + retraction = Retraction.for(target) + federation_entity = described_class.build(retraction) + + expect(federation_entity).to be_instance_of(DiasporaFederation::Entities::Retraction) + expect(federation_entity.author).to eq(target.author.diaspora_handle) + expect(federation_entity.target_guid).to eq(target.guid) + expect(federation_entity.target_type).to eq("Photo") + end + + it "builds a Contact for a Contact retraction" do + target = FactoryGirl.create(:contact, receiving: false) + retraction = Retraction.for(target) + federation_entity = described_class.build(retraction) + + expect(federation_entity).to be_instance_of(DiasporaFederation::Entities::Contact) + expect(federation_entity.author).to eq(target.user.diaspora_handle) + expect(federation_entity.recipient).to eq(target.person.diaspora_handle) + expect(federation_entity.sharing).to be_falsey + expect(federation_entity.following).to be_falsey + end + end + context "StatusMessage" do it "builds a status message" do diaspora_entity = FactoryGirl.create(:status_message) @@ -274,88 +301,25 @@ describe Diaspora::Federation::Entities do end end - describe ".build_retraction" do - context "Retraction" do - it "builds a Retraction for a Photo" do - target = FactoryGirl.create(:photo, author: alice.person) - retraction = Retraction.for(target, alice) - federation_retraction = described_class.build_retraction(retraction) + describe ".retraction_data_for" do + it "returns the data for a Photo retraction" do + target = FactoryGirl.create(:photo, author: alice.person) + retraction_data = described_class.retraction_data_for(target) - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::Retraction) - expect(federation_retraction.author).to eq(target.author.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.guid) - expect(federation_retraction.target_type).to eq("Photo") - end - - it "builds a Retraction for a Contact" do - target = FactoryGirl.create(:contact) - retraction = Retraction.for(target, target.user) - federation_retraction = described_class.build_retraction(retraction) - - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::Retraction) - expect(federation_retraction.author).to eq(target.user.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.user.guid) - expect(federation_retraction.target_type).to eq("Person") - end + expect(retraction_data[:author]).to eq(target.author.diaspora_handle) + expect(retraction_data[:target_guid]).to eq(target.guid) + expect(retraction_data[:target_type]).to eq("Photo") end - context "SignedRetraction" do - it "builds a SignedRetraction for a StatusMessage" do - target = FactoryGirl.create(:status_message, author: alice.person) - retraction = Retraction.for(target, alice) - federation_retraction = described_class.build_retraction(retraction) + it "returns the data for a Contact entity" do + target = FactoryGirl.create(:contact, receiving: false) + retraction_data = described_class.retraction_data_for(target) - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::SignedRetraction) - expect(federation_retraction.author).to eq(target.author.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.guid) - expect(federation_retraction.target_type).to eq("Post") - end - - it "builds a SignedRetraction for a Reshare" do - target = FactoryGirl.create(:reshare, author: alice.person) - retraction = Retraction.for(target, alice) - federation_retraction = described_class.build_retraction(retraction) - - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::SignedRetraction) - expect(federation_retraction.author).to eq(target.author.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.guid) - expect(federation_retraction.target_type).to eq("Post") - end - end - - context "RelayableRetraction" do - it "builds a RelayableRetraction for a Comment" do - target = FactoryGirl.create(:comment, author: alice.person) - retraction = Retraction.for(target, alice) - federation_retraction = described_class.build_retraction(retraction) - - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::RelayableRetraction) - expect(federation_retraction.author).to eq(alice.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.guid) - expect(federation_retraction.target_type).to eq("Comment") - end - - it "builds a RelayableRetraction for a Like" do - target = FactoryGirl.create(:like, author: alice.person) - retraction = Retraction.for(target, alice) - federation_retraction = described_class.build_retraction(retraction) - - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::RelayableRetraction) - expect(federation_retraction.author).to eq(alice.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.guid) - expect(federation_retraction.target_type).to eq("Like") - end - - it "builds a RelayableRetraction for a PollParticipation" do - target = FactoryGirl.create(:poll_participation, author: alice.person) - retraction = Retraction.for(target, alice) - federation_retraction = described_class.build_retraction(retraction) - - expect(federation_retraction).to be_instance_of(DiasporaFederation::Entities::RelayableRetraction) - expect(federation_retraction.author).to eq(alice.diaspora_handle) - expect(federation_retraction.target_guid).to eq(target.guid) - expect(federation_retraction.target_type).to eq("PollParticipation") - end + expect(retraction_data[:author]).to eq(target.user.diaspora_handle) + expect(retraction_data[:recipient]).to eq(target.person.diaspora_handle) + expect(retraction_data[:sharing]).to be_falsey + expect(retraction_data[:following]).to be_falsey + expect(retraction_data[:target_type]).to eq("Contact") end end end diff --git a/spec/lib/diaspora/federation/receive_spec.rb b/spec/lib/diaspora/federation/receive_spec.rb index f871dad6c..3da798df1 100644 --- a/spec/lib/diaspora/federation/receive_spec.rb +++ b/spec/lib/diaspora/federation/receive_spec.rb @@ -103,7 +103,7 @@ describe Diaspora::Federation::Receive do :contact_entity, author: sender.diaspora_handle, recipient: alice.diaspora_handle, - sharing: "false" + sharing: false ) } diff --git a/spec/models/user/connecting_spec.rb b/spec/models/user/connecting_spec.rb index 455ce2143..40ef55ce6 100644 --- a/spec/models/user/connecting_spec.rb +++ b/spec/models/user/connecting_spec.rb @@ -87,6 +87,7 @@ describe User::Connecting, type: :model do contact = local_leia.contact_for(remote_raphael) retraction = double + expect(contact).to receive(:receiving=).with(false) expect(Retraction).to receive(:for).with(contact).and_return(retraction) expect(retraction).to receive(:defer_dispatch).with(local_leia)