Implement integration tests for the federation messages receive feature
These are some initial tests, more to come. It tests some features of Request, StatusMessage, Comment, Like, Participation, Retraction, SignedRetraction, RelayableRetraction entities receive process.
This commit is contained in:
parent
08b910bd88
commit
922d26f976
7 changed files with 525 additions and 28 deletions
|
|
@ -317,6 +317,36 @@ class Person < ActiveRecord::Base
|
||||||
self
|
self
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def webfinger
|
||||||
|
DiasporaFederation::Discovery::WebFinger.new(
|
||||||
|
acct_uri: "acct:#{diaspora_handle}",
|
||||||
|
alias_url: AppConfig.url_to("/people/#{guid}"),
|
||||||
|
hcard_url: AppConfig.url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(guid)),
|
||||||
|
seed_url: AppConfig.pod_uri,
|
||||||
|
profile_url: profile_url,
|
||||||
|
atom_url: atom_url,
|
||||||
|
salmon_url: receive_url,
|
||||||
|
guid: guid,
|
||||||
|
public_key: serialized_public_key
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def hcard
|
||||||
|
DiasporaFederation::Discovery::HCard.new(
|
||||||
|
guid: guid,
|
||||||
|
nickname: username,
|
||||||
|
full_name: "#{profile.first_name} #{profile.last_name}".strip,
|
||||||
|
url: AppConfig.pod_uri,
|
||||||
|
photo_large_url: image_url,
|
||||||
|
photo_medium_url: image_url(:thumb_medium),
|
||||||
|
photo_small_url: image_url(:thumb_small),
|
||||||
|
public_key: serialized_public_key,
|
||||||
|
searchable: searchable,
|
||||||
|
first_name: profile.first_name,
|
||||||
|
last_name: profile.last_name
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
|
|
||||||
def clean_url
|
def clean_url
|
||||||
|
|
|
||||||
|
|
@ -8,38 +8,12 @@ DiasporaFederation.configure do |config|
|
||||||
config.define_callbacks do
|
config.define_callbacks do
|
||||||
on :fetch_person_for_webfinger do |handle|
|
on :fetch_person_for_webfinger do |handle|
|
||||||
person = Person.find_local_by_diaspora_handle(handle)
|
person = Person.find_local_by_diaspora_handle(handle)
|
||||||
if person
|
person.webfinger if person
|
||||||
DiasporaFederation::Discovery::WebFinger.new(
|
|
||||||
acct_uri: "acct:#{person.diaspora_handle}",
|
|
||||||
alias_url: AppConfig.url_to("/people/#{person.guid}"),
|
|
||||||
hcard_url: AppConfig.url_to(DiasporaFederation::Engine.routes.url_helpers.hcard_path(person.guid)),
|
|
||||||
seed_url: AppConfig.pod_uri,
|
|
||||||
profile_url: person.profile_url,
|
|
||||||
atom_url: person.atom_url,
|
|
||||||
salmon_url: person.receive_url,
|
|
||||||
guid: person.guid,
|
|
||||||
public_key: person.serialized_public_key
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
on :fetch_person_for_hcard do |guid|
|
on :fetch_person_for_hcard do |guid|
|
||||||
person = Person.find_local_by_guid(guid)
|
person = Person.find_local_by_guid(guid)
|
||||||
if person
|
person.hcard if person
|
||||||
DiasporaFederation::Discovery::HCard.new(
|
|
||||||
guid: person.guid,
|
|
||||||
nickname: person.username,
|
|
||||||
full_name: "#{person.profile.first_name} #{person.profile.last_name}".strip,
|
|
||||||
url: AppConfig.pod_uri,
|
|
||||||
photo_large_url: person.image_url,
|
|
||||||
photo_medium_url: person.image_url(:thumb_medium),
|
|
||||||
photo_small_url: person.image_url(:thumb_small),
|
|
||||||
public_key: person.serialized_public_key,
|
|
||||||
searchable: person.searchable,
|
|
||||||
first_name: person.profile.first_name,
|
|
||||||
last_name: person.profile.last_name
|
|
||||||
)
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
on :save_person_after_webfinger do |person|
|
on :save_person_after_webfinger do |person|
|
||||||
|
|
@ -61,5 +35,33 @@ DiasporaFederation.configure do |config|
|
||||||
|
|
||||||
person_entity.save!
|
person_entity.save!
|
||||||
end
|
end
|
||||||
|
|
||||||
|
on :fetch_private_key_by_diaspora_id do |diaspora_id|
|
||||||
|
key = Person.where(diaspora_handle: diaspora_id).joins(:owner).pluck(:serialized_private_key).first
|
||||||
|
OpenSSL::PKey::RSA.new key unless key.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
on :fetch_author_private_key_by_entity_guid do |entity_type, guid|
|
||||||
|
key = entity_type.constantize.where(guid: guid).joins(author: :owner).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_handle: diaspora_id).pluck(:serialized_public_key).first
|
||||||
|
OpenSSL::PKey::RSA.new key unless key.nil?
|
||||||
|
end
|
||||||
|
|
||||||
|
on :fetch_author_public_key_by_entity_guid do |entity_type, guid|
|
||||||
|
key = entity_type.constantize.where(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_type.constantize.where(guid: guid).joins(author: :owner).exists?
|
||||||
|
end
|
||||||
|
|
||||||
|
on :fetch_entity_author_id_by_guid do |entity_type, guid|
|
||||||
|
entity_type.constantize.where(guid: guid).joins(:author).pluck(:diaspora_handle).first
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
require "spec_helper"
|
require "spec_helper"
|
||||||
|
require "diaspora_federation/test"
|
||||||
|
|
||||||
describe "diaspora federation callbacks" do
|
describe "diaspora federation callbacks" do
|
||||||
describe ":fetch_person_for_webfinger" do
|
describe ":fetch_person_for_webfinger" do
|
||||||
|
|
@ -147,4 +148,122 @@ describe "diaspora federation callbacks" do
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def create_a_local_person
|
||||||
|
FactoryGirl.create(:user).person
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_a_remote_person
|
||||||
|
FactoryGirl.create(:person)
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_post_by_a_local_person
|
||||||
|
FactoryGirl.create(:status_message, author: create_a_local_person).guid
|
||||||
|
end
|
||||||
|
|
||||||
|
def create_post_by_a_remote_person
|
||||||
|
FactoryGirl.create(:status_message, author: create_a_remote_person).guid
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :fetch_private_key_by_diaspora_id do
|
||||||
|
it "returns a private key for a local user" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, create_a_local_person.diaspora_handle)
|
||||||
|
).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for a remote user" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, create_a_remote_person.diaspora_handle)
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for an unknown id" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, FactoryGirl.generate(:diaspora_id))
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :fetch_author_private_key_by_entity_guid do
|
||||||
|
it "returns a private key for a post by a local user" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", create_post_by_a_local_person)
|
||||||
|
).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for a post by a remote user" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", create_post_by_a_remote_person)
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for an unknown post" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", FactoryGirl.generate(:guid))
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :fetch_public_key_by_diaspora_id do
|
||||||
|
it "returns a public key for a person" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, create_a_remote_person.diaspora_handle)
|
||||||
|
).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for an unknown person" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, FactoryGirl.generate(:diaspora_id))
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :fetch_author_public_key_by_entity_guid do
|
||||||
|
it "returns a public key for a known post" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", create_post_by_a_remote_person)
|
||||||
|
).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for an unknown post" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", FactoryGirl.generate(:guid))
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :entity_author_is_local? do
|
||||||
|
it "returns true for a post by a local user" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", create_post_by_a_local_person)
|
||||||
|
).to be(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false for a post by a remote user" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", create_post_by_a_remote_person)
|
||||||
|
).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns false for a unknown post" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", FactoryGirl.generate(:diaspora_id))
|
||||||
|
).to be(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe :fetch_entity_author_id_by_guid do
|
||||||
|
it "returns id for a existing guid" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", create_post_by_a_remote_person)
|
||||||
|
).not_to be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it "returns nil for a non-existing guid" do
|
||||||
|
expect(
|
||||||
|
DiasporaFederation.callbacks.trigger(described_class, "Post", FactoryGirl.generate(:guid))
|
||||||
|
).to be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
125
spec/integration/federation/federation_messages_generation.rb
Normal file
125
spec/integration/federation/federation_messages_generation.rb
Normal file
|
|
@ -0,0 +1,125 @@
|
||||||
|
def generate_xml(entity, remote_user, user)
|
||||||
|
DiasporaFederation::Salmon::EncryptedSlap.generate_xml(
|
||||||
|
remote_user.diaspora_handle,
|
||||||
|
OpenSSL::PKey::RSA.new(remote_user.encryption_key),
|
||||||
|
entity,
|
||||||
|
OpenSSL::PKey::RSA.new(user.encryption_key)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_status_message
|
||||||
|
@entity = FactoryGirl.build(
|
||||||
|
:status_message_entity,
|
||||||
|
diaspora_id: @remote_user.diaspora_handle,
|
||||||
|
public: false
|
||||||
|
)
|
||||||
|
|
||||||
|
generate_xml(@entity, @remote_user, @user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_forged_status_message
|
||||||
|
substitute_wrong_key(@remote_user, 1)
|
||||||
|
generate_status_message
|
||||||
|
end
|
||||||
|
|
||||||
|
def mock_private_key_for_user(user)
|
||||||
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
|
.with(:fetch_private_key_by_diaspora_id, user.person.diaspora_handle)
|
||||||
|
.once
|
||||||
|
.and_return(user.encryption_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def retraction_mock_callbacks(entity, sender)
|
||||||
|
return unless [
|
||||||
|
DiasporaFederation::Entities::SignedRetraction,
|
||||||
|
DiasporaFederation::Entities::RelayableRetraction
|
||||||
|
].include?(entity.class)
|
||||||
|
|
||||||
|
mock_private_key_for_user(sender)
|
||||||
|
|
||||||
|
allow(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
|
.with(
|
||||||
|
:fetch_entity_author_id_by_guid,
|
||||||
|
entity.target_type,
|
||||||
|
entity.target_guid
|
||||||
|
)
|
||||||
|
.once
|
||||||
|
.and_return(sender.encryption_key)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_retraction(entity_name, target_object, sender=@remote_user)
|
||||||
|
@entity = FactoryGirl.build(
|
||||||
|
entity_name,
|
||||||
|
diaspora_id: sender.diaspora_handle,
|
||||||
|
target_guid: target_object.guid,
|
||||||
|
target_type: target_object.class.to_s
|
||||||
|
)
|
||||||
|
|
||||||
|
retraction_mock_callbacks(@entity, sender)
|
||||||
|
|
||||||
|
generate_xml(@entity, sender, @user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_forged_retraction(entity_name, target_object, sender=@remote_user)
|
||||||
|
times = 1
|
||||||
|
if %i(signed_retraction_entity relayable_retraction_entity).include?(entity_name)
|
||||||
|
times += 2
|
||||||
|
end
|
||||||
|
|
||||||
|
substitute_wrong_key(sender, times)
|
||||||
|
generate_retraction(entity_name, target_object, sender)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_relayable_local_parent(entity_name)
|
||||||
|
@entity = FactoryGirl.build(
|
||||||
|
entity_name,
|
||||||
|
parent_guid: @local_message.guid,
|
||||||
|
diaspora_id: @remote_user.person.diaspora_handle
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_private_key_for_user(@remote_user)
|
||||||
|
|
||||||
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
|
.with(:fetch_author_private_key_by_entity_guid, "Post", kind_of(String))
|
||||||
|
.and_return(nil)
|
||||||
|
generate_xml(@entity, @remote_user, @user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def generate_relayable_remote_parent(entity_name)
|
||||||
|
@entity = FactoryGirl.build(
|
||||||
|
entity_name,
|
||||||
|
parent_guid: @remote_message.guid,
|
||||||
|
diaspora_id: @remote_user2.person.diaspora_handle
|
||||||
|
)
|
||||||
|
|
||||||
|
mock_private_key_for_user(@remote_user2)
|
||||||
|
|
||||||
|
expect(DiasporaFederation.callbacks).to receive(:trigger)
|
||||||
|
.with(
|
||||||
|
:fetch_author_private_key_by_entity_guid,
|
||||||
|
"Post",
|
||||||
|
@remote_message.guid
|
||||||
|
)
|
||||||
|
.once
|
||||||
|
.and_return(@remote_user.encryption_key)
|
||||||
|
generate_xml(@entity, @remote_user, @user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def substitute_wrong_key(user, times_number)
|
||||||
|
expect(user).to receive(:encryption_key).exactly(times_number).times.and_return(
|
||||||
|
OpenSSL::PKey::RSA.new(1024)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks when a remote pod wants to send us a relayable without having a key for declared diaspora ID
|
||||||
|
def generate_relayable_local_parent_wrong_author_key(entity_name)
|
||||||
|
substitute_wrong_key(@remote_user, 2)
|
||||||
|
generate_relayable_local_parent(entity_name)
|
||||||
|
end
|
||||||
|
|
||||||
|
# Checks when a remote pod C wants to send us a relayable from its user, but bypassing the pod B where
|
||||||
|
# remote status came from.
|
||||||
|
def generate_relayable_remote_parent_wrong_parent_key(entity_name)
|
||||||
|
substitute_wrong_key(@remote_user, 2)
|
||||||
|
generate_relayable_remote_parent(entity_name)
|
||||||
|
end
|
||||||
146
spec/integration/federation/receive_federation_messages.rb
Normal file
146
spec/integration/federation/receive_federation_messages.rb
Normal file
|
|
@ -0,0 +1,146 @@
|
||||||
|
require "spec_helper"
|
||||||
|
require "diaspora_federation/test"
|
||||||
|
require "integration/federation/federation_messages_generation"
|
||||||
|
require "integration/federation/shared_receive_relayable"
|
||||||
|
require "integration/federation/shared_receive_retraction"
|
||||||
|
|
||||||
|
describe Workers::ReceiveEncryptedSalmon do
|
||||||
|
before do
|
||||||
|
@user = alice
|
||||||
|
allow(User).to receive(:find) { |id|
|
||||||
|
@user if id == @user.id
|
||||||
|
}
|
||||||
|
|
||||||
|
@remote_user = FactoryGirl.build(:user) # user on pod B
|
||||||
|
@remote_user2 = FactoryGirl.build(:user) # user on pod C
|
||||||
|
|
||||||
|
allow_any_instance_of(DiasporaFederation::Discovery::Discovery)
|
||||||
|
.to receive(:webfinger) {|instance|
|
||||||
|
[@remote_user, @remote_user2].find {|user| user.diaspora_handle == instance.diaspora_id }.person.webfinger
|
||||||
|
}
|
||||||
|
allow_any_instance_of(DiasporaFederation::Discovery::Discovery)
|
||||||
|
.to receive(:hcard) {|instance|
|
||||||
|
[@remote_user, @remote_user2].find {|user| user.diaspora_handle == instance.diaspora_id }.person.hcard
|
||||||
|
}
|
||||||
|
|
||||||
|
@remote_person = Person.find_or_fetch_by_identifier(@remote_user.diaspora_handle)
|
||||||
|
@remote_person2 = Person.find_or_fetch_by_identifier(@remote_user2.diaspora_handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "treats sharing request recive correctly" do
|
||||||
|
entity = FactoryGirl.build(:request_entity, recipient_id: @user.diaspora_handle)
|
||||||
|
|
||||||
|
expect(Diaspora::Fetcher::Public).to receive(:queue_for).exactly(1).times
|
||||||
|
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_xml(entity, @remote_user, @user))
|
||||||
|
|
||||||
|
expect(@user.contacts.count).to eq(2)
|
||||||
|
new_contact = @user.contacts.order(created_at: :asc).last
|
||||||
|
expect(new_contact).not_to be_nil
|
||||||
|
expect(new_contact.sharing).to eq(true)
|
||||||
|
expect(new_contact.person.diaspora_handle).to eq(@remote_user.diaspora_handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't save the status message if there is no sharing" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_status_message)
|
||||||
|
|
||||||
|
expect(StatusMessage.exists?(guid: @entity.guid)).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "with messages which require sharing" do
|
||||||
|
before do
|
||||||
|
@remote_person = Person.find_or_fetch_by_identifier(@remote_user.diaspora_handle)
|
||||||
|
contact = @user.contacts.find_or_initialize_by(person_id: @remote_person.id)
|
||||||
|
contact.sharing = true
|
||||||
|
contact.save
|
||||||
|
end
|
||||||
|
|
||||||
|
it "treats status message receive correctly" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_status_message)
|
||||||
|
|
||||||
|
expect(StatusMessage.exists?(guid: @entity.guid)).to be(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't accept status message with wrong signature" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_forged_status_message)
|
||||||
|
|
||||||
|
expect(StatusMessage.exists?(guid: @entity.guid)).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "retractions for non-relayable objects" do
|
||||||
|
%w(
|
||||||
|
retraction
|
||||||
|
signed_retraction
|
||||||
|
).each do |retraction_entity_name|
|
||||||
|
context "with #{retraction_entity_name}" do
|
||||||
|
%w(status_message photo).each do |target|
|
||||||
|
context "with #{target}" do
|
||||||
|
it_behaves_like "it retracts non-relayable object" do
|
||||||
|
let(:target_object) { FactoryGirl.create(target.to_sym, author: @remote_person) }
|
||||||
|
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "with messages which require a status to operate on" do
|
||||||
|
before do
|
||||||
|
@local_message = FactoryGirl.create(:status_message, author: @user.person)
|
||||||
|
@remote_message = FactoryGirl.create(:status_message, author: @remote_person)
|
||||||
|
end
|
||||||
|
|
||||||
|
%w(comment like participation).each do |entity|
|
||||||
|
context "with #{entity}" do
|
||||||
|
it_behaves_like "it deals correctly with a relayable" do
|
||||||
|
let(:entity_name) { "#{entity}_entity".to_sym }
|
||||||
|
let(:klass) { entity.camelize.constantize }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe "retractions for relayable objects" do
|
||||||
|
%w(
|
||||||
|
retraction
|
||||||
|
signed_retraction
|
||||||
|
relayable_retraction
|
||||||
|
).each do |retraction_entity_name|
|
||||||
|
context "with #{retraction_entity_name}" do
|
||||||
|
context "with comment" do
|
||||||
|
it_behaves_like "it retracts relayable object" do
|
||||||
|
# case for to-upstream federation
|
||||||
|
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
|
||||||
|
let(:target_object) { FactoryGirl.create(:comment, author: @remote_person, post: @local_message) }
|
||||||
|
let(:sender) { @remote_user }
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like "it retracts relayable object" do
|
||||||
|
# case for to-downsteam federation
|
||||||
|
let(:target_object) { FactoryGirl.create(:comment, author: @remote_person2, post: @remote_message) }
|
||||||
|
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
|
||||||
|
let(:sender) { @remote_user }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context "with like" do
|
||||||
|
it_behaves_like "it retracts relayable object" do
|
||||||
|
# case for to-upstream federation
|
||||||
|
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
|
||||||
|
let(:target_object) { FactoryGirl.create(:like, author: @remote_person, target: @local_message) }
|
||||||
|
let(:sender) { @remote_user }
|
||||||
|
end
|
||||||
|
|
||||||
|
it_behaves_like "it retracts relayable object" do
|
||||||
|
# case for to-downsteam federation
|
||||||
|
let(:target_object) { FactoryGirl.create(:like, author: @remote_person2, target: @remote_message) }
|
||||||
|
let(:entity_name) { "#{retraction_entity_name}_entity".to_sym }
|
||||||
|
let(:sender) { @remote_user }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
31
spec/integration/federation/shared_receive_relayable.rb
Normal file
31
spec/integration/federation/shared_receive_relayable.rb
Normal file
|
|
@ -0,0 +1,31 @@
|
||||||
|
shared_examples_for "it deals correctly with a relayable" do
|
||||||
|
it "treats upstream receive correctly" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_relayable_local_parent(entity_name))
|
||||||
|
received_entity = klass.find_by(guid: @entity.guid)
|
||||||
|
expect(received_entity).not_to be_nil
|
||||||
|
expect(received_entity.author.diaspora_handle).to eq(@remote_person.diaspora_handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "rejects an upstream entity with a malformed author signature" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(
|
||||||
|
@user.id,
|
||||||
|
generate_relayable_local_parent_wrong_author_key(entity_name)
|
||||||
|
)
|
||||||
|
expect(klass.exists?(guid: @entity.guid)).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "treats downstream receive correctly" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_relayable_remote_parent(entity_name))
|
||||||
|
received_entity = klass.find_by(guid: @entity.guid)
|
||||||
|
expect(received_entity).not_to be_nil
|
||||||
|
expect(received_entity.author.diaspora_handle).to eq(@remote_person2.diaspora_handle)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "declines downstream receive when sender signed with a wrong key" do
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(
|
||||||
|
@user.id,
|
||||||
|
generate_relayable_remote_parent_wrong_parent_key(entity_name)
|
||||||
|
)
|
||||||
|
expect(klass.exists?(guid: @entity.guid)).to be(false)
|
||||||
|
end
|
||||||
|
end
|
||||||
44
spec/integration/federation/shared_receive_retraction.rb
Normal file
44
spec/integration/federation/shared_receive_retraction.rb
Normal file
|
|
@ -0,0 +1,44 @@
|
||||||
|
shared_examples_for "it retracts non-relayable object" do
|
||||||
|
it "retracts object by a correct retraction message" do
|
||||||
|
target_klass = target_object.class.to_s.constantize
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_retraction(entity_name, target_object))
|
||||||
|
|
||||||
|
expect(target_klass.exists?(guid: target_object.guid)).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't retract object when retraction has wrong signatures" do
|
||||||
|
target_klass = target_object.class.to_s.constantize
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_forged_retraction(entity_name, target_object))
|
||||||
|
|
||||||
|
expect(target_klass.exists?(guid: target_object.guid)).to be(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't retract object when sender is different from target object" do
|
||||||
|
target_klass = target_object.class.to_s.constantize
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(
|
||||||
|
@user.id,
|
||||||
|
generate_retraction(entity_name, target_object, @remote_user2)
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(target_klass.exists?(guid: target_object.guid)).to be(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
shared_examples_for "it retracts relayable object" do
|
||||||
|
it "retracts object by a correct message" do
|
||||||
|
target_klass = target_object.class.to_s.constantize
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(@user.id, generate_retraction(entity_name, target_object, sender))
|
||||||
|
|
||||||
|
expect(target_klass.exists?(guid: target_object.guid)).to be(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "doesn't retract object when retraction has wrong signatures" do
|
||||||
|
target_klass = target_object.class.to_s.constantize
|
||||||
|
Workers::ReceiveEncryptedSalmon.new.perform(
|
||||||
|
@user.id,
|
||||||
|
generate_forged_retraction(entity_name, target_object, sender)
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(target_klass.exists?(guid: target_object.guid)).to be(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue