use related entity as parent for relayables

This commit is contained in:
Benjamin Neff 2016-03-28 07:10:02 +02:00
parent 3ac21b585b
commit 23fc8dc180
16 changed files with 94 additions and 24 deletions

View file

@ -8,6 +8,9 @@ module DiasporaFederation
# @deprecated
LEGACY_SIGNATURE_ORDER = %i(guid parent_guid text author).freeze
# The {Comment} parent is a {Post}
PARENT_TYPE = "Post".freeze
include Relayable
# @!attribute [r] text
@ -22,7 +25,7 @@ module DiasporaFederation
# The {Comment} parent is a Post
# @return [String] parent type
def parent_type
"Post"
PARENT_TYPE
end
end
end

View file

@ -8,6 +8,9 @@ module DiasporaFederation
# @deprecated
LEGACY_SIGNATURE_ORDER = %i(guid parent_guid text created_at author conversation_guid).freeze
# The {Message} parent is a {Conversation}
PARENT_TYPE = "Conversation".freeze
include Relayable
# @!attribute [r] text
@ -29,7 +32,7 @@ module DiasporaFederation
# The {Message} parent is a {Conversation}
# @return [String] parent type
def parent_type
"Conversation"
PARENT_TYPE
end
end
end

View file

@ -8,6 +8,9 @@ module DiasporaFederation
# @deprecated
LEGACY_SIGNATURE_ORDER = %i(guid parent_guid author poll_answer_guid).freeze
# The {PollParticipation} parent is a {Poll}
PARENT_TYPE = "Poll".freeze
include Relayable
# @!attribute [r] poll_answer_guid
@ -19,7 +22,7 @@ module DiasporaFederation
# The {PollParticipation} parent is a {Poll}
# @return [String] parent type
def parent_type
"Poll"
PARENT_TYPE
end
end
end

View file

@ -10,6 +10,10 @@ module DiasporaFederation
# digest instance used for signing
DIGEST = OpenSSL::Digest::SHA256.new
# parent entity
# @return [RelatedEntity] parent entity
attr_reader :parent
# order from the parsed xml for signature
# @return [Array] order from xml
attr_reader :xml_order
@ -68,6 +72,7 @@ module DiasporaFederation
# @param [Hash] additional_xml_elements additional xml elements
# @see DiasporaFederation::Entity#initialize
def initialize(data, xml_order=nil, additional_xml_elements={})
@parent = data[:parent] if data
@xml_order = xml_order
@additional_xml_elements = additional_xml_elements
@ -197,8 +202,18 @@ module DiasporaFederation
end
end
add_parent(entity_data)
new(entity_data, xml_order, additional_xml_elements).tap(&:verify_signatures)
end
def add_parent(data)
data[:parent] = fetch_parent(data)
end
def fetch_parent(data)
type = data[:parent_type] || self::PARENT_TYPE
DiasporaFederation.callbacks.trigger(:fetch_related_entity, type, data[:parent_guid])
end
end
# Raised, if creating the author_signature failes, because the private key was not found

View file

@ -87,6 +87,7 @@ module DiasporaFederation
factory :relayable_entity, class: DiasporaFederation::Entities::Relayable do
parent_guid { generate(:guid) }
parent { FactoryGirl.build(:related_entity) }
end
factory :participation_entity,

View file

@ -9,6 +9,7 @@ module DiasporaFederation
rule :author, %i(not_empty diaspora_id)
rule :guid, :guid
rule :parent_guid, :guid
rule :parent, :not_nil
end
end
end

View file

@ -60,8 +60,11 @@ KEY
let(:new_data) { "foobar" }
let(:text) { "this is a very informative comment" }
let(:parent) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
let(:comment) {
Entities::Comment.new(author: author, guid: guid, parent_guid: parent_guid, text: text, new_data: new_data)
Entities::Comment.new(
author: author, guid: guid, parent_guid: parent_guid, text: text, parent: parent, new_data: new_data
)
}
let(:legacy_comment_xml_alice) {
@ -204,6 +207,9 @@ XML
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
:fetch_author_private_key_by_entity_guid, "Post", parent_guid
).and_return(parent_key)
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
:fetch_related_entity, "Post", parent_guid
).and_return(parent)
xml = Nokogiri::XML::Document.parse(new_data_comment_xml_alice).root
Salmon::XmlPayload.unpack(xml).to_xml
@ -221,6 +227,9 @@ XML
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
:fetch_author_private_key_by_entity_guid, "Post", parent_guid
).and_return(parent_key)
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
:fetch_related_entity, "Post", parent_guid
).and_return(parent)
end
it "relays legacy signatures and xml" do
@ -253,6 +262,9 @@ XML
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
:fetch_author_public_key_by_entity_guid, "Post", parent_guid
).and_return(parent_key.public_key)
expect(DiasporaFederation.callbacks).to receive(:trigger).with(
:fetch_related_entity, "Post", parent_guid
).and_return(parent)
end
it "parses legacy signatures and xml" do

View file

