diff --git a/lib/diaspora_federation.rb b/lib/diaspora_federation.rb index 38c8d29..adb7e83 100644 --- a/lib/diaspora_federation.rb +++ b/lib/diaspora_federation.rb @@ -24,10 +24,7 @@ module DiasporaFederation fetch_person_for_hcard save_person_after_webfinger fetch_private_key_by_diaspora_id - fetch_author_private_key_by_entity_guid fetch_public_key_by_diaspora_id - fetch_author_public_key_by_entity_guid - entity_author_is_local? fetch_entity_author_id_by_guid fetch_related_entity queue_public_receive @@ -152,30 +149,11 @@ module DiasporaFederation # @param [String] Diaspora ID of the person # @return [OpenSSL::PKey::RSA] key # - # fetch_author_private_key_by_entity_guid - # Fetches a private key of the person who authored an entity identified by a given guid - # @param [String] entity_type (Post, Comment, Like, etc) - # @param [String] guid of the entity - # @return [OpenSSL::PKey::RSA] key - # # fetch_public_key_by_diaspora_id # Fetches a public key of a person by her Diaspora ID from the application # @param [String] Diaspora ID of the person # @return [OpenSSL::PKey::RSA] key # - # fetch_author_public_key_by_entity_guid - # Fetches a public key of the person who authored an entity identified by a given guid - # @param [String] entity_type (Post, Comment, Like, etc) - # @param [String] guid of the entity - # @return [OpenSSL::PKey::RSA] key - # - # entity_author_is_local? - # Reports if the author of the entity identified by a given guid is local on the pod - # where we operate. - # @param [String] entity_type (Post, Comment, Like, etc) - # @param [String] guid of the entity - # @return [Boolean] - # # fetch_entity_author_id_by_guid # Fetches Diaspora ID of the person who authored the entity identified by a given guid # @param [String] entity_type (Post, Comment, Like, etc) diff --git a/lib/diaspora_federation/entities/relayable.rb b/lib/diaspora_federation/entities/relayable.rb index abb8376..ac22047 100644 --- a/lib/diaspora_federation/entities/relayable.rb +++ b/lib/diaspora_federation/entities/relayable.rb @@ -86,17 +86,15 @@ module DiasporaFederation raise PublicKeyNotFound, "author_signature author=#{author} guid=#{guid}" if pubkey.nil? raise SignatureVerificationFailed, "wrong author_signature" unless verify_signature(pubkey, author_signature) - parent_author_local = DiasporaFederation.callbacks.trigger(:entity_author_is_local?, parent_type, parent_guid) - verify_parent_author_signature unless parent_author_local + verify_parent_author_signature unless parent.local end private # this happens only on downstream federation def verify_parent_author_signature - pubkey = DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid, parent_type, parent_guid) - - raise PublicKeyNotFound, "parent_author_signature parent_guid=#{parent_guid} guid=#{guid}" if pubkey.nil? + pubkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, parent.author) + raise PublicKeyNotFound, "parent_author_signature parent_author=#{parent.author} guid=#{guid}" if pubkey.nil? unless verify_signature(pubkey, parent_author_signature) raise SignatureVerificationFailed, "wrong parent_author_signature parent_guid=#{parent_guid}" end @@ -132,9 +130,7 @@ module DiasporaFederation # sign with parent author key, if the parent author is local (if the private key is found) # @return [String] A Base64 encoded signature of #signature_data with key def sign_with_parent_author_if_available - privkey = DiasporaFederation.callbacks.trigger( - :fetch_author_private_key_by_entity_guid, parent_type, parent_guid - ) + privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, parent.author) if privkey sign_with_key(privkey).tap do logger.info "event=sign status=complete signature=parent_author_signature guid=#{guid}" diff --git a/spec/integration/comment_integration_spec.rb b/spec/integration/comment_integration_spec.rb index b48698a..c1a5be6 100644 --- a/spec/integration/comment_integration_spec.rb +++ b/spec/integration/comment_integration_spec.rb @@ -191,7 +191,7 @@ XML :fetch_private_key_by_diaspora_id, author ).and_return(author_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_private_key_by_entity_guid, "Post", parent_guid + :fetch_private_key_by_diaspora_id, parent.author ).and_return(nil) comment.to_xml @@ -202,10 +202,7 @@ XML :fetch_public_key_by_diaspora_id, author ).and_return(author_key.public_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Post", parent_guid - ).and_return(true) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_private_key_by_entity_guid, "Post", parent_guid + :fetch_private_key_by_diaspora_id, parent.author ).and_return(parent_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_related_entity, "Post", parent_guid @@ -222,10 +219,7 @@ XML :fetch_public_key_by_diaspora_id, author ).and_return(author_key.public_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Post", parent_guid - ).and_return(true) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_private_key_by_entity_guid, "Post", parent_guid + :fetch_private_key_by_diaspora_id, parent.author ).and_return(parent_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_related_entity, "Post", parent_guid @@ -252,15 +246,14 @@ XML end context "parsing on every other pod" do + let(:parent) { FactoryGirl.build(:related_entity, author: bob.diaspora_id, local: false) } + before do expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_key.public_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Post", parent_guid - ).and_return(false) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Post", parent_guid + :fetch_public_key_by_diaspora_id, parent.author ).and_return(parent_key.public_key) expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_related_entity, "Post", parent_guid diff --git a/spec/lib/diaspora_federation/entities/conversation_spec.rb b/spec/lib/diaspora_federation/entities/conversation_spec.rb index 0bf4425..d050acf 100644 --- a/spec/lib/diaspora_federation/entities/conversation_spec.rb +++ b/spec/lib/diaspora_federation/entities/conversation_spec.rb @@ -3,16 +3,16 @@ module DiasporaFederation let(:parent) { FactoryGirl.create(:conversation, author: bob) } let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) } let(:signed_msg1) { - msg = FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid).send(:xml_elements) - Entities::Message.new(msg.merge(parent: parent_entity)) + FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity) + .send(:xml_elements).merge(parent: parent_entity) } let(:signed_msg2) { - msg = FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid).send(:xml_elements) - Entities::Message.new(msg.merge(parent: parent_entity)) + FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity) + .send(:xml_elements).merge(parent: parent_entity) } let(:data) { FactoryGirl.attributes_for(:conversation_entity).merge!( - messages: [signed_msg1, signed_msg2], + messages: [Entities::Message.new(signed_msg1), Entities::Message.new(signed_msg2)], author: bob.diaspora_id, guid: parent.guid, participants: "#{bob.diaspora_id};#{FactoryGirl.generate(:diaspora_id)}" diff --git a/spec/lib/diaspora_federation/entities/relayable_spec.rb b/spec/lib/diaspora_federation/entities/relayable_spec.rb index 0161bdf..71b58d3 100644 --- a/spec/lib/diaspora_federation/entities/relayable_spec.rb +++ b/spec/lib/diaspora_federation/entities/relayable_spec.rb @@ -8,8 +8,9 @@ module DiasporaFederation let(:author) { FactoryGirl.generate(:diaspora_id) } let(:property) { "hello" } let(:new_property) { "some text" } - let(:parent) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) } - let(:hash) { {guid: guid, author: author, parent_guid: parent_guid, property: property} } + let(:local_parent) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) } + let(:remote_parent) { FactoryGirl.build(:related_entity, author: bob.diaspora_id, local: false) } + let(:hash) { {guid: guid, author: author, parent_guid: parent_guid, parent: local_parent, property: property} } let(:legacy_signature_data) { "#{guid};#{author};#{property};#{parent_guid}" } @@ -39,19 +40,15 @@ module DiasporaFederation it "doesn't raise anything if correct signatures with legacy-string were passed" do hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) hash[:parent_author_signature] = sign_with_key(parent_pkey, legacy_signature_data) + hash[:parent] = remote_parent expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Parent", parent_guid + :fetch_public_key_by_diaspora_id, remote_parent.author ).and_return(parent_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(false) - expect { SomeRelayable.new(hash).verify_signatures }.not_to raise_error end @@ -79,19 +76,15 @@ module DiasporaFederation it "raises when no public key for parent author was fetched" do hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) + hash[:parent] = remote_parent expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Parent", parent_guid + :fetch_public_key_by_diaspora_id, remote_parent.author ).and_return(nil) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(false) - expect { SomeRelayable.new(hash).verify_signatures }.to raise_error Entities::Relayable::PublicKeyNotFound @@ -100,19 +93,15 @@ module DiasporaFederation it "raises when bad parent author signature was passed" do hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) hash[:parent_author_signature] = nil + hash[:parent] = remote_parent expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Parent", parent_guid + :fetch_public_key_by_diaspora_id, remote_parent.author ).and_return(parent_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(false) - expect { SomeRelayable.new(hash).verify_signatures }.to raise_error Entities::Relayable::SignatureVerificationFailed @@ -121,15 +110,12 @@ module DiasporaFederation it "doesn't raise if parent_author_signature isn't set but we're on upstream federation" do hash[:author_signature] = sign_with_key(author_pkey, legacy_signature_data) hash[:parent_author_signature] = nil + hash[:parent] = local_parent expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(true) - expect { SomeRelayable.new(hash).verify_signatures }.not_to raise_error end @@ -140,19 +126,15 @@ module DiasporaFederation hash[:author_signature] = sign_with_key(author_pkey, signature_data) hash[:parent_author_signature] = sign_with_key(parent_pkey, signature_data) + hash[:parent] = remote_parent expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Parent", parent_guid + :fetch_public_key_by_diaspora_id, remote_parent.author ).and_return(parent_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(false) - expect { SomeRelayable.new(hash, xml_order).verify_signatures }.not_to raise_error end @@ -162,19 +144,15 @@ module DiasporaFederation hash[:author_signature] = sign_with_key(author_pkey, signature_data_with_new_property) hash[:parent_author_signature] = sign_with_key(parent_pkey, signature_data_with_new_property) + hash[:parent] = remote_parent expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Parent", parent_guid + :fetch_public_key_by_diaspora_id, remote_parent.author ).and_return(parent_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(false) - expect { SomeRelayable.new(hash, xml_order, "new_property" => new_property).verify_signatures }.not_to raise_error @@ -220,9 +198,8 @@ XML expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_private_key_by_diaspora_id, author ).and_return(author_pkey) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_private_key_by_entity_guid, "Parent", parent_guid + :fetch_private_key_by_diaspora_id, local_parent.author ).and_return(parent_pkey) xml = SomeRelayable.new(hash).to_xml @@ -238,9 +215,8 @@ XML expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_private_key_by_diaspora_id, author ).and_return(author_pkey) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_private_key_by_entity_guid, "Parent", parent_guid + :fetch_private_key_by_diaspora_id, local_parent.author ).and_return(parent_pkey) xml_order = [:author, :guid, :parent_guid, "new_property", :property] @@ -278,9 +254,8 @@ XML expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_private_key_by_diaspora_id, author ).and_return(author_pkey) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_private_key_by_entity_guid, "Parent", parent_guid + :fetch_private_key_by_diaspora_id, local_parent.author ).and_return(nil) xml = SomeRelayable.new(hash).to_xml @@ -290,23 +265,20 @@ XML end describe ".from_xml" do + before do + expect(DiasporaFederation.callbacks).to receive(:trigger).with( + :fetch_related_entity, "Parent", parent_guid + ).and_return(remote_parent) + end + context "parsing" do before do expect(DiasporaFederation.callbacks).to receive(:trigger).with( :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_author_public_key_by_entity_guid, "Parent", parent_guid + :fetch_public_key_by_diaspora_id, remote_parent.author ).and_return(parent_pkey.public_key) - - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :entity_author_is_local?, "Parent", parent_guid - ).and_return(false) - - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_related_entity, "Parent", parent_guid - ).and_return(parent) end let(:new_signature_data) { "#{author};#{guid};#{parent_guid};#{new_property};#{property}" } @@ -366,10 +338,6 @@ XML :fetch_public_key_by_diaspora_id, author ).and_return(author_pkey.public_key) - expect(DiasporaFederation.callbacks).to receive(:trigger).with( - :fetch_related_entity, "Parent", parent_guid - ).and_return(parent) - expect { SomeRelayable.from_xml(xml) }.to raise_error DiasporaFederation::Entities::Relayable::SignatureVerificationFailed diff --git a/test/dummy/config/initializers/diaspora_federation.rb b/test/dummy/config/initializers/diaspora_federation.rb index 8c03c36..acd5b41 100644 --- a/test/dummy/config/initializers/diaspora_federation.rb +++ b/test/dummy/config/initializers/diaspora_federation.rb @@ -65,27 +65,12 @@ DiasporaFederation.configure do |config| OpenSSL::PKey::RSA.new(key) unless key.nil? end - on :fetch_author_private_key_by_entity_guid do |entity_type, guid| - key = Entity.where(entity_type: entity_type, guid: guid).joins(:author).pluck(:serialized_private_key).first - OpenSSL::PKey::RSA.new(key) unless key.nil? - end - on :fetch_public_key_by_diaspora_id do |diaspora_id| key = Person.where(diaspora_id: diaspora_id).pluck(:serialized_public_key).first key = DiasporaFederation::Discovery::Discovery.new(diaspora_id).fetch_and_save.exported_key if key.nil? OpenSSL::PKey::RSA.new(key) unless key.nil? end - on :fetch_author_public_key_by_entity_guid do |entity_type, guid| - key = Entity.where(entity_type: entity_type, guid: guid).joins(:author).pluck(:serialized_public_key).first - OpenSSL::PKey::RSA.new(key) unless key.nil? - end - - on :entity_author_is_local? do |entity_type, guid| - Entity.where(entity_type: entity_type, guid: guid).joins(:author) - .where.not("people.serialized_private_key" => nil).exists? - end - on :fetch_entity_author_id_by_guid do |entity_type, guid| Entity.where(entity_type: entity_type, guid: guid).joins(:author).pluck(:diaspora_id).first end