refactoring relayable signature-checking
verify signature after creating the entity instance
This commit is contained in:
parent
583d567d67
commit
adf14283e3
14 changed files with 103 additions and 111 deletions
|
|
@ -21,6 +21,12 @@ module DiasporaFederation
|
||||||
# @see Person#diaspora_id
|
# @see Person#diaspora_id
|
||||||
# @return [String] diaspora ID
|
# @return [String] diaspora ID
|
||||||
property :diaspora_id, xml_name: :diaspora_handle
|
property :diaspora_id, xml_name: :diaspora_handle
|
||||||
|
|
||||||
|
# The {Comment} parent is a Post
|
||||||
|
# @return [String] target type
|
||||||
|
def target_type
|
||||||
|
"Post"
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -35,8 +35,8 @@ module DiasporaFederation
|
||||||
property :conversation_guid
|
property :conversation_guid
|
||||||
|
|
||||||
# The {Message} parent is a {Conversation}
|
# The {Message} parent is a {Conversation}
|
||||||
# @return [String] parent entity type
|
# @return [String] target type
|
||||||
def self.get_target_entity_type(*)
|
def target_type
|
||||||
"Conversation"
|
"Conversation"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ module DiasporaFederation
|
||||||
property :poll_answer_guid
|
property :poll_answer_guid
|
||||||
|
|
||||||
# The {PollParticipation} parent is a {Poll}
|
# The {PollParticipation} parent is a {Poll}
|
||||||
# @return [String] parent entity type
|
# @return [String] target type
|
||||||
def self.get_target_entity_type(*)
|
def target_type
|
||||||
"Poll"
|
"Poll"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -31,11 +31,25 @@ 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
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
# get the type of the parent entity
|
# Adds signatures to the hash with the keys of the author and the parent
|
||||||
# @return [String] parent entity type
|
# if the signatures are not in the hash yet and if the keys are available.
|
||||||
def self.get_target_entity_type(data)
|
#
|
||||||
data[:target_type] || "Post"
|
# @return [Hash] entity data hash with updated signatures
|
||||||
|
def to_signed_h
|
||||||
|
to_h.tap do |hash|
|
||||||
|
if author_signature.nil?
|
||||||
|
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, diaspora_id)
|
||||||
|
hash[:author_signature] = Signing.sign_with_key(hash, privkey) unless privkey.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
if parent_author_signature.nil?
|
||||||
|
privkey = DiasporaFederation.callbacks.trigger(
|
||||||
|
:fetch_author_private_key_by_entity_guid, target_type, parent_guid
|
||||||
|
)
|
||||||
|
hash[:parent_author_signature] = Signing.sign_with_key(hash, privkey) unless privkey.nil?
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
@ -45,9 +59,7 @@ module DiasporaFederation
|
||||||
# @return [Nokogiri::XML::Element] root element containing properties as child elements
|
# @return [Nokogiri::XML::Element] root element containing properties as child elements
|
||||||
def to_xml
|
def to_xml
|
||||||
entity_xml.tap do |xml|
|
entity_xml.tap do |xml|
|
||||||
hash = to_h
|
hash = to_signed_h
|
||||||
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]
|
||||||
end
|
end
|
||||||
|
|
@ -58,61 +70,29 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
|
|
||||||
# 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 [Class] klass entity type
|
|
||||||
# @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, klass)
|
def verify_signatures
|
||||||
pubkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, data[:diaspora_id])
|
pubkey = DiasporaFederation.callbacks.trigger(:fetch_public_key_by_diaspora_id, diaspora_id)
|
||||||
raise SignatureVerificationFailed, "failed to fetch public key for #{data[:diaspora_id]}" if pubkey.nil?
|
raise SignatureVerificationFailed, "failed to fetch public key for #{diaspora_id}" if pubkey.nil?
|
||||||
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
raise SignatureVerificationFailed, "wrong author_signature" unless Signing.verify_signature(
|
||||||
data, data[:author_signature], pubkey
|
data, author_signature, pubkey
|
||||||
)
|
)
|
||||||
|
|
||||||
author_is_local = DiasporaFederation.callbacks.trigger(
|
author_is_local = DiasporaFederation.callbacks.trigger(:entity_author_is_local?, target_type, parent_guid)
|
||||||
:entity_author_is_local?,
|
verify_parent_signature unless author_is_local
|
||||||
klass.get_target_entity_type(data),
|
|
||||||
data[:parent_guid]
|
|
||||||
)
|
|
||||||
verify_parent_signature(data, klass) unless author_is_local
|
|
||||||
end
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
# this happens only on downstream federation
|
# this happens only on downstream federation
|
||||||
# @param [Hash] data hash with data to verify
|
def verify_parent_signature
|
||||||
# @param [Class] klass entity type
|
pubkey = DiasporaFederation.callbacks.trigger(:fetch_author_public_key_by_entity_guid, target_type, parent_guid)
|
||||||
def self.verify_parent_signature(data, klass)
|
|
||||||
pubkey = DiasporaFederation.callbacks.trigger(
|
raise SignatureVerificationFailed, "failed to fetch public key for author of #{parent_guid}" if pubkey.nil?
|
||||||
: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 pubkey.nil?
|
|
||||||
raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature(
|
raise SignatureVerificationFailed, "wrong parent_author_signature" unless Signing.verify_signature(
|
||||||
data, data[:parent_author_signature], pubkey
|
data, parent_author_signature, pubkey
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
private_class_method :verify_parent_signature
|
|
||||||
|
|
||||||
# Adds signatures to a given hash with the keys of the author and the parent
|
|
||||||
# if the signatures are not in the hash yet and if the keys are available.
|
|
||||||
#
|
|
||||||
# @param [Hash] data hash given for a signing
|
|
||||||
# @param [Class] klass entity type
|
|
||||||
def self.update_signatures!(data, klass)
|
|
||||||
if data[:author_signature].nil?
|
|
||||||
privkey = DiasporaFederation.callbacks.trigger(:fetch_private_key_by_diaspora_id, data[:diaspora_id])
|
|
||||||
data[:author_signature] = Signing.sign_with_key(data, privkey) unless privkey.nil?
|
|
||||||
end
|
|
||||||
|
|
||||||
if data[:parent_author_signature].nil?
|
|
||||||
privkey = DiasporaFederation.callbacks.trigger(
|
|
||||||
:fetch_author_private_key_by_entity_guid,
|
|
||||||
klass.get_target_entity_type(data),
|
|
||||||
data[:parent_guid]
|
|
||||||
)
|
|
||||||
data[:parent_author_signature] = Signing.sign_with_key(data, privkey) unless privkey.nil?
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -35,6 +35,10 @@ module DiasporaFederation
|
||||||
class Entity
|
class Entity
|
||||||
extend PropertiesDSL
|
extend PropertiesDSL
|
||||||
|
|
||||||
|
# the original data hash with which the entity was created
|
||||||
|
# @return [Hash] original data
|
||||||
|
attr_reader :data
|
||||||
|
|
||||||
# Initializes the Entity with the given attribute hash and freezes the created
|
# Initializes the Entity with the given attribute hash and freezes the created
|
||||||
# instance it returns.
|
# instance it returns.
|
||||||
#
|
#
|
||||||
|
|
@ -56,6 +60,8 @@ module DiasporaFederation
|
||||||
raise ArgumentError, "missing required properties: #{missing_props.join(', ')}"
|
raise ArgumentError, "missing required properties: #{missing_props.join(', ')}"
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@data = data
|
||||||
|
|
||||||
self.class.default_values.merge(data).each do |k, v|
|
self.class.default_values.merge(data).each do |k, v|
|
||||||
instance_variable_set("@#{k}", nilify(v)) if setable?(k, v)
|
instance_variable_set("@#{k}", nilify(v)) if setable?(k, v)
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -97,11 +97,9 @@ module DiasporaFederation
|
||||||
end
|
end
|
||||||
}]
|
}]
|
||||||
|
|
||||||
if klass.included_modules.include?(Entities::Relayable)
|
klass.new(data).tap do |entity|
|
||||||
Entities::Relayable.verify_signatures(data, klass)
|
entity.verify_signatures if entity.respond_to? :verify_signatures
|
||||||
end
|
end
|
||||||
|
|
||||||
klass.new(data)
|
|
||||||
end
|
end
|
||||||
private_class_method :populate_entity
|
private_class_method :populate_entity
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,10 +21,7 @@ module DiasporaFederation
|
||||||
# @param [Symbol] factory_name the factory to generate attributes for (normally entity name)
|
# @param [Symbol] factory_name the factory to generate attributes for (normally entity name)
|
||||||
# @return [Hash] hash with correct signatures
|
# @return [Hash] hash with correct signatures
|
||||||
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
|
FactoryGirl.build(factory_name).to_signed_h
|
||||||
sort_hash(FactoryGirl.attributes_for(factory_name), klass).tap do |data|
|
|
||||||
DiasporaFederation::Entities::Relayable.update_signatures!(data, klass)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Generates attributes for signed retraction entity constructor with correct signatures in it
|
# Generates attributes for signed retraction entity constructor with correct signatures in it
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ XML
|
||||||
|
|
||||||
it_behaves_like "a relayable Entity"
|
it_behaves_like "a relayable Entity"
|
||||||
|
|
||||||
describe ".get_target_entity_type" do
|
describe "#target_type" do
|
||||||
it "returns \"Post\" as target type" do
|
it "returns \"Post\" as target type" do
|
||||||
expect(described_class.get_target_entity_type(data)).to eq("Post")
|
expect(described_class.new(data).target_type).to eq("Post")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -22,9 +22,9 @@ XML
|
||||||
|
|
||||||
it_behaves_like "a relayable Entity"
|
it_behaves_like "a relayable Entity"
|
||||||
|
|
||||||
describe ".get_target_entity_type" do
|
describe "#target_type" do
|
||||||
it "returns data[:target_type] as target type" do
|
it "returns data[:target_type] as target type" do
|
||||||
expect(described_class.get_target_entity_type(data)).to eq(data[:target_type])
|
expect(described_class.new(data).target_type).to eq(data[:target_type])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -23,9 +23,9 @@ XML
|
||||||
|
|
||||||
it_behaves_like "a relayable Entity"
|
it_behaves_like "a relayable Entity"
|
||||||
|
|
||||||
describe ".get_target_entity_type" do
|
describe "#target_type" do
|
||||||
it "returns \"Conversation\" as target type" do
|
it "returns \"Conversation\" as target type" do
|
||||||
expect(described_class.get_target_entity_type(data)).to eq("Conversation")
|
expect(described_class.new(data).target_type).to eq("Conversation")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ XML
|
||||||
|
|
||||||
it_behaves_like "a relayable Entity"
|
it_behaves_like "a relayable Entity"
|
||||||
|
|
||||||
describe ".get_target_entity_type" do
|
describe "#target_type" do
|
||||||
it "returns data[:target_type] as target type" do
|
it "returns data[:target_type] as target type" do
|
||||||
expect(described_class.get_target_entity_type(data)).to eq(data[:target_type])
|
expect(described_class.new(data).target_type).to eq(data[:target_type])
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -21,9 +21,9 @@ XML
|
||||||
|
|
||||||
it_behaves_like "a relayable Entity"
|
it_behaves_like "a relayable Entity"
|
||||||
|
|
||||||
describe ".get_target_entity_type" do
|
describe "#target_type" do
|
||||||
it "returns \"Poll\" as target type" do
|
it "returns \"Poll\" as target type" do
|
||||||
expect(described_class.get_target_entity_type(data)).to eq("Poll")
|
expect(described_class.new(data).target_type).to eq("Poll")
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -12,9 +12,15 @@ module DiasporaFederation
|
||||||
|
|
||||||
class SomeRelayable < Entity
|
class SomeRelayable < Entity
|
||||||
include Entities::Relayable
|
include Entities::Relayable
|
||||||
|
|
||||||
|
property :diaspora_id, xml_name: :diaspora_handle
|
||||||
|
|
||||||
|
def target_type
|
||||||
|
"Target"
|
||||||
|
end
|
||||||
end
|
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)
|
||||||
hash[:parent_author_signature] = Signing.sign_with_key(hash, parent_pkey)
|
hash[:parent_author_signature] = Signing.sign_with_key(hash, parent_pkey)
|
||||||
|
|
@ -24,14 +30,14 @@ module DiasporaFederation
|
||||||
).and_return(author_pkey.public_key)
|
).and_return(author_pkey.public_key)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:fetch_author_public_key_by_entity_guid, "Post", hash[:parent_guid]
|
:fetch_author_public_key_by_entity_guid, "Target", hash[:parent_guid]
|
||||||
).and_return(parent_pkey.public_key)
|
).and_return(parent_pkey.public_key)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:entity_author_is_local?, "Post", hash[:parent_guid]
|
:entity_author_is_local?, "Target", hash[:parent_guid]
|
||||||
).and_return(false)
|
).and_return(false)
|
||||||
|
|
||||||
expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.not_to raise_error
|
expect { SomeRelayable.new(hash).verify_signatures }.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
|
||||||
|
|
@ -39,9 +45,9 @@ module DiasporaFederation
|
||||||
:fetch_public_key_by_diaspora_id, anything
|
:fetch_public_key_by_diaspora_id, anything
|
||||||
).and_return(nil)
|
).and_return(nil)
|
||||||
|
|
||||||
expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error(
|
expect {
|
||||||
Entities::Relayable::SignatureVerificationFailed
|
SomeRelayable.new(hash).verify_signatures
|
||||||
)
|
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises when bad author signature was passed" do
|
it "raises when bad author signature was passed" do
|
||||||
|
|
@ -51,9 +57,9 @@ module DiasporaFederation
|
||||||
:fetch_public_key_by_diaspora_id, hash[:diaspora_id]
|
: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, SomeRelayable) }.to raise_error(
|
expect {
|
||||||
Entities::Relayable::SignatureVerificationFailed
|
SomeRelayable.new(hash).verify_signatures
|
||||||
)
|
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises when no public key for parent author was fetched" do
|
it "raises when no public key for parent author was fetched" do
|
||||||
|
|
@ -64,16 +70,16 @@ module DiasporaFederation
|
||||||
).and_return(author_pkey.public_key)
|
).and_return(author_pkey.public_key)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:fetch_author_public_key_by_entity_guid, "Post", hash[:parent_guid]
|
:fetch_author_public_key_by_entity_guid, "Target", hash[:parent_guid]
|
||||||
).and_return(nil)
|
).and_return(nil)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:entity_author_is_local?, "Post", hash[:parent_guid]
|
:entity_author_is_local?, "Target", hash[:parent_guid]
|
||||||
).and_return(false)
|
).and_return(false)
|
||||||
|
|
||||||
expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error(
|
expect {
|
||||||
Entities::Relayable::SignatureVerificationFailed
|
SomeRelayable.new(hash).verify_signatures
|
||||||
)
|
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
it "raises when bad parent author signature was passed" do
|
it "raises when bad parent author signature was passed" do
|
||||||
|
|
@ -85,16 +91,16 @@ module DiasporaFederation
|
||||||
).and_return(author_pkey.public_key)
|
).and_return(author_pkey.public_key)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:fetch_author_public_key_by_entity_guid, "Post", hash[:parent_guid]
|
:fetch_author_public_key_by_entity_guid, "Target", hash[:parent_guid]
|
||||||
).and_return(parent_pkey.public_key)
|
).and_return(parent_pkey.public_key)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:entity_author_is_local?, "Post", hash[:parent_guid]
|
:entity_author_is_local?, "Target", hash[:parent_guid]
|
||||||
).and_return(false)
|
).and_return(false)
|
||||||
|
|
||||||
expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.to raise_error(
|
expect {
|
||||||
Entities::Relayable::SignatureVerificationFailed
|
SomeRelayable.new(hash).verify_signatures
|
||||||
)
|
}.to raise_error Entities::Relayable::SignatureVerificationFailed
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't raise if parent_author_signature isn't set but we're on upstream federation" do
|
it "doesn't raise if parent_author_signature isn't set but we're on upstream federation" do
|
||||||
|
|
@ -106,35 +112,33 @@ module DiasporaFederation
|
||||||
).and_return(author_pkey.public_key)
|
).and_return(author_pkey.public_key)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:entity_author_is_local?, "Post", hash[:parent_guid]
|
:entity_author_is_local?, "Target", hash[:parent_guid]
|
||||||
).and_return(true)
|
).and_return(true)
|
||||||
|
|
||||||
expect { Entities::Relayable.verify_signatures(hash, SomeRelayable) }.not_to raise_error
|
expect { SomeRelayable.new(hash).verify_signatures }.not_to raise_error
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
describe ".update_singatures!" do
|
describe "#to_signed_h" do
|
||||||
it "updates signatures when they were nil and keys were supplied" do
|
it "updates signatures when they were nil and keys were supplied" do
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:fetch_private_key_by_diaspora_id, hash[:diaspora_id]
|
:fetch_private_key_by_diaspora_id, hash[:diaspora_id]
|
||||||
).and_return(author_pkey)
|
).and_return(author_pkey)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:fetch_author_private_key_by_entity_guid, "Post", hash[:parent_guid]
|
:fetch_author_private_key_by_entity_guid, "Target", hash[:parent_guid]
|
||||||
).and_return(parent_pkey)
|
).and_return(parent_pkey)
|
||||||
|
|
||||||
Entities::Relayable.update_signatures!(hash, SomeRelayable)
|
signed_hash = SomeRelayable.new(hash).to_signed_h
|
||||||
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(signed_hash, signed_hash[:author_signature], author_pkey)).to be_truthy
|
||||||
|
expect(Signing.verify_signature(signed_hash, signed_hash[:parent_author_signature], parent_pkey)).to be_truthy
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't change signatures if they are already set" do
|
it "doesn't change signatures if they are already set" do
|
||||||
signatures = {author_signature: "aa", parent_author_signature: "bb"}
|
hash.merge!(author_signature: "aa", parent_author_signature: "bb").delete(:some_other_data)
|
||||||
hash.merge!(signatures)
|
|
||||||
|
|
||||||
Entities::Relayable.update_signatures!(hash, SomeRelayable)
|
expect(SomeRelayable.new(hash).to_signed_h).to eq(hash)
|
||||||
expect(hash[:author_signature]).to eq(signatures[:author_signature])
|
|
||||||
expect(hash[:parent_author_signature]).to eq(signatures[:parent_author_signature])
|
|
||||||
end
|
end
|
||||||
|
|
||||||
it "doesn't change signatures if keys weren't supplied" do
|
it "doesn't change signatures if keys weren't supplied" do
|
||||||
|
|
@ -143,12 +147,13 @@ module DiasporaFederation
|
||||||
).and_return(nil)
|
).and_return(nil)
|
||||||
|
|
||||||
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
|
||||||
:fetch_author_private_key_by_entity_guid, "Post", hash[:parent_guid]
|
:fetch_author_private_key_by_entity_guid, "Target", hash[:parent_guid]
|
||||||
).and_return(nil)
|
).and_return(nil)
|
||||||
|
|
||||||
Entities::Relayable.update_signatures!(hash, SomeRelayable)
|
signed_hash = SomeRelayable.new(hash).to_signed_h
|
||||||
expect(hash[:author_signature]).to eq(nil)
|
|
||||||
expect(hash[:parent_author_signature]).to eq(nil)
|
expect(signed_hash[:author_signature]).to eq(nil)
|
||||||
|
expect(signed_hash[:parent_author_signature]).to eq(nil)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -147,7 +147,7 @@ XML
|
||||||
it "calls signatures verification on relayable unpack" do
|
it "calls signatures verification on relayable unpack" do
|
||||||
entity = FactoryGirl.build(:comment_entity)
|
entity = FactoryGirl.build(:comment_entity)
|
||||||
payload = Salmon::XmlPayload.pack(entity)
|
payload = Salmon::XmlPayload.pack(entity)
|
||||||
expect(Entities::Relayable).to receive(:verify_signatures).once
|
expect(Signing).to receive(:verify_signature).twice.and_call_original
|
||||||
Salmon::XmlPayload.unpack(payload)
|
Salmon::XmlPayload.unpack(payload)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue