MS DG made receive encapsulated in an object

This commit is contained in:
maxwell 2011-01-11 11:58:30 -08:00
parent 23de681cb8
commit 25f388d903
22 changed files with 280 additions and 186 deletions

View file

@ -10,7 +10,8 @@ module Jobs
def self.perform(user_id, xml, salmon_author_id) def self.perform(user_id, xml, salmon_author_id)
user = User.find(user_id) user = User.find(user_id)
salmon_author = Person.find(salmon_author_id) salmon_author = Person.find(salmon_author_id)
user.receive(xml, salmon_author) zord = Postzord::Receiver.new(user, :person => salmon_author)
zord.parse_and_receive(xml)
end end
end end
end end

View file

@ -5,6 +5,8 @@
module Jobs module Jobs
class ReceiveLocal class ReceiveLocal
require File.join(Rails.root, 'lib/postzord/receiver')
extend ResqueJobLogging extend ResqueJobLogging
@queue = :receive_local @queue = :receive_local
def self.perform(user_id, person_id, object_type, object_id) def self.perform(user_id, person_id, object_type, object_id)
@ -12,7 +14,8 @@ module Jobs
person = Person.find(person_id) person = Person.find(person_id)
object = object_type.constantize.first(:id => object_id) object = object_type.constantize.first(:id => object_id)
user.receive_object(object, person) z = Postzord::Receiver.new(user, :person => person, :object => object)
z.receive_object
end end
end end
end end

View file

@ -3,13 +3,15 @@
# the COPYRIGHT file. # the COPYRIGHT file.
require File.join(Rails.root, 'lib/postzord/receiver')
module Jobs module Jobs
class ReceiveSalmon class ReceiveSalmon
extend ResqueJobLogging extend ResqueJobLogging
@queue = :receive_salmon @queue = :receive_salmon
def self.perform(user_id, xml) def self.perform(user_id, xml)
user = User.find(user_id) user = User.find(user_id)
user.receive_salmon(xml) zord = Postzord::Receiver.new(user, :salmon_xml => xml)
zord.perform
end end
end end
end end

View file

@ -90,6 +90,8 @@ require File.join(Rails.root, 'lib/postzord/dispatch')
def receive(user, person) def receive(user, person)
Rails.logger.info("event=receive payload_type=request sender=#{self.from} to=#{self.to}") Rails.logger.info("event=receive payload_type=request sender=#{self.from} to=#{self.to}")
user.receive_contact_request(self) user.receive_contact_request(self)
self.save
self
end end
private private

View file

@ -152,6 +152,16 @@ class User
end end
end end
def update_user_refs_and_add_to_aspects(post)
Rails.logger.debug("Saving post: #{post}")
post.user_refs += 1
post.save
aspects = self.aspects_with_person(post.person)
self.add_to_streams(post, aspects.map{|x| x.id} )
post
end
def add_to_streams(post, aspect_ids) def add_to_streams(post, aspect_ids)
self.raw_visible_posts << post self.raw_visible_posts << post
self.save self.save

View file

@ -1,11 +1,9 @@
require File.join(Rails.root, 'lib/diaspora/user/connecting') require File.join(Rails.root, 'lib/diaspora/user/connecting')
require File.join(Rails.root, 'lib/diaspora/user/querying') require File.join(Rails.root, 'lib/diaspora/user/querying')
require File.join(Rails.root, 'lib/diaspora/user/receiving')
module Diaspora module Diaspora
module UserModules module UserModules
include Connecting include Connecting
include Querying include Querying
include Receiving
end end
end end

View file

@ -44,7 +44,6 @@ module Diaspora
end end
def receive_contact_request(contact_request) def receive_contact_request(contact_request)
#response from a contact request you sent #response from a contact request you sent
if original_contact = self.contact_for(contact_request.from) if original_contact = self.contact_for(contact_request.from)
receive_request_acceptance(contact_request, original_contact) receive_request_acceptance(contact_request, original_contact)

View file

