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
|
# @see Conversation#guid
|
||||||
# @return [String] conversation guid
|
# @return [String] conversation guid
|
||||||
property :conversation_guid
|
property :conversation_guid
|
||||||
|
|
||||||
|
def self.get_target_entity_type(*)
|
||||||
|
"Conversation"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@ module DiasporaFederation
|
||||||
# @see PollAnswer#guid
|
# @see PollAnswer#guid
|
||||||
# @return [String] poll answer guid
|
# @return [String] poll answer guid
|
||||||
property :poll_answer_guid
|
property :poll_answer_guid
|
||||||
|
|
||||||
|
def self.get_target_entity_type(*)
|
||||||
|
"Poll"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -31,6 +31,10 @@ module DiasporaFederation
|
||||||
property :parent_guid
|
property :parent_guid
|
||||||
property :parent_author_signature, default: nil
|
property :parent_author_signature, default: nil
|
||||||
property :author_signature, default: nil
|
property :author_signature, default: nil
|
||||||
|
|
||||||
|
def self.get_target_entity_type(data)
|
||||||
|
data[:target_type] || "Post"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -40,7 +44,7 @@ module DiasporaFederation
|
||||||
def to_xml
|
def to_xml
|
||||||
entity_xml.tap do |xml|
|
entity_xml.tap do |xml|
|
||||||
hash = to_h
|
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("author_signature").content = hash[:author_signature]
|
||||||
xml.at_xpath("parent_author_signature").content = hash[:parent_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)
|
# verifies the signatures (+author_signature+ and +parent_author_signature+ if needed)
|
||||||
# @param [Hash] data hash with data to verify
|
# @param [Hash] data hash with data to verify
|
||||||
# @raise [SignatureVerificationFailed] if the signature is not valid or no public key is found
|
# @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])
|
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, "failed to fetch public key for #{data[:diaspora_id]}" if pkey.nil?
|
||||||
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
||||||
data, data[:author_signature], pkey
|
data, data[:author_signature], pkey
|
||||||
)
|
)
|
||||||
|
|
||||||
author_is_local = DiasporaFederation.callbacks.trigger(:entity_author_is_local?, "Post", data[:parent_guid])
|
author_is_local = DiasporaFederation.callbacks.trigger(
|
||||||
verify_parent_signature(data) unless author_is_local
|
:entity_author_is_local?,
|
||||||
|
klass.get_target_entity_type(data),
|
||||||
|
data[:parent_guid]
|
||||||
|
)
|
||||||
|
verify_parent_signature(data, klass) unless author_is_local
|
||||||
end
|
end
|
||||||
|
|
||||||
# this happens only on downstream federation
|
# this happens only on downstream federation
|
||||||
# @param [Hash] data hash with data to verify
|
# @param [Hash] data hash with data to verify
|
||||||
def self.verify_parent_signature(data)
|
def self.verify_parent_signature(data, klass)
|
||||||
pkey = DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid, "Post", data[:parent_guid])
|
pkey = DiasporaFederation.callbacks.trigger(
|
||||||
|
:fetch_author_public_key_by_entity_guid,
|
||||||
|
klass.get_target_entity_type(data),
|
||||||
|
data[:parent_guid]
|
||||||
|
)
|
||||||
raise SignatureVerificationFailed,
|
raise SignatureVerificationFailed,
|
||||||
"failed to fetch public key for author of #{data[:parent_guid]}" if pkey.nil?
|
"failed to fetch public key for author of #{data[:parent_guid]}" if pkey.nil?
|
||||||
raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature(
|
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.
|
# if the signatures are not in the hash yet and if the keys are available.
|
||||||
#
|
#
|
||||||
# @param [Hash] data hash given for a signing
|
# @param [Hash] data hash given for a signing
|
||||||
def self.update_signatures!(data)
|
def self.update_signatures!(data, klass)
|
||||||
if data[:author_signature].nil?
|
if data[:author_signature].nil?
|
||||||
pkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
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?
|
data[:author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
||||||
|
|
@ -90,7 +102,7 @@ module DiasporaFederation
|
||||||
if data[:parent_author_signature].nil?
|
if data[:parent_author_signature].nil?
|
||||||
pkey = DiasporaFederation.callbacks.trigger(
|
pkey = DiasporaFederation.callbacks.trigger(
|
||||||
:fetch_author_private_key_by_entity_guid,
|
:fetch_author_private_key_by_entity_guid,
|
||||||
"Post",
|
klass.get_target_entity_type(data),
|
||||||
data[:parent_guid]
|
data[:parent_guid]
|
||||||
)
|
)
|
||||||
data[:parent_author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
data[:parent_author_signature] = Signing.sign_with_key(data, pkey) unless pkey.nil?
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,9 @@ module DiasporaFederation
|
||||||
end
|
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)
|
klass.new(data)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ module DiasporaFederation
|
||||||
def self.relayable_attributes_with_signatures(factory_name)
|
def self.relayable_attributes_with_signatures(factory_name)
|
||||||
klass = FactoryGirl.factory_by_name(factory_name).build_class
|
klass = FactoryGirl.factory_by_name(factory_name).build_class
|
||||||
sort_hash(FactoryGirl.attributes_for(factory_name), klass).tap do |data|
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,11 @@ XML
|
||||||
it_behaves_like "an XML Entity"
|
it_behaves_like "an XML Entity"
|
||||||
|
|
||||||
it_behaves_like "a relayable 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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -21,5 +21,11 @@ XML
|
||||||
it_behaves_like "an XML Entity"
|
it_behaves_like "an XML Entity"
|
||||||
|
|
||||||
it_behaves_like "a relayable 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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -22,5 +22,11 @@ XML
|
||||||
it_behaves_like "an XML Entity"
|
it_behaves_like "an XML Entity"
|
||||||
|
|
||||||
it_behaves_like "a relayable 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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,11 @@ XML
|
||||||
it_behaves_like "an XML Entity"
|
it_behaves_like "an XML Entity"
|
||||||
|
|
||||||
it_behaves_like "a relayable 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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -20,5 +20,11 @@ XML
|
||||||
it_behaves_like "an XML Entity"
|
it_behaves_like "an XML Entity"
|
||||||
|
|
||||||
it_behaves_like "a relayable 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
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -10,6 +10,10 @@ module DiasporaFederation
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class SomeRelayable < Entity
|
||||||
|
include Entities::Relayable
|
||||||
|
end
|
||||||
|
|
||||||
describe ".verify_signatures" do
|
describe ".verify_signatures" do
|
||||||
it "doesn't raise anything if correct data were passed" do
|
it "doesn't raise anything if correct data were passed" do
|
||||||
hash[:author_signature] = Signing.sign_with_key(hash, author_pkey)
|
hash[:author_signature] = Signing.sign_with_key(hash, author_pkey)
|
||||||
|
|
@ -28,14 +32,14 @@ module DiasporaFederation
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
||||||
.and_return(false)
|
.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
|
end
|
||||||
|
|
||||||
it "raises when no public key for author was fetched" do
|
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)
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(:fetch_public_key_by_diaspora_id, anything)
|
||||||
.and_return(nil)
|
.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
|
Entities::Relayable::SignatureVerificationFailed
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
@ -46,7 +50,7 @@ module DiasporaFederation
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
.with(:fetch_public_key_by_diaspora_id, hash[:diaspora_id])
|
.with(:fetch_public_key_by_diaspora_id, hash[:diaspora_id])
|
||||||
.and_return(author_pkey.public_key)
|
.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
|
Entities::Relayable::SignatureVerificationFailed
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
@ -67,7 +71,7 @@ module DiasporaFederation
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
||||||
.and_return(false)
|
.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
|
Entities::Relayable::SignatureVerificationFailed
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
@ -89,7 +93,7 @@ module DiasporaFederation
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
||||||
.and_return(false)
|
.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
|
Entities::Relayable::SignatureVerificationFailed
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
@ -104,7 +108,7 @@ module DiasporaFederation
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
.with(:entity_author_is_local?, "Post", hash[:parent_guid])
|
||||||
.and_return(true)
|
.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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -121,7 +125,7 @@ module DiasporaFederation
|
||||||
)
|
)
|
||||||
.and_return(parent_pkey)
|
.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[:author_signature], author_pkey)).to be_truthy
|
||||||
expect(Signing.verify_signature(hash, hash[:parent_author_signature], parent_pkey)).to be_truthy
|
expect(Signing.verify_signature(hash, hash[:parent_author_signature], parent_pkey)).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
@ -130,7 +134,7 @@ module DiasporaFederation
|
||||||
signatures = {author_signature: "aa", parent_author_signature: "bb"}
|
signatures = {author_signature: "aa", parent_author_signature: "bb"}
|
||||||
hash.merge!(signatures)
|
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[:author_signature]).to eq(signatures[:author_signature])
|
||||||
expect(hash[:parent_author_signature]).to eq(signatures[:parent_author_signature])
|
expect(hash[:parent_author_signature]).to eq(signatures[:parent_author_signature])
|
||||||
end
|
end
|
||||||
|
|
@ -147,7 +151,7 @@ module DiasporaFederation
|
||||||
)
|
)
|
||||||
.and_return(nil)
|
.and_return(nil)
|
||||||
|
|
||||||
Entities::Relayable.update_signatures!(hash)
|
Entities::Relayable.update_signatures!(hash, SomeRelayable)
|
||||||
expect(hash[:author_signature]).to eq(nil)
|
expect(hash[:author_signature]).to eq(nil)
|
||||||
expect(hash[:parent_author_signature]).to eq(nil)
|
expect(hash[:parent_author_signature]).to eq(nil)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue