From a0545c37de642156abbc573162489381263585fd Mon Sep 17 00:00:00 2001 From: cmrd Senya Date: Tue, 15 Dec 2015 02:03:58 +0300 Subject: [PATCH] Allow parent entity types different than "Post" Entities::Message requires "Conversation" at the place, for instance. --- lib/diaspora_federation/entities/message.rb | 4 +++ .../entities/poll_participation.rb | 4 +++ lib/diaspora_federation/entities/relayable.rb | 28 +++++++++++++------ lib/diaspora_federation/salmon/xml_payload.rb | 4 ++- lib/diaspora_federation/test.rb | 2 +- .../entities/comment_spec.rb | 6 ++++ .../diaspora_federation/entities/like_spec.rb | 6 ++++ .../entities/message_spec.rb | 6 ++++ .../entities/participation_spec.rb | 6 ++++ .../entities/poll_participation_spec.rb | 6 ++++ .../entities/relayable_spec.rb | 22 +++++++++------ 11 files changed, 75 insertions(+), 19 deletions(-) diff --git a/lib/diaspora_federation/entities/message.rb b/lib/diaspora_federation/entities/message.rb index 5a9383c..86f51f0 100644 --- a/lib/diaspora_federation/entities/message.rb +++ b/lib/diaspora_federation/entities/message.rb @@ -33,6 +33,10 @@ module DiasporaFederation # @see Conversation#guid # @return [String] conversation guid property :conversation_guid + + def self.get_target_entity_type(*) + "Conversation" + end end end end diff --git a/lib/diaspora_federation/entities/poll_participation.rb b/lib/diaspora_federation/entities/poll_participation.rb index 8439fa2..1d6e241 100644 --- a/lib/diaspora_federation/entities/poll_participation.rb +++ b/lib/diaspora_federation/entities/poll_participation.rb @@ -23,6 +23,10 @@ module DiasporaFederation # @see PollAnswer#guid # @return [String] poll answer guid property :poll_answer_guid + + def self.get_target_entity_type(*) + "Poll" + end end end end diff --git a/lib/diaspora_federation/entities/relayable.rb b/lib/diaspora_federation/entities/relayable.rb index 7998e4a..898d8b8 100644 --- a/lib/diaspora_federation/entities/relayable.rb +++ b/lib/diaspora_federation/entities/relayable.rb @@ -31,6 +31,10 @@ module DiasporaFederation property :parent_guid property :parent_author_signature, default: nil property :author_signature, default: nil + + def self.get_target_entity_type(data) + data[:target_type] || "Post" + end end end @@ -40,7 +44,7 @@ module DiasporaFederation def to_xml entity_xml.tap do |xml| hash = to_h - Relayable.update_signatures!(hash) + Relayable.update_signatures!(hash, self.class) xml.at_xpath("author_signature").content = hash[:author_signature] xml.at_xpath("parent_author_signature").content = hash[:parent_author_signature] @@ -54,21 +58,29 @@ module DiasporaFederation # verifies the signatures (+author_signature+ and +parent_author_signature+ if needed) # @param [Hash] data hash with data to verify # @raise [SignatureVerificationFailed] if the signature is not valid or no public key is found - def self.verify_signatures(data) + def self.verify_signatures(data, klass) pkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, data[:diaspora_id]) raise SignatureVerificationFailed, "failed to fetch public key for #{data[:diaspora_id]}" if pkey.nil? raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature( data, data[:author_signature], pkey ) - author_is_local = DiasporaFederation.callbacks.trigger(:entity_author_is_local?, "Post", data[:parent_guid]) - verify_parent_signature(data) unless author_is_local + author_is_local = DiasporaFederation.callbacks.trigger( + :entity_author_is_local?, + klass.get_target_entity_type(data), + data[:parent_guid] + ) + verify_parent_signature(data, klass) unless author_is_local end # this happens only on downstream federation # @param [Hash] data hash with data to verify - def self.verify_parent_signature(data) - pkey = DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid, "Post", data[:parent_guid]) + def self.verify_parent_signature(data, klass) + pkey = DiasporaFederation.callbacks.trigger( + :fetch_author_public_key_by_entity_guid, + klass.get_target_entity_type(data), + data[:parent_guid] + ) raise SignatureVerificationFailed, "failed to fetch public key for author of #{data[:parent_guid]}" if pkey.nil? raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature( @@ -81,7 +93,7 @@ module DiasporaFederation # if the signatures are not in the hash yet and if the keys are available. # # @param [Hash] data hash given for a signing - def self.update_signatures!(data) + def self.update_signatures!(data, klass) if data[:author_signature].nil? pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id]) data[:author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil? @@ -90,7 +102,7 @@ module DiasporaFederation if data[:parent_author_signature].nil? pkey = DiasporaFederation.callbacks.trigger( :fetch_author_private_key_by_entity_guid, - "Post", + klass.get_target_entity_type(data), data[:parent_guid] ) data[:parent_author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil? diff --git a/lib/diaspora_federation/salmon/xml_payload.rb b/lib/diaspora_federation/salmon/xml_payload.rb index 40d527e..e7bd490 100644 --- a/lib/diaspora_federation/salmon/xml_payload.rb +++ b/lib/diaspora_federation/salmon/xml_payload.rb @@ -99,7 +99,9 @@ module DiasporaFederation end }] - Entities::Relayable.verify_signatures(data) if klass.included_modules.include?(Entities::Relayable) + if klass.included_modules.include?(Entities::Relayable) + Entities::Relayable.verify_signatures(data, klass) + end klass.new(data) end diff --git a/lib/diaspora_federation/test.rb b/lib/diaspora_federation/test.rb index d9d8ef9..2282e2c 100644 --- a/lib/diaspora_federation/test.rb +++ b/lib/diaspora_federation/test.rb @@ -23,7 +23,7 @@ module DiasporaFederation def self.relayable_attributes_with_signatures(factory_name) klass = FactoryGirl.factory_by_name(factory_name).build_class sort_hash(FactoryGirl.attributes_for(factory_name), klass).tap do |data| - DiasporaFederation::Entities::Relayable.update_signatures!(data) + DiasporaFederation::Entities::Relayable.update_signatures!(data, klass) end end diff --git a/spec/lib/diaspora_federation/entities/comment_spec.rb b/spec/lib/diaspora_federation/entities/comment_spec.rb index bd42cfb..6b01444 100644 --- a/spec/lib/diaspora_federation/entities/comment_spec.rb +++ b/spec/lib/diaspora_federation/entities/comment_spec.rb @@ -20,5 +20,11 @@ XML it_behaves_like "an XML Entity" it_behaves_like "a relayable Entity" + + describe ".get_target_entity_type" do + it "returns \"Post\" as target type" do + expect(described_class.get_target_entity_type(data)).to eq("Post") + end + end end end diff --git a/spec/lib/diaspora_federation/entities/like_spec.rb b/spec/lib/diaspora_federation/entities/like_spec.rb index abeef41..478fc60 100644 --- a/spec/lib/diaspora_federation/entities/like_spec.rb +++ b/spec/lib/diaspora_federation/entities/like_spec.rb @@ -21,5 +21,11 @@ XML it_behaves_like "an XML Entity" it_behaves_like "a relayable Entity" + + describe ".get_target_entity_type" do + it "returns data[:target_type] as target type" do + expect(described_class.get_target_entity_type(data)).to eq(data[:target_type]) + end + end end end diff --git a/spec/lib/diaspora_federation/entities/message_spec.rb b/spec/lib/diaspora_federation/entities/message_spec.rb index a843035..c335b10 100644 --- a/spec/lib/diaspora_federation/entities/message_spec.rb +++ b/spec/lib/diaspora_federation/entities/message_spec.rb @@ -22,5 +22,11 @@ XML it_behaves_like "an XML Entity" it_behaves_like "a relayable Entity" + + describe ".get_target_entity_type" do + it "returns \"Conversation\" as target type" do + expect(described_class.get_target_entity_type(data)).to eq("Conversation") + end + end end end diff --git a/spec/lib/diaspora_federation/entities/participation_spec.rb b/spec/lib/diaspora_federation/entities/participation_spec.rb index 9aee0ee..cbb0307 100644 --- a/spec/lib/diaspora_federation/entities/participation_spec.rb +++ b/spec/lib/diaspora_federation/entities/participation_spec.rb @@ -20,5 +20,11 @@ XML it_behaves_like "an XML Entity" it_behaves_like "a relayable Entity" + + describe ".get_target_entity_type" do + it "returns data[:target_type] as target type" do + expect(described_class.get_target_entity_type(data)).to eq(data[:target_type]) + end + end end end diff --git a/spec/lib/diaspora_federation/entities/poll_participation_spec.rb b/spec/lib/diaspora_federation/entities/poll_participation_spec.rb index 815a8a2..980f0f8 100644 --- a/spec/lib/diaspora_federation/entities/poll_participation_spec.rb +++ b/spec/lib/diaspora_federation/entities/poll_participation_spec.rb @@ -20,5 +20,11 @@ XML it_behaves_like "an XML Entity" it_behaves_like "a relayable Entity" + + describe ".get_target_entity_type" do + it "returns \"Poll\" as target type" do + expect(described_class.get_target_entity_type(data)).to eq("Poll") + end + end end end diff --git a/spec/lib/diaspora_federation/entities/relayable_spec.rb b/spec/lib/diaspora_federation/entities/relayable_spec.rb index 3757627..7175c0d 100644 --- a/spec/lib/diaspora_federation/entities/relayable_spec.rb +++ b/spec/lib/diaspora_federation/entities/relayable_spec.rb @@ -10,6 +10,10 @@ module DiasporaFederation } } + class SomeRelayable < Entity + include Entities::Relayable + end + describe ".verify_signatures" do it "doesn't raise anything if correct data were passed" do hash[:author_signature] = Signing.sign_with_key(hash, author_pkey) @@ -28,14 +32,14 @@ module DiasporaFederation expect(DiasporaFederation.callbacks).to receive(:trigger) .with(:entity_author_is_local?, "Post", hash[:parent_guid]) .and_return(false) - expect { Entities::Relayable.verify_signatures(hash) }.not_to raise_error + expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.not_to raise_error end it "raises when no public key for author was fetched" do expect(DiasporaFederation.callbacks).to receive(:trigger).with(:fetch_public_key_by_diaspora_id, anything) .and_return(nil) - expect { Entities::Relayable.verify_signatures(hash) }.to raise_error( + expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error( Entities::Relayable::SignatureVerificationFailed ) end @@ -46,7 +50,7 @@ module DiasporaFederation expect(DiasporaFederation.callbacks).to receive(:trigger) .with(:fetch_public_key_by_diaspora_id, hash[:diaspora_id]) .and_return(author_pkey.public_key) - expect { Entities::Relayable.verify_signatures(hash) }.to raise_error( + expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error( Entities::Relayable::SignatureVerificationFailed ) end @@ -67,7 +71,7 @@ module DiasporaFederation expect(DiasporaFederation.callbacks).to receive(:trigger) .with(:entity_author_is_local?, "Post", hash[:parent_guid]) .and_return(false) - expect { Entities::Relayable.verify_signatures(hash) }.to raise_error( + expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error( Entities::Relayable::SignatureVerificationFailed ) end @@ -89,7 +93,7 @@ module DiasporaFederation expect(DiasporaFederation.callbacks).to receive(:trigger) .with(:entity_author_is_local?, "Post", hash[:parent_guid]) .and_return(false) - expect { Entities::Relayable.verify_signatures(hash) }.to raise_error( + expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error( Entities::Relayable::SignatureVerificationFailed ) end @@ -104,7 +108,7 @@ module DiasporaFederation expect(DiasporaFederation.callbacks).to receive(:trigger) .with(:entity_author_is_local?, "Post", hash[:parent_guid]) .and_return(true) - expect { Entities::Relayable.verify_signatures(hash) }.not_to raise_error + expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.not_to raise_error end end @@ -121,7 +125,7 @@ module DiasporaFederation ) .and_return(parent_pkey) - Entities::Relayable.update_signatures!(hash) + Entities::Relayable.update_signatures!(hash, SomeRelayable) expect(Signing.verify_signature(hash, hash[:author_signature], author_pkey)).to be_truthy expect(Signing.verify_signature(hash, hash[:parent_author_signature], parent_pkey)).to be_truthy end @@ -130,7 +134,7 @@ module DiasporaFederation signatures = {author_signature: "aa", parent_author_signature: "bb"} hash.merge!(signatures) - Entities::Relayable.update_signatures!(hash) + Entities::Relayable.update_signatures!(hash, SomeRelayable) expect(hash[:author_signature]).to eq(signatures[:author_signature]) expect(hash[:parent_author_signature]).to eq(signatures[:parent_author_signature]) end @@ -147,7 +151,7 @@ module DiasporaFederation ) .and_return(nil) - Entities::Relayable.update_signatures!(hash) + Entities::Relayable.update_signatures!(hash, SomeRelayable) expect(hash[:author_signature]).to eq(nil) expect(hash[:parent_author_signature]).to eq(nil) end