From 92ce4eacf842f7a2fa74f298407062a4e0c891a3 Mon Sep 17 00:00:00 2001 From: Benjamin Neff Date: Sun, 4 Jun 2017 01:44:46 +0200 Subject: [PATCH] Validate the author of the root post for a reshare --- docs/_entities/reshare.md | 4 ++++ lib/diaspora_federation/entities/reshare.rb | 13 +++++++---- .../entities/reshare_spec.rb | 22 ++++++++++++++----- 3 files changed, 30 insertions(+), 9 deletions(-) diff --git a/docs/_entities/reshare.md b/docs/_entities/reshare.md index 580fc50..b863ce3 100644 --- a/docs/_entities/reshare.md +++ b/docs/_entities/reshare.md @@ -4,6 +4,9 @@ title: Reshare This entity represents a reshare of a [StatusMessage][status_message]. It inherits from [Post][post]. +The recipient must [fetch][fetching] the root from `root_author` if the post is not already known. +When the `root_guid` is already available locally, the recipient must validate that it's from `root_author`. + ## Properties | Property | Type | Description | @@ -40,5 +43,6 @@ This entity represents a reshare of a [StatusMessage][status_message]. It inheri [timestamp]: {{ site.baseurl }}/federation/types.html#timestamp [string]: {{ site.baseurl }}/federation/types.html#string [boolean]: {{ site.baseurl }}/federation/types.html#boolean +[fetching]: {{ site.baseurl }}/federation/fetching.html [post]: {{ site.baseurl }}/entities/post.html [status_message]: {{ site.baseurl }}/entities/status_message.html diff --git a/lib/diaspora_federation/entities/reshare.rb b/lib/diaspora_federation/entities/reshare.rb index 308e53b..8444e97 100644 --- a/lib/diaspora_federation/entities/reshare.rb +++ b/lib/diaspora_federation/entities/reshare.rb @@ -29,16 +29,21 @@ module DiasporaFederation end # Fetch and receive root post from remote, if not available locally - def fetch_root - root = DiasporaFederation.callbacks.trigger(:fetch_related_entity, "Post", root_guid) - Federation::Fetcher.fetch_public(root_author, "Post", root_guid) unless root + # and validates if it's from the correct author + def validate_root + root = RelatedEntity.fetch(root_author, "Post", root_guid) + + return if root_author == root.author + + raise Entity::ValidationError, + "root_author mismatch: obj=#{self} root_author=#{root_author} known_root_author=#{root.author}" end # Fetch root post after parse # @see Entity.from_hash # @return [Entity] instance def self.from_hash(hash) - super.tap(&:fetch_root) + super.tap(&:validate_root) end end end diff --git a/spec/lib/diaspora_federation/entities/reshare_spec.rb b/spec/lib/diaspora_federation/entities/reshare_spec.rb index e01ecf1..664ddfd 100644 --- a/spec/lib/diaspora_federation/entities/reshare_spec.rb +++ b/spec/lib/diaspora_federation/entities/reshare_spec.rb @@ -56,12 +56,24 @@ XML end end - context "fetch root" do - it "fetches the root post if it is not available already" do - expect_callback(:fetch_related_entity, "Post", data[:root_guid]).and_return(nil) - expect(Federation::Fetcher).to receive(:fetch_public).with(data[:root_author], "Post", data[:root_guid]) + context "parse xml" do + describe "#validate_root" do + it "fetches the root post if it is not available already" do + root = Fabricate(:related_entity, author: bob.diaspora_id) + expect_callback(:fetch_related_entity, "Post", data[:root_guid]).and_return(nil, root) + expect(Federation::Fetcher).to receive(:fetch_public).with(data[:root_author], "Post", data[:root_guid]) - Entities::Reshare.from_xml(Nokogiri::XML(xml).root) + Entities::Reshare.from_xml(Nokogiri::XML(xml).root) + end + + it "validates the author of the root post" do + fake_root = Fabricate(:related_entity, author: alice.diaspora_id) + expect_callback(:fetch_related_entity, "Post", data[:root_guid]).and_return(fake_root) + + expect { + Entities::Reshare.from_xml(Nokogiri::XML(xml).root) + }.to raise_error Entity::ValidationError + end end end end