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
|
||||
end
|
||||
|
||||
def self.build_from_webfinger(profile, hcard)
|
||||
def self.create_from_webfinger(profile, hcard)
|
||||
return nil if profile.nil? || !profile.valid_diaspora_profile?
|
||||
new_person = Person.new
|
||||
new_person.exported_key = profile.public_key
|
||||
|
|
|
|||
|
|
@ -64,6 +64,20 @@ class Post
|
|||
user.people_in_aspects(user.aspects_with_post(self.id))
|
||||
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
|
||||
def destroy_comments
|
||||
comments.each{|c| c.destroy}
|
||||
|
|
|
|||
|
|
@ -24,15 +24,23 @@ module Diaspora
|
|||
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)
|
||||
salmon_author.save
|
||||
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)
|
||||
|
|
@ -40,27 +48,11 @@ module Diaspora
|
|||
return
|
||||
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
|
||||
object.person = person if object.respond_to? :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
|
||||
object.person = person if object.respond_to? :person=
|
||||
receive_object(object, person)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
@ -111,9 +103,7 @@ module Diaspora
|
|||
end
|
||||
|
||||
def receive_comment comment
|
||||
|
||||
commenter = comment.person
|
||||
|
||||
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}")
|
||||
return
|
||||
|
|
|
|||
|
|
@ -19,5 +19,9 @@ module Diaspora
|
|||
def subscribers(user)
|
||||
raise 'you must override subscribers in order to enable federation on this model'
|
||||
end
|
||||
|
||||
def receive(user, salmon_author)
|
||||
raise 'you must override receive in order to enable federation on this model'
|
||||
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,6 +13,7 @@ class Webfinger
|
|||
end
|
||||
|
||||
def fetch
|
||||
begin
|
||||
person = Person.by_account_identifier(@account)
|
||||
if person
|
||||
Rails.logger.info("event=webfinger status=success route=local target=#{@account}")
|
||||
|
|
@ -29,7 +30,10 @@ class Webfinger
|
|||
Rails.logger.info("event=webfinger status=failure route=remote target=#{@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
|
||||
|
||||
private
|
||||
|
|
@ -77,7 +81,7 @@ class Webfinger
|
|||
end
|
||||
|
||||
card = HCard.build hcard.body
|
||||
p = Person.build_from_webfinger(wf_profile, card)
|
||||
p = Person.create_from_webfinger(wf_profile, card)
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
|||
|
|
@ -33,30 +33,6 @@ describe Diaspora::Parser do
|
|||
proc { user.receive xml, user2.person }.should change(StatusMessage, :count).by(-1)
|
||||
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
|
||||
user.send_contact_request_to(user2.person, aspect)
|
||||
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