@ -1,82 +0,0 @@
require File.join(Rails.root, 'lib/webfinger')
require File.join(Rails.root, 'lib/diaspora/parser')
module Diaspora
module UserModules
module Receiving
def receive_salmon salmon_xml
salmon = Salmon::SalmonSlap.parse salmon_xml, self
webfinger = Webfinger.new(salmon.author_email)
begin
salmon_author = webfinger.fetch
rescue Exception => e
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='#{e.message}'")
end
if salmon.verified_for_key?(salmon_author.public_key)
self.receive(salmon.parsed_data, salmon_author)
else
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='not_verified for key'")
end
end
def receive xml, salmon_author
object = Diaspora::Parser.from_xml(xml)
Rails.logger.info("event=receive status=start recipient=#{self.diaspora_handle} payload_type=#{object.class} sender=#{salmon_author.diaspora_handle}")
#special casey
if object.is_a?(Request)
object.sender_handle = salmon_author.diaspora_handle
end
if object.is_a?(Comment)
xml_author = (owns?(object.post))? object.diaspora_handle : object.post.person.diaspora_handle
person = Webfinger.new(object.diaspora_handle).fetch
else
xml_author = object.diaspora_handle
person = salmon_author
end
#begin similar
unless object.is_a?(Request) || self.contact_for(salmon_author)
Rails.logger.info("event=receive status=abort reason='sender not connected to recipient' recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type=#{object.class}")
return
end
if (salmon_author.diaspora_handle != xml_author)
Rails.logger.info("event=receive status=abort reason='author in xml does not match retrieved person' payload_type=#{object.class} recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle}")
return
end
if person
Rails.logger.info("event=receive status=complete recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type#{object.class}")
object.person = person if object.respond_to? :person=
receive_object(object, person)
end
end
def receive_object(object,person)
obj = object.receive(self, person)
Notification.notify(self, object, person) unless object.is_a? Retraction
obj
end
def update_user_refs_and_add_to_aspects(post)
Rails.logger.debug("Saving post: #{post}")
post.user_refs += 1
post.save
self.raw_visible_posts << post
self.save
aspects = self.aspects_with_person(post.person)
aspects.each do |aspect|
aspect.posts << post
aspect.save
end
post.socket_to_uid(self, :aspect_ids => aspects.map{|x| x.id}) if (post.respond_to?(:socket_to_uid) && !self.owns?(post))
post
end
end
end
end

View file

@ -7,23 +7,78 @@ require File.join(Rails.root, 'lib/diaspora/parser')
module Postzord module Postzord
class Receiver class Receiver
def initialize(user, opts={})
def initialize(user, salmon_xml)
@user = user @user = user
@salmon = Salmon::SalmonSlap.parse(salmon_xml, @user) @user_person = @user.person
@salmon_author = Webfinger.new(@salmon.author_email).fetch
@salmon_xml = opts[:salmon_xml]
@sender = opts[:person] || Webfinger.new(self.salmon.author_email).fetch
@author = @sender
@object = opts[:object]
end end
def perform def perform
if @salmon_author && @salmon.verified_for_key?(@salmon_author.public_key) if @sender && self.salmon.verified_for_key?(@sender.public_key)
@object = Diaspora::Parser.from_xml(@salmon.parsed_data) parse_and_receive(salmon.parsed_data)
@object.receive
else else
Rails.logger.info("event=receive status=abort recipient=#{@user.diaspora_handle} sender=#{@salmon.author_email} reason='not_verified for key'") Rails.logger.info("event=receive status=abort recipient=#{@user.diaspora_handle} sender=#{@salmon.author_email} reason='not_verified for key'")
nil nil
end end
end end
def parse_and_receive(xml)
@object ||= Diaspora::Parser.from_xml(xml)
if self.valid_object?
receive_object
end
end
def receive_object
obj = @object.receive(@user, @author)
Notification.notify(@user, @object, @author) unless @object.is_a?(Retraction)
obj
end
def salmon
@salmon ||= Salmon::SalmonSlap.parse(@salmon_xml, @user)
end
protected protected
def valid_object?
Rails.logger.info("event=receive status=start recipient=#{@user_person.diaspora_handle} payload_type=#{@object.class} sender=#{@sender.diaspora_handle}")
#special casey
if @object.is_a?(Request)
@object.sender_handle = @sender.diaspora_handle
end
if @object.is_a?(Comment)
xml_author = (@user.owns?(@object.post))? @object.diaspora_handle : @object.post.person.diaspora_handle
@author = Webfinger.new(@object.diaspora_handle).fetch
else
xml_author = @object.diaspora_handle
end
#begin similar
unless @object.is_a?(Request) || @user.contact_for(@sender)
Rails.logger.info("event=receive status=abort reason='sender not connected to recipient' recipient=#{@user_person.diaspora_handle} sender=#{@sender.diaspora_handle} payload_type=#{@object.class}")
return false
end
if (@author.diaspora_handle != xml_author)
Rails.logger.info("event=receive status=abort reason='author in xml does not match retrieved person' payload_type=#{@object.class} recipient=#{@user_person.diaspora_handle} sender=#{@sender.diaspora_handle}")
return false
end
if @author
Rails.logger.info("event=receive status=complete recipient=#{@user_person.diaspora_handle} sender=#{@sender.diaspora_handle} payload_type#{@object.class}")
@object.person = @author if @object.respond_to? :person=
end
@object
end
end end
end end

View file

@ -13,11 +13,13 @@ describe InvitationsController do
let!(:aspect) { user.aspects.create(:name => "WIN!!") } let!(:aspect) { user.aspects.create(:name => "WIN!!") }
before do before do
request.env["devise.mapping"] = Devise.mappings[:user] request.env["devise.mapping"] = Devise.mappings[:user]
end end
describe "#create" do describe "#create" do
before do before do
user.invites = 5 user.invites = 5
sign_in :user, user sign_in :user, user
@ -89,9 +91,11 @@ describe InvitationsController do
end end
it 'adds a pending request' do it 'adds a pending request' do
put :update, @accept_params put :update, @accept_params
Request.to(invited.person).count.should == 1 Request.to(invited.person).count.should == 1
end end
end end
context 'failure' do context 'failure' do
before do before do

View file

@ -4,7 +4,7 @@
require 'spec_helper' require 'spec_helper'
describe User do describe 'a user receives a post' do
let(:user) { make_user } let(:user) { make_user }
let(:aspect) { user.aspects.create(:name => 'heroes') } let(:aspect) { user.aspects.create(:name => 'heroes') }
@ -25,7 +25,7 @@ describe User do
status = user2.post(:status_message, :message => "Users do things", :to => aspect2.id) status = user2.post(:status_message, :message => "Users do things", :to => aspect2.id)
xml = status.to_diaspora_xml xml = status.to_diaspora_xml
Diaspora::WebSocket.should_receive(:queue_to_user).exactly(:once) Diaspora::WebSocket.should_receive(:queue_to_user).exactly(:once)
user.receive xml, user2.person Postzord::Receiver.new(user, :object => status, :person => user2.person)
end end
it 'should be able to parse and store a status message from xml' do it 'should be able to parse and store a status message from xml' do
@ -35,7 +35,10 @@ describe User do
user2.delete user2.delete
status_message.destroy status_message.destroy
lambda {user.receive xml , user2.person}.should change(Post,:count).by(1) lambda {
zord = Postzord::Receiver.new(user, :person => user2.person)
zord.parse_and_receive(xml)
}.should change(Post,:count).by(1)
end end
it 'should not create new aspects on message receive' do it 'should not create new aspects on message receive' do
@ -48,19 +51,6 @@ describe User do
user.aspects.size.should == num_aspects user.aspects.size.should == num_aspects
end end
describe '#receive_salmon' do
it 'should handle the case where the webfinger fails' do
pending "Write this to test #receive_salmon"
Webfinger.stub!(:fetch).and_return(nil)
proc{
user2.post :status_message, :message => "store this!", :to => aspect2.id
}.should_not raise_error
end
end
context 'update posts' do context 'update posts' do
it 'does not update posts not marked as mutable' do it 'does not update posts not marked as mutable' do
status = user.post :status_message, :message => "store this!", :to => aspect.id status = user.post :status_message, :message => "store this!", :to => aspect.id

View file

@ -30,7 +30,11 @@ describe Diaspora::Parser do
retraction = Retraction.for(message) retraction = Retraction.for(message)
xml = retraction.to_diaspora_xml xml = retraction.to_diaspora_xml
proc { user.receive xml, user2.person }.should change(StatusMessage, :count).by(-1) proc {
zord = Postzord::Receiver.new(user, :person => user2.person)
zord.parse_and_receive(xml)
}.should change(StatusMessage, :count).by(-1)
end end
it "should activate the Person if I initiated a request to that url" do it "should activate the Person if I initiated a request to that url" do
@ -51,7 +55,10 @@ describe Diaspora::Parser do
retraction = Retraction.for(user2) retraction = Retraction.for(user2)
retraction_xml = retraction.to_diaspora_xml retraction_xml = retraction.to_diaspora_xml
lambda { user.receive retraction_xml, user2.person }.should change { lambda {
zord = Postzord::Receiver.new(user, :person => user2.person)
zord.parse_and_receive(retraction_xml)
}.should change {
aspect.reload.contacts.size }.by(-1) aspect.reload.contacts.size }.by(-1)
end end
@ -78,7 +85,8 @@ describe Diaspora::Parser do
old_profile.first_name.should == 'bob' old_profile.first_name.should == 'bob'
#Marshal profile #Marshal profile
user.receive xml, person zord = Postzord::Receiver.new(user, :person => person)
zord.parse_and_receive(xml)
#Check that marshaled profile is the same as old profile #Check that marshaled profile is the same as old profile
person = Person.first(:id => person.id) person = Person.first(:id => person.id)

