Allow parent entity types different than "Post"
Entities::Message requires "Conversation" at the place, for instance.
This commit is contained in:
parent
358e844772
commit
a0545c37de
11 changed files with 75 additions and 19 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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?
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Reference in a new issue