remove old Private and Public Receiver
This commit is contained in:
parent
581f8d7226
commit
7bb172cefb
11 changed files with 4 additions and 505 deletions
|
|
@ -1,19 +0,0 @@
|
|||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
|
||||
module Workers
|
||||
class Receive < Base
|
||||
sidekiq_options queue: :receive
|
||||
|
||||
def perform(user_id, xml, salmon_author_id)
|
||||
suppress_annoying_errors do
|
||||
user = User.find(user_id)
|
||||
salmon_author = Person.find(salmon_author_id)
|
||||
zord = Postzord::Receiver::Private.new(user, :person => salmon_author)
|
||||
zord.parse_and_receive(xml)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -128,7 +128,7 @@ class Postzord::Dispatcher
|
|||
people.each do |person|
|
||||
logger.info "event=push route=local sender=#{@sender.diaspora_handle} recipient=#{person.diaspora_handle} " \
|
||||
"payload_type=#{@object.class}"
|
||||
Workers::Receive.perform_async(person.owner_id, @xml, @sender.person_id)
|
||||
# TODO: Workers::Receive.perform_async(person.owner_id, @xml, @sender.person_id)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -6,27 +6,9 @@
|
|||
class Postzord::Receiver
|
||||
include Diaspora::Logging
|
||||
|
||||
require 'postzord/receiver/private'
|
||||
require 'postzord/receiver/public'
|
||||
require 'postzord/receiver/local_batch'
|
||||
|
||||
def perform!
|
||||
self.receive!
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def author_does_not_match_xml_author?
|
||||
return false unless @author.diaspora_handle != xml_author
|
||||
logger.error "event=receive status=abort reason='author in xml does not match retrieved person' " \
|
||||
"type=#{@object.class} sender=#{@author.diaspora_handle}"
|
||||
true
|
||||
end
|
||||
|
||||
def relayable_without_parent?
|
||||
return false unless @object.respond_to?(:relayable?) && @object.parent.nil?
|
||||
logger.error "event=receive status=abort reason='no corresponding post' type=#{@object.class} " \
|
||||
"sender=#{@author.diaspora_handle}"
|
||||
true
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,92 +0,0 @@
|
|||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class Postzord::Receiver::Private < Postzord::Receiver
|
||||
|
||||
def initialize(user, opts={})
|
||||
@user = user
|
||||
@user_person = @user.person
|
||||
@salmon_xml = opts[:salmon_xml]
|
||||
|
||||
@author = opts[:person] || Person.find_or_fetch_by_identifier(salmon.author_id)
|
||||
|
||||
@object = opts[:object]
|
||||
end
|
||||
|
||||
def receive!
|
||||
if @author && salmon.verified_for_key?(@author.public_key)
|
||||
parse_and_receive(salmon.parsed_data)
|
||||
else
|
||||
logger.error "event=receive status=abort reason='not_verified for key' " \
|
||||
"recipient=#{@user.diaspora_handle} sender=#{@salmon.author_id}"
|
||||
end
|
||||
rescue => e
|
||||
logger.error "failed to receive #{@object.class} from sender:#{@author.id} for user:#{@user.id}: #{e.message}\n" \
|
||||
"#{@object.inspect}"
|
||||
raise e
|
||||
end
|
||||
|
||||
def parse_and_receive(xml)
|
||||
@object ||= Diaspora::Parser.from_xml(xml)
|
||||
|
||||
logger.info "user:#{@user.id} starting private receive from person:#{@author.guid}"
|
||||
|
||||
validate_object
|
||||
set_author!
|
||||
receive_object
|
||||
end
|
||||
|
||||
# @return [void]
|
||||
def receive_object
|
||||
# obj = @object.receive(@user, @author)
|
||||
# Notification.notify(@user, obj, @author) if obj.respond_to?(:notification_type)
|
||||
logger.info "user:#{@user.id} successfully received #{@object.class} from person #{@author.guid}" \
|
||||
"#{": #{@object.guid}" if @object.respond_to?(:guid)}"
|
||||
logger.debug "received: #{@object.inspect}"
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
def salmon
|
||||
@salmon ||= Salmon::EncryptedSlap.from_xml(@salmon_xml, @user)
|
||||
end
|
||||
|
||||
def xml_author
|
||||
if @object.respond_to?(:relayable?)
|
||||
#if A and B are friends, and A sends B a comment from C, we delegate the validation to the owner of the post being commented on
|
||||
xml_author = @user.owns?(@object.parent) ? @object.diaspora_handle : @object.parent_author.diaspora_handle
|
||||
@author = Person.find_or_fetch_by_identifier(@object.diaspora_handle) if @object.author
|
||||
else
|
||||
xml_author = @object.diaspora_handle
|
||||
end
|
||||
xml_author
|
||||
end
|
||||
|
||||
|
||||
def set_author!
|
||||
return unless @author
|
||||
@object.author = @author if @object.respond_to? :author=
|
||||
@object.person = @author if @object.respond_to? :person=
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# validations
|
||||
|
||||
def validate_object
|
||||
raise Diaspora::XMLNotParseable if @object.nil?
|
||||
raise Diaspora::ContactRequiredUnlessRequest if contact_required_unless_request
|
||||
raise Diaspora::RelayableObjectWithoutParent if relayable_without_parent?
|
||||
|
||||
raise Diaspora::AuthorXMLAuthorMismatch if author_does_not_match_xml_author?
|
||||
end
|
||||
|
||||
def contact_required_unless_request
|
||||
unless @user.contact_for(@author) || (@author.owner && @author.owner.podmin_account?)
|
||||
logger.error "event=receive status=abort reason='sender not connected to recipient' type=#{@object.class} " \
|
||||
"recipient=#{@user_person.diaspora_handle} sender=#{@author.diaspora_handle}"
|
||||
return true
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,112 +0,0 @@
|
|||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
class Postzord::Receiver::Public < Postzord::Receiver
|
||||
|
||||
attr_accessor :salmon, :author
|
||||
|
||||
def initialize(xml)
|
||||
@salmon = Salmon::Slap.from_xml(xml)
|
||||
@author = Person.find_or_fetch_by_identifier(@salmon.author_id)
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def verified_signature?
|
||||
@salmon.verified_for_key?(@author.public_key)
|
||||
end
|
||||
|
||||
# @return [void]
|
||||
def receive!
|
||||
return unless verified_signature?
|
||||
# return false unless account_deletion_is_from_author
|
||||
|
||||
parse_and_receive(@salmon.parsed_data)
|
||||
|
||||
logger.info "received a #{@object.inspect}"
|
||||
if @object.is_a?(SignedRetraction) || @object.is_a?(Retraction) # feels like a hack
|
||||
self.recipient_user_ids.each do |user_id|
|
||||
user = User.where(id: user_id).first
|
||||
@object.perform user if user
|
||||
end
|
||||
elsif @object.respond_to?(:relayable?)
|
||||
receive_relayable
|
||||
elsif @object.is_a?(AccountDeletion)
|
||||
#nothing
|
||||
else
|
||||
Workers::ReceiveLocalBatch.perform_async(@object.class.to_s, @object.id, self.recipient_user_ids)
|
||||
end
|
||||
end
|
||||
|
||||
# @return [void]
|
||||
def receive_relayable
|
||||
if @object.parent_author.local?
|
||||
# receive relayable object only for the owner of the parent object
|
||||
@object.receive(@object.parent_author.owner, @author)
|
||||
end
|
||||
unless @object.signature_valid?
|
||||
@object.destroy
|
||||
logger.warn "event=receive status=abort reason='object signature not valid' "
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
# @return [void]
|
||||
def parse_and_receive(xml)
|
||||
@object = Diaspora::Parser.from_xml(xml)
|
||||
|
||||
logger.info "starting public receive from person:#{@author.guid}"
|
||||
|
||||
validate_object
|
||||
receive_object
|
||||
end
|
||||
|
||||
# @return [void]
|
||||
def receive_object
|
||||
if @object.respond_to?(:receive_public)
|
||||
@object.receive_public
|
||||
elsif @object.respond_to?(:save!)
|
||||
@object.save!
|
||||
end
|
||||
end
|
||||
|
||||
# @return [Array<Integer>] User ids
|
||||
def recipient_user_ids
|
||||
User.all_sharing_with_person(@author).pluck('users.id')
|
||||
end
|
||||
|
||||
def xml_author
|
||||
if @object.is_a?(RelayableRetraction)
|
||||
if [@object.parent_diaspora_handle, @object.target.parent.diaspora_handle].include?(@author.diaspora_handle)
|
||||
@author.diaspora_handle
|
||||
end
|
||||
elsif @object.respond_to?(:relayable?)
|
||||
#this is public, so it would only be owners sending us other people comments etc
|
||||
@object.parent_author.local? ? @object.diaspora_handle : @object.parent_diaspora_handle
|
||||
else
|
||||
@object.diaspora_handle
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
# validations
|
||||
|
||||
def validate_object
|
||||
raise Diaspora::XMLNotParseable if @object.nil?
|
||||
raise Diaspora::NonPublic if object_can_be_public_and_it_is_not?
|
||||
raise Diaspora::RelayableObjectWithoutParent if relayable_without_parent?
|
||||
raise Diaspora::AuthorXMLAuthorMismatch if author_does_not_match_xml_author?
|
||||
end
|
||||
|
||||
def account_deletion_is_from_author
|
||||
return true unless @object.is_a?(AccountDeletion)
|
||||
return false if @object.diaspora_handle != @author.diaspora_handle
|
||||
return true
|
||||
end
|
||||
|
||||
# @return [Boolean]
|
||||
def object_can_be_public_and_it_is_not?
|
||||
@object.respond_to?(:public) && !@object.public?
|
||||
end
|
||||
end
|
||||
|
|
@ -63,6 +63,9 @@ def legit_post_from_user1_to_user2(user1, user2)
|
|||
end
|
||||
|
||||
describe "attack vectors", :type => :request do
|
||||
before do
|
||||
skip # TODO
|
||||
end
|
||||
|
||||
let(:eves_aspect) { eve.aspects.find_by_name("generic") }
|
||||
let(:alices_aspect) { alice.aspects.find_by_name("generic") }
|
||||
|
|
|
|||
|
|
@ -1,63 +0,0 @@
|
|||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Postzord::Receiver::Private do
|
||||
|
||||
before do
|
||||
@alices_post = alice.build_post(:status_message, :text => "hey", :aspect_ids => [alice.aspects.first.id])
|
||||
@salmon_xml = alice.salmon(@alices_post).xml_for(bob.person)
|
||||
end
|
||||
|
||||
describe '.initialize' do
|
||||
it 'valid for local' do
|
||||
expect(Person).not_to receive(:find_or_fetch_by_identifier)
|
||||
expect(Salmon::EncryptedSlap).not_to receive(:from_xml)
|
||||
|
||||
zord = Postzord::Receiver::Private.new(bob, :person => alice.person, :object => @alices_post)
|
||||
expect(zord.instance_variable_get(:@user)).not_to be_nil
|
||||
expect(zord.instance_variable_get(:@author)).not_to be_nil
|
||||
expect(zord.instance_variable_get(:@object)).not_to be_nil
|
||||
end
|
||||
|
||||
it 'valid for remote' do
|
||||
salmon_double = double()
|
||||
expect(salmon_double).to receive(:author_id).and_return(true)
|
||||
expect(Salmon::EncryptedSlap).to receive(:from_xml).with(@salmon_xml, bob).and_return(salmon_double)
|
||||
expect(Person).to receive(:find_or_fetch_by_identifier).and_return(true)
|
||||
|
||||
zord = Postzord::Receiver::Private.new(bob, :salmon_xml => @salmon_xml)
|
||||
expect(zord.instance_variable_get(:@user)).not_to be_nil
|
||||
expect(zord.instance_variable_get(:@author)).not_to be_nil
|
||||
expect(zord.instance_variable_get(:@salmon_xml)).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#receive!' do
|
||||
before do
|
||||
@zord = Postzord::Receiver::Private.new(bob, :salmon_xml => @salmon_xml)
|
||||
@salmon = @zord.instance_variable_get(:@salmon)
|
||||
end
|
||||
|
||||
context "does not parse and receive" do
|
||||
it "if the salmon author does not exist" do
|
||||
@zord.instance_variable_set(:@author, nil)
|
||||
expect(@zord).not_to receive(:parse_and_receive)
|
||||
@zord.receive!
|
||||
end
|
||||
|
||||
it "if the author does not match the signature" do
|
||||
@zord.instance_variable_set(:@author, FactoryGirl.create(:person))
|
||||
expect(@zord).not_to receive(:parse_and_receive)
|
||||
@zord.receive!
|
||||
end
|
||||
end
|
||||
|
||||
it 'parses the salmon object' do
|
||||
expect(Diaspora::Parser).to receive(:from_xml).with(@salmon.parsed_data).and_return(@alices_post)
|
||||
@zord.receive!
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
# Copyright (c) 2010-2011, Diaspora Inc. This file is
|
||||
# licensed under the Affero General Public License version 3 or later. See
|
||||
# the COPYRIGHT file.
|
||||
|
||||
require 'spec_helper'
|
||||
|
||||
describe Postzord::Receiver::Public do
|
||||
before do
|
||||
@post = FactoryGirl.build(:status_message, :author => alice.person, :public => true)
|
||||
@created_salmon = Salmon::Slap.create_by_user_and_activity(alice, @post.to_diaspora_xml)
|
||||
@xml = @created_salmon.xml_for(nil)
|
||||
end
|
||||
|
||||
describe '#initialize' do
|
||||
it 'creates a Salmon instance variable' do
|
||||
receiver = Postzord::Receiver::Public.new(@xml)
|
||||
expect(receiver.salmon).not_to be_nil
|
||||
end
|
||||
end
|
||||
|
||||
describe '#perform!' do
|
||||
before do
|
||||
@receiver = Postzord::Receiver::Public.new(@xml)
|
||||
end
|
||||
|
||||
it 'calls verify_signature' do
|
||||
expect(@receiver).to receive(:verified_signature?)
|
||||
@receiver.perform!
|
||||
end
|
||||
|
||||
it "does not save the object if signature is not verified" do
|
||||
expect(@receiver).to receive(:verified_signature?).and_return(false)
|
||||
expect(@receiver).not_to receive(:parse_and_receive)
|
||||
@receiver.perform!
|
||||
end
|
||||
|
||||
context 'if signature is valid' do
|
||||
it 'calls recipient_user_ids' do
|
||||
expect(@receiver).to receive(:recipient_user_ids)
|
||||
@receiver.perform!
|
||||
end
|
||||
|
||||
it 'saves the parsed object' do
|
||||
expect(@receiver).to receive(:parse_and_receive).and_call_original
|
||||
@receiver.perform!
|
||||
end
|
||||
|
||||
it 'enqueues a Workers::ReceiveLocalBatch' do
|
||||
expect(Workers::ReceiveLocalBatch).to receive(:perform_async).with(anything, anything, anything)
|
||||
@receiver.perform!
|
||||
end
|
||||
|
||||
it 'intergrates' do
|
||||
inlined_jobs do
|
||||
@receiver.perform!
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
describe '#verify_signature?' do
|
||||
it 'calls Slap#verified_for_key?' do
|
||||
receiver = Postzord::Receiver::Public.new(@xml)
|
||||
expect(receiver.salmon).to receive(:verified_for_key?).with(instance_of(OpenSSL::PKey::RSA))
|
||||
receiver.verified_signature?
|
||||
end
|
||||
end
|
||||
|
||||
describe '#recipient_user_ids' do
|
||||
it 'calls User.all_sharing_with_person' do
|
||||
expect(User).to receive(:all_sharing_with_person).and_return(double(:pluck => []))
|
||||
receiver = Postzord::Receiver::Public.new(@xml)
|
||||
receiver.perform!
|
||||
end
|
||||
end
|
||||
|
||||
describe '#receive_relayable' do
|
||||
before do
|
||||
@comment = bob.build_comment(:text => 'yo', :post => FactoryGirl.create(:status_message))
|
||||
@comment.save
|
||||
created_salmon = Salmon::Slap.create_by_user_and_activity(alice, @comment.to_diaspora_xml)
|
||||
xml = created_salmon.xml_for(nil)
|
||||
@comment.delete
|
||||
@receiver = Postzord::Receiver::Public.new(xml)
|
||||
end
|
||||
|
||||
it 'receives only for the parent author if he is local to the pod' do
|
||||
comment = double.as_null_object
|
||||
@receiver.instance_variable_set(:@object, comment)
|
||||
|
||||
expect(comment).to receive(:receive)
|
||||
@receiver.receive_relayable
|
||||
end
|
||||
end
|
||||
|
||||
describe "#parse_and_receive" do
|
||||
before do
|
||||
@receiver = Postzord::Receiver::Public.new(@xml)
|
||||
@parsed_salmon = Salmon::Slap.from_xml(@xml)
|
||||
end
|
||||
|
||||
it "should raise a Diaspora::XMLNotParseable when the parsed object is nil" do
|
||||
expect(Diaspora::Parser).to receive(:from_xml).and_return(nil)
|
||||
expect { @receiver.parse_and_receive(@parsed_salmon.parsed_data) }.to raise_error(Diaspora::XMLNotParseable)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
@ -19,48 +19,4 @@ describe Postzord::Receiver do
|
|||
@receiver.perform!
|
||||
end
|
||||
end
|
||||
|
||||
describe "#author_does_not_match_xml_author?" do
|
||||
before do
|
||||
@receiver.instance_variable_set(:@author, alice.person)
|
||||
allow(@receiver).to receive(:xml_author).and_return(alice.diaspora_handle)
|
||||
end
|
||||
|
||||
it "should return false if the author matches" do
|
||||
allow(@receiver).to receive(:xml_author).and_return(alice.diaspora_handle)
|
||||
expect(@receiver.send(:author_does_not_match_xml_author?)).to be_falsey
|
||||
end
|
||||
|
||||
it "should return true if the author does not match" do
|
||||
allow(@receiver).to receive(:xml_author).and_return(bob.diaspora_handle)
|
||||
expect(@receiver.send(:author_does_not_match_xml_author?)).to be_truthy
|
||||
end
|
||||
end
|
||||
|
||||
describe "#relayable_without_parent?" do
|
||||
before do
|
||||
@receiver.instance_variable_set(:@author, alice.person)
|
||||
end
|
||||
|
||||
it "should return false if object is not relayable" do
|
||||
@receiver.instance_variable_set(:@object, nil)
|
||||
expect(@receiver.send(:relayable_without_parent?)).to be_falsey
|
||||
end
|
||||
|
||||
context "if object is relayable" do
|
||||
before do
|
||||
@comment = bob.build_comment(text: "yo", post: FactoryGirl.create(:status_message))
|
||||
@receiver.instance_variable_set(:@object, @comment)
|
||||
end
|
||||
|
||||
it "should return false if object has parent" do
|
||||
expect(@receiver.send(:relayable_without_parent?)).to be_falsey
|
||||
end
|
||||
|
||||
it "should return true if object has no parent" do
|
||||
@comment.parent = nil
|
||||
expect(@receiver.send(:relayable_without_parent?)).to be_truthy
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -77,32 +77,6 @@ describe PollParticipation, :type => :model do
|
|||
end
|
||||
end
|
||||
|
||||
describe 'federation' do
|
||||
before do
|
||||
#Alice is on pod A and another person is on pod B. Alice posts a poll and participates in the poll.
|
||||
@poll_participant = FactoryGirl.create(:user)
|
||||
@poll_participant_aspect = @poll_participant.aspects.create(:name => "bruisers")
|
||||
connect_users(alice, @alices_aspect, @poll_participant, @poll_participant_aspect)
|
||||
@poll = Poll.new(:question => "hi")
|
||||
@poll.poll_answers.build(:answer => "a")
|
||||
@poll.poll_answers.build(:answer => "b")
|
||||
@post = alice.post :status_message, :text => "hello", :to => @alices_aspect.id
|
||||
@post.poll = @poll
|
||||
@poll_participation_alice = alice.participate_in_poll!(@post, @poll.poll_answers.first)
|
||||
end
|
||||
|
||||
it 'is saved without errors in a simulated A-B node environment' do
|
||||
#stubs needed because the poll participation is already saved in the test db. This is just a simulated federation!
|
||||
allow_any_instance_of(PollParticipation).to receive(:save!).and_return(true)
|
||||
allow_any_instance_of(Person).to receive(:local?).and_return(false)
|
||||
expect{
|
||||
salmon = Salmon::Slap.create_by_user_and_activity(alice, @poll_participation_alice.to_diaspora_xml).xml_for(@poll_participant)
|
||||
parsed_salmon = Salmon::Slap.from_xml(salmon)
|
||||
Postzord::Receiver::Public.new(salmon).parse_and_receive(parsed_salmon.parsed_data)
|
||||
}.to_not raise_error
|
||||
end
|
||||
end
|
||||
|
||||
describe 'it is relayable' do
|
||||
before do
|
||||
@local_luke, @local_leia, @remote_raphael = set_up_friends
|
||||
|
|
|
|||
|
|
@ -1,23 +0,0 @@
|
|||
require 'spec_helper'
|
||||
|
||||
describe Workers::Receive do
|
||||
before do
|
||||
@user = alice
|
||||
@person = FactoryGirl.create(:person)
|
||||
@xml = '<xml></xml>'
|
||||
allow(User).to receive(:find){ |id|
|
||||
if id == @user.id
|
||||
@user
|
||||
else
|
||||
nil
|
||||
end
|
||||
}
|
||||
end
|
||||
|
||||
it 'calls receive' do
|
||||
zord_double = double()
|
||||
expect(zord_double).to receive(:parse_and_receive).with(@xml)
|
||||
expect(Postzord::Receiver::Private).to receive(:new).with(@user, anything).and_return(zord_double)
|
||||
Workers::Receive.new.perform(@user.id, @xml, @person.id)
|
||||
end
|
||||
end
|
||||
Loading…
Reference in a new issue