View file

@ -8,64 +8,93 @@ require File.join(Rails.root, 'lib/postzord')
require File.join(Rails.root, 'lib/postzord/receiver') require File.join(Rails.root, 'lib/postzord/receiver')
describe Postzord::Receiver do describe Postzord::Receiver do
before do
@user = make_user
@user2 = make_user
@person2 = @user2.person
aspect1 = @user.aspects.create(:name => "hey")
aspect2 = @user2.aspects.create(:name => "hey")
connect_users(@user, aspect1, @user2, aspect2)
@original_post = @user2.build_post(:status_message, :message => "hey", :aspect_ids => [aspect2.id])
@salmon_xml = @user2.salmon(@original_post).xml_for(@user.person)
end
describe '.initialize' do describe '.initialize' do
it 'has @salmon_xml and an @user' do it 'valid for local' do
xml = "yeah" Webfinger.should_not_receive(:new)
user = 'faa' Salmon::SalmonSlap.should_not_receive(:parse)
zord = Postzord::Receiver.new(@user, :person => @person2, :object => @original_post)
zord.instance_variable_get(:@user).should_not be_nil
zord.instance_variable_get(:@sender).should_not be_nil
zord.instance_variable_get(:@object).should_not be_nil
end
it 'valid for remote' do
salmon_mock = mock() salmon_mock = mock()
web_mock = mock() web_mock = mock()
web_mock.should_receive(:fetch).and_return true web_mock.should_receive(:fetch).and_return true
salmon_mock.should_receive(:author_email).and_return(true) salmon_mock.should_receive(:author_email).and_return(true)
Salmon::SalmonSlap.should_receive(:parse).with(xml, user).and_return(salmon_mock) Salmon::SalmonSlap.should_receive(:parse).with(@salmon_xml, @user).and_return(salmon_mock)
Webfinger.should_receive(:new).and_return(web_mock) Webfinger.should_receive(:new).and_return(web_mock)
zord = Postzord::Receiver.new(user, xml) zord = Postzord::Receiver.new(@user, :salmon_xml => @salmon_xml)
zord.instance_variable_get(:@user).should_not be_nil zord.instance_variable_get(:@user).should_not be_nil
zord.instance_variable_get(:@salmon).should_not be_nil zord.instance_variable_get(:@sender).should_not be_nil
zord.instance_variable_get(:@salmon_author).should_not be_nil zord.instance_variable_get(:@salmon_xml).should_not be_nil
end end
end end
describe '#perform' do describe '#perform' do
before do before do
@user = make_user @zord = Postzord::Receiver.new(@user, :salmon_xml => @salmon_xml)
@user2 = make_user
@person2 = @user2.person
a = @user2.aspects.create(:name => "hey")
@original_post = @user2.build_post(:status_message, :message => "hey", :aspect_ids => [a.id])
salmon_xml = @user2.salmon(@original_post).xml_for(@user.person)
@zord = Postzord::Receiver.new(@user, salmon_xml)
@salmon = @zord.instance_variable_get(:@salmon) @salmon = @zord.instance_variable_get(:@salmon)
end end
context 'returns nil' do context 'returns nil' do
it 'if the salmon author does not exist' do it 'if the salmon author does not exist' do
@zord.instance_variable_set(:@salmon_author, nil) @zord.instance_variable_set(:@sender, nil)
@zord.perform.should be_nil @zord.perform.should be_nil
end end
it 'if the author does not match the signature' do it 'if the author does not match the signature' do
@zord.instance_variable_set(:@salmon_author, Factory(:person)) @zord.instance_variable_set(:@sender, Factory(:person))
@zord.perform.should be_nil @zord.perform.should be_nil
end end
end end
context 'returns the sent object' do context 'returns the sent object' do
it 'returns the received object on success' do it 'returns the received object on success' do
pending
object = @zord.perform object = @zord.perform
object.should respond_to(:to_diaspora_xml) object.should respond_to(:to_diaspora_xml)
end end
end end
it 'parses the salmon object' do it 'parses the salmon object' do
pending Diaspora::Parser.should_receive(:from_xml).with(@salmon.parsed_data).and_return(@original_post)
Diaspora::Parser.should_receive(:from_xml).with(@salmon.parsed_data)
@zord.perform @zord.perform
end end
end end
describe 'receive_object' do
before do
@zord = Postzord::Receiver.new(@user, :person => @person2, :object => @original_post)
@salmon = @zord.instance_variable_get(:@salmon)
end
it 'calls Notification.notify' do
Notification.should_receive(:notify)
@zord.receive_object
end
it 'calls receive on @object' do
obj = @zord.instance_variable_get(:@object).should_receive(:receive)
@zord.receive_object
end
end
end end

View file

@ -165,7 +165,8 @@ describe Comment do
aspect.post_ids.include?(@user_status.id).should be true aspect.post_ids.include?(@user_status.id).should be true
comment = Comment.new(:person_id => @person.id, :diaspora_handle => @person.diaspora_handle, :text => "cats", :post => @user_status) comment = Comment.new(:person_id => @person.id, :diaspora_handle => @person.diaspora_handle, :text => "cats", :post => @user_status)
user.receive comment.to_diaspora_xml, @person zord = Postzord::Receiver.new(user, :person => @person)
zord.parse_and_receive(comment.to_diaspora_xml)
aspect.reload aspect.reload
aspect.post_ids.include?(@user_status.id).should be true aspect.post_ids.include?(@user_status.id).should be true

View file

@ -33,7 +33,9 @@ describe Jobs::ReceiveLocal do
end end
it 'calls receive_object' do it 'calls receive_object' do
@user1.should_receive(:receive_object).with(@status, @user2.person).and_return(true) m = mock()
m.should_receive(:receive_object)
Postzord::Receiver.should_receive(:new).and_return(m)
Jobs::ReceiveLocal.perform(@user1.id, @user2.person.id, @status_type, @status.id) Jobs::ReceiveLocal.perform(@user1.id, @user2.person.id, @status_type, @status.id)
end end
end end

View file

@ -14,10 +14,10 @@ describe Jobs::ReceiveSalmon do
} }
end end
it 'calls receive_salmon' do it 'calls receive_salmon' do
@user.should_receive(:receive_salmon).with(@xml).once salmon_mock = mock()
salmon_mock.should_receive(:perform)
Postzord::Receiver.should_receive(:new).and_return(salmon_mock)
Jobs::ReceiveSalmon.perform(@user.id, @xml) Jobs::ReceiveSalmon.perform(@user.id, @xml)
end end
end end

View file

@ -13,8 +13,11 @@ describe Jobs::Receive do
end end
} }
end end
it 'calls receive' do it 'calls receive' do
@user.should_receive(:receive).with(@xml, @person).once zord_mock = mock()
zord_mock.should_receive(:parse_and_receive).with(@xml)
Postzord::Receiver.should_receive(:new).with(@user, anything).and_return(zord_mock)
Jobs::Receive.perform(@user.id, @xml, @person.id) Jobs::Receive.perform(@user.id, @xml, @person.id)
end end
end end

View file

@ -133,7 +133,7 @@ describe Photo do
id = @photo.id id = @photo.id
@photo.destroy @photo.destroy
user2.receive xml, @user.person @photo.receive(user2, @user.person)
new_photo = Photo.first(:id => id) new_photo = Photo.first(:id => id)
new_photo.url.nil?.should be false new_photo.url.nil?.should be false

View file

@ -122,6 +122,12 @@ describe Request do
@hash[:sender].serialized_public_key.should be_nil @hash[:sender].serialized_public_key.should be_nil
end end
end end
describe '#receive' do
end
describe 'xml' do describe 'xml' do
before do before do
@request = Request.new(:from => @user.person, :to => @user2.person, :into => @aspect) @request = Request.new(:from => @user.person, :to => @user2.person, :into => @aspect)

View file

@ -21,13 +21,15 @@ describe "attack vectors" do
it 'does not save a post from a non-contact' do it 'does not save a post from a non-contact' do
post_from_non_contact = bad_user.build_post( :status_message, :message => 'hi') post_from_non_contact = bad_user.build_post( :status_message, :message => 'hi')
xml = bad_user.salmon(post_from_non_contact).xml_for(user.person) salmon_xml = bad_user.salmon(post_from_non_contact).xml_for(user.person)
post_from_non_contact.delete post_from_non_contact.delete
bad_user.delete bad_user.delete
post_count = Post.count post_count = Post.count
user.receive_salmon(xml) zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
user.raw_visible_posts.include?(post_from_non_contact).should be false user.raw_visible_posts.include?(post_from_non_contact).should be false
Post.count.should == post_count Post.count.should == post_count
end end
@ -40,7 +42,11 @@ describe "attack vectors" do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
original_message.diaspora_handle = user.diaspora_handle original_message.diaspora_handle = user.diaspora_handle
user3.receive_salmon(user.salmon(original_message).xml_for(user3.person))
salmon_xml = user.salmon(original_message).xml_for(user3.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
user3.reload.visible_posts.should_not include(original_message) user3.reload.visible_posts.should_not include(original_message)
end end
@ -54,11 +60,16 @@ describe "attack vectors" do
it "does not save a message over an old message with a different author" do it "does not save a message over an old message with a different author" do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
user.receive_salmon(user2.salmon(original_message).xml_for(user.person)) salmon_xml = user2.salmon(original_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
lambda { lambda {
malicious_message = Factory.build( :status_message, :id => original_message.id, :message => 'BAD!!!', :person => user3.person) malicious_message = Factory.build( :status_message, :id => original_message.id, :message => 'BAD!!!', :person => user3.person)
user.receive_salmon(user3.salmon(malicious_message).xml_for(user.person)) salmon_xml = user3.salmon(malicious_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
}.should_not change{user.reload.raw_visible_posts.count} }.should_not change{user.reload.raw_visible_posts.count}
original_message.reload.message.should == "store this!" original_message.reload.message.should == "store this!"
@ -67,11 +78,18 @@ describe "attack vectors" do
it 'does not save a message over an old message with the same author' do it 'does not save a message over an old message with the same author' do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
salmon_xml = user2.salmon(original_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
lambda { lambda {
malicious_message = Factory.build( :status_message, :id => original_message.id, :message => 'BAD!!!', :person => user2.person) malicious_message = Factory.build( :status_message, :id => original_message.id, :message => 'BAD!!!', :person => user2.person)
user.receive_salmon(user3.salmon(malicious_message).xml_for(user.person))
salmon_xml2 = user3.salmon(malicious_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
}.should_not change{user.reload.raw_visible_posts.count} }.should_not change{user.reload.raw_visible_posts.count}
original_message.reload.message.should == "store this!" original_message.reload.message.should == "store this!"
@ -85,14 +103,22 @@ describe "attack vectors" do
user2.reload user2.reload
first_name = user2.profile.first_name first_name = user2.profile.first_name
user.receive_salmon(user3.salmon(profile).xml_for(user.person)) salmon_xml = user3.salmon(profile).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
user2.reload user2.reload
user2.profile.first_name.should == first_name user2.profile.first_name.should == first_name
end end
it "ignores retractions on a post not owned by the retraction's sender" do it "ignores retractions on a post not owned by the retraction's sender" do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
salmon_xml = user2.salmon(original_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
user.raw_visible_posts.count.should be 1 user.raw_visible_posts.count.should be 1
ret = Retraction.new ret = Retraction.new
@ -100,7 +126,10 @@ describe "attack vectors" do
ret.diaspora_handle = user3.person.diaspora_handle ret.diaspora_handle = user3.person.diaspora_handle
ret.type = original_message.class.to_s ret.type = original_message.class.to_s
user.receive_salmon(user3.salmon(ret).xml_for(user.person)) salmon_xml = user3.salmon(ret).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
StatusMessage.count.should be 1 StatusMessage.count.should be 1
user.reload.raw_visible_posts.count.should be 1 user.reload.raw_visible_posts.count.should be 1
end end
@ -117,12 +146,21 @@ describe "attack vectors" do
original_message.delete original_message.delete
StatusMessage.count.should be 0 StatusMessage.count.should be 0
proc{ user.receive_salmon(user3.salmon(ret).xml_for(user.person)) }.should_not raise_error proc {
salmon_xml = user3.salmon(ret).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
}.should_not raise_error
end end
it 'should not receive retractions where the retractor and the salmon author do not match' do it 'should not receive retractions where the retractor and the salmon author do not match' do
original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id original_message = user2.post :status_message, :message => 'store this!', :to => aspect2.id
user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
salmon_xml = user2.salmon(original_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
user.raw_visible_posts.count.should be 1 user.raw_visible_posts.count.should be 1
ret = Retraction.new ret = Retraction.new
@ -131,7 +169,11 @@ describe "attack vectors" do
ret.type = original_message.class.to_s ret.type = original_message.class.to_s
lambda { lambda {
user.receive_salmon(user3.salmon(ret).xml_for(user.person))
salmon_xml = user3.salmon(ret).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
}.should_not change(StatusMessage, :count) }.should_not change(StatusMessage, :count)
user.reload.raw_visible_posts.count.should be 1 user.reload.raw_visible_posts.count.should be 1
end end
@ -143,7 +185,11 @@ describe "attack vectors" do
ret.type = user2.person.class.to_s ret.type = user2.person.class.to_s
proc{ proc{
user.receive_salmon(user3.salmon(ret).xml_for(user.person)) salmon_xml = user3.salmon(ret).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
}.should_not change{user.reload.contacts.count} }.should_not change{user.reload.contacts.count}
end end
@ -154,19 +200,27 @@ describe "attack vectors" do
ret.type = user2.person.class.to_s ret.type = user2.person.class.to_s
proc{ proc{
user.receive_salmon(user3.salmon(ret).xml_for(user.person)) salmon_xml = user3.salmon(ret).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
}.should_not change{user.reload.contacts.count} }.should_not change{user.reload.contacts.count}
end end
it 'does not let me update other persons post' do it 'does not let me update other persons post' do
pending "this needs to be a photo" pending "this needs to be a photo"
original_message = user2.post(:photo, :user_file => uploaded_photo, :caption => "store this!", :to => aspect2.id) original_message = user2.post(:photo, :user_file => uploaded_photo, :caption => "store this!", :to => aspect2.id)
user.receive_salmon(user2.salmon(original_message).xml_for(user.person))
salmon_xml = user2.salmon(original_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
original_message.diaspora_handle = user3.diaspora_handle original_message.diaspora_handle = user3.diaspora_handle
original_message.caption = "bad bad bad" original_message.caption = "bad bad bad"
xml = user3.salmon(original_message).xml_for(user.person)
user.receive_salmon(xml) salmon_xml = user3.salmon(original_message).xml_for(user.person)
zord = Postzord::Receiver.new(user, :salmon_xml => salmon_xml)
zord.perform
original_message.reload.caption.should == "store this!" original_message.reload.caption.should == "store this!"
end end

View file

@ -58,7 +58,8 @@ describe Diaspora::UserModules::Connecting do
it 'enqueues a mail job' do it 'enqueues a mail job' do
Resque.should_receive(:enqueue).with(Jobs::MailRequestReceived, user.id, person.id) Resque.should_receive(:enqueue).with(Jobs::MailRequestReceived, user.id, person.id)
user.receive_object(@r, person) zord = Postzord::Receiver.new(user, :object => @r, :person => person)
zord.receive_object
end end
end end
@ -83,21 +84,21 @@ describe Diaspora::UserModules::Connecting do
end end
it 'enqueues a mail job' do it 'enqueues a mail job' do
Resque.should_receive(:enqueue).with(Jobs::MailRequestAcceptance, user.id, user2.person.id).once Resque.should_receive(:enqueue).with(Jobs::MailRequestAcceptance, user.id, user2.person.id).once
user.receive_object(@acceptance, user2.person) zord = Postzord::Receiver.new(user, :object => @acceptance, :person => user2.person)
zord.receive_object
end end
end end
context 'received a contact request' do context 'received a contact request' do
let(:request_for_user) {Request.instantiate(:to => user.person, :from => person)} let(:request_for_user) {Request.instantiate(:to => user.person, :from => person)}
let(:request2_for_user) {Request.instantiate(:to => user.person, :from => person_one)} let(:request2_for_user) {Request.instantiate(:to => user.person, :from => person_one)}
let(:request_from_myself) {Request.instantiate(:to => user.person, :from => user.person)} let(:request_from_myself) {Request.instantiate(:to => user.person, :from => user.person)}
before do before do
user.receive(request_for_user.to_diaspora_xml, person) Request.instantiate(:from => person, :to => user.person).save
Request.instantiate(:from => person_one, :to => user.person).save
@received_request = Request.from(person).to(user.person).first @received_request = Request.from(person).to(user.person).first
user.receive(request2_for_user.to_diaspora_xml, person_one)
@received_request2 = Request.from(person_one).to(user.person).first @received_request2 = Request.from(person_one).to(user.person).first
user.reload
end end
it "should delete an accepted contact request" do it "should delete an accepted contact request" do
@ -127,33 +128,37 @@ describe Diaspora::UserModules::Connecting do
Request.to(user2).count.should == 0 Request.to(user2).count.should == 0
user2.contacts.empty?.should be true user2.contacts.empty?.should be true
@request = Request.instantiate(:to => user.person, :from => person_one) @request1 = Request.instantiate(:to => user.person, :from => person_one)
@request_two = Request.instantiate(:to => user2.person, :from => person_one) @request2 = Request.instantiate(:to => user2.person, :from => person_one)
@request_three = Request.instantiate(:to => user2.person, :from => user.person) @request3 = Request.instantiate(:to => user2.person, :from => user.person)
@req_xml = @request.to_diaspora_xml @req1_xml = @request1.to_diaspora_xml
@req_two_xml = @request_two.to_diaspora_xml @req2_xml = @request2.to_diaspora_xml
@req_three_xml = @request_three.to_diaspora_xml @req3_xml = @request3.to_diaspora_xml
@request.destroy @request1.destroy
@request_two.destroy @request2.destroy
@request_three.destroy @request3.destroy
end end
context 'request from one remote person to one local user' do context 'request from one remote person to one local user' do
before do before do
@received_request = user2.receive @req_three_xml, user.person zord = Postzord::Receiver.new(user, :person => user.person)
@received_request = zord.parse_and_receive(@req3_xml)
@received_request.reload
end end
it 'should connect the user other user on the same pod' do it 'should connect the user other user on the same pod' do
proc { proc {
user2.accept_contact_request @received_request, aspect2 user2.accept_contact_request(@received_request, aspect2)
}.should_not change(Person, :count) }.should_not change(Person, :count)
user2.contact_for(user.person).should_not be_nil user2.contact_for(user.person).should_not be_nil
end end
it 'should not delete the ignored user on the same pod' do it 'should not delete the ignored user on the same pod' do
proc { proc {
user2.ignore_contact_request @received_request.id user2.ignore_contact_request(@received_request.id)
}.should_not change(Person, :count) }.should_not change(Person, :count)
user2.contact_for(user.person).should be_nil user2.contact_for(user.person).should be_nil
end end
@ -161,8 +166,11 @@ describe Diaspora::UserModules::Connecting do
context 'Two users receiving requests from one person' do context 'Two users receiving requests from one person' do
before do before do
@req_to_user = user.receive @req_xml, person_one zord1 = Postzord::Receiver.new(user, :person => person_one)
@req_to_user2 = user2.receive @req_two_xml, person_one zord2 = Postzord::Receiver.new(user, :person => person_one)
@req_to_user = zord1.parse_and_receive(@req1_xml)
@req_to_user2 = zord2.parse_and_receive(@req2_xml)
end end
describe '#accept_contact_request' do describe '#accept_contact_request' do
@ -203,12 +211,12 @@ describe Diaspora::UserModules::Connecting do
end end
it "keeps the right counts of contacts" do it "keeps the right counts of contacts" do
received_req = user.receive @request.to_diaspora_xml, person_one received_req = @request.receive(user, person_one)
Request.to(user).count.should == 1 Request.to(user).count.should == 1
user.reload.contacts.size.should be 0 user.reload.contacts.size.should be 0
received_req2 = user.receive @request_two.to_diaspora_xml, person_two received_req2 = @request_two.receive(user, person_two)
Request.to(user).count.should == 2 Request.to(user).count.should == 2
user.reload.contacts.size.should be 0 user.reload.contacts.size.should be 0

View file

@ -60,7 +60,8 @@ describe User do
it "queries by aspect" do it "queries by aspect" do
connect_users(user, first_aspect, user2, user2.aspects.first) connect_users(user, first_aspect, user2, user2.aspects.first)
user.receive status_message1.to_diaspora_xml, user2.person
status_message1.receive(user, user2.person)
user.visible_posts(:by_members_of => first_aspect).should =~ [status_message1] user.visible_posts(:by_members_of => first_aspect).should =~ [status_message1]
user.visible_posts(:by_members_of => second_aspect).should =~ [] user.visible_posts(:by_members_of => second_aspect).should =~ []