@ -1,9 +1,10 @@
module DiasporaFederation
describe Entities::Comment do
let(:parent) { FactoryGirl.create(:post, author: bob) }
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
let(:data) {
FactoryGirl.build(:comment_entity, author: alice.diaspora_id, parent_guid: parent.guid).send(:xml_elements)
.merge(created_at: Time.now.utc)
FactoryGirl.build(:comment_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
.send(:xml_elements).merge(created_at: Time.now.utc, parent: parent_entity)
}
let(:xml) {
@ -19,7 +20,7 @@ module DiasporaFederation
XML
}
it_behaves_like "an Entity subclass"
it_behaves_like "an Entity subclass", [:parent]
it_behaves_like "an XML Entity", [:created_at]
@ -35,6 +36,7 @@ XML
created_at = Time.now.utc - 1.minute
comment_data = FactoryGirl.build(:comment_entity, author: alice.diaspora_id, parent_guid: parent.guid).to_h
comment_data[:created_at] = created_at
comment_data[:parent] = parent_entity
comment = described_class.new(comment_data, %i(author guid parent_guid text created_at))
parsed_comment = described_class.from_xml(comment.to_xml)

View file

@ -1,13 +1,14 @@
module DiasporaFederation
describe Entities::Conversation do
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)
Entities::Message.new(msg.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)
Entities::Message.new(msg.merge(parent: parent_entity))
}
let(:data) {
FactoryGirl.attributes_for(:conversation_entity).merge!(

View file

@ -1,13 +1,15 @@
module DiasporaFederation
describe Entities::Like do
let(:parent) { FactoryGirl.create(:post, author: bob) }
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
let(:data) {
FactoryGirl.build(
:like_entity,
author: alice.diaspora_id,
parent_guid: parent.guid,
parent_type: parent.entity_type
).send(:xml_elements)
parent_type: parent.entity_type,
parent: parent_entity
).send(:xml_elements).merge(parent: parent_entity)
}
let(:xml) {
@ -24,7 +26,7 @@ module DiasporaFederation
XML
}
it_behaves_like "an Entity subclass"
it_behaves_like "an Entity subclass", [:parent]
it_behaves_like "an XML Entity"

View file

@ -1,8 +1,10 @@
module DiasporaFederation
describe Entities::Message do
let(:parent) { FactoryGirl.create(:conversation, author: bob) }
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
let(:data) {
FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid).send(:xml_elements)
FactoryGirl.build(:message_entity, author: alice.diaspora_id, parent_guid: parent.guid, parent: parent_entity)
.send(:xml_elements).merge(parent: parent_entity)
}
let(:xml) {
@ -20,7 +22,7 @@ module DiasporaFederation
XML
}
it_behaves_like "an Entity subclass"
it_behaves_like "an Entity subclass", [:parent]
it_behaves_like "an XML Entity"

View file

@ -1,13 +1,15 @@
module DiasporaFederation
describe Entities::Participation do
let(:parent) { FactoryGirl.create(:post, author: bob) }
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
let(:data) {
FactoryGirl.build(
:participation_entity,
author: alice.diaspora_id,
parent_guid: parent.guid,
parent_type: parent.entity_type
).send(:xml_elements)
parent_type: parent.entity_type,
parent: parent_entity
).send(:xml_elements).merge(parent: parent_entity)
}
let(:xml) {
@ -23,7 +25,7 @@ module DiasporaFederation
XML
}
it_behaves_like "an Entity subclass"
it_behaves_like "an Entity subclass", [:parent]
it_behaves_like "an XML Entity"

View file

@ -1,12 +1,14 @@
module DiasporaFederation
describe Entities::PollParticipation do
let(:parent) { FactoryGirl.create(:poll, author: bob) }
let(:parent_entity) { FactoryGirl.build(:related_entity, author: bob.diaspora_id) }
let(:data) {
FactoryGirl.build(
:poll_participation_entity,
author: alice.diaspora_id,
parent_guid: parent.guid
).send(:xml_elements)
parent_guid: parent.guid,
parent: parent_entity
).send(:xml_elements).merge(parent: parent_entity)
}
let(:xml) {
@ -22,7 +24,7 @@ module DiasporaFederation
XML
}
it_behaves_like "an Entity subclass"
it_behaves_like "an Entity subclass", [:parent]
it_behaves_like "an XML Entity"

View file

@ -8,6 +8,7 @@ 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(:legacy_signature_data) { "#{guid};#{author};#{property};#{parent_guid}" }
@ -15,12 +16,14 @@ module DiasporaFederation
class SomeRelayable < Entity
LEGACY_SIGNATURE_ORDER = %i(guid author property parent_guid).freeze
PARENT_TYPE = "Parent".freeze
include Entities::Relayable
property :property
def parent_type
"Parent"
PARENT_TYPE
end
end
@ -300,6 +303,10 @@ XML
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}" }
@ -359,6 +366,10 @@ 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

View file

@ -1,10 +1,10 @@
shared_examples "an Entity subclass" do
shared_examples "an Entity subclass" do |ignored_props=[]|
it "should be an Entity" do
expect(described_class).to be < DiasporaFederation::Entity
end
it "has its properties set" do
expect(described_class.class_props.keys).to include(*data.keys)
expect(described_class.class_props.keys).to include(*(data.keys - ignored_props))
end
context "behaviour" do
@ -26,7 +26,9 @@ shared_examples "an Entity subclass" do
describe "#to_h" do
it "should resemble the input data" do
expect(instance.to_h).to eq(data)
hash = instance.to_h
ignored_props.each {|key| data.delete(key) }
expect(hash).to eq(data)
end
end
end

View file

@ -33,6 +33,14 @@ shared_examples "a relayable validator" do
let(:property) { :parent_guid }
end
end
describe "#parent" do
it_behaves_like "a property with a value validation/restriction" do
let(:property) { :parent }
let(:wrong_values) { [nil] }
let(:correct_values) { [FactoryGirl.build(:related_entity)] }
end
end
end
shared_examples "a property with a value validation/restriction" do