basic receive cleanup
This commit is contained in:
parent
6bb132b25e
commit
daab8e80ce
9 changed files with 248 additions and 63 deletions
|
|
@ -122,7 +122,7 @@ class Person
|
||||||
(person.nil? || person.remote?) ? nil : person
|
(person.nil? || person.remote?) ? nil : person
|
||||||
end
|
end
|
||||||
|
|
||||||
def self.build_from_webfinger(profile, hcard)
|
def self.create_from_webfinger(profile, hcard)
|
||||||
return nil if profile.nil? || !profile.valid_diaspora_profile?
|
return nil if profile.nil? || !profile.valid_diaspora_profile?
|
||||||
new_person = Person.new
|
new_person = Person.new
|
||||||
new_person.exported_key = profile.public_key
|
new_person.exported_key = profile.public_key
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,20 @@ class Post
|
||||||
user.people_in_aspects(user.aspects_with_post(self.id))
|
user.people_in_aspects(user.aspects_with_post(self.id))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def receive(postzord)
|
||||||
|
xml_author = object.diaspora_handle
|
||||||
|
if (postzord.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 nil
|
||||||
|
end
|
||||||
|
|
||||||
|
if postzord.user.contact_for(postzord.salmon_author)
|
||||||
|
self.person = postzord.salmon_author
|
||||||
|
#do post receive
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
protected
|
protected
|
||||||
def destroy_comments
|
def destroy_comments
|
||||||
comments.each{|c| c.destroy}
|
comments.each{|c| c.destroy}
|
||||||
|
|
|
||||||
|
|
@ -24,15 +24,23 @@ module Diaspora
|
||||||
object = Diaspora::Parser.from_xml(xml)
|
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}")
|
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)
|
if object.is_a?(Request)
|
||||||
salmon_author.save
|
salmon_author.save
|
||||||
object.sender_handle = salmon_author.diaspora_handle
|
object.sender_handle = salmon_author.diaspora_handle
|
||||||
end
|
end
|
||||||
|
|
||||||
if object.is_a?(Comment)
|
if object.is_a?(Comment)
|
||||||
xml_author = (owns?(object.post))? object.diaspora_handle : object.post.person.diaspora_handle
|
xml_author = (owns?(object.post))? object.diaspora_handle : object.post.person.diaspora_handle
|
||||||
|
person = Webfinger.new(object.diaspora_handle).fetch
|
||||||
else
|
else
|
||||||
xml_author = object.diaspora_handle
|
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
|
end
|
||||||
|
|
||||||
if (salmon_author.diaspora_handle != xml_author)
|
if (salmon_author.diaspora_handle != xml_author)
|
||||||
|
|
@ -40,27 +48,11 @@ module Diaspora
|
||||||
return
|
return
|
||||||
end
|
end
|
||||||
|
|
||||||
e = Webfinger.new(object.diaspora_handle)
|
|
||||||
|
|
||||||
begin
|
|
||||||
person = e.fetch
|
|
||||||
rescue Exception => e
|
|
||||||
Rails.logger.info("event=receive status=abort reason='#{e.message}' payload_type=#{object.class} recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle}")
|
|
||||||
return
|
|
||||||
end
|
|
||||||
|
|
||||||
if person
|
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=
|
object.person = person if object.respond_to? :person=
|
||||||
|
receive_object(object, person)
|
||||||
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
|
|
||||||
else
|
|
||||||
receive_object(object, person)
|
|
||||||
Rails.logger.info("event=receive status=complete recipient=#{self.diaspora_handle} sender=#{salmon_author.diaspora_handle} payload_type#{object.class}")
|
|
||||||
|
|
||||||
return object
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
@ -111,9 +103,7 @@ module Diaspora
|
||||||
end
|
end
|
||||||
|
|
||||||
def receive_comment comment
|
def receive_comment comment
|
||||||
|
|
||||||
commenter = comment.person
|
commenter = comment.person
|
||||||
|
|
||||||
unless comment.post.person == self.person || comment.verify_post_creator_signature
|
unless comment.post.person == self.person || comment.verify_post_creator_signature
|
||||||
Rails.logger.info("event=receive status=abort reason='comment signature not valid' recipient=#{self.diaspora_handle} sender=#{comment.post.person.diaspora_handle} payload_type=#{comment.class} post_id=#{comment.post_id}")
|
Rails.logger.info("event=receive status=abort reason='comment signature not valid' recipient=#{self.diaspora_handle} sender=#{comment.post.person.diaspora_handle} payload_type=#{comment.class} post_id=#{comment.post_id}")
|
||||||
return
|
return
|
||||||
|
|
|
||||||
|
|
@ -19,5 +19,9 @@ module Diaspora
|
||||||
def subscribers(user)
|
def subscribers(user)
|
||||||
raise 'you must override subscribers in order to enable federation on this model'
|
raise 'you must override subscribers in order to enable federation on this model'
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def receive(user, salmon_author)
|
||||||
|
raise 'you must override receive in order to enable federation on this model'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
||||||
29
lib/postzord/receiver.rb
Normal file
29
lib/postzord/receiver.rb
Normal file
|
|
@ -0,0 +1,29 @@
|
||||||
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
#
|
||||||
|
require File.join(Rails.root, 'lib/webfinger')
|
||||||
|
require File.join(Rails.root, 'lib/diaspora/parser')
|
||||||
|
|
||||||
|
module Postzord
|
||||||
|
class Receiver
|
||||||
|
|
||||||
|
def initialize(user, salmon_xml)
|
||||||
|
@user = user
|
||||||
|
@salmon = Salmon::SalmonSlap.parse(salmon_xml, @user)
|
||||||
|
@salmon_author = Webfinger.new(@salmon.author_email).fetch
|
||||||
|
end
|
||||||
|
|
||||||
|
def perform
|
||||||
|
if @salmon_author && @salmon.verified_for_key?(@salmon_author.public_key)
|
||||||
|
@object = Diaspora::Parser.from_xml(@salmon.parsed_data)
|
||||||
|
|
||||||
|
else
|
||||||
|
Rails.logger.info("event=receive status=abort recipient=#{@user.diaspora_handle} sender=#{@salmon.author_email} reason='not_verified for key'")
|
||||||
|
nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
@ -13,23 +13,27 @@ class Webfinger
|
||||||
end
|
end
|
||||||
|
|
||||||
def fetch
|
def fetch
|
||||||
person = Person.by_account_identifier(@account)
|
begin
|
||||||
if person
|
person = Person.by_account_identifier(@account)
|
||||||
Rails.logger.info("event=webfinger status=success route=local target=#{@account}")
|
if person
|
||||||
return person
|
Rails.logger.info("event=webfinger status=success route=local target=#{@account}")
|
||||||
end
|
return person
|
||||||
|
end
|
||||||
|
|
||||||
profile_url = get_xrd
|
profile_url = get_xrd
|
||||||
webfinger_profile = get_webfinger_profile(profile_url)
|
webfinger_profile = get_webfinger_profile(profile_url)
|
||||||
fingered_person = make_person_from_webfinger(webfinger_profile)
|
fingered_person = make_person_from_webfinger(webfinger_profile)
|
||||||
if fingered_person
|
if fingered_person
|
||||||
Rails.logger.info("event=webfinger status=success route=remote target=#{@account}")
|
Rails.logger.info("event=webfinger status=success route=remote target=#{@account}")
|
||||||
fingered_person
|
fingered_person
|
||||||
else
|
else
|
||||||
Rails.logger.info("event=webfinger status=failure route=remote target=#{@account}")
|
Rails.logger.info("event=webfinger status=failure route=remote target=#{@account}")
|
||||||
raise WebfingerFailedError.new(@account)
|
raise WebfingerFailedError.new(@account)
|
||||||
|
end
|
||||||
|
rescue
|
||||||
|
Rails.logger.info("event=receive status=abort recipient=#{self.diaspora_handle} sender=#{salmon.author_email} reason='#{e.message}'")
|
||||||
|
nil
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
@ -77,7 +81,7 @@ class Webfinger
|
||||||
end
|
end
|
||||||
|
|
||||||
card = HCard.build hcard.body
|
card = HCard.build hcard.body
|
||||||
p = Person.build_from_webfinger(wf_profile, card)
|
p = Person.create_from_webfinger(wf_profile, card)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -33,30 +33,6 @@ describe Diaspora::Parser do
|
||||||
proc { user.receive xml, user2.person }.should change(StatusMessage, :count).by(-1)
|
proc { user.receive xml, user2.person }.should change(StatusMessage, :count).by(-1)
|
||||||
end
|
end
|
||||||
|
|
||||||
context "connecting" do
|
|
||||||
|
|
||||||
let(:good_request) { FakeHttpRequest.new(:success)}
|
|
||||||
it "should create a new person upon getting a person request" do
|
|
||||||
remote_user = Factory.create(:user)
|
|
||||||
new_person = remote_user.person
|
|
||||||
|
|
||||||
request = Request.new(:to =>user.person, :from => new_person)
|
|
||||||
xml = remote_user.salmon(request).xml_for(user.person)
|
|
||||||
request.delete
|
|
||||||
request.from.delete
|
|
||||||
remote_user.delete
|
|
||||||
new_person.delete
|
|
||||||
|
|
||||||
Person.should_receive(:by_account_identifier).twice.and_return(new_person)
|
|
||||||
|
|
||||||
lambda {
|
|
||||||
user.receive_salmon xml
|
|
||||||
}.should change(Person, :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
|
||||||
user.send_contact_request_to(user2.person, aspect)
|
user.send_contact_request_to(user2.person, aspect)
|
||||||
request = Request.to(user2).from(user).first
|
request = Request.to(user2).from(user).first
|
||||||
|
|
|
||||||
69
spec/lib/postzord/receiver_spec.rb
Normal file
69
spec/lib/postzord/receiver_spec.rb
Normal file
|
|
@ -0,0 +1,69 @@
|
||||||
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
require File.join(Rails.root, 'lib/postzord')
|
||||||
|
require File.join(Rails.root, 'lib/postzord/receiver')
|
||||||
|
|
||||||
|
describe Postzord::Receiver do
|
||||||
|
describe '.initialize' do
|
||||||
|
it 'has @salmon_xml and an @user' do
|
||||||
|
xml = "yeah"
|
||||||
|
user = 'faa'
|
||||||
|
salmon_mock = mock()
|
||||||
|
web_mock = mock()
|
||||||
|
web_mock.should_receive(:fetch).and_return true
|
||||||
|
salmon_mock.should_receive(:author_email).and_return(true)
|
||||||
|
Salmon::SalmonSlap.should_receive(:parse).with(xml, user).and_return(salmon_mock)
|
||||||
|
Webfinger.should_receive(:new).and_return(web_mock)
|
||||||
|
|
||||||
|
zord = Postzord::Receiver.new(user, xml)
|
||||||
|
zord.instance_variable_get(:@user).should_not be_nil
|
||||||
|
zord.instance_variable_get(:@salmon).should_not be_nil
|
||||||
|
zord.instance_variable_get(:@salmon_author).should_not be_nil
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#perform' do
|
||||||
|
before do
|
||||||
|
@user = make_user
|
||||||
|
@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)
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'returns nil' do
|
||||||
|
it 'if the salmon author does not exist' do
|
||||||
|
@zord.instance_variable_set(:@salmon_author, nil)
|
||||||
|
@zord.perform.should be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'if the author does not match the signature' do
|
||||||
|
@zord.instance_variable_set(:@salmon_author, Factory(:person))
|
||||||
|
@zord.perform.should be_nil
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'returns the sent object' do
|
||||||
|
it 'returns the received object on success' do
|
||||||
|
object = @zord.perform
|
||||||
|
object.should respond_to(:to_diaspora_xml)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'parses the salmon object' do
|
||||||
|
Diaspora::Parser.should_receive(:from_xml).with(@salmon.parsed_data)
|
||||||
|
@zord.perform
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
99
spec/lib/webfinger_spec.rb
Normal file
99
spec/lib/webfinger_spec.rb
Normal file
|
|
@ -0,0 +1,99 @@
|
||||||
|
# Copyright (c) 2010, Diaspora Inc. This file is
|
||||||
|
# licensed under the Affero General Public License version 3 or later. See
|
||||||
|
# the COPYRIGHT file.
|
||||||
|
|
||||||
|
require 'spec_helper'
|
||||||
|
|
||||||
|
require File.join(Rails.root, 'lib/webfinger')
|
||||||
|
|
||||||
|
describe Webfinger do
|
||||||
|
let(:user1) { make_user }
|
||||||
|
let(:user2) { make_user }
|
||||||
|
|
||||||
|
let(:account) {"foo@tom.joindiaspora.com"}
|
||||||
|
let(:person){ Factory(:person, :diaspora_handle => account)}
|
||||||
|
let(:finger){Webfinger.new(account)}
|
||||||
|
|
||||||
|
let(:good_request) { FakeHttpRequest.new(:success)}
|
||||||
|
|
||||||
|
let(:diaspora_xrd) {File.open(File.join(Rails.root, 'spec/fixtures/host_xrd')).read}
|
||||||
|
let(:diaspora_finger) {File.open(File.join(Rails.root, 'spec/fixtures/finger_xrd')).read}
|
||||||
|
let(:hcard_xml) {File.open(File.join(Rails.root, 'spec/fixtures/hcard_response')).read}
|
||||||
|
|
||||||
|
|
||||||
|
let(:non_diaspora_xrd) {File.open(File.join(Rails.root, 'spec/fixtures/nonseed_finger_xrd')).read}
|
||||||
|
let(:non_diaspora_hcard) {File.open(File.join(Rails.root, 'spec/fixtures/evan_hcard')).read}
|
||||||
|
|
||||||
|
context 'setup' do
|
||||||
|
let(:action){ Proc.new{|person| person.inspect }}
|
||||||
|
|
||||||
|
describe '#intialize' do
|
||||||
|
it 'sets account ' do
|
||||||
|
n = Webfinger.new("mbs348@gmail.com")
|
||||||
|
n.instance_variable_get(:@account).should_not be nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should set ssl as the default' do
|
||||||
|
foo = Webfinger.new(account)
|
||||||
|
foo.instance_variable_get(:@ssl).should be true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'webfinger query chain processing' do
|
||||||
|
describe '#webfinger_profile_url' do
|
||||||
|
it 'should parse out the webfinger template' do
|
||||||
|
finger.send(:webfinger_profile_url, diaspora_xrd).should == "http://tom.joindiaspora.com/webfinger/?q=#{account}"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return nil if not an xrd' do
|
||||||
|
finger.send(:webfinger_profile_url, '<html></html>').should be nil
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should return the template for xrd' do
|
||||||
|
finger.send(:webfinger_profile_url, diaspora_xrd).should == 'http://tom.joindiaspora.com/webfinger/?q=foo@tom.joindiaspora.com'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
describe '#xrd_url' do
|
||||||
|
it 'should return canonical host-meta url for http' do
|
||||||
|
finger.instance_variable_set(:@ssl, false)
|
||||||
|
finger.send(:xrd_url).should == "http://tom.joindiaspora.com/.well-known/host-meta"
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'can return the https version' do
|
||||||
|
finger.send(:xrd_url).should == "https://tom.joindiaspora.com/.well-known/host-meta"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
context 'webfingering local people' do
|
||||||
|
it 'should return a person from the database if it matches its handle' do
|
||||||
|
person.save
|
||||||
|
finger.fetch.id.should == person.id
|
||||||
|
end
|
||||||
|
end
|
||||||
|
it 'should fetch a diaspora webfinger and make a person for them' do
|
||||||
|
diaspora_xrd.stub!(:body).and_return(diaspora_xrd)
|
||||||
|
hcard_xml.stub!(:body).and_return(hcard_xml)
|
||||||
|
diaspora_finger.stub!(:body).and_return(diaspora_finger)
|
||||||
|
RestClient.stub!(:get).and_return(diaspora_xrd, diaspora_finger, hcard_xml)
|
||||||
|
#new_person = Factory.build(:person, :diaspora_handle => "tom@tom.joindiaspora.com")
|
||||||
|
# http://tom.joindiaspora.com/.well-known/host-meta
|
||||||
|
f = Webfinger.new("tom@tom.joindiaspora.com").fetch
|
||||||
|
|
||||||
|
f.should be_valid
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'should retry with http if https fails' do
|
||||||
|
f = Webfinger.new("tom@tom.joindiaspora.com")
|
||||||
|
|
||||||
|
diaspora_xrd.stub!(:body).and_return(diaspora_xrd)
|
||||||
|
RestClient.should_receive(:get).twice.and_return(nil, diaspora_xrd)
|
||||||
|
f.should_receive(:xrd_url).twice
|
||||||
|
f.send(:get_xrd)
|
||||||
|
f.instance_variable_get(:@ssl).should == false
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
end
|
||||||
Loading…
Reference in a new issue