use data from parent-RelatedEntity for Relayables
This commit is contained in:
parent
23fc8dc180
commit
8f2b3e6a14
6 changed files with 39 additions and 119 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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)}"